[addon multiplefileupload] MultipleFileUpload – form control

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Honza Kuchař
Člen | 1662
+
0
-

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
+
0
-

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:

  1. Uploadify
  2. 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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

Ahoj,
nenašel by se prosím někdo, kdo má upraven MFU pro PHP 5.3 ve verzi Nette s namespaci (0.9.3)? Snažím se jej upravit, ale tápu v něm a nedaří se mi to. Děkuji

despiq
Člen | 320
+
0
-

mam ale starou verzi

Honza Kuchař
Člen | 1662
+
0
-

@Despiq: prosím pošli mi to mail. Můj mail máš u sebe na mailu. :)

Honza Kuchař
Člen | 1662
+
0
-

Despiqova verze je publikována zde.

jedná se o verzi: VERSION = ‚$Rev: 55 $ released on $Date: 2010–04–01 11:08:37 +0200 (Čt, 01 4 2010) $‘; Tedy verze před přidáním interfaců. Více informací najdete v komentářím k jednotlivých revizí, například v TortoiseSVN nebo přímo zde.

Manny7
Člen | 67
+
0
-

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
+
0
-

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)

Manny7
Člen | 67
+
0
-

Už mě moc nenapadá, jak se z tohoto problému vymotat – tak sem zkusím pastnout tu miniaplikaci (hned po rozbalení jede). Mám tam nastaven onen automatický start po výběru souboru, který ne a ne chodit (s běžným submit odesláním jde)… Za jakékoli tipy na řešení budu rád

Honza Kuchař
Člen | 1662
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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

Editoval Vyki (24. 8. 2010 23:19)

Honza Kuchař
Člen | 1662
+
0
-

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)

Vyki
Člen | 388
+
0
-

Beru zpět tu chybu se dvěma uploadery v jednom formu. Když jsem to zkoušel, zapomněl jsem do presenteru pro tento případ přidat něco jako

<?php
	$data['upload'] = array_merge($data['upload'], $data['upload2']);
?>
Honza Kuchař
Člen | 1662
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

Ano, ano. Plupload je další na řadě.

despiq
Člen | 320
+
0
-

na Plupload se tesim, je sexy a multi technologickej

iguana007
Člen | 970
+
0
-

Plupload +1

Honza Kuchař
Člen | 1662
+
0
-

+1 nikomu v této chvíli nepomůže. Čeká se na někoho, kdo přepíše toto do podoby interface.

Bernard Williams
Člen | 207
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

hmmm, asi vím o čem mluvíš. Tak to je spíše bug. Pokusím se to opravit (ale ne hned).

Ofi
Člen | 13
+
0
-

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
+
0
-

Stačí stáhnout nejnovější revizi a mít načtené alespoň dva interfaces. (výchozí stav)

Ofi
Člen | 13
+
0
-

a nojo, to jsem si neuvědomil… druhý problém však zůstává..

Honza Kuchař
Člen | 1662
+
0
-

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
+
0
-

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
+
0
-

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 ;)

masterr
Začátečník | 141
+
0
-

Jak to pls stáhnu? Stahl jsem si TortoiseSVN, ale nejak se v tom nevyznam…Můžete dát nějakou konečnou verzi do .raru?

Honza Kuchař
Člen | 1662
+
0
-

Konečná verze není, proto je to na SVN. Ale poradím ti:

  1. vytvoř nějakou složku u sebe na PC
  2. na ni klikni pravým tlačítkem a dej Checkout (případně TortoiseSVN->checkout)
  3. zadej adresu SVN repozitáře, kterou najdeš na stránce s dokumentací doplňku
  4. OK
  5. čekej
  6. Máš to stažené
  7. OK = zavřít
masterr
Začátečník | 141
+
0
-

Dík

masterr
Začátečník | 141
+
0
-

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
+
0
-
<?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?

Vyki
Člen | 388
+
0
-

Vím o problému v IE7, kde to nešlape (v IE 6 to překvapivě funguje), ale zkus debugovat. Třeba firebugem ve FF, mrkni jesti se při natahování některých JS a SWF souborů nevyhazuje 404.

Editoval Vyki (30. 9. 2010 22:41)

Honza Kuchař
Člen | 1662
+
0
-

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.

Čelo
Člen | 42
+
0
-

co zkusit IE tester?

Vyki
Člen | 388
+
0
-

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)

despiq
Člen | 320
+
0
-

IE7 zrusit, je to stejnej srac jako IE6 a v necem jeste horsi, proboha upgradujte to tem lidem co to pouzivaj dyt je to 4 roky stary a kristepane ono to pouziva jeste 14% lidi

to mame za trest, jen nevim co jsme mrkvosoftu udelali

masterr
Začátečník | 141
+
0
-

Tak ve FireBugu mi to hází:

MFUFallbackController is not defined
[Break on this error] new MFUFallbackController(document.get...\n}).call(this);","destruct":true}]);

Proč, co se s tím dá dělat?

Honza Kuchař
Člen | 1662
+
0
-

Asi se to spustí, než je ta třída načtená…

xpitris
Člen | 9
+
0
-

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
+
0
-

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.