[addon multiplefileupload] MultipleFileUpload – form control
- Honza Kuchař
- Člen | 1662
Pokus se vymazat obsah metody cleanup, pak se ti nebudou z databáze vymazávat nepotřebné řádky a můžeš zjistit, co se tam děje.
P.S.: Na hostingu je asi SQLite3
- Honza Kuchař
- Člen | 1662
Dnes se na SVN objevila nová revize s pořadovým číslem 61. Je to poměrně velký balík změn, takže prosím o řádné otestování a bugfixy. Jde o dlouho slibovanou podporu pro více interfaců, takže se nyní jako interface dá přidat do MFU i swfupload, či cokoli jeného. A také přibyla podpora pro fallback. Pod každý uploaderem je odkaz. Po kliknutí se provede fallback o úroveň níže. V distribuci jsou v současné době k dispozici dva interfacy:
- Uploadify
- HTML4SingleUpload
Dokumentaci dopíšu v co nejkratším čase. Nejspíš ji rozdělím na více stránek, protože už se ta stránka příšerně rozrostla.
Co znamená interface v prostředí MultipleFileUploaderu?
Je to balíček několika funkcí a šablon, který má za úkol zobrazit interface klientovi a načíst data, která vygeneroval na klientské části. Tyto data předá modelu (driveru). O zbytek se stará MultipleFileUpload.
Interfacy se dají registrovat v booststrapu následujícím způsobem:
MultipleFileUpload::getUIRegistrator()
->clear()
->register("MFUUIHTML4SingleUpload")
->register("MFUUIUploadify");
Jak vypadá třída interface?
class nazevInterfacu extends MFUUIBase /* musí implementovat MFUUIInterface */ {
/**
* Is this upload your upload? (upload from this interface)
*/
public function isThisYourUpload() {
return true nebo false;
/* tato metoda se volá před zavoláním metody handleUploads a slouží k identifikaci, zda právě probíhající upload proběhl z tohoto interface. Doporučuji klientské části zařadit do nějakého paramateru název interface, pro zaručené rozpoznání. */
}
/**
* Handles uploaded files
* forwards it to model
*/
public function handleUploads() {
// Načti surová data a předej je modelu.
// return true způsobí, že se už nebude volat handleUploads od žádného dalšího interface.
return true; // Skip all next interfaces
}
/**
* Renders interface to <div>
*/
public function render(MultipleFileUpload $upload) {
/* Vygeneruje HTML interface */
$template = $this->createTemplate(dirname(__FILE__)."/html.phtml");
$template->mfu = $upload;
return $template->__toString(TRUE);
}
/**
* Renders JavaScript body of function.
*/
public function renderInitJavaScript(MultipleFileUpload $upload) {
/* Vygeneruje JavaScript, který se spustí při inicializaci interface */
return $this->createTemplate(dirname(__FILE__)."/initJS.js")->__toString(TRUE);
}
/**
* Renders JavaScript body of function.
*/
public function renderDestructJavaScript(MultipleFileUpload $upload) {
/* Vygeneruje JavaScript, který se spustí při destrukci interface */
return true;
}
/* U obou těchto funkcí se na straně klienta kontroluje návratová hodnota, která musí být true, jinak nepoběhne fallback na další interface. Obě funkce jsou volány ve scope MFUFallbackControlleru, z něj si můžete jednoduše vytáhnout DOM provek přes jeho proměnou rootEl. */
}
MFU na straně klienta – fallbacky
Na straně klienta sedí třída, která se ovládá velmi jednoduše. Najdu
se v DOMu objekt, který má ID, které vrací
FormControl::getHtmlId()
. (většinou něco jako
frmNázevFormuláře-názevPolíčka) V něm se ukrývá proměná
fallbackCntrl ve které se skrývá instance třídy MFUFallbackController
(JavaScript). Ta má několik metod z nich nejdůležitější
následující:
fallback – ta přehodí interface o jeden níže.
Vyzkoušet si to možete na příkladu na serveru, když si do své konzole
FireBugu (či něčeho obdobného) zadáte
document.getElementById("frmform-upload").fallbackCntrl.fallback();
skočí MFU o jeden interface dolů, tedy na HTML4 upload a protože už není k dispozici další fallback zmizí automaticky i odkaz na fallback.
- Honza Kuchař
- Člen | 1662
Takže v této chvíli počítám, za jak dlouho se objeví balíčky na plupload a swfupload. Vzhledem k tomu, že kód už je tady na fóru, bude to práce jistě na chvíli.
- Honza Kuchař
- Člen | 1662
Dnes byla vydána revize 69, byl změněn způsob registrace queues modelu. (modelu, který ukládá data) Prosím změňte způsob registrace v bootstrapu na
MultipleFileUpload::setQueuesModel(new MFUQueuesDibi());
proměnná queuesModel je nyní protected. Je to kvůli internímu lazy loadingu, díky kterému se nyní při použití alternativního driveru nenatahuje i SQLite model. Žádný jiný vliv na funkčnost by tato zněmna neměla mít.
- Honza Kuchař
- Člen | 1662
Interface zařazeny do dokumentace: https://componette.org/search/?…
A vyšel článek/tutoriál, jak vytvořil vlastní interface: https://componette.org/search/?…
- Manny7
- Člen | 67
Ahoj,
používám verzi MFU na PHP 5.3 a vše mi jde v pohodě. Když si chci ale
upravit uploadify tak, aby mi ihned po vybrání souboru ten soubor začalo
kopírovat, nastane chyba – v logu mám následující:
PHP Warning: SQLiteDatabase::query(): database schema has changed in C:\xampp\htdocs\upload\app\controls\MultipleFileUpload\Models\SQLite\MFUQueuesSQLite.php on line 56
PHP Warning: SQLiteDatabase::query(): cannot commit - no transaction is active in C:\xampp\htdocs\upload\app\controls\MultipleFileUpload\Models\SQLite\MFUQueuesSQLite.php on line 56
PHP Fatal error: Uncaught exception 'InvalidStateException' with message 'Can't execute queury: 'END TRANSACTION'. error: cannot commit - no transaction is active' in C:\xampp\htdocs\upload\app\controls\MultipleFileUpload\Models\SQLite\MFUQueuesSQLite.php:58
Používám Xampp s PHP ve verzi 5.3. Z hlášky vidím, že je problém s SQLite, ale nevím, jak jej doinstalovat.. ale taky mi vrtá hlavou, jaktože se při pouhé změně způsobu odeslání souboru vynořila tahle hláška a při běžném odeslání přes SUBMIT to šlo v pohodě… Děkuji za případné objasnění
- Honza Kuchař
- Člen | 1662
Netuším, budeš muset debugovat. Ale žádné racionální vysvětlení k tomu nemám.
//EDIT: Ta hláška mi něco říká… Tuším je to nějaká chyba PHP + SQLite. Zkus hledat.
Editoval Honza Kuchař (15. 8. 2010 23:09)
- Honza Kuchař
- Člen | 1662
Smůla, tu tvoji verzi jsem netestoval, ale když vezmu nejnovější revizi, a nastavím auto: true, tak všechno funguje. Bude potřeba samozřejmě upravit GUI.
- Honza Kuchař
- Člen | 1662
Ale stejně si myslím, že to není moc user-friendly, on jen vybere soubory a ty už mu je stahuješ z počítače. Já si před odesláním formuláře ty data kontroluji. Pokud už by to bylo odeslané, nešlo by to.
- Vyki
- Člen | 388
Zdravím, mám už téměř hotový interface pro swf upload, podívat a otestovat můžete zde: http://mfu.rovy.cz/document_root. Dolaďuji ještě pár věcí takže ke stažení to sem dám do dvou dnů.
- Honza Kuchař
- Člen | 1662
Tak to jsi mi udělal velikou radost. Protože vidět, že ta práce nebyla k ničemu je opravdu potešující. ;)
A samozřejmě jménem komunity Nette, komunity MFU a mým jménem Ti děkuji za spolupráci!
- Vyki
- Člen | 388
MFUUISwfupload
je nový interface pro MFU. Základní informace o SWF Uploadu neleznete na zde. Swfupload není narozdíl od uploadify postavený na jQuery, ale pro implementaci do MFU jsem použil SWFUpload jQuery plugin. Výhodu je že se instance SWFU asociuje s DOM elementem díky čemuž můžeme používat tento plugin tak jak jsme zvyklí např. z uploadify.
Javascript
Největsí výhodou SWFU jsou JS callbacky, kde se dá ovlivnit chování
celého pluginu – ty najdete v souboru handlers.js
.
V ukázkové verzi jsem použil standartní callbacky z oficiálních examples
swfu. Jsou však přepsány pro použití s jQuery.
PHP Interface
Na straně serveru je interface hodně podobný MFUUIUploadify. Až na šablony se jednalo spíše o kosmetické úpravy.
Možnosti
Oproti první verzi, kterou jsem zde publikoval před více jak měsícem, upload v této verzi se odesílá opravdu až po stisknutí tlačítka odeslat.
Testováno
IE 8, IE 6, FF 3.6.8, CHROME 5.0.375.127 – vše OK
Pokud narazíte na nějaký problém tak to sem napište ať to můžeme opravit. Jinak nejsem příliš kovaný v JS tak pokud narazíte na nějakou zbytečně složitou konstrukci tak budu jedině rád, když přijdete s vylepšením.
Download
- Ukázka zde: http://mfu.rovy.cz/document_root/
- Je součástí distribuce: stahujte ze SVN
Editoval Vyki (24. 8. 2010 23:19)
- Honza Kuchař
- Člen | 1662
Jsem teď mimo pracoviště, tedy zatím to dokumentace nepřidám. Více uploaderů v jednom formuláři by nemělo dělat problém, dokonce jsem to tak i jednou používat a fungovalo to. To bude nejspíš někde nějaký překlep. (můj)
- Honza Kuchař
- Člen | 1662
Náš to v distribici. Prosím veškteré změny, které budš chtít provést v pluginu, mi posílej na mail již s novou adresářovou strukturou, která je teď v distribuci. Děkuji moc za spolupráci!
- Lopo
- Člen | 277
narazil som na webe na http://www.shift8creative.com/…r/index.html – ak by to pomohlo pri dalsom vyvoji aspon nejakou inspiraciou
- Vyki
- Člen | 388
Lopo napsal(a):
narazil som na webe na http://www.shift8creative.com/…r/index.html – ak by to pomohlo pri dalsom vyvoji aspon nejakou inspiraciou
Nepřišel jsem v demu na to jak vybrat více adresářů najednou (na jedno otevření průzkumníka). Zdá se, že to dialogové okno to neumožňuje. Nezdá se mi to jako žhavý kandidát pro přidání interfacu. Plupload by byl určitě větší výzva :o)
- Honza Kuchař
- Člen | 1662
- Bernard Williams
- Člen | 207
Nazdárek,
právě jsem testuji MFU a přišel jsem na jednu věc, co není nejspíš ošetřená. Pokud používám ne-HTML4 form, tak mi při výběru velkého souboru (přesahujícího hodnotu upload_max_filesize) vyskočí JS okno, že tento soubor bude ignorován – to je ok. Pokud použiji HTML4 form, tak na mě už žádné JS okno nevyskočí. Form se tváří, jakoby se vše odeslalo v pořádku, ale přijde mi jen potvrzující hláška o všech ostatních souborech – daný velký soubor to úplně přeskočilo a přeskočilo to taky případné ošetření v onSubmit(). Uživatel pak může přehlédnout, že tento soubor to nenahrálo, protože se mu neobjevila žádná chybová hláška. Jak tuhle situaci řešíte? Dá se to JS v HTML4 zapnout nebo ho donutit, aby se dostal až na PHP validaci?
Děkuji
Bernard
- Honza Kuchař
- Člen | 1662
To omezení se nastavuje z omezení PHPka. Tedy nic s tím neudělám. Ale informační hlášku by to chtělo. Že bychom tam přidali nějaký callback, který by udělal flash-message?
- Bernard Williams
- Člen | 207
Jasný, nejde mi taky o to omezení z PHP. Jde o to, že uživatel není nijak informován, že je ten soubor příliš velký. Nějaká flash message popř. potlačení toho skipnutí, aby si to mohl člověk ošetřit sám, by bylo super.
- Honza Kuchař
- Člen | 1662
hmmm, asi vím o čem mluvíš. Tak to je spíše bug. Pokusím se to opravit (ale ne hned).
- Ofi
- Člen | 13
jak se to udělá abych měl pod tím tlačítkem „Nejdou vám soubory nahrát? Klikněte zde.“ ? díky
a ještě něco: když mám v tom formuláři další pole, která mají nějaké podmínky.. uživatel je nesplní, vyskočí alert, ale po odkliknutí se obrázky začnou uploadovat a stránka se přeměruje.. nedá se to nějak udělat aby to toto nedělalo!?
Editoval Ofi (9. 9. 2010 14:04)
- Honza Kuchař
- Člen | 1662
Stačí stáhnout nejnovější revizi a mít načtené alespoň dva interfaces. (výchozí stav)
- Honza Kuchař
- Člen | 1662
To bude asi nějaký bug v klientské části MFU, pokud chcete rychlé řešení, debugujte a potom se o řešení podělte zde na fóru. Já se k tomu dostanu až poměrně za dlouho. (měsíc až půl roku)
- Vyki
- Člen | 388
Ofi napsal(a):
a ještě něco: když mám v tom formuláři další pole, která mají nějaké podmínky.. uživatel je nesplní, vyskočí alert, ale po odkliknutí se obrázky začnou uploadovat a stránka se přeměruje.. nedá se to nějak udělat aby to toto nedělalo!?
Nevím, ale osobně ve formuláři, který není jenom pro upload samotný mám dvě tlačítka. To, které submituje upload, form nevaliduje:
<?php
$form->addSubmit('savefile', 'Nahrát přílohy')
->setValidationScope(FALSE)
->onClick[] = callback($this, 'savefileClicked');
[...]
public function savefileClicked(SubmitButton $button){
}
?>
.. a pak druhé, které form validuje, to kterým se odešle celý form a při úspěchu dojte k přesměrování.
- Ofi
- Člen | 13
Vyki napsal(a):
Nevím, ale osobně ve formuláři, který není jenom pro upload samotný mám dvě tlačítka. To, které submituje upload, form nevaliduje
nj, jenže já potřebuju, aby se fotky nahrály jen v případě jsou-li data v pořádku, tedy připraveny pro uložení do databáze.
Honza Kuchař napsal(a):
To bude asi nějaký bug v klientské části MFU, pokud chcete rychlé řešení, debugujte a potom se o řešení podělte zde na fóru. Já se k tomu dostanu až poměrně za dlouho. (měsíc až půl roku)
můžu zkusit, ale v debugování nejsem zrovna zdatný, pochybuji, že něco objevím ;)
- Honza Kuchař
- Člen | 1662
Konečná verze není, proto je to na SVN. Ale poradím ti:
- vytvoř nějakou složku u sebe na PC
- na ni klikni pravým tlačítkem a dej Checkout (případně TortoiseSVN->checkout)
- zadej adresu SVN repozitáře, kterou najdeš na stránce s dokumentací doplňku
- OK
- čekej
- Máš to stažené
- OK = zavřít
- masterr
- Začátečník | 141
Multiplefileupload se mi nezobrazi v ty flash forme, kde lze vybrat vice
souborů, jen pouze 5 file inputů.
Nevíš čím to může být? Zkoušeno ve FF a Opeře.
Nemám v bootstrap.php robot loader, jinak vše mám podle "":https://componette.org/search/?… .
- masterr
- Začátečník | 141
<?php
/**
* My Application bootstrap file.
*/
// Step 1: Load Nette Framework
// this allows load Nette Framework classes automatically so that
// you don't have to litter your code with 'require' statements
require LIBS_DIR . '/Nette/loader.php';
// Step 2: Configure environment
// 2a) enable Nette\Debug for better exception and error visualisation
// 2b) load configuration from config.ini file
Environment::loadConfig();
//...
$application = Environment::getApplication();
$application->catchExceptions = FALSE;
// Step 3: Configure application
// 3a) get and setup a front controller
$application = Environment::getApplication();
$application->errorPresenter = 'Error';
//$application->catchExceptions = TRUE;
dibi::connect(Environment::getConfig('database'));
MultipleFileUpload::register();
MultipleFileUpload::getUIRegistrator()
->clear()
->register("MFUUIHTML4SingleUpload")
->register("MFUUIUploadify");
// Custom file validation function:
function validateMFUFile(HttpUploadedFile $file) {
return $file->isOk();
}
MultipleFileUpload::$validateFileCallback = callback("validateMFUFile");
// Step 4: Setup application router
$router = $application->getRouter();
// mod_rewrite detection
if (function_exists('apache_get_modules') && in_array('mod_rewrite', apache_get_modules())) {
$router[] = new Route('index.php', array(
'module' => 'Front',
'presenter' => 'Default',
), Route::ONE_WAY);
$router[] = new Route('<presenter>/<action>/<id>', array(
'presenter' => 'Front:Default',
'action' => 'default',
'id' => NULL,
));
} else {
$router[] = new SimpleRouter('Front:Default:default');
}
Debug::enable(Debug::DEVELOPMENT);
Environment::setMode(Environment::DEVELOPMENT);
Debug::$strictMode = TRUE;
// Step 5: Run the application!
$application->run();
Všechny soubory jsem tam překopíroval. Proč to nejede?
- Honza Kuchař
- Člen | 1662
O problému v IE7 vůbec nevím… A ani nemám možnost to otestovat. Všude už je IE8 či IE9 Beta.
- Vyki
- Člen | 388
Honza Kuchař napsal(a):
O problému v IE7 vůbec nevím… A ani nemám možnost to otestovat. Všude už je IE8 či IE9 Beta.
Já se taky divil. Zjistila to jedna dáma při správě profilu svého obchodu na stránkách, které které spravuju. Mám sedmičky s XP modem, kde jsem zapnul IE6 a bylo to v pohodě. Potom jsem IE6 upgradoval na IE7 a nestačil jsem se divit, SWF uploader nikde.
Editoval Vyki (1. 10. 2010 10:46)
- xpitris
- Člen | 9
Snazim se o ukladani souboru do databaze MySQL pomoci dibi, ale mam problem s touto Exception:
InvalidStateException: Queues model is not set!
definice v bootstrap.php
dibi::connect(Environment::getConfig('database'));
MultipleFileUpload::register();
MultipleFileUpload::getUIRegistrator()
->clear()
->register('MFUUISwfupload');
MultipleFileUpload::setQueuesModel(new MFUQueuesDibi());
Zajimave je, ze pokud dam
\Nette\Debug::barDump($this->queuesModel);
v metodach
setQueuesModel
a getQueuesModel
v tride
BaseQueueModel.php
, tak mi to pri ukladani do DB ukaze nekolikere
volani techto metod, pricemz pouze v jednom pripade vraci
getQueuesModel
null (to vyhodi vyse uvedenou vyjimku), v ostatnich
pripadech je queuesModel
naplneny.
Pouzivam posledni verzi MFU z trunku, PHP 5.3.3 a Nette 2.0 dev.
DB driver mam mysqli.
Nema nekdo tuseni proc se tohle deje?
- Honza Kuchař
- Člen | 1662
To je opravdu zváštní… Ještě se mi to nestalo. Takže bych to tipoval na Nette 2.0-dev nebo bych zkusil přehodit pořadí
MultipleFileUpload::setQueuesModel(new MFUQueuesDibi());
MultipleFileUpload::getUIRegistrator()
->clear()
->register('MFUUISwfupload');
MultipleFileUpload::register();
Ale možná to nehraje roli, moc si nepamatuji, jestli to může mít nějaký vliv. Spíše asi ne, ale je to první co mě napadlo.