Nepředávají se parametry signálu. Úprava komponenty Plupload

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

Dobrý den,
snažím se protlačit vlastní token pro callback funkci v presenteru ($uploader->setOnSuccess(callback($this, ‚onFileUploaded‘))), která se volá když je soubor úspěšně nahrán. Bohužel jsem z celé komponentu trochu zmatený, protože je evidentně předělávaná z nette verze 0.9-.

Upravil jsem soubor JqueryUIWidget/template/default.latte, tak aby když je soubor nahrán volal původní signál tento signál: url : {link upload! $pluploadSettings->getToken()}

class JQueryUIWidget extends \Nette\Application\UI\Control
{

    // Rooftop
    private $rooftop;

    // Template
    private $template;

    // Component for magic loading of Js and Css
    private $libsComponent;


    /*********** Init ***********/
    public function __construct($presenter, $name,\Echo511\Plupload\Rooftop $rooftop)
    {
	$this->rooftop = $rooftop;
	parent::__construct($presenter, $name);


        $this->_createTemplate();

        if($this->rooftop->isMagical())
            $this->monitor('Nette\Application\UI\Presenter');
	flog($this->params);
    }


    /*********** Only magic loading purposes ***********/
    public function attached($presenter)
    {
        $components = $presenter->getComponents(true, 'Echo511\Plupload\Components\Libs\Libs');
        foreach($components as $component) {
            $this->libsComponent = $component;
            break;
        }

        if($this->libsComponent === null) {
            $this->libsComponent = new \Echo511\Plupload\Components\Libs\Libs($this, 'libs');
            $this->libsComponent->setTempLibsDir($this->rooftop->tempLibsDir);
        }
    }


    /*********** Rendering ***********/
    private function _createTemplate()
    {
        $template = $this->createTemplate();
        $template->registerFilter(new \Nette\Latte\Engine);

        $template->tempLibsDir = $this->rooftop->tempLibsDir;
        $template->pluploadSettings = $this->rooftop->pluploadSettings;

        $template->isMagical = $this->rooftop->isMagical();

        $template->setFile(__DIR__ . '/templates/default.latte');
        $this->template = $template;
    }

    public function render($token = 'test')
    {
        $this->template->token = $token;
        $this->template->libsComponent = $this->libsComponent;
        $this->template->render();
    }


    /*********** Upload ***********/
    public function handleUpload($token)
    {
        $this->rooftop->upload($token);
    }

}

Nastává podobná situace jako zde: https://forum.nette.org/…y-komponenty

Když si dumpnu $this->params do firelogu, zobrazí se jen prázdné pole []. Zjistil jsem, že komponenta nevolala konstruktor rodičovské třídy Control. Snažil jsem se to opravit viz kód, ale situace je pořád stejná.

Editoval danielseek (29. 3. 2013 9:48)

echo
Člen | 134
+
0
-

Zdravím,
možná vás to překvapí, ale komponenta je psána přímo pro Nette 2.0. Psal jsem ji pro svou základní potřebu a tak mohou některé věci chybět.

Komponenta nevolala constructor Control, protože není třeba, za předpokladu, že využíváte createComponent…(). Nette připojuje komponenty do stromu presenteru zde: https://api.nette.org/…ner.php.html#149.

Funkci flog() neznám a ani na php.net o ni není zmínka, předpokládám, že se jedná o nějaké php rozšíření a že právě touto funkcí provádíte onen dump.

Komponenta podle mě parametry sama číst neumí, musí se na to ošklivě přes $this->presenter->getParameter($name).

Mé řešení:
přepište si Echo511\Plupload\Uploaders\Defaults tak, aby při volání onSuccess nevracela pouze upload, ale i token.

řádek 184

$this->onSuccess->invokeArgs(array($upload, $this->token));

A je to.

Michal Vyšinský
Člen | 608
+
0
-

Funkci flog() neznám a ani na php.net o ni není zmínka, předpokládám, že se jedná o nějaké php rozšíření a že právě touto funkcí provádíte onen dump.

Řekl bych, že flog bude jeho vlastní shortcut pro Nette\Diagnostics\FireLogger::log()

Editoval CherryBoss (29. 3. 2013 12:44)

danielseek
Člen | 42
+
0
-

Řekl bych, že flog bude jeho vlastní shortcut pro Nette\Diagnostics\FireLogger::log()

Ano omlouvám se jestli vás zmátla je to skutečně jen zkratka. Nette\Diagnostics\FireLogger::log() psát tohle mi příjde otřesné :D

Editoval danielseek (29. 3. 2013 13:06)

danielseek
Člen | 42
+
0
-

Řídil jsem se tímto tutoriálem: https://doc.nette.org/cs/quickstart#…

Autor zde používá signály v komponentách a předává jim parametry.

Zkoušel jsem si dumpnout $this->presenter->params a o nějakém tokenu tam není ani známky.

To co navrhujete už jsem použil. Nicméně mi to samo o sobě nepomůže, protože takový token se pokaždé mění, resp. není svázán s Plupload komponentou. V současné chvíli jsem si přidal do třídy PluploadSettings metodu setFormToken. Poté v šablone JqueryUIWidget/template/default.latte
používám tuto konstrukci:

url : {link upload! $pluploadSettings->getToken()}

Ve výsledku vznikne tato url:

url : "\/admin.image-manager\/add-gallery?plupload-token=9378967&do=plupload-upload",

Editoval danielseek (29. 3. 2013 13:19)

echo
Člen | 134
+
0
-

$this->presenter->params byl nástřel, nebude to fungovat, pokud si to nenastavíte.

Token se měnit nemůže a JE svázán s komponentou. Dokazuje to i vaše $pluploadSettings->getToken(). Pokud se vám mění (resp. jej měníte při vytváření komponenty), porušujete logiku komponenty a nechápu, jak vám může fungovat chunking.

danielseek
Člen | 42
+
0
-

Idea byla taková, že v Presenteru se vygeneruje token a ten je identifikací této konkrétní instance Pluupload. (Pro chunking využívám jiného tokenu.) Jestliže ovšem volám signál vytváří se na nové stránce nová instance Presenteru a tudíž by byl i jiný token, proto ho musím nějak předat z toho původního presenteru.

Možná mi něco uniká, omlouvám jsem v nette skutečně začátečník.

Editoval danielseek (29. 3. 2013 19:33)

echo
Člen | 134
+
0
-

Nechápu, kde je problém. Z url zmíněné ve vašem příspěvku usuzuji, že potřebujete vytvořit novou galerii.

Galerii budu vytvářet jenom jednu, ale uživatel může mít 2 okna a nahrávat zároveň do dvou nově tvořených galerií ⇒ potřeba to odlišit. V presenteru si zavedu persistent proměnnou $instance a tu použiji pro generování tokenu v createComponentPlupload().

public function createComponentPlupload()
{
    // Main object
    $uploader = new Echo511\Plupload\Rooftop();

    // Use magic for loading Js and Css?
    // $uploader->disableMagic();

    // Configuring paths
    $uploader->setWwwDir(WWW_DIR) // Full path to your frontend directory
             ->setBasePath($this->template->basePath) // BasePath provided by Nette
             ->setTempLibsDir(WWW_DIR . '/plupload511/test'); // Full path to the location of plupload libs (js, css)

    // Configuring plupload
    $uploader->createSettings()
             ->setRuntimes(array('html5')) // Available: gears, flash, silverlight, browserplus, html5
             ->setMaxFileSize('1000mb')
             ->setMaxChunkSize('1mb'); // What is chunk you can find here: http://www.plupload.com/documentation.php

    // Configuring uploader
    $uploader->createUploader()
             ->setTempUploadsDir(WWW_DIR . '/plupload511/tempDir') // Where should be placed temporaly files
             ->setToken($this->instance) // Resolves file names collisions in temp directory
             ->setOnSuccess(array($this, 'processFileUpload')); // Callback when upload is successful: returns Nette\Http\FileUpload

    return $uploader->getComponent();
}

Samozřejmě je nutné zajistit, aby $instance nebyla null. To dělat ve startup(), NE v konstruktoru!

public function startup()
{
	parent::startup(); // call parent - important!

	if($this->instance === null)
		$this->redirect('this', array('instance' => String::randomize(...)));
}

Komponenta o $instance neví – ta má token (i když je to de facto ten samý string).

V presenteru v handleru onSuccesUpload() mi stačí pouze parametr $upload, k $instance se dostanu přes $this->instance.

public function processFileUpload(FileUpload $upload)
{
	// zde uložit upload do session - jako token použít $this->instance.
	// naplnit formulář ze session
	// překreslit formulář
}

Na zpracování formuláře samozřejmě zvláštní handler.