Nepředávají se parametry signálu. Úprava komponenty Plupload
- danielseek
- Člen | 42
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
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
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
Ř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
Ří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
$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
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
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.