MultipleFileUpload
MultipleFileUpload (zkráceně MFU) je doplněk pro Nette Framework, který vašim uživatelům umožní pohodlně, jednoduše a interaktivně odesílat hromady souborů. Komfort nabízí nejen uživateli, ale i programátorovi. Uživatel může na pár kliknutí odeslat celé fotoalbum a programátorovi stačí na implementaci tohoto doplňku pouhé 2 řádky kódu. Navíc tento doplněk podporuje AJAX pro maximální rychlost a uživatelské pohodlí! I na uživatele se staršími prohlížeči se myslelo. Pokud prohlížeč nesplňuje minimální požadavky, uživatel může odeslat soubory standardním způsobem.
| Autor doplňku | Honza Kuchař |
|---|---|
| Autor driver(ů) | Honza Kuchař (sqlite a log driver), Martin Sadový (dibi driver) |
| Autor interface(ů) | Honza Kuchař (HTML4SingleUpload, Plupload, Uploadify), Roman Vykuka (SWFUpload) |
| Inspirováno | http://forum.nette.org/…iewtopic.php?… |
| Licence | New BSD License |
| Diskuse | http://forum.nette.org/…form-control |
| Demo | http://multiplefileupload.projekty.mujserver.net/ |
| Stav | Stabilní. Nicméně pár problémů k vyřešení to ještě je – viz kapitola Známé problémy |
| Nette | viz závislosti |
Instalace
- Zkopírujte následující soubory:
- app/controls/MultipleFileUpload/*
- document_root/css/MultipleFileUpload/*
- document_root/images/MultipleFileUpload/*
- document_root/js/MultipleFileUpload/*
- document_root/swf/MultipleFileUpload/*
- document_root/xap/MultipleFileUpload/*
- Do bootstrapu za registraci RobotLoaderu
a před
$application->run();přidejte následující řádku.MultipleFileUpload::register(); - Do vašeho layoutu případně do stránek, kde chcete používat MFU,
přidejte následující řádek před tag
</head>{!=MultipleFileUpload::getHead()}Tímto krokem načtete a zaregistrujete Multiple File Upload.
Pokud používáte Nette 0.9.2 nebo nižší, čtěte zde: http://forum.nette.org/…sunu-souboru . V Nette 0.9.3-RC je už tato „chyba“ opravena. http://github.com/…2f8ae53e84a1
Pokud na vašem serveru běží PHP pod (Fast)CGI, je doporučená verze Nette 0.9.4. V této verzi je už opravené získávání hlaviček. Viz http://github.com/…e84a260119db.
Nette 2.0 zatím není oficiálně podporováno, nicméně díky skvělé, aktivní komunitě můžete již dnes využívat originální MultipleFileUpload na Nette 2.0 a PHP 5.3.
A potom už můžete začít Multiple File Uploader používat.
Použití
$f = new AppForm($this,$name);
$f->addMultipleFileUpload("pokus1","Testík",20)
->addRule("MultipleFileUpload::validateFilled","Musíte odeslat alespoň jeden soubor!")
->addRule("MultipleFileUpload::validateFileSize","Soubory jsou dohromady moc veliké!",1024); // 1 KB
Do formuláře je potřeba opravdu zadávat přímo callback, protože ZATÍM není podporována validace na straně klienta!
Jako hodnotu MFU ve formuláři dostanu pole ve kterém je každý soubor validní (prošel HttpUploadedFile::isOK()) a je instancí HttpUploadedFile. Všechny soubory co zůstanou v tempech po odeslání formuláře budou smazány.
Takto vypadá pole co dostanete ke zpracování ($hodnoty =
$form->getValues();):
array(1) {
0 => object(HttpUploadedFile) (5) {
"name" private => string(15) "application.ini"
"type" private => string(24) "application/octet-stream"
"size" private => int(164)
"tmpName" private => string(107) "xxx"
"error" private => int(0)
}
}
Vzhled prvku můžete upravovat v šablonách
MultipleFileUpload-withJS.phtml a
MultipleFileUpload-withoutJS.phtml. Popřípadě zde můžete
i měnit nastavení uploadify.
Závislosti
- Nette
- minimální verze Nette 0.9.1, 0.9.2 (nutnost přepsat HttpUploadedFile::move())
- doporučená verze Nette 0.9.3 (nebo vyšší)
- s Nette 1.0-dev komunita říká, že vše funguje bez problémů.
- Nette 2.0 zatím není oficiálně podporováno, nicméně díky skvělé, aktivní komunitě můžete již dnes využívat originální MultipleFileUpload na Nette 2.0 a PHP 5.3.
- JavaScript: Závisí na použitém interface
- Například interface Uploadify:
- jQuery, Uploadify, swfobject.js, livequery, upravený ajax-form driver
- originální
jquery.uploadify.jsnefunguje s Internet Explorerem, protože má v id objektu pomlčku. IE to interpretuje jako mínus. Proto jsem vydal upravenou verzi, kterou najdete na svn ve složcetrunk/document_root/js/. (od rev. 19) - originální
swfobject.jsnefunguje v Internet Exploreru, protože Internet Explorer má bug s flashem ve formuláři. Upravenou verzi tohoto souboru najdete na svn ve složcetrunk/document_root/js/. (od rev. 20)
Známé problémy
Uploadify
- pokud není k dispozici Flash Player, nenastane automatický fallback a ani není k dispozici ruční fallback na klasické nahrávání souborů
HTML4SingleUpload
- nabídne se i pokud formulář funguje ajaxově (soubory se samozřejmě neodešlou). Nějaké nápady jak toto vyřešit?
Drivery
Driver má za úkol skladovat informace o přenesených souborech a samotné soubory. V distribuci Multiple File Uploadu se driverů nachází hned několik.
| Driver | Autor | Licence | Umístění | Thread-safe | Popis | Instalace | Stav |
|---|---|---|---|---|---|---|---|
| SQLite v. 2 | Honza Kuchař | New BSD | distribuce | ano | Ukládá informace o přenesených souborech do databáze SQLite. (využívá php_sqlite; nevyžaduje dibi) | Stačí povolit zápis (chmod(0777)) ve složce app/controls/drivers/Sqlite/database.sdb. | Doporučený, Stabilní |
| Dibi | Martin Sadový (prvotní implementace) + Honza Kuchař (učesáno; přidán workaround pro http://forum.dibiphp.com/…bytku-vstupu?…) | New BSD | distribuce | ano | Ukládá informace o přenesených souborech do jakékoli databáze, kterou podporuje Dibi. (vyžaduje Dibi; tabulku musíte v databázi ručně vytvořit; v distribuci přiloženy dumpy databází mysql (Martin) a postgres (Honza)) | Zprovozníte dibi, vytvoříte tabulku files v databázi. (viz dumpy databází) | Experimentální (nejspíš si ho budete muset poupravit právě pro vaši databázi, ale bez úprav by to mělo fungovat pod MySQL a PgSQL) |
| Log | Honza Kuchař | New BSD | distribuce | ano | Nikam nic neukládá. Slouží pro vývojáře k zjištění pořadí volaných metod v driveru. Pro běžného uživatele nemá žádný význam. | Nakonfigurovat Logger. | Stabilní |
A jak to v praxi zaregistrovat? Je to jednoduché. Podívejte se do souboru bootstrap.php v distribuci. Najdete tam zhruba toto:
// Optional step: register driver
//
// As default driver is used Sqlite driver
// @see http://addons.nettephp.com/cs/multiplefileupload#toc-drivery
//
// When you want to use other driver use something like this:
Dibi::connect(array(
"driver" => "postgre",
"host" => "127.0.0.1",
"dbname" => "MFU",
"schema" => "public",
"user" => "postgres",
"pass" => "toor",
"charset" => "UTF-8"
));
//MultipleFileUpload::$queuesModel = new MFUQueuesDibi(); // do revize 69
MultipleFileUpload::setQueuesModel(new MFUQueuesDibi()); // od revize 69 (včetně)
Interfacy
Začal bych tím co to vlastně je. Je to jakýsi balíček s uživatelským rozhraním a jeho pozadím na straně serveru, které čeká na data od klientského rozhraní. Část na straně serveru má za úkol předat přijatá data ve specifikované formě modelu. Nejlépe pochopíte, pokud si zobrazíte již funkční interfacy v distribuci.
V současné chvíli máme v distribuci tyto interfacy:
| Interface | Autor | Licence | Vyžadován JavaScript? | Popis |
|---|---|---|---|---|
| HTML4SingleUpload | Honza Kuchař | NewBSD | Ne | Implementuje standardní HTML4 odesílací políčka |
| Plupload | Honza Kuchař | NewBSD | Ano | Implementuje plupload |
| SWFUpload | Roman Vykuka | NewBSD | Ano | Implementuje SwfUpload; více informací o tomto interface na fóru. |
| Uploadify | Honza Kuchař | NewBSD | Ano | Implementuje Uploadify |
Teď tedy čistě praktická a logická otázka, jak ten interface
zaregistrovat a používat? Registrace v do MFU se dělá pomocí předání
názvu třídy interface. V MFU jsou třídy interfaců pojmenování jako
MFUUI a následuje název interface. Tedy například
MFUUIUploadify. Poté už nám zbývá jen interface zaregistrovat.
Jak na to nám ukáže příklad z bootstrapu.
MultipleFileUpload::getUIRegistrator()
->clear()
->register("MFUUIHTML4SingleUpload")
->register("MFUUIUploadify");
Jak vidíte nejdříve jsme získali od objektu MFU UIRegistrator. To je třída, která v sobě uchovává informace o zaregistrovaných interfacech. Tedy nejdříve jsme vymazali již zaregistrované výchozí hodnoty (HTML4SingleUpload, Uploadify). A nyní zaregistrujeme nějaký svůj interface. Pořadí můžeme libovolně měnit, jediné co musíme dodržet je, aby první registrovaný interface nevyžadoval JavaScript, protože ten jako jediný se vygeneruje do stránky, pokud ho prohlížeč nepodporuje.
Pokud máte svoje klientské řešení a chcete ho používat s MFU, čtěte článek Jak na vlastní interface?.
Podpora v prohlížečích
Liší se interface od interface. Tedy postupně.
HTML4SingleUpload
Nevím jak textové prohlížeče, ale jinak by měl být podporován všude.
Plupload
- Všude, kde funguje Javascript.
- Co jsem zkoušel, jdou odesílat opravdu gigantické soubory, nejvíce jsem
zkoušel 6GB. Ale pozor, potom použije knihovnu na zjišťování velikostí
souborů, pokud ji potřebujete vědět.
HttpUploadeFilevám bude vracet nesmysly, u takto velikých souborů.
SWFUpload
(Honza: Prosím autora o doplnění. Já jsem kompatibilitu netestoval. Nicméně bude to dost podovné jako uploadify)
Uploadify
| OS | Prohlížeč | Verze | Kvalita podpory | Komentář |
|---|---|---|---|---|
| Win7 | Google Chrome | 2 | ***** | Bez výhrad |
| 4.1.249.1025 beta | ***** | Bez výhrad | ||
| Opera | 10.0 | ***** | Bez výhrad | |
| 9.65 | ***** | Bez výhrad | ||
| Firefox | 3.5 | **** | O něco pomalejší než Google Chrome a Opera. Možná je to ale způsobeno nějakým nainstalovaným doplňkem. | |
| 3.6 | **** | O něco pomalejší než Google Chrome a Opera. Možná je to ale způsobeno nějakým nainstalovaným doplňkem. | ||
| Internet Explorer | všechny | – | Mezi soubory z nějakých důvodů chvíli čeká. Potřeba ošetřit několik chyb v IE/Flash, aby MFU vůbec fungovalo. (viz Závislosti) | |
| 8 | *** | Soubory odesílá klidně v deseti vláknech. (ale každé vlákno vždy chvíli čeká) Tzn. funguje to v celku správně. | ||
| WinXP | 6 | * | Soubory odesílá pouze v jednom vlákně. Tzn. taky to nějak funguje. |
Pokud není váš prohlížeč v předcházející tabulce, tak prosím napište na fórum, zada ve vašem prohlížeči MFU funguje, či nikoli. A pokud ano, tak jak.
Demo
http://multiplefileupload.projekty.mujserver.net/
SVN
https://svn.mujserver.net:8443/…pload/trunk/
(verze pro PHP 5.2.x) (uživatel: guest, heslo: (nechat
prázdné))
Komentáře 
Honza Kuchař | 1. 4. 2011, 17:56 | comment
Opraveno.
nn2 | 19. 4. 2011, 20:33 | comment
Kdyby někomu nefungoval dibi driver, tak funkční tabulka vypadá takto:
CREATE TABLE files (
id int(11) NOT NULL AUTO_INCREMENT,
queueID varchar(100) NOT NULL,
created int(11) NOT NULL,
data text NOT NULL,
name text NOT NULL,
chunk int(11) NOT NULL,
chunks int(11) NOT NULL,
PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Honza Kuchař | 8. 11. 2011, 18:03 | comment
Opraveno v distribuci.

fak | 20. 3. 2011, 5:37 | comment
Jen jsem chtěl podotknout, že je třeba vložit do layoutu před konec hlavičky:
{!=MultipleFileUpload::getHead()}
strávil jsem 3 hodiny hledáním..