From e53eac88cabddb27ed1d8b3ba942ca353620d49e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kucha=C5=99?= Date: Tue, 20 Sep 2016 10:15:17 +0200 Subject: [PATCH 01/26] composer: bumped compatibility with nette ~2.4 (thanks @akyn84, @lubo) --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 93cc56a..955e424 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ } }, "require": { - "php": ">= 5.3.0", - "nette/nette": ">= 2.0" + "php": ">= 5.6.0", + "nette/nette": "~2.4" } } From 9c460564845c3adbe7cef69a82c0f16857b5d91f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kucha=C5=99?= Date: Tue, 20 Sep 2016 10:39:34 +0200 Subject: [PATCH 02/26] got rid of Environment (introduced dependency on Container) (thanks @akyn84, @lubo) --- MultipleFileUpload/MultipleFileUpload.php | 52 ++++++++++--------- MultipleFileUpload/UI/AbstractInterface.php | 21 ++++---- .../UI/HTML4SingleUpload/Controller.php | 6 ++- MultipleFileUpload/UI/Plupload/Controller.php | 34 +++++++----- MultipleFileUpload/UI/Registrator.php | 4 +- .../UI/Uploadify/Controller.php | 26 ++++++---- 6 files changed, 78 insertions(+), 65 deletions(-) diff --git a/MultipleFileUpload/MultipleFileUpload.php b/MultipleFileUpload/MultipleFileUpload.php index 720f06e..d4946ea 100644 --- a/MultipleFileUpload/MultipleFileUpload.php +++ b/MultipleFileUpload/MultipleFileUpload.php @@ -15,14 +15,15 @@ use MultipleFileUpload\Model\IQueue, MultipleFileUpload\Model\IQueues, MultipleFileUpload\UI\Registrator, - Nette\Environment, + Latte, + Nette, + Nette\Bridges, Nette\Forms, Nette\Forms\Container, Nette\Forms\Controls\UploadControl, Nette\Http\FileUpload, Nette\InvalidStateException, Nette\NotSupportedException, - Nette\Utils\Callback, Nette\Utils\Html, Nette\Utils\Strings; @@ -63,6 +64,9 @@ class MultipleFileUpload extends UploadControl public static $baseWWWRoot = null; + /** @var Nette\DI\Container */ + private static $container; + /** * Initialize MFU */ @@ -74,23 +78,22 @@ public static function init() $uiReg->register("MultipleFileUpload\\UI\\Plupload"); // Set default check callback - self::$validateFileCallback = callback(__CLASS__, "validateFile"); + self::$validateFileCallback = [__CLASS__, "validateFile"]; - // TODO: remove this magic - self::$baseWWWRoot = Environment::getHttpRequest()->url->baseUrl . "MultipleFileUpload/"; + self::$baseWWWRoot = self::$container->getByType('Nette\Http\IRequest')->url->baseUrl . "MultipleFileUpload/"; } /** * Register MFU into Nette */ - public static function register() + public static function register($container) { - self::init(); - - $application = Environment::getApplication(); - $application->onStartup[] = callback(__CLASS__, "handleUploads"); - $application->onShutdown[] = callback(__CLASS__, "cleanCache"); + self::$container = $container; + self::init(); + $application = $container->getByType('Nette\Application\Application'); + $application->onStartup[] = [__CLASS__, "handleUploads"]; + $application->onShutdown[] = [__CLASS__, "cleanCache"]; } @@ -133,8 +136,7 @@ public static function handleUploads() self::$handleUploadsCalled = true; } - $req = Environment::getHttpRequest(); - + $req = self::$container->getByType('Nette\Http\IRequest'); // Workaround for: http://forum.nettephp.com/cs/3680-httprequest-getheaders-a-content-type $contentType = $req->getHeader("content-type"); if (!$contentType and isset($_SERVER["CONTENT_TYPE"])) { @@ -147,7 +149,7 @@ public static function handleUploads() self::getQueuesModel()->initialize(); - foreach (self::getUIRegistrator()->getInterfaces() AS $interface) { + foreach (self::getUIRegistrator()->getInterfaces(self::$container) AS $interface) { // \Nette\Diagnostics\Debugger::log($interface->getReflection()->getName().": is this your upload? ".$interface->isThisYourUpload()); if ($interface->isThisYourUpload()) { $ret = $interface->handleUploads(); @@ -174,7 +176,8 @@ public static function validateFile(FileUpload $file) */ public static function cleanCache() { - if (!Environment::isProduction() or rand(1, 100) < 5) { + $parameters = self::$container->getParameters(); + if (!$parameters['productionMode'] or rand(1, 100) < 5) { self::getQueuesModel()->cleanup(); } } @@ -186,8 +189,9 @@ public static function cleanCache() */ public static function getQueuesModel() { - if (!self::$queuesModel) { // if nothing is set, setup sqlite model, which should work on all systems with SQLite - self::setQueuesModel(new Model\SQLite3\Queues()); + if (!self::$queuesModel) { // if nothing is set, setup sqlite model, which should work on all systems with MySQL + $queuesModel = new Model\MySQL\Queues(self::$container, self::$container->getService("database.default")); + self::setQueuesModel($queuesModel); } if (!self::$queuesModel instanceof IQueues) { @@ -291,12 +295,11 @@ public function getControl() //
$tokenField = Html::el('input type=hidden')->name($this->getHtmlName() . '[token]')->value($this->getToken()); - $control->add($tokenField); + $control->addHtml($tokenField); //
$fallbacks = array(); - - $interfaces = self::getUIRegistrator()->getInterfaces(); + $interfaces = self::getUIRegistrator()->getInterfaces(self::$container); $num = count($interfaces); $cnt = 1; foreach ($interfaces AS $interface) { @@ -324,14 +327,15 @@ public function getControl() } $cnt++; - $control->add($container); + $control->addHtml($container); } - $template = new UI\Template(); - $template->setFile(dirname(__FILE__) . DIRECTORY_SEPARATOR . "RegisterJS.latte"); + $latte = new Latte\Engine(); + $template = new Bridges\ApplicationLatte\Template($latte); + $template->setFile(__DIR__ . DIRECTORY_SEPARATOR . "RegisterJS.latte"); $template->id = $this->getHtmlId(); $template->fallbacks = $fallbacks; - $control->add($template->__toString(TRUE)); + $control->addHtml($template->__toString(TRUE)); /* //
$withoutJS = Html::el("div class=withoutJS"); diff --git a/MultipleFileUpload/UI/AbstractInterface.php b/MultipleFileUpload/UI/AbstractInterface.php index dca6bdf..6d06ea8 100644 --- a/MultipleFileUpload/UI/AbstractInterface.php +++ b/MultipleFileUpload/UI/AbstractInterface.php @@ -12,11 +12,12 @@ namespace MultipleFileUpload\UI; use MultipleFileUpload\MultipleFileUpload, - Nette\Environment, + Latte, + Nette\Bridges, Nette\Http\FileUpload, Nette\Http\Request, Nette\Object, - Nette\Utils\Callback; + Nette\Http\IRequest; /** * Abstract UI Controller @@ -27,9 +28,9 @@ abstract class AbstractInterface extends Object implements IUserInterface protected $httpRequest; - public function __construct() + public function __construct(IRequest $httpRequest) { - $this->httpRequest = Environment::getHttpRequest(); + $this->httpRequest = $httpRequest; } @@ -72,18 +73,14 @@ function processFile($token, $file) } - /** - * @return Template - */ - protected function createTemplate($file = null) + protected function createTemplate() { - $template = new Template($file); - + $latte = new Latte\Engine(); + $template = new Bridges\ApplicationLatte\Template($latte); $template->baseUrl = $this->httpRequest->url->baseUrl; $template->basePath = rtrim($template->baseUrl, '/'); $template->interface = $this; - - $template->registerHelperLoader('Nette\Templating\Helpers::loader'); + $template->addFilter(NULL, 'Latte\Macros\CoreMacros::install'); return $template; } diff --git a/MultipleFileUpload/UI/HTML4SingleUpload/Controller.php b/MultipleFileUpload/UI/HTML4SingleUpload/Controller.php index 45be20f..53db45c 100644 --- a/MultipleFileUpload/UI/HTML4SingleUpload/Controller.php +++ b/MultipleFileUpload/UI/HTML4SingleUpload/Controller.php @@ -89,7 +89,8 @@ public function handleUploads() */ public function render(MultipleFileUpload $upload) { - $template = $this->createTemplate(dirname(__FILE__) . "/html.latte"); + $template = parent::createTemplate(); + $template->setFile(__DIR__ . "/html.latte"); $template->maxFiles = $upload->maxFiles; $template->mfu = $upload; return $template->__toString(TRUE); @@ -101,7 +102,8 @@ public function render(MultipleFileUpload $upload) */ public function renderInitJavaScript(MultipleFileUpload $upload) { - return $this->createTemplate(dirname(__FILE__) . "/initJS.latte")->__toString(TRUE); + $template = parent::createTemplate(); + return $template->setFile(__DIR__ . "/initJS.latte")->__toString(TRUE); } diff --git a/MultipleFileUpload/UI/Plupload/Controller.php b/MultipleFileUpload/UI/Plupload/Controller.php index ce15a7f..2d30fee 100644 --- a/MultipleFileUpload/UI/Plupload/Controller.php +++ b/MultipleFileUpload/UI/Plupload/Controller.php @@ -221,27 +221,31 @@ function getHtmlIdFlashCompatible(MultipleFileUpload $upload) */ public function render(MultipleFileUpload $upload) { - $template = $this->createTemplate(dirname(__FILE__) . "/html.latte"); - $template->id = $this->getHtmlIdFlashCompatible($upload); - return $template->__toString(TRUE); + $template = parent::createTemplate(); + $template->setFile(__DIR__ . "/html.latte"); + $template->id = $this->getHtmlIdFlashCompatible($upload); + return $template->__toString(TRUE); } - /** + /**}} * Renders JavaScript body of function. */ public function renderInitJavaScript(MultipleFileUpload $upload) { - $tpl = $this->createTemplate(dirname(__FILE__) . "/initJS.latte"); - $tpl->token = $upload->getToken(); - $tpl->sizeLimit = $upload->maxFileSize; - $tpl->maxFiles = $upload->maxFiles; + $template = parent::createTemplate(); + $template->setFile(__DIR__ . "/initJS.latte"); + $template->token = $upload->getToken(); + $template->sizeLimit = $upload->maxFileSize; + $template->maxFiles = $upload->maxFiles; // TODO: make creation of link nicer! - $baseUrl = $this->httpRequest->url->baseUrl; - $tpl->uploadLink = $baseUrl . "?token=" . $tpl->token . "&uploader=plupload"; - $tpl->id = $this->getHtmlIdFlashCompatible($upload); - return $tpl->__toString(TRUE); + //$baseUrl = $this->httpRequest->url->baseUrl; + //$template->uploadLink = $baseUrl . "?token=" . $template->token . "&uploader=plupload"; + $url = $this->httpRequest->url; + $template->uploadLink = $url->scheme . "://" . $url->host . $url->path . '?' . $url->query . "&token=" . $template->token . "&uploader=plupload"; + $template->id = $this->getHtmlIdFlashCompatible($upload); + return $template->__toString(TRUE); } @@ -250,7 +254,8 @@ public function renderInitJavaScript(MultipleFileUpload $upload) */ public function renderDestructJavaScript(MultipleFileUpload $upload) { - return $this->createTemplate(dirname(__FILE__) . "/destructJS.js")->__toString(TRUE); + $template = parent::createTemplate(); + $template->setFile(__DIR__ . "/destructJS.js")->__toString(TRUE); } @@ -259,7 +264,8 @@ public function renderDestructJavaScript(MultipleFileUpload $upload) */ public function renderHeadSection() { - return $this->createTemplate(dirname(__FILE__) . "/head.latte")->__toString(TRUE); + $template = parent::createTemplate(); + $template->setFile(__DIR__ . "/head.latte")->__toString(TRUE); } diff --git a/MultipleFileUpload/UI/Registrator.php b/MultipleFileUpload/UI/Registrator.php index dafe9f9..e3aaf22 100644 --- a/MultipleFileUpload/UI/Registrator.php +++ b/MultipleFileUpload/UI/Registrator.php @@ -46,12 +46,12 @@ public function clear() } - public function getInterfaces() + public function getInterfaces($container) { $interfaces = $this->interfaces; foreach ($interfaces AS $key => $interface) { if (is_string($interface)) { - $interface = $interfaces[$key] = new $interface; + $interface = $interfaces[$key] = new $interface($container->getByType('Nette\Http\IRequest')); } if (!$interface instanceof IUserInterface) { throw new InvalidArgumentException($interface->reflection->name . " is not compatible with MFU!"); diff --git a/MultipleFileUpload/UI/Uploadify/Controller.php b/MultipleFileUpload/UI/Uploadify/Controller.php index 95ca628..2d50fdf 100644 --- a/MultipleFileUpload/UI/Uploadify/Controller.php +++ b/MultipleFileUpload/UI/Uploadify/Controller.php @@ -68,7 +68,8 @@ public function handleUploads() */ public function render(MultipleFileUpload $upload) { - $template = $this->createTemplate(dirname(__FILE__) . "/html.latte"); + $template = parent::createTemplate(); + $template->setFile(__DIR__ . "/html.latte"); $template->uploadifyId = $upload->getHtmlId() . "-uploadifyBox"; return $template->__toString(TRUE); } @@ -79,14 +80,15 @@ public function render(MultipleFileUpload $upload) */ public function renderInitJavaScript(MultipleFileUpload $upload) { - $tpl = $this->createTemplate(dirname(__FILE__) . "/initJS.latte"); - $tpl->sizeLimit = $upload->maxFileSize; - $tpl->token = $upload->getToken(); - $tpl->maxFiles = $upload->maxFiles; - $tpl->backLink = (string) $upload->form->action; - $tpl->uploadifyId = $upload->getHtmlId() . "-uploadifyBox"; - $tpl->simUploadFiles = $upload->simUploadThreads; - return $tpl->__toString(TRUE); + $template = parent::createTemplate(); + $template->setFile(__DIR__ . "/initJS.latte"); + $template->sizeLimit = $upload->maxFileSize; + $template->token = $upload->getToken(); + $template->maxFiles = $upload->maxFiles; + $template->backLink = (string) $upload->form->action; + $template->uploadifyId = $upload->getHtmlId() . "-uploadifyBox"; + $template->simUploadFiles = $upload->simUploadThreads; + return $template->__toString(TRUE); } @@ -95,7 +97,8 @@ public function renderInitJavaScript(MultipleFileUpload $upload) */ public function renderDestructJavaScript(MultipleFileUpload $upload) { - return $this->createTemplate(dirname(__FILE__) . "/destructJS.js")->__toString(TRUE); + $template = parent::createTemplate(); + return $template->setFile(__DIR__ . "/destructJS.js")->__toString(TRUE); } @@ -104,7 +107,8 @@ public function renderDestructJavaScript(MultipleFileUpload $upload) */ public function renderHeadSection() { - return $this->createTemplate(dirname(__FILE__) . "/head.latte")->__toString(TRUE); + $template = parent::createTemplate(); + $template->setFile(__DIR__ . "/head.latte")->__toString(TRUE); } From 570f0d6b9baecfdf8233e8dfc86abe567cb13294 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kucha=C5=99?= Date: Tue, 20 Sep 2016 10:39:57 +0200 Subject: [PATCH 03/26] latter: {? replaced with {php (thanks @akyn84, @lubo) --- MultipleFileUpload/UI/HTML4SingleUpload/html.latte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MultipleFileUpload/UI/HTML4SingleUpload/html.latte b/MultipleFileUpload/UI/HTML4SingleUpload/html.latte index f0e6e64..b89bf42 100755 --- a/MultipleFileUpload/UI/HTML4SingleUpload/html.latte +++ b/MultipleFileUpload/UI/HTML4SingleUpload/html.latte @@ -34,7 +34,7 @@ * @link http://nettephp.com/cs/extras/multiplefileupload *} -{? +{php $input = \Nette\Utils\Html::el("input type=file")->name($mfu->getHtmlName().'[files][]'); } From 6b06f4c251f4a60571cbbcb3eead7fd322e90c42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kucha=C5=99?= Date: Tue, 20 Sep 2016 10:40:52 +0200 Subject: [PATCH 04/26] model: introduced second implementation of driver for MySQL over Nette\Database (thanks @akyn84, @lubo) --- MultipleFileUpload/Model/IQueue.php | 2 +- MultipleFileUpload/Model/MySQL/Queue.php | 162 +++++++++++++++++++++ MultipleFileUpload/Model/MySQL/Queues.php | 137 +++++++++++++++++ MultipleFileUpload/Model/MySQL/setupDB.sql | 17 +++ 4 files changed, 317 insertions(+), 1 deletion(-) create mode 100644 MultipleFileUpload/Model/MySQL/Queue.php create mode 100644 MultipleFileUpload/Model/MySQL/Queues.php create mode 100644 MultipleFileUpload/Model/MySQL/setupDB.sql diff --git a/MultipleFileUpload/Model/IQueue.php b/MultipleFileUpload/Model/IQueue.php index 25843df..eabd9f1 100644 --- a/MultipleFileUpload/Model/IQueue.php +++ b/MultipleFileUpload/Model/IQueue.php @@ -72,7 +72,7 @@ function addFileManually($name, $chunk, $chunks); * @param type $chunk * @param FileUpload $file */ - function updateFile($name, $chunk, FileUpload $file = null); + function updateFile($name, $chunk, FileUpload $file); /** * Gets all files in queue diff --git a/MultipleFileUpload/Model/MySQL/Queue.php b/MultipleFileUpload/Model/MySQL/Queue.php new file mode 100644 index 0000000..e4fe1a2 --- /dev/null +++ b/MultipleFileUpload/Model/MySQL/Queue.php @@ -0,0 +1,162 @@ +getQueuesModel()->query($sql); + } + + /** + * Add file to queue + * @param FileUpload $file + */ + function addFile(FileUpload $file) + { + $file->move($this->getUniqueFilePath()); + $this->getQueuesModel()->getConnection()->query(" + INSERT INTO files (queueID, created, data, name) VALUES ( + ?,?,?,?)", $this->getQueueID(), time(), "X'" . bin2hex(serialize($file)) . "'", $file->getName()); + } + + + // TODO: rename!!! + /** + * Add file to queue manually + * @param FileUpload $file + * @param int $chunk + * @param int $chunks + */ + function addFileManually($name, $chunk, $chunks) + { + $this->getQueuesModel()->getConnection()->query(" + INSERT INTO files (queueID, created, name, chunk, chunks) VALUES (?, ?, ?, ?, ?) + ", $this->getQueueID(), time(), $name, $chunk, $chunks); + } + + + /** + * Update file + * @param string $name + * @param int $chunk + * @param FileUpload $file + */ + function updateFile($name, $chunk, FileUpload $file) + { + $this->query("START TRANSACTION"); + $this->getQueuesModel()->getConnection()->query("UPDATE files SET chunk = ? WHERE queueID = ? AND name = ?", $chunk, $this->getQueueID(), $name); + if ($file) { + // use blob for storing serialized object, see https://bugs.php.net/bug.php?id=63419 and https://bugs.php.net/bug.php?id=62361 + //$blob = fopen($file->getTemporaryFile(), 'rb'); + $blob = serialize($file); + $pdo = $this->getQueuesModel()->getConnection()->getPdo(); + $stmt = $pdo->prepare("UPDATE files SET data = :data WHERE queueID = :queueID AND name = :name;"); + $stmt->bindParam(':data', $blob, \PDO::PARAM_LOB); + $queueID = $this->getQueueID(); + $stmt->bindParam(':queueID', $queueID); + $stmt->bindParam(':name', $name); + $stmt->execute(); + } + $this->query("COMMIT WORK"); + } + + + /** + * Get upload directory path + * @return string + */ + function getUploadedFilesTemporaryPath() + { + if (!Queues::$uploadsTempDir) { + throw new InvalidStateException("Directory for temp files is not set."); + } + + if (!file_exists(Queues::$uploadsTempDir)) { + mkdir(Queues::$uploadsTempDir, 0777, true); + } + + if (!is_writable(Queues::$uploadsTempDir)) { + throw new InvalidStateException("Directory for temp files is not writable!"); + } + + return Queues::$uploadsTempDir; + } + + + /** + * Get files + * @return FileUpload[] + */ + function getFiles() + { + $files = []; + foreach($this->getQueuesModel()->getConnection()->query("SELECT * FROM files WHERE queueID = ?", $this->getQueueID())->fetchPairs('id', 'data') as $row) { + if(($file = unserialize($row)) instanceof FileUpload) { + $files[] = $file; + } + }; + return $files; + } + + + /** + * Delete temporary files + */ + function delete() + { + $dir = realpath($this->getUploadedFilesTemporaryPath()); + foreach ($this->getFiles() AS $file) { + $fileDir = dirname($file->getTemporaryFile()); + if (realpath($fileDir) == $dir and file_exists($file->getTemporaryFile())) { + // Delete file only if user leaved file in temp directory + @unlink($file->getTemporaryFile()); // intentionally @ + } + } + + $this->getQueuesModel()->getConnection()->query("DELETE FROM files WHERE queueID = ?", $this->getQueueID()); + } + + + /** + * When was queue last accessed? + * @return int timestamp + */ + function getLastAccess() + { + $lastAccess = (int) $this->getQueuesModel()->getConnection()->query(" + SELECT created + FROM files + WHERE queueID = ? + ORDER BY created DESC + ", $this->getQueueID())->fetch()->created; + return $lastAccess; + } + + +} \ No newline at end of file diff --git a/MultipleFileUpload/Model/MySQL/Queues.php b/MultipleFileUpload/Model/MySQL/Queues.php new file mode 100644 index 0000000..4c600bd --- /dev/null +++ b/MultipleFileUpload/Model/MySQL/Queues.php @@ -0,0 +1,137 @@ +getParameters(); + self::$container = $container; + self::$uploadsTempDir = $parameters['tempDir'] . DIRECTORY_SEPARATOR . "uploads-MFU"; + $this->connection = $connection; + } + + + /** + * Initialize driver + */ + function initialize() + { + + } + + + function getConnection() + { + return $this->connection; + } + + + /** + * Execute query + * @param string $sql + * @return Nette\Database\ResultSet + * @throws InvalidStateException + */ + function query($sql) + { + $res = $this->getConnection()->query($sql); + if (!$res) { + throw new InvalidStateException("Can't execute query: '" . $sql . "'. error: " . $this->getConnection()->lastErrorMsg()); + } + return $res; + } + + /** + * Get queue (create if needed) + * @param string $id + * @return Queue + */ + function getQueue($id) + { + return $this->createQueueObj($id); + } + + + /** + * Factory for Queue + * @param string $queueID + * @return Queue + */ + function createQueueObj($queueID) + { + $parameters = self::$container->getParameters(); + $queue = new Queue($parameters['tempDir']); + $queue->setQueuesModel($this); + $queue->setQueueID($queueID); + $queue->initialize(); + return $queue; + } + + + /** + * Execute cleanup + */ + function cleanup() + { + $this->query('START TRANSACTION'); + foreach ($this->getQueues() AS $queue) { + if ($queue->getLastAccess() < time() - $this->getLifeTime()) { + //$queue->delete(); + } + } + $this->query('COMMIT WORK'); + } + + + /** + * Get all queues + * @return IQueue[] + */ + function getQueues() + { + $queuesOut = array(); + $res = $this->query(' + SELECT queueID + FROM files + GROUP BY queueID + '); + + foreach($res->fetchPairs('queueID') as $row) { + $queuesOut[] = $this->createQueueObj($row['queueID']); + } + + return $queuesOut; + } + +} diff --git a/MultipleFileUpload/Model/MySQL/setupDB.sql b/MultipleFileUpload/Model/MySQL/setupDB.sql new file mode 100644 index 0000000..052f1ed --- /dev/null +++ b/MultipleFileUpload/Model/MySQL/setupDB.sql @@ -0,0 +1,17 @@ +--Table: files + +--DROP TABLE files; + +CREATE TABLE files ( + id integer AUTO_INCREMENT PRIMARY KEY, + queueID char(255) NOT NULL, + created integer NOT NULL, + data blob, + chunk integer NOT NULL DEFAULT 1, + chunks integer NOT NULL DEFAULT 1, + name varchar(255) NOT NULL +); + +CREATE UNIQUE INDEX files_name + ON files + (name); From fb01df664491d1c5d888699735232779c56f8708 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kucha=C5=99?= Date: Tue, 20 Sep 2016 12:17:22 +0200 Subject: [PATCH 05/26] .gitignore: vendor, .idea --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index d094d36..ace654b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ /nbproject/ /composer.lock -/Nette/ \ No newline at end of file +/Nette/ +.idea/ +vendor/ From 27d2bc9bc29ead1e7cea0c91b2f164f8951a8430 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=BDubom=C3=ADr=20Andr=C3=ADsek?= Date: Sat, 24 Sep 2016 21:57:30 +0200 Subject: [PATCH 06/26] MySQL driver: removed --- MultipleFileUpload/Model/MySQL/Queue.php | 162 --------------------- MultipleFileUpload/Model/MySQL/Queues.php | 137 ----------------- MultipleFileUpload/Model/MySQL/setupDB.sql | 17 --- 3 files changed, 316 deletions(-) delete mode 100644 MultipleFileUpload/Model/MySQL/Queue.php delete mode 100644 MultipleFileUpload/Model/MySQL/Queues.php delete mode 100644 MultipleFileUpload/Model/MySQL/setupDB.sql diff --git a/MultipleFileUpload/Model/MySQL/Queue.php b/MultipleFileUpload/Model/MySQL/Queue.php deleted file mode 100644 index e4fe1a2..0000000 --- a/MultipleFileUpload/Model/MySQL/Queue.php +++ /dev/null @@ -1,162 +0,0 @@ -getQueuesModel()->query($sql); - } - - /** - * Add file to queue - * @param FileUpload $file - */ - function addFile(FileUpload $file) - { - $file->move($this->getUniqueFilePath()); - $this->getQueuesModel()->getConnection()->query(" - INSERT INTO files (queueID, created, data, name) VALUES ( - ?,?,?,?)", $this->getQueueID(), time(), "X'" . bin2hex(serialize($file)) . "'", $file->getName()); - } - - - // TODO: rename!!! - /** - * Add file to queue manually - * @param FileUpload $file - * @param int $chunk - * @param int $chunks - */ - function addFileManually($name, $chunk, $chunks) - { - $this->getQueuesModel()->getConnection()->query(" - INSERT INTO files (queueID, created, name, chunk, chunks) VALUES (?, ?, ?, ?, ?) - ", $this->getQueueID(), time(), $name, $chunk, $chunks); - } - - - /** - * Update file - * @param string $name - * @param int $chunk - * @param FileUpload $file - */ - function updateFile($name, $chunk, FileUpload $file) - { - $this->query("START TRANSACTION"); - $this->getQueuesModel()->getConnection()->query("UPDATE files SET chunk = ? WHERE queueID = ? AND name = ?", $chunk, $this->getQueueID(), $name); - if ($file) { - // use blob for storing serialized object, see https://bugs.php.net/bug.php?id=63419 and https://bugs.php.net/bug.php?id=62361 - //$blob = fopen($file->getTemporaryFile(), 'rb'); - $blob = serialize($file); - $pdo = $this->getQueuesModel()->getConnection()->getPdo(); - $stmt = $pdo->prepare("UPDATE files SET data = :data WHERE queueID = :queueID AND name = :name;"); - $stmt->bindParam(':data', $blob, \PDO::PARAM_LOB); - $queueID = $this->getQueueID(); - $stmt->bindParam(':queueID', $queueID); - $stmt->bindParam(':name', $name); - $stmt->execute(); - } - $this->query("COMMIT WORK"); - } - - - /** - * Get upload directory path - * @return string - */ - function getUploadedFilesTemporaryPath() - { - if (!Queues::$uploadsTempDir) { - throw new InvalidStateException("Directory for temp files is not set."); - } - - if (!file_exists(Queues::$uploadsTempDir)) { - mkdir(Queues::$uploadsTempDir, 0777, true); - } - - if (!is_writable(Queues::$uploadsTempDir)) { - throw new InvalidStateException("Directory for temp files is not writable!"); - } - - return Queues::$uploadsTempDir; - } - - - /** - * Get files - * @return FileUpload[] - */ - function getFiles() - { - $files = []; - foreach($this->getQueuesModel()->getConnection()->query("SELECT * FROM files WHERE queueID = ?", $this->getQueueID())->fetchPairs('id', 'data') as $row) { - if(($file = unserialize($row)) instanceof FileUpload) { - $files[] = $file; - } - }; - return $files; - } - - - /** - * Delete temporary files - */ - function delete() - { - $dir = realpath($this->getUploadedFilesTemporaryPath()); - foreach ($this->getFiles() AS $file) { - $fileDir = dirname($file->getTemporaryFile()); - if (realpath($fileDir) == $dir and file_exists($file->getTemporaryFile())) { - // Delete file only if user leaved file in temp directory - @unlink($file->getTemporaryFile()); // intentionally @ - } - } - - $this->getQueuesModel()->getConnection()->query("DELETE FROM files WHERE queueID = ?", $this->getQueueID()); - } - - - /** - * When was queue last accessed? - * @return int timestamp - */ - function getLastAccess() - { - $lastAccess = (int) $this->getQueuesModel()->getConnection()->query(" - SELECT created - FROM files - WHERE queueID = ? - ORDER BY created DESC - ", $this->getQueueID())->fetch()->created; - return $lastAccess; - } - - -} \ No newline at end of file diff --git a/MultipleFileUpload/Model/MySQL/Queues.php b/MultipleFileUpload/Model/MySQL/Queues.php deleted file mode 100644 index 4c600bd..0000000 --- a/MultipleFileUpload/Model/MySQL/Queues.php +++ /dev/null @@ -1,137 +0,0 @@ -getParameters(); - self::$container = $container; - self::$uploadsTempDir = $parameters['tempDir'] . DIRECTORY_SEPARATOR . "uploads-MFU"; - $this->connection = $connection; - } - - - /** - * Initialize driver - */ - function initialize() - { - - } - - - function getConnection() - { - return $this->connection; - } - - - /** - * Execute query - * @param string $sql - * @return Nette\Database\ResultSet - * @throws InvalidStateException - */ - function query($sql) - { - $res = $this->getConnection()->query($sql); - if (!$res) { - throw new InvalidStateException("Can't execute query: '" . $sql . "'. error: " . $this->getConnection()->lastErrorMsg()); - } - return $res; - } - - /** - * Get queue (create if needed) - * @param string $id - * @return Queue - */ - function getQueue($id) - { - return $this->createQueueObj($id); - } - - - /** - * Factory for Queue - * @param string $queueID - * @return Queue - */ - function createQueueObj($queueID) - { - $parameters = self::$container->getParameters(); - $queue = new Queue($parameters['tempDir']); - $queue->setQueuesModel($this); - $queue->setQueueID($queueID); - $queue->initialize(); - return $queue; - } - - - /** - * Execute cleanup - */ - function cleanup() - { - $this->query('START TRANSACTION'); - foreach ($this->getQueues() AS $queue) { - if ($queue->getLastAccess() < time() - $this->getLifeTime()) { - //$queue->delete(); - } - } - $this->query('COMMIT WORK'); - } - - - /** - * Get all queues - * @return IQueue[] - */ - function getQueues() - { - $queuesOut = array(); - $res = $this->query(' - SELECT queueID - FROM files - GROUP BY queueID - '); - - foreach($res->fetchPairs('queueID') as $row) { - $queuesOut[] = $this->createQueueObj($row['queueID']); - } - - return $queuesOut; - } - -} diff --git a/MultipleFileUpload/Model/MySQL/setupDB.sql b/MultipleFileUpload/Model/MySQL/setupDB.sql deleted file mode 100644 index 052f1ed..0000000 --- a/MultipleFileUpload/Model/MySQL/setupDB.sql +++ /dev/null @@ -1,17 +0,0 @@ ---Table: files - ---DROP TABLE files; - -CREATE TABLE files ( - id integer AUTO_INCREMENT PRIMARY KEY, - queueID char(255) NOT NULL, - created integer NOT NULL, - data blob, - chunk integer NOT NULL DEFAULT 1, - chunks integer NOT NULL DEFAULT 1, - name varchar(255) NOT NULL -); - -CREATE UNIQUE INDEX files_name - ON files - (name); From db98b25d6dad9a23bfa2256897a08b762d4ca851 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kucha=C5=99?= Date: Tue, 4 Oct 2016 21:37:55 +0200 Subject: [PATCH 07/26] NetteDatabaseModel: removed magic configuration from container (+ reformatting) --- MultipleFileUpload/Model/NetteDatabase/Queue.php | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/MultipleFileUpload/Model/NetteDatabase/Queue.php b/MultipleFileUpload/Model/NetteDatabase/Queue.php index ff6913b..c0bcc2e 100644 --- a/MultipleFileUpload/Model/NetteDatabase/Queue.php +++ b/MultipleFileUpload/Model/NetteDatabase/Queue.php @@ -12,7 +12,6 @@ namespace MultipleFileUpload\Model\NetteDatabase; use MultipleFileUpload\Model\BaseQueue, - Nette\Environment, Nette\Http\FileUpload, Nette\InvalidStateException; @@ -68,8 +67,9 @@ function addFileManually($name, $chunk, $chunks) function updateFile($name, $chunk, FileUpload $file = null) { - $this->getConnection()->beginTransaction(); - $selection = $this->getConnection()->table($this->getFilesTable())->where('queueID', $this->getQueueID())->where('name', $name); + $connection = $this->getConnection(); + $connection->beginTransaction(); + $selection = $connection->table($this->getFilesTable())->where('queueID', $this->getQueueID())->where('name', $name); $data = array("chunk" => $chunk); if ($file){ @@ -79,7 +79,7 @@ function updateFile($name, $chunk, FileUpload $file = null) foreach ($selection as $row){ $row->update($data); } - $this->getConnection()->commit(); + $connection->commit(); } @@ -90,17 +90,13 @@ function updateFile($name, $chunk, FileUpload $file = null) function getUploadedFilesTemporaryPath() { if (!Queues::$uploadsTempDir) { - Queues::$uploadsTempDir = Environment::expand("%tempDir%" . DIRECTORY_SEPARATOR . "uploads-MFU"); + throw new InvalidStateException("Directory for temp files is not set."); } if (!file_exists(Queues::$uploadsTempDir)) { mkdir(Queues::$uploadsTempDir, 0777, true); } - if (!is_writable(Queues::$uploadsTempDir)) { - Queues::$uploadsTempDir = Environment::expand("%tempDir%"); - } - if (!is_writable(Queues::$uploadsTempDir)) { throw new InvalidStateException("Directory for temp files is not writable!"); } @@ -152,4 +148,4 @@ function getLastAccess() } -} \ No newline at end of file +} From d4da69a4c572e5af231a07c54ef6228774ce7fa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kucha=C5=99?= Date: Tue, 4 Oct 2016 21:38:23 +0200 Subject: [PATCH 08/26] NetteDatabase/Queues.php: added depencency on Container --- MultipleFileUpload/Model/NetteDatabase/Queues.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/MultipleFileUpload/Model/NetteDatabase/Queues.php b/MultipleFileUpload/Model/NetteDatabase/Queues.php index 63335f9..b909f60 100644 --- a/MultipleFileUpload/Model/NetteDatabase/Queues.php +++ b/MultipleFileUpload/Model/NetteDatabase/Queues.php @@ -13,7 +13,7 @@ use MultipleFileUpload\Model\BaseQueues, MultipleFileUpload\Model\IQueue, - Nette\InvalidStateException; + Nette; /** * Multiple File Uploader driver for Nette\Database @@ -48,9 +48,15 @@ public function getFilesTable(){ return self::$filesTable; } - public function __construct(\Nette\Database\Context $database) + public function __construct($container) { - $this->database = $database; + $parameters = $container->getParameters(); + self::$uploadsTempDir = $parameters['tempDir']; + $temp = $parameters['tempDir'] . DIRECTORY_SEPARATOR . "uploads-MFU"; + $journal = new Nette\Caching\Storages\SQLiteJournal($temp); + $cacheStorage = new Nette\Caching\Storages\FileStorage($temp, $journal); + $structure = new Nette\Database\Structure($container->getService("database.default"), $cacheStorage); + $this->database = new Nette\Database\Context($container->getService("database.default"), $structure); } // From 30a814a2a82a9fcdfc7add42e03216a7ea84b3d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kucha=C5=99?= Date: Tue, 4 Oct 2016 21:38:48 +0200 Subject: [PATCH 09/26] MultipleFileUpload: added dependency on container --- MultipleFileUpload/MultipleFileUpload.php | 43 ++++++++++------------- 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/MultipleFileUpload/MultipleFileUpload.php b/MultipleFileUpload/MultipleFileUpload.php index d4946ea..1731abb 100644 --- a/MultipleFileUpload/MultipleFileUpload.php +++ b/MultipleFileUpload/MultipleFileUpload.php @@ -15,9 +15,9 @@ use MultipleFileUpload\Model\IQueue, MultipleFileUpload\Model\IQueues, MultipleFileUpload\UI\Registrator, - Latte, - Nette, - Nette\Bridges, + Latte, + Nette, + Nette\Bridges, Nette\Forms, Nette\Forms\Container, Nette\Forms\Controls\UploadControl, @@ -63,9 +63,8 @@ class MultipleFileUpload extends UploadControl */ public static $baseWWWRoot = null; - - /** @var Nette\DI\Container */ - private static $container; + /** @var Nette\DI\Container */ + private static $container; /** * Initialize MFU @@ -79,18 +78,19 @@ public static function init() // Set default check callback self::$validateFileCallback = [__CLASS__, "validateFile"]; - - self::$baseWWWRoot = self::$container->getByType('Nette\Http\IRequest')->url->baseUrl . "MultipleFileUpload/"; + self::$baseWWWRoot = self::$container->getByType('Nette\Http\IRequest')->url->baseUrl . "MultipleFileUpload/"; } /** * Register MFU into Nette */ - public static function register($container) + public static function register($container, string $queuesModel) { - self::$container = $container; - self::init(); + self::$container = $container; + $namespace = '\MultipleFileUpload\Model\\'. $queuesModel . '\Queues'; + self::$queuesModel = new $namespace($container); + self::init(); $application = $container->getByType('Nette\Application\Application'); $application->onStartup[] = [__CLASS__, "handleUploads"]; $application->onShutdown[] = [__CLASS__, "cleanCache"]; @@ -176,7 +176,7 @@ public static function validateFile(FileUpload $file) */ public static function cleanCache() { - $parameters = self::$container->getParameters(); + $parameters = self::$container->getParameters(); if (!$parameters['productionMode'] or rand(1, 100) < 5) { self::getQueuesModel()->cleanup(); } @@ -189,13 +189,8 @@ public static function cleanCache() */ public static function getQueuesModel() { - if (!self::$queuesModel) { // if nothing is set, setup sqlite model, which should work on all systems with MySQL - $queuesModel = new Model\MySQL\Queues(self::$container, self::$container->getService("database.default")); - self::setQueuesModel($queuesModel); - } - if (!self::$queuesModel instanceof IQueues) { - throw new InvalidStateException("Queues model is not instance of Model\IQueues!"); + throw new InvalidStateException("Queues model was not set or is not instance of Model\IQueues!"); } return self::$queuesModel; } @@ -330,12 +325,12 @@ public function getControl() $control->addHtml($container); } - $latte = new Latte\Engine(); - $template = new Bridges\ApplicationLatte\Template($latte); - $template->setFile(__DIR__ . DIRECTORY_SEPARATOR . "RegisterJS.latte"); - $template->id = $this->getHtmlId(); - $template->fallbacks = $fallbacks; - $control->addHtml($template->__toString(TRUE)); + $latte = new Latte\Engine(); + $template = new Bridges\ApplicationLatte\Template($latte); + $template->setFile(__DIR__ . DIRECTORY_SEPARATOR . "RegisterJS.latte"); + $template->id = $this->getHtmlId(); + $template->fallbacks = $fallbacks; + $control->addHtml($template->__toString(TRUE)); /* //
$withoutJS = Html::el("div class=withoutJS"); From bd73dcb089d7ca34981b7044e68148ae504d170c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=BDubom=C3=ADr=20Andr=C3=ADsek?= Date: Sun, 25 Sep 2016 18:54:12 +0200 Subject: [PATCH 10/26] DI extension: introduced simple extension --- MultipleFileUpload/Extension.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 MultipleFileUpload/Extension.php diff --git a/MultipleFileUpload/Extension.php b/MultipleFileUpload/Extension.php new file mode 100644 index 0000000..529a464 --- /dev/null +++ b/MultipleFileUpload/Extension.php @@ -0,0 +1,24 @@ +methods['initialize']; + $initialize->addBody('MultipleFileUpload\MultipleFileUpload::init($this->getByType(?), $this->getParameters());', ['Nette\Http\IRequest']); + $initialize->addBody('MultipleFileUpload\MultipleFileUpload::register($this->getService(?));', ['mfuStorage']); + $initialize->addBody('$this->getService(?)->onStartup[] = [?, ?];', ['application', 'MultipleFileUpload\MultipleFileUpload', 'handleUploads']); + $initialize->addBody('$this->getService(?)->onShutdown[] = [?, ?];', ['application', 'MultipleFileUpload\MultipleFileUpload', 'cleanCache']); + } + +} From 91614d667609fa9c0befc036468532a8663a286b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kucha=C5=99?= Date: Tue, 4 Oct 2016 21:48:02 +0200 Subject: [PATCH 11/26] MultipleFileUpload: explicit register() function parameters --- MultipleFileUpload/MultipleFileUpload.php | 41 ++++++++++------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/MultipleFileUpload/MultipleFileUpload.php b/MultipleFileUpload/MultipleFileUpload.php index 1731abb..26e5eb4 100644 --- a/MultipleFileUpload/MultipleFileUpload.php +++ b/MultipleFileUpload/MultipleFileUpload.php @@ -63,37 +63,35 @@ class MultipleFileUpload extends UploadControl */ public static $baseWWWRoot = null; - /** @var Nette\DI\Container */ - private static $container; + /** @var Nette\Http\IRequest */ + private static $request; + /** @var bool */ + private static $productionMode; + /** * Initialize MFU */ - public static function init() + public static function init(Nette\Http\IRequest $request, Array $parameters) { // Init UI registrator $uiReg = self::$interfaceRegistrator = new Registrator(); $uiReg->register("MultipleFileUpload\\UI\\HTML4SingleUpload"); $uiReg->register("MultipleFileUpload\\UI\\Plupload"); - + self::$request = $request; + self::$productionMode = $parameters['productionMode']; // Set default check callback self::$validateFileCallback = [__CLASS__, "validateFile"]; - self::$baseWWWRoot = self::$container->getByType('Nette\Http\IRequest')->url->baseUrl . "MultipleFileUpload/"; + self::$baseWWWRoot = self::$request->url->baseUrl . "MultipleFileUpload/"; } /** * Register MFU into Nette */ - public static function register($container, string $queuesModel) - { - self::$container = $container; - $namespace = '\MultipleFileUpload\Model\\'. $queuesModel . '\Queues'; - self::$queuesModel = new $namespace($container); - self::init(); - $application = $container->getByType('Nette\Application\Application'); - $application->onStartup[] = [__CLASS__, "handleUploads"]; - $application->onShutdown[] = [__CLASS__, "cleanCache"]; + public static function register(Model\IQueues $queuesModel) + { + self::$queuesModel = $queuesModel; } @@ -136,7 +134,7 @@ public static function handleUploads() self::$handleUploadsCalled = true; } - $req = self::$container->getByType('Nette\Http\IRequest'); + $req = self::$request; // Workaround for: http://forum.nettephp.com/cs/3680-httprequest-getheaders-a-content-type $contentType = $req->getHeader("content-type"); if (!$contentType and isset($_SERVER["CONTENT_TYPE"])) { @@ -149,7 +147,7 @@ public static function handleUploads() self::getQueuesModel()->initialize(); - foreach (self::getUIRegistrator()->getInterfaces(self::$container) AS $interface) { + foreach (self::getUIRegistrator()->getInterfaces(self::$request) AS $interface) { // \Nette\Diagnostics\Debugger::log($interface->getReflection()->getName().": is this your upload? ".$interface->isThisYourUpload()); if ($interface->isThisYourUpload()) { $ret = $interface->handleUploads(); @@ -175,9 +173,8 @@ public static function validateFile(FileUpload $file) * Cleans cache */ public static function cleanCache() - { - $parameters = self::$container->getParameters(); - if (!$parameters['productionMode'] or rand(1, 100) < 5) { + { + if (false == self::$productionMode or rand(1, 100) < 5) { self::getQueuesModel()->cleanup(); } } @@ -257,15 +254,13 @@ public static function getHead() */ public $simUploadThreads; - - /** + /** * Constructor * @param string $label Label */ public function __construct($label = NULL, $maxSelectedFiles = 25) { parent::__construct($label); - if (!self::$handleUploadsCalled) { throw new InvalidStateException("MultipleFileUpload::handleUpload() has not been called. Call `MultipleFileUpload::register();` from your bootstrap before you call Applicaton::run();"); }; @@ -294,7 +289,7 @@ public function getControl() //
$fallbacks = array(); - $interfaces = self::getUIRegistrator()->getInterfaces(self::$container); + $interfaces = self::getUIRegistrator()->getInterfaces(self::$request); $num = count($interfaces); $cnt = 1; foreach ($interfaces AS $interface) { From 7c2d610e73a46cbee324225a4e9df6b9393dd1a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kucha=C5=99?= Date: Tue, 4 Oct 2016 21:49:23 +0200 Subject: [PATCH 12/26] Queues: ??? --- MultipleFileUpload/Model/NetteDatabase/Queues.php | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/MultipleFileUpload/Model/NetteDatabase/Queues.php b/MultipleFileUpload/Model/NetteDatabase/Queues.php index b909f60..21bb900 100644 --- a/MultipleFileUpload/Model/NetteDatabase/Queues.php +++ b/MultipleFileUpload/Model/NetteDatabase/Queues.php @@ -48,15 +48,14 @@ public function getFilesTable(){ return self::$filesTable; } - public function __construct($container) + public function __construct($database, $tempDir) { - $parameters = $container->getParameters(); - self::$uploadsTempDir = $parameters['tempDir']; - $temp = $parameters['tempDir'] . DIRECTORY_SEPARATOR . "uploads-MFU"; - $journal = new Nette\Caching\Storages\SQLiteJournal($temp); - $cacheStorage = new Nette\Caching\Storages\FileStorage($temp, $journal); - $structure = new Nette\Database\Structure($container->getService("database.default"), $cacheStorage); - $this->database = new Nette\Database\Context($container->getService("database.default"), $structure); + $connection = new Nette\Database\Connection($database['dsn'], $database['user'], $database['password']); + self::$uploadsTempDir = $tempDir . DIRECTORY_SEPARATOR . "uploads-MFU"; + $journal = new Nette\Caching\Storages\SQLiteJournal(self::$uploadsTempDir); + $cacheStorage = new Nette\Caching\Storages\FileStorage(self::$uploadsTempDir, $journal); + $structure = new Nette\Database\Structure($connection, $cacheStorage); + $this->database = new Nette\Database\Context($connection, $structure); } // From 683510a717aa376cd97cd7494bf9b15feb84117d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=BDubom=C3=ADr=20Andr=C3=ADsek?= Date: Sun, 25 Sep 2016 19:37:28 +0200 Subject: [PATCH 13/26] UI\Registrator: requires HttpRequest insted of container --- MultipleFileUpload/UI/Registrator.php | 129 +++++++++++++------------- 1 file changed, 65 insertions(+), 64 deletions(-) diff --git a/MultipleFileUpload/UI/Registrator.php b/MultipleFileUpload/UI/Registrator.php index e3aaf22..79f0f1f 100644 --- a/MultipleFileUpload/UI/Registrator.php +++ b/MultipleFileUpload/UI/Registrator.php @@ -1,65 +1,66 @@ -interfaces[] = $interface; - } elseif (is_string($interface)) { - // User gives us only namespace - $this->interfaces[] = $interface . "\\Controller"; - } else { - throw new InvalidArgumentException("Not supported interface!"); - } - return $this; - } - - - public function clear() - { - $this->interfaces = array(); - return $this; - } - - - public function getInterfaces($container) - { - $interfaces = $this->interfaces; - foreach ($interfaces AS $key => $interface) { - if (is_string($interface)) { - $interface = $interfaces[$key] = new $interface($container->getByType('Nette\Http\IRequest')); - } - if (!$interface instanceof IUserInterface) { - throw new InvalidArgumentException($interface->reflection->name . " is not compatible with MFU!"); - } - } - $this->interfaces = $interfaces; - return array_reverse($interfaces); - } - - +interfaces[] = $interface; + } elseif (is_string($interface)) { + // User gives us only namespace + $this->interfaces[] = $interface . "\\Controller"; + } else { + throw new InvalidArgumentException("Not supported interface!"); + } + return $this; + } + + + public function clear() + { + $this->interfaces = array(); + return $this; + } + + + public function getInterfaces(Request $request) + { + $interfaces = $this->interfaces; + foreach ($interfaces AS $key => $interface) { + if (is_string($interface)) { + $interface = $interfaces[$key] = new $interface($request); + } + if (!$interface instanceof IUserInterface) { + throw new InvalidArgumentException($interface->reflection->name . " is not compatible with MFU!"); + } + } + $this->interfaces = $interfaces; + return array_reverse($interfaces); + } + + } \ No newline at end of file From 4cbaf8bd5ca355ec0eb54c31371a772c81476cfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kucha=C5=99?= Date: Tue, 4 Oct 2016 21:52:33 +0200 Subject: [PATCH 14/26] UI\AbstractInterface: requires HttpRequest instead of Container --- MultipleFileUpload/UI/AbstractInterface.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/MultipleFileUpload/UI/AbstractInterface.php b/MultipleFileUpload/UI/AbstractInterface.php index 6d06ea8..dbba0d2 100644 --- a/MultipleFileUpload/UI/AbstractInterface.php +++ b/MultipleFileUpload/UI/AbstractInterface.php @@ -12,12 +12,12 @@ namespace MultipleFileUpload\UI; use MultipleFileUpload\MultipleFileUpload, - Latte, - Nette\Bridges, + Nette, + Latte, + Nette\Bridges, Nette\Http\FileUpload, Nette\Http\Request, - Nette\Object, - Nette\Http\IRequest; + Nette\Object; /** * Abstract UI Controller @@ -28,7 +28,7 @@ abstract class AbstractInterface extends Object implements IUserInterface protected $httpRequest; - public function __construct(IRequest $httpRequest) + public function __construct(Nette\Http\Request$httpRequest) { $this->httpRequest = $httpRequest; } From d3a6884c6a601711e15ca51ebf0377ca8a29540f Mon Sep 17 00:00:00 2001 From: Lubo Date: Mon, 3 Oct 2016 14:55:44 +0200 Subject: [PATCH 15/26] Queues: fixed edge case --- MultipleFileUpload/Model/NetteDatabase/Queues.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MultipleFileUpload/Model/NetteDatabase/Queues.php b/MultipleFileUpload/Model/NetteDatabase/Queues.php index 21bb900..6f510c1 100644 --- a/MultipleFileUpload/Model/NetteDatabase/Queues.php +++ b/MultipleFileUpload/Model/NetteDatabase/Queues.php @@ -52,8 +52,8 @@ public function __construct($database, $tempDir) { $connection = new Nette\Database\Connection($database['dsn'], $database['user'], $database['password']); self::$uploadsTempDir = $tempDir . DIRECTORY_SEPARATOR . "uploads-MFU"; - $journal = new Nette\Caching\Storages\SQLiteJournal(self::$uploadsTempDir); - $cacheStorage = new Nette\Caching\Storages\FileStorage(self::$uploadsTempDir, $journal); + !file_exists(self::$uploadsTempDir) ? mkdir(self::$uploadsTempDir, 0775, true) : null; + $cacheStorage = new Nette\Caching\Storages\FileStorage(self::$uploadsTempDir); $structure = new Nette\Database\Structure($connection, $cacheStorage); $this->database = new Nette\Database\Context($connection, $structure); } From 6f9352f63f9ffb1b9114ecffc0e03a708602bb88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kucha=C5=99?= Date: Tue, 4 Oct 2016 21:34:17 +0200 Subject: [PATCH 16/26] notes --- MultipleFileUpload/Model/NetteDatabase/Queue.php | 2 +- MultipleFileUpload/Model/NetteDatabase/Queues.php | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/MultipleFileUpload/Model/NetteDatabase/Queue.php b/MultipleFileUpload/Model/NetteDatabase/Queue.php index c0bcc2e..60902a7 100644 --- a/MultipleFileUpload/Model/NetteDatabase/Queue.php +++ b/MultipleFileUpload/Model/NetteDatabase/Queue.php @@ -90,7 +90,7 @@ function updateFile($name, $chunk, FileUpload $file = null) function getUploadedFilesTemporaryPath() { if (!Queues::$uploadsTempDir) { - throw new InvalidStateException("Directory for temp files is not set."); + throw new InvalidStateException("Directory for temp files is not set."); } if (!file_exists(Queues::$uploadsTempDir)) { diff --git a/MultipleFileUpload/Model/NetteDatabase/Queues.php b/MultipleFileUpload/Model/NetteDatabase/Queues.php index 6f510c1..478d1af 100644 --- a/MultipleFileUpload/Model/NetteDatabase/Queues.php +++ b/MultipleFileUpload/Model/NetteDatabase/Queues.php @@ -50,9 +50,10 @@ public function getFilesTable(){ public function __construct($database, $tempDir) { - $connection = new Nette\Database\Connection($database['dsn'], $database['user'], $database['password']); + // TODO: wrong; there must be not dependency on container here + $connection = new Nette\Database\Connection($database['dsn'], $database['user'], $database['password']); self::$uploadsTempDir = $tempDir . DIRECTORY_SEPARATOR . "uploads-MFU"; - !file_exists(self::$uploadsTempDir) ? mkdir(self::$uploadsTempDir, 0775, true) : null; + !file_exists(self::$uploadsTempDir) ? mkdir(self::$uploadsTempDir, 0775, TRUE) : NULL; $cacheStorage = new Nette\Caching\Storages\FileStorage(self::$uploadsTempDir); $structure = new Nette\Database\Structure($connection, $cacheStorage); $this->database = new Nette\Database\Context($connection, $structure); From c763cf50aed7e2049ba1efc974683c81713ed212 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kucha=C5=99?= Date: Tue, 4 Oct 2016 21:41:28 +0200 Subject: [PATCH 17/26] MultipleFileUpload: formatting --- MultipleFileUpload/MultipleFileUpload.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/MultipleFileUpload/MultipleFileUpload.php b/MultipleFileUpload/MultipleFileUpload.php index 26e5eb4..3598471 100644 --- a/MultipleFileUpload/MultipleFileUpload.php +++ b/MultipleFileUpload/MultipleFileUpload.php @@ -66,9 +66,9 @@ class MultipleFileUpload extends UploadControl /** @var Nette\Http\IRequest */ private static $request; - /** @var bool */ - private static $productionMode; - + /** @var bool */ + private static $productionMode; + /** * Initialize MFU */ @@ -78,8 +78,8 @@ public static function init(Nette\Http\IRequest $request, Array $parameters) $uiReg = self::$interfaceRegistrator = new Registrator(); $uiReg->register("MultipleFileUpload\\UI\\HTML4SingleUpload"); $uiReg->register("MultipleFileUpload\\UI\\Plupload"); - self::$request = $request; - self::$productionMode = $parameters['productionMode']; + self::$request = $request; + self::$productionMode = $parameters['productionMode']; // Set default check callback self::$validateFileCallback = [__CLASS__, "validateFile"]; self::$baseWWWRoot = self::$request->url->baseUrl . "MultipleFileUpload/"; @@ -173,8 +173,8 @@ public static function validateFile(FileUpload $file) * Cleans cache */ public static function cleanCache() - { - if (false == self::$productionMode or rand(1, 100) < 5) { + { + if (FALSE == self::$productionMode or rand(1, 100) < 5) { self::getQueuesModel()->cleanup(); } } From e53bc11913610c44ea6d01b6b17d33a66824a3b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kucha=C5=99?= Date: Tue, 4 Oct 2016 21:45:49 +0200 Subject: [PATCH 18/26] formatting --- MultipleFileUpload/MultipleFileUpload.php | 2 +- MultipleFileUpload/UI/AbstractInterface.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MultipleFileUpload/MultipleFileUpload.php b/MultipleFileUpload/MultipleFileUpload.php index 3598471..56b64f3 100644 --- a/MultipleFileUpload/MultipleFileUpload.php +++ b/MultipleFileUpload/MultipleFileUpload.php @@ -254,7 +254,7 @@ public static function getHead() */ public $simUploadThreads; - /** + /** * Constructor * @param string $label Label */ diff --git a/MultipleFileUpload/UI/AbstractInterface.php b/MultipleFileUpload/UI/AbstractInterface.php index dbba0d2..dcfb765 100644 --- a/MultipleFileUpload/UI/AbstractInterface.php +++ b/MultipleFileUpload/UI/AbstractInterface.php @@ -28,7 +28,7 @@ abstract class AbstractInterface extends Object implements IUserInterface protected $httpRequest; - public function __construct(Nette\Http\Request$httpRequest) + public function __construct(Nette\Http\Request $httpRequest) { $this->httpRequest = $httpRequest; } From 27ef5c53f18fe6ea6e737a594c25ec07dcd37bfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kucha=C5=99?= Date: Tue, 4 Oct 2016 21:54:45 +0200 Subject: [PATCH 19/26] refactoring: removed wrongly used ternary operator --- MultipleFileUpload/Model/NetteDatabase/Queues.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MultipleFileUpload/Model/NetteDatabase/Queues.php b/MultipleFileUpload/Model/NetteDatabase/Queues.php index 478d1af..0d2272d 100644 --- a/MultipleFileUpload/Model/NetteDatabase/Queues.php +++ b/MultipleFileUpload/Model/NetteDatabase/Queues.php @@ -53,7 +53,9 @@ public function __construct($database, $tempDir) // TODO: wrong; there must be not dependency on container here $connection = new Nette\Database\Connection($database['dsn'], $database['user'], $database['password']); self::$uploadsTempDir = $tempDir . DIRECTORY_SEPARATOR . "uploads-MFU"; - !file_exists(self::$uploadsTempDir) ? mkdir(self::$uploadsTempDir, 0775, TRUE) : NULL; + if(!file_exists(self::$uploadsTempDir)) { + mkdir(self::$uploadsTempDir, 0775, TRUE); + }; $cacheStorage = new Nette\Caching\Storages\FileStorage(self::$uploadsTempDir); $structure = new Nette\Database\Structure($connection, $cacheStorage); $this->database = new Nette\Database\Context($connection, $structure); From d30cb3284c993f56b100d2bbacab27af9715ed9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=BDubom=C3=ADr=20Andr=C3=ADsek?= Date: Sun, 16 Oct 2016 20:14:59 +0200 Subject: [PATCH 20/26] DI model --- MultipleFileUpload/Model/NetteDatabase/Queues.php | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/MultipleFileUpload/Model/NetteDatabase/Queues.php b/MultipleFileUpload/Model/NetteDatabase/Queues.php index 0d2272d..ff48f30 100644 --- a/MultipleFileUpload/Model/NetteDatabase/Queues.php +++ b/MultipleFileUpload/Model/NetteDatabase/Queues.php @@ -48,17 +48,13 @@ public function getFilesTable(){ return self::$filesTable; } - public function __construct($database, $tempDir) + public function __construct(string $tempDir, Nette\Database\Context $database) { - // TODO: wrong; there must be not dependency on container here - $connection = new Nette\Database\Connection($database['dsn'], $database['user'], $database['password']); self::$uploadsTempDir = $tempDir . DIRECTORY_SEPARATOR . "uploads-MFU"; if(!file_exists(self::$uploadsTempDir)) { mkdir(self::$uploadsTempDir, 0775, TRUE); - }; - $cacheStorage = new Nette\Caching\Storages\FileStorage(self::$uploadsTempDir); - $structure = new Nette\Database\Structure($connection, $cacheStorage); - $this->database = new Nette\Database\Context($connection, $structure); + } + $this->database = $database; } // From 9aa59f323b1e0b8549459ea57ad22aeadd0e408e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=BDubom=C3=ADr=20Andr=C3=ADsek?= Date: Sat, 22 Oct 2016 14:13:38 +0200 Subject: [PATCH 21/26] [Extension] --- MultipleFileUpload/Extension.php | 38 +- MultipleFileUpload/MultipleFileUpload.php | 1059 ++++++++++----------- MultipleFileUpload/UI/Registrator.php | 16 + MultipleFileUpload/config.neon | 4 + 4 files changed, 567 insertions(+), 550 deletions(-) create mode 100644 MultipleFileUpload/config.neon diff --git a/MultipleFileUpload/Extension.php b/MultipleFileUpload/Extension.php index 529a464..b279fa5 100644 --- a/MultipleFileUpload/Extension.php +++ b/MultipleFileUpload/Extension.php @@ -4,21 +4,27 @@ use Nette; -class Extension extends Nette\DI\CompilerExtension { - - public function loadConfiguration() { - } - - public function beforeCompile() { - parent::beforeCompile(); - } - - public function afterCompile(Nette\PhpGenerator\ClassType $class) { - $initialize = $class->methods['initialize']; - $initialize->addBody('MultipleFileUpload\MultipleFileUpload::init($this->getByType(?), $this->getParameters());', ['Nette\Http\IRequest']); - $initialize->addBody('MultipleFileUpload\MultipleFileUpload::register($this->getService(?));', ['mfuStorage']); - $initialize->addBody('$this->getService(?)->onStartup[] = [?, ?];', ['application', 'MultipleFileUpload\MultipleFileUpload', 'handleUploads']); - $initialize->addBody('$this->getService(?)->onShutdown[] = [?, ?];', ['application', 'MultipleFileUpload\MultipleFileUpload', 'cleanCache']); - } +class Extension extends Nette\DI\CompilerExtension +{ + + + public function loadConfiguration() { + $builder = $this->getContainerBuilder(); + $this->compiler->parseServices($builder, $this->loadFromFile(__DIR__ . '/config.neon')); + } + + + public function beforeCompile() { + parent::beforeCompile(); + } + + + public function afterCompile(Nette\PhpGenerator\ClassType $class) { + $initialize = $class->methods['initialize']; + $initialize->addBody('Nette\Forms\Container::extensionMethod("\Nette\Forms\Container::addMultipleFileUpload", function (\Nette\Forms\Container $_this, $name, $label = null, $maxFileSize = 25) { return $_this[$name] = new MultipleFileUpload\MultipleFileUpload($label, $maxFileSize, $this->getByType(?), $this->getByType(?)); });', ['Nette\Http\IRequest', 'MultipleFileUpload\UI\Registrator']); + $initialize->addBody('MultipleFileUpload\MultipleFileUpload::init($this->getService(?), $this->getByType(?), $this->getByType(?));', ['mfuStorage', 'Nette\Http\IRequest', 'MultipleFileUpload\UI\Registrator']); + $initialize->addBody('$this->getService(?)->onStartup[] = [?, ?];', ['application', 'MultipleFileUpload\MultipleFileUpload', 'handleUploads']); + $initialize->addBody('$this->getService(?)->onShutdown[] = [?, ?];', ['application', 'MultipleFileUpload\MultipleFileUpload', 'cleanCache']); + } } diff --git a/MultipleFileUpload/MultipleFileUpload.php b/MultipleFileUpload/MultipleFileUpload.php index 56b64f3..c3114f2 100644 --- a/MultipleFileUpload/MultipleFileUpload.php +++ b/MultipleFileUpload/MultipleFileUpload.php @@ -1,534 +1,525 @@ -register("MultipleFileUpload\\UI\\HTML4SingleUpload"); - $uiReg->register("MultipleFileUpload\\UI\\Plupload"); - self::$request = $request; - self::$productionMode = $parameters['productionMode']; - // Set default check callback - self::$validateFileCallback = [__CLASS__, "validateFile"]; - self::$baseWWWRoot = self::$request->url->baseUrl . "MultipleFileUpload/"; - } - - - /** - * Register MFU into Nette - */ - public static function register(Model\IQueues $queuesModel) - { - self::$queuesModel = $queuesModel; - } - - - /* ########## HANDLING UPLOADS ########### */ - - /** - * Sets life time of files in queue (shortcut for self::getQueuesModel()->setLifeTime) - * @param int $lifeTime Time in seconds - */ - static function setLifeTime($lifeTime) - { - self::getQueuesModel() - ->setLifeTime((int) $lifeTime); - } - - - protected static function _doSetLifetime() - { - // Auto config of lifeTime - $maxInputTime = (int) ini_get("max_input_time"); - // default if no max input time defined (-1) - if ($maxInputTime < 0) { - $lifeTime = 3600; - } else { - $lifeTime = $maxInputTime + 5; - } - - self::setLifeTime($lifeTime); - } - - - /** - * Handles uploading files - */ - public static function handleUploads() - { - if (self::$handleUploadsCalled === true) { - return; - } else { - self::$handleUploadsCalled = true; - } - - $req = self::$request; - // Workaround for: http://forum.nettephp.com/cs/3680-httprequest-getheaders-a-content-type - $contentType = $req->getHeader("content-type"); - if (!$contentType and isset($_SERVER["CONTENT_TYPE"])) { - $contentType = $_SERVER["CONTENT_TYPE"]; - } - - if ($req->getMethod() !== "POST") { - return; - } - - self::getQueuesModel()->initialize(); - - foreach (self::getUIRegistrator()->getInterfaces(self::$request) AS $interface) { -// \Nette\Diagnostics\Debugger::log($interface->getReflection()->getName().": is this your upload? ".$interface->isThisYourUpload()); - if ($interface->isThisYourUpload()) { - $ret = $interface->handleUploads(); - if ($ret === true) - break; - } - } - } - - - /** - * Checks file if is ok and can be processed - * @param FileUpload $file - * @return bool - */ - public static function validateFile(FileUpload $file) - { - return $file->isOk(); - } - - - /** - * Cleans cache - */ - public static function cleanCache() - { - if (FALSE == self::$productionMode or rand(1, 100) < 5) { - self::getQueuesModel()->cleanup(); - } - } - - - /** - * @return IQueues - * @throws InvalidStateException - */ - public static function getQueuesModel() - { - if (!self::$queuesModel instanceof IQueues) { - throw new InvalidStateException("Queues model was not set or is not instance of Model\IQueues!"); - } - return self::$queuesModel; - } - - - /** - * Sets new queues model - * @param IQueues $model - */ - public static function setQueuesModel(IQueues $model) { - self::$queuesModel = $model; - self::_doSetLifetime(); - } - - - /** - * @return Registrator - */ - public static function getUIRegistrator() - { - if (!self::$interfaceRegistrator instanceof Registrator) { - throw new InvalidStateException("Interface registrator is not instance of MultipleFileUpload\UI\Registrator!"); - } - return self::$interfaceRegistrator; - } - - - public static function getHead() - { - // TODO: Add MFUFallbackController? - - $out = ""; - foreach (self::getUIRegistrator()->getInterfaces() AS $interface) { - $out .= $interface->renderHeadSection(); - } - return $out; - } - - - /* * **************************************************************************** - * ************************* Form Control ************************************** - * ***************************************************************************** */ - /** - * Unique identifier - * @var string - */ - public $token; - - /** - * Maximum selected files in one input - * @var int - */ - public $maxFiles; - - /** - * Maximum file size of single uploaded file - * @var int - */ - public $maxFileSize; - - /** - * How many threads will be used to upload files - * @var int - */ - public $simUploadThreads; - - /** - * Constructor - * @param string $label Label - */ - public function __construct($label = NULL, $maxSelectedFiles = 25) - { - parent::__construct($label); - if (!self::$handleUploadsCalled) { - throw new InvalidStateException("MultipleFileUpload::handleUpload() has not been called. Call `MultipleFileUpload::register();` from your bootstrap before you call Applicaton::run();"); - }; - - $this->maxFiles = $maxSelectedFiles; - $this->control = Html::el("div"); // TODO: support for prototype - $this->maxFileSize = self::parseIniSize(ini_get('upload_max_filesize')); - $this->simUploadThreads = 5; - } - - - /** - * Generates control - * @return Html - */ - public function getControl() - { - $this->setOption('rendered', TRUE); - - // Create control - $control = Html::el('div class=MultipleFileUpload')->id($this->getHtmlId()); - - //
- $tokenField = Html::el('input type=hidden')->name($this->getHtmlName() . '[token]')->value($this->getToken()); - $control->addHtml($tokenField); - //
- - $fallbacks = array(); - $interfaces = self::getUIRegistrator()->getInterfaces(self::$request); - $num = count($interfaces); - $cnt = 1; - foreach ($interfaces AS $interface) { - $html = $interface->render($this); - // remove wrapping {else} diff --git a/MultipleFileUpload/UI/Swfupload/Controller.php b/MultipleFileUpload/UI/Swfupload/Controller.php index cb8bac2..f9b6908 100644 --- a/MultipleFileUpload/UI/Swfupload/Controller.php +++ b/MultipleFileUpload/UI/Swfupload/Controller.php @@ -1,113 +1,116 @@ -httpRequest->getPost('sender') === "MFU-Swfupload"; - } - - - /** - * Handles uploaded files - * forwards it to model - */ - public function handleUploads() - { - $token = $this->httpRequest->getPost('token'); - if (!$token) { - return; - } - - /* @var $file FileUpload */ - foreach ($this->httpRequest->getFiles() AS $file) { - self::processFile($token, $file); - } - - // Response to client - echo "1"; - - // End the script - exit; - } - - - /** - * Renders interface to
- */ - public function render(MultipleFileUpload $upload) - { - $template = $this->createTemplate(dirname(__FILE__) . "/html.latte"); - $template->swfuId = $upload->getHtmlId() . "-swfuBox"; - return $template->__toString(TRUE); - } - - - /** - * Renders JavaScript body of function. - */ - public function renderInitJavaScript(MultipleFileUpload $upload) - { - $tpl = $this->createTemplate(dirname(__FILE__) . "/initJS.latte"); - $tpl->sizeLimit = ini_get('upload_max_filesize') . 'B'; - $tpl->token = $upload->getToken(); - $tpl->maxFiles = $upload->maxFiles; - $tpl->backLink = (string) $upload->form->action; - $tpl->swfuId = $upload->getHtmlId() . "-swfuBox"; - $tpl->simUploadFiles = $upload->simUploadThreads; - return $tpl->__toString(TRUE); - } - - - /** - * Renders JavaScript body of function. - */ - public function renderDestructJavaScript(MultipleFileUpload $upload) - { - return $this->createTemplate(dirname(__FILE__) . "/destructJS.js")->__toString(TRUE); - } - - - /** - * Renders set-up tags to attribute - */ - public function renderHeadSection() - { - return $this->createTemplate(dirname(__FILE__) . "/head.latte")->__toString(TRUE); - } - - +httpRequest->getPost('sender') === "MFU-Swfupload"; + } + + + /** + * Handles uploaded files + * forwards it to model + */ + public function handleUploads() + { + $token = $this->httpRequest->getPost('token'); + if (!$token) { + return; + } + + /* @var $file FileUpload */ + foreach ($this->httpRequest->getFiles() AS $file) { + self::processFile($token, $file); + } + + // Response to client + echo "1"; + + // End the script + exit; + } + + + /** + * Renders interface to
+ */ + public function render(MultipleFileUpload $upload) + { + $template = $this->createTemplate(dirname(__FILE__) . "/html.latte"); + $template->swfuId = $upload->getHtmlId() . "-swfuBox"; + return $template->__toString(TRUE); + } + + + /** + * Renders JavaScript body of function. + */ + public function renderInitJavaScript(MultipleFileUpload $upload) + { + $template = $this->createTemplate(dirname(__FILE__) . "/initJS.latte"); + $template->sizeLimit = ini_get('upload_max_filesize') . 'B'; + $template->token = $upload->getToken(); + $template->maxFiles = $upload->maxFiles; + $template->backLink = (string) $upload->form->action; + $template->swfuId = $upload->getHtmlId() . "-swfuBox"; + $template->simUploadFiles = $upload->simUploadThreads; + $template->flash_url = $this->httpRequest->url->baseUrl . '/swf/swfupload.swf'; + $template->flash9_url = $this->httpRequest->url->baseUrl . '/swf/swfupload_fp9.swf'; + $template->button_image_url = $this->httpRequest->url->baseUrl . 'imgs/XPButtonUploadText_89x88.png'; + return $template->__toString(TRUE); + } + + + /** + * Renders JavaScript body of function. + */ + public function renderDestructJavaScript(MultipleFileUpload $upload) + { + return $this->createTemplate(dirname(__FILE__) . "/destructJS.js")->__toString(TRUE); + } + + + /** + * Renders set-up tags to attribute + */ + public function renderHeadSection() + { + return $this->createTemplate(dirname(__FILE__) . "/head.latte")->__toString(TRUE); + } + + } \ No newline at end of file diff --git a/MultipleFileUpload/UI/Swfupload/initJS.latte b/MultipleFileUpload/UI/Swfupload/initJS.latte index dd3d1f4..eb48263 100644 --- a/MultipleFileUpload/UI/Swfupload/initJS.latte +++ b/MultipleFileUpload/UI/Swfupload/initJS.latte @@ -1,34 +1,34 @@ - \ No newline at end of file From 38200123a3f356a02a6420e2e349535cafee2164 Mon Sep 17 00:00:00 2001 From: Lubo Date: Mon, 14 Nov 2016 09:43:44 +0100 Subject: [PATCH 24/26] [NetteDatabase php 5.6 cmopatibility] --- MultipleFileUpload/Model/NetteDatabase/Queues.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MultipleFileUpload/Model/NetteDatabase/Queues.php b/MultipleFileUpload/Model/NetteDatabase/Queues.php index ff48f30..d0da20e 100644 --- a/MultipleFileUpload/Model/NetteDatabase/Queues.php +++ b/MultipleFileUpload/Model/NetteDatabase/Queues.php @@ -48,7 +48,7 @@ public function getFilesTable(){ return self::$filesTable; } - public function __construct(string $tempDir, Nette\Database\Context $database) + public function __construct($tempDir, Nette\Database\Context $database) { self::$uploadsTempDir = $tempDir . DIRECTORY_SEPARATOR . "uploads-MFU"; if(!file_exists(self::$uploadsTempDir)) { From 1494fbf208c230a3629232a38fb94ce564ad8d39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kucha=C5=99?= Date: Sat, 28 Jan 2017 17:14:12 +0100 Subject: [PATCH 25/26] todos and comments --- MultipleFileUpload/Extension.php | 34 +++- MultipleFileUpload/Model/Dibi/Queue.php | 3 +- MultipleFileUpload/Model/Dibi/Queues.php | 10 +- .../Model/NetteDatabase/Queues.php | 4 +- MultipleFileUpload/Model/SQLite/.gitignore | 1 - MultipleFileUpload/Model/SQLite/Queue.php | 131 ------------ MultipleFileUpload/Model/SQLite/Queues.php | 189 ------------------ MultipleFileUpload/Model/SQLite/setupDB.sql | 17 -- MultipleFileUpload/Model/SQLite3/Queues.php | 13 +- MultipleFileUpload/MultipleFileUpload.php | 8 +- 10 files changed, 53 insertions(+), 357 deletions(-) delete mode 100644 MultipleFileUpload/Model/SQLite/.gitignore delete mode 100644 MultipleFileUpload/Model/SQLite/Queue.php delete mode 100644 MultipleFileUpload/Model/SQLite/Queues.php delete mode 100644 MultipleFileUpload/Model/SQLite/setupDB.sql diff --git a/MultipleFileUpload/Extension.php b/MultipleFileUpload/Extension.php index b279fa5..fc9cfbf 100644 --- a/MultipleFileUpload/Extension.php +++ b/MultipleFileUpload/Extension.php @@ -6,8 +6,7 @@ class Extension extends Nette\DI\CompilerExtension { - - + public function loadConfiguration() { $builder = $this->getContainerBuilder(); $this->compiler->parseServices($builder, $this->loadFromFile(__DIR__ . '/config.neon')); @@ -21,10 +20,33 @@ public function beforeCompile() { public function afterCompile(Nette\PhpGenerator\ClassType $class) { $initialize = $class->methods['initialize']; - $initialize->addBody('Nette\Forms\Container::extensionMethod("\Nette\Forms\Container::addMultipleFileUpload", function (\Nette\Forms\Container $_this, $name, $label = null, $maxFileSize = 25) { return $_this[$name] = new MultipleFileUpload\MultipleFileUpload($label, $maxFileSize, $this->getByType(?), $this->getByType(?)); });', ['Nette\Http\IRequest', 'MultipleFileUpload\UI\Registrator']); - $initialize->addBody('MultipleFileUpload\MultipleFileUpload::init($this->getService(?), $this->getByType(?), $this->getByType(?));', ['mfuStorage', 'Nette\Http\IRequest', 'MultipleFileUpload\UI\Registrator']); - $initialize->addBody('$this->getService(?)->onStartup[] = [?, ?];', ['application', 'MultipleFileUpload\MultipleFileUpload', 'handleUploads']); - $initialize->addBody('$this->getService(?)->onShutdown[] = [?, ?];', ['application', 'MultipleFileUpload\MultipleFileUpload', 'cleanCache']); + + // add ->addMultipleFileUpload shortcut into forms + $initialize->addBody( + 'Nette\Forms\Container::extensionMethod( + "\Nette\Forms\Container::addMultipleFileUpload", + function (\Nette\Forms\Container $_this, $name, $label = null, $maxFileSize = 25) { + return $_this[$name] = new MultipleFileUpload\MultipleFileUpload($label, $maxFileSize, $this->getByType(?), $this->getByType(?)); + } + );', + ['Nette\Http\IRequest', 'MultipleFileUpload\UI\Registrator'] + ); + + $initialize->addBody( + 'MultipleFileUpload\MultipleFileUpload::init( + $this->getByType(?), $this->getByType(?), $this->getByType(?) + );', + ['MultipleFileUpload\Model\IQueues', 'Nette\Http\IRequest', 'MultipleFileUpload\UI\Registrator'] + ); + + $initialize->addBody( + '$this->getService(?)->onStartup[] = [?, ?];', + ['application', 'MultipleFileUpload\MultipleFileUpload', 'handleUploads'] + ); + $initialize->addBody( + '$this->getService(?)->onShutdown[] = [?, ?];', + ['application', 'MultipleFileUpload\MultipleFileUpload', 'cleanCache'] + ); } } diff --git a/MultipleFileUpload/Model/Dibi/Queue.php b/MultipleFileUpload/Model/Dibi/Queue.php index 3333a8d..5c5527b 100644 --- a/MultipleFileUpload/Model/Dibi/Queue.php +++ b/MultipleFileUpload/Model/Dibi/Queue.php @@ -24,6 +24,7 @@ */ class Queue extends BaseQueue { + // todo: use $this->queuesModel->getTempDir() (non-existing now) /** * Executes query @@ -158,4 +159,4 @@ function getLastAccess() } -} \ No newline at end of file +} diff --git a/MultipleFileUpload/Model/Dibi/Queues.php b/MultipleFileUpload/Model/Dibi/Queues.php index e10f43c..e582284 100644 --- a/MultipleFileUpload/Model/Dibi/Queues.php +++ b/MultipleFileUpload/Model/Dibi/Queues.php @@ -44,9 +44,13 @@ function initialize() } + // todo: Queue should have reference to Queues (remove static dependency ---> there is then not assumed that there is onlu one Queues instance in the app) + // todo: remove self::$uploadsTempDir ---> create private $uploadsTempDir + // todo: create getTempDir() + public function __construct(string $tempDir, DibiConnection $conection) { - self::$uploadsTempDir = $tempDir . DIRECTORY_SEPARATOR . "uploads-MFU"; + self::$uploadsTempDir = $tempDir; if(!file_exists(self::$uploadsTempDir)) { mkdir(self::$uploadsTempDir, 0775, TRUE); } @@ -80,7 +84,7 @@ function getQueue($id) */ function createQueueObj($queueID) { - $queue = new Queue(); + $queue = new Queue(); // todo: remove setQueuesModel --> move to __construct $queue->setQueuesModel($this); $queue->setQueueID($queueID); $queue->initialize(); @@ -121,4 +125,4 @@ function getQueues() } -} \ No newline at end of file +} diff --git a/MultipleFileUpload/Model/NetteDatabase/Queues.php b/MultipleFileUpload/Model/NetteDatabase/Queues.php index d0da20e..99ca727 100644 --- a/MultipleFileUpload/Model/NetteDatabase/Queues.php +++ b/MultipleFileUpload/Model/NetteDatabase/Queues.php @@ -50,7 +50,7 @@ public function getFilesTable(){ public function __construct($tempDir, Nette\Database\Context $database) { - self::$uploadsTempDir = $tempDir . DIRECTORY_SEPARATOR . "uploads-MFU"; + self::$uploadsTempDir = $tempDir; if(!file_exists(self::$uploadsTempDir)) { mkdir(self::$uploadsTempDir, 0775, TRUE); } @@ -126,4 +126,4 @@ function getQueues() } -} \ No newline at end of file +} diff --git a/MultipleFileUpload/Model/SQLite/.gitignore b/MultipleFileUpload/Model/SQLite/.gitignore deleted file mode 100644 index 0177c42..0000000 --- a/MultipleFileUpload/Model/SQLite/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/database.sdb diff --git a/MultipleFileUpload/Model/SQLite/Queue.php b/MultipleFileUpload/Model/SQLite/Queue.php deleted file mode 100644 index 29eb3c8..0000000 --- a/MultipleFileUpload/Model/SQLite/Queue.php +++ /dev/null @@ -1,131 +0,0 @@ -getQueuesModel()->query($sql); - } - - - /** - * Adds file to queue - * @param FileUpload $file - */ - function addFile(FileUpload $file) - { - $file->move($this->getUniqueFilePath()); - $this->query('INSERT INTO files (queueID, created, data, name) VALUES ("' . sqlite_escape_string($this->getQueueID()) . '",' . time() . ',\'' . sqlite_escape_string(serialize($file)) . '\', \'' . sqlite_escape_string($file->getName()) . '\')'); - } - - - // TODO: rename!!! - function addFileManually($name, $chunk, $chunks) - { - $this->query('INSERT INTO files (queueID, created, name, chunk, chunks) VALUES ("' . sqlite_escape_string($this->getQueueID()) . '",' . time() . ',\'' . sqlite_escape_string($name) . '\', \'' . sqlite_escape_string($chunk) . '\', \'' . sqlite_escape_string($chunks) . '\')'); - } - - - function updateFile($name, $chunk, FileUpload $file = null) - { - $this->query("BEGIN TRANSACTION"); - $where = 'queueID = \'' . sqlite_escape_string($this->getQueueID()) . '\' AND name = \'' . sqlite_escape_string($name) . '\''; - $this->query('UPDATE files SET chunk = \'' . sqlite_escape_string($chunk) . '\' WHERE ' . $where); - if ($file) { - $this->query('UPDATE files SET data = \'' . sqlite_escape_string(serialize($file)) . '\' WHERE ' . $where); - } - $this->query("END TRANSACTION"); - } - - - /** - * Gets upload directory path - * @return string - */ - function getUploadedFilesTemporaryPath() - { - if (!Queues::$uploadsTempDir) { - throw new InvalidStateException("Directory for temp files is not set."); - } - - if (!file_exists(Queues::$uploadsTempDir)) { - mkdir(Queues::$uploadsTempDir, 0777, true); - } - - if (!is_writable(Queues::$uploadsTempDir)) { - throw new InvalidStateException("Directory for temp files is not writable!"); - } - - return Queues::$uploadsTempDir; - } - - - /** - * Gets files - * @return FileUpload[] - */ - function getFiles() - { - $files = array(); - - foreach ($this->query("SELECT * FROM files WHERE queueID = '" . sqlite_escape_string($this->getQueueID()) . "'")->fetchAll() AS $row) { - $f = unserialize($row["data"]); - if (!$f instanceof FileUpload) - continue; - $files[] = $f; - } - return $files; - } - - - function delete() - { - $dir = realpath($this->getUploadedFilesTemporaryPath()); - foreach ($this->getFiles() AS $file) { - $fileDir = dirname($file->getTemporaryFile()); - if (realpath($fileDir) == $dir and file_exists($file->getTemporaryFile())) { - // Delete file only if user leaved file in temp directory - @unlink($file->getTemporaryFile()); // intentionally @ - } - } - - $this->query("DELETE FROM files WHERE queueID = '" . sqlite_escape_string($this->getQueueID()) . "'"); - } - - - /** - * When was queue last accessed? - * @return int timestamp - */ - function getLastAccess() - { - $lastAccess = (int) $this->query("SELECT created - FROM files - WHERE queueID = '" . sqlite_escape_string($this->getQueueID()) . "' - ORDER BY created DESC")->fetchSingle(); - return $lastAccess; - } - - -} \ No newline at end of file diff --git a/MultipleFileUpload/Model/SQLite/Queues.php b/MultipleFileUpload/Model/SQLite/Queues.php deleted file mode 100644 index 529a4a8..0000000 --- a/MultipleFileUpload/Model/SQLite/Queues.php +++ /dev/null @@ -1,189 +0,0 @@ -connection = $connection; - } - // - - function getConnection() - { - if (!$this->connection) { - $this->connection = $this->openDB(); - - // load database - if (filesize(self::$databasePath) == 0) { - //$this->beginTransaction(); - $this->connection->queryExec(file_get_contents(dirname(__FILE__) . "/setupDB.sql"), $error); - if ($error) { - throw new InvalidStateException("Can't create SQLite database: " . $error); - } - //$this->endTransaction(); - } - } - return $this->connection; - } - - - /** - * Executes query - * @param string $sql - * @return SQLiteResult - * @throws InvalidStateException - */ - function query($sql) - { - $r = $this->getConnection()->query($sql, SQLITE_ASSOC, $error); - if ($error) { - throw new InvalidStateException("Can't execute queury: '" . $sql . "'. error: " . $error); - } - return $r; - } - - - /* function beginTransaction() { - $this->query("BEGIN TRANSACTION"); - } - - function endTransaction() { - $this->query("END TRANSACTION"); - } */ - - /** - * Open SQLite file - * @return SQLiteDatabase - * @throws InvalidStateException - */ - function openDB() - { - - if (!($connection = new \SQLiteDatabase(self::$databasePath, 0777, $error))) { - throw new InvalidStateException("Can't create sqlite database: " . $error); - } - - return $connection; - } - - - // - - /** - * Gets queue (create if needed) - * @param string $id - * @return Queue - */ - function getQueue($id) - { - return $this->createQueueObj($id); - } - - - /** - * Queue factory. - * @param string $queueID - * @return Queue - */ - function createQueueObj($queueID) - { - $queue = new Queue(); - $queue->setQueuesModel($this); - $queue->setQueueID($queueID); - $queue->initialize(); - return $queue; - } - - - /** - * Executes cleanup - */ - function cleanup() - { - $this->query("BEGIN TRANSACTION"); - foreach ($this->getQueues() AS $queue) { - if ($queue->getLastAccess() < time() - $this->getLifeTime()) { - $queue->delete(); - } - } - $this->query("END TRANSACTION"); - - // physically delete files marked for deletion - $this->query("VACUUM"); - } - - - /** - * Gets all queues - * @return IQueue[] - */ - function getQueues() - { - $queuesOut = array(); - $qs = $this->query("SELECT queueID - FROM files - GROUP BY queueID")->fetchAll(); - - foreach ($qs AS $row) { - $queuesOut[] = $this->createQueueObj($row["queueID"]); - } - - return $queuesOut; - } - - - static function init() - { - - } - - -} -Queues::init(); diff --git a/MultipleFileUpload/Model/SQLite/setupDB.sql b/MultipleFileUpload/Model/SQLite/setupDB.sql deleted file mode 100644 index 56bab59..0000000 --- a/MultipleFileUpload/Model/SQLite/setupDB.sql +++ /dev/null @@ -1,17 +0,0 @@ ---Table: files - ---DROP TABLE files; - -CREATE TABLE files ( - id integer PRIMARY KEY, - queueID char(13) NOT NULL, - created integer NOT NULL, - data text, - chunk integer NOT NULL DEFAULT 1, - chunks integer NOT NULL DEFAULT 1, - name varchar(255) NOT NULL -); - -CREATE UNIQUE INDEX files_Name - ON files - (name); diff --git a/MultipleFileUpload/Model/SQLite3/Queues.php b/MultipleFileUpload/Model/SQLite3/Queues.php index 05491f9..1611d38 100644 --- a/MultipleFileUpload/Model/SQLite3/Queues.php +++ b/MultipleFileUpload/Model/SQLite3/Queues.php @@ -47,14 +47,19 @@ function initialize() } - public function __construct(string $tempDir, SQLite3 $connection) + // todo: add to Travis CI parallel lint https://github.com/JakubOnderka/PHP-Parallel-Lint + // todo: remove me :-) http://eyeleo.com/ + + /** + * */ + public function __construct($tempDir, $databaseFilePath) { - self::$uploadsTempDir = $tempDir . DIRECTORY_SEPARATOR . "uploads-MFU"; + self::$uploadsTempDir = $tempDir; if(!file_exists(self::$uploadsTempDir)) { mkdir(self::$uploadsTempDir, 0775, TRUE); } - self::$databasePath = dirname(__FILE__) . "/database.sqlite3"; - $this->connection = $connection; + self::$databasePath = $databaseFilePath; + $this->connection = new SQLite3($databaseFilePath); } diff --git a/MultipleFileUpload/MultipleFileUpload.php b/MultipleFileUpload/MultipleFileUpload.php index 4dfce1d..b38f1e3 100644 --- a/MultipleFileUpload/MultipleFileUpload.php +++ b/MultipleFileUpload/MultipleFileUpload.php @@ -68,13 +68,15 @@ class MultipleFileUpload extends UploadControl /** - * Initialize MFU + * Initialize MFU uploads handling and cache cleanups + * For form control initialization {@see self::__contruct()}. */ public static function init(Model\IQueues $queuesModel, Nette\Http\IRequest $request, UI\Registrator $registrator) { self::$queuesModel = $queuesModel; self::$request = $request; self::$interfaceRegistrator = $registrator; + // Set default check callback self::$validateFileCallback = [__CLASS__, "validateFile"]; self::$baseWWWRoot = self::$request->url->baseUrl . "MultipleFileUpload/"; @@ -196,7 +198,7 @@ public static function setQueuesModel(IQueues $model) { public static function getUIRegistrator() { if (!self::$interfaceRegistrator instanceof Registrator) { - throw new InvalidStateException("Interface registrator is not instance of MultipleFileUpload\UI\Registrator!"); + throw new InvalidStateException("Interface registrator is not instance of MultipleFileUpload\\UI\\Registrator!"); } return self::$interfaceRegistrator; } @@ -522,4 +524,4 @@ function FormContainer_addMultipleFileUpload(Forms\Container $_this, $name, $lab Container::extensionMethod("\Nette\Forms\Container::addMultipleFileUpload", "MultipleFileUpload\FormContainer_addMultipleFileUpload"); - */ \ No newline at end of file + */ From 9ac871bd963037cb8b7655686ddf4b5e917ded22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=BDubom=C3=ADr=20Andr=C3=ADsek?= Date: Sat, 4 Feb 2017 14:45:19 +0100 Subject: [PATCH 26/26] DibiDriver: removed static queues variable --- MultipleFileUpload/Model/Dibi/Queue.php | 11 +++++------ MultipleFileUpload/Model/Dibi/Queues.php | 12 ++++-------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/MultipleFileUpload/Model/Dibi/Queue.php b/MultipleFileUpload/Model/Dibi/Queue.php index 5c5527b..232569b 100644 --- a/MultipleFileUpload/Model/Dibi/Queue.php +++ b/MultipleFileUpload/Model/Dibi/Queue.php @@ -24,7 +24,6 @@ */ class Queue extends BaseQueue { - // todo: use $this->queuesModel->getTempDir() (non-existing now) /** * Executes query @@ -94,19 +93,19 @@ function updateFile($name, $chunk, FileUpload $file = null) */ function getUploadedFilesTemporaryPath() { - if (!Queues::$uploadsTempDir) { + if (!$this->getQueuesModel()->uploadsTempDir) { throw new InvalidStateException("Directory for temp files is not set."); } - if (!file_exists(Queues::$uploadsTempDir)) { - mkdir(Queues::$uploadsTempDir, 0777, true); + if (!file_exists($this->getQueuesModel()->uploadsTempDir)) { + mkdir($this->getQueuesModel()->uploadsTempDir, 0777, true); } - if (!is_writable(Queues::$uploadsTempDir)) { + if (!is_writable($this->getQueuesModel()->uploadsTempDir)) { throw new InvalidStateException("Directory for temp files is not writable!"); } - return Queues::$uploadsTempDir; + return $this->getQueuesModel()->uploadsTempDir; } diff --git a/MultipleFileUpload/Model/Dibi/Queues.php b/MultipleFileUpload/Model/Dibi/Queues.php index e582284..5fd3729 100644 --- a/MultipleFileUpload/Model/Dibi/Queues.php +++ b/MultipleFileUpload/Model/Dibi/Queues.php @@ -27,7 +27,7 @@ class Queues extends BaseQueues * Path to directory of uploaded files (temp) * @var string */ - public static $uploadsTempDir; + public $uploadsTempDir; /** * Connection @@ -44,15 +44,11 @@ function initialize() } - // todo: Queue should have reference to Queues (remove static dependency ---> there is then not assumed that there is onlu one Queues instance in the app) - // todo: remove self::$uploadsTempDir ---> create private $uploadsTempDir - // todo: create getTempDir() - public function __construct(string $tempDir, DibiConnection $conection) { - self::$uploadsTempDir = $tempDir; - if(!file_exists(self::$uploadsTempDir)) { - mkdir(self::$uploadsTempDir, 0775, TRUE); + $this->uploadsTempDir = $tempDir; + if(!file_exists($this->uploadsTempDir)) { + mkdir($this->uploadsTempDir, 0775, TRUE); } $this->conection = $conection; }