diff --git a/core/lib/Thelia/Action/Document.php b/core/lib/Thelia/Action/Document.php index 86fc51ac5..2a630be2f 100644 --- a/core/lib/Thelia/Action/Document.php +++ b/core/lib/Thelia/Action/Document.php @@ -25,8 +25,13 @@ namespace Thelia\Action; use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpFoundation\File\File; +use Thelia\Core\Event\DocumentCreateOrUpdateEvent; +use Thelia\Core\Event\DocumentDeleteEvent; use Thelia\Core\Event\DocumentEvent; +use Thelia\Exception\ImageException; use Thelia\Model\ConfigQuery; +use Thelia\Tools\FileManager; use Thelia\Tools\URL; use Imagine\Document\ImagineInterface; @@ -129,11 +134,139 @@ class Document extends BaseCachedFile implements EventSubscriberInterface $event->setDocumentUrl(URL::getInstance()->absoluteUrl($document_url, null, URL::PATH_TO_FILE)); } + /** + * Take care of saving document in the database and file storage + * + * @param DocumentCreateOrUpdateEvent $event Document event + * + * @throws \Thelia\Exception\ImageException + * @todo refactor make all documents using propel inheritance and factorise image behaviour into one single clean action + */ + public function saveDocument(DocumentCreateOrUpdateEvent $event) + { + $this->adminLogAppend( + $this->container->get('thelia.translator')->trans( + 'Saving documents for %parentName% parent id %parentId% (%parentType%)', + array( + '%parentName%' => $event->getParentName(), + '%parentId%' => $event->getParentId(), + '%parentType%' => $event->getDocumentType() + ), + 'document' + ) + ); + + $fileManager = new FileManager($this->container); + $model = $event->getModelDocument(); + + $nbModifiedLines = $model->save(); + $event->setModelDocument($model); + + if (!$nbModifiedLines) { + throw new ImageException( + sprintf( + 'Document "%s" with parent id %s (%s) failed to be saved', + $event->getParentName(), + $event->getParentId(), + $event->getDocumentType() + ) + ); + } + + $newUploadedFile = $fileManager->copyUploadedFile($event->getParentId(), $event->getDocumentType(), $event->getModelDocument(), $event->getUploadedFile()); + $event->setUploadedFile($newUploadedFile); + } + + /** + * Take care of updating document in the database and file storage + * + * @param DocumentCreateOrUpdateEvent $event Document event + * + * @throws \Thelia\Exception\ImageException + * @todo refactor make all documents using propel inheritance and factorise image behaviour into one single clean action + */ + public function updateDocument(DocumentCreateOrUpdateEvent $event) + { + $this->adminLogAppend( + $this->container->get('thelia.translator')->trans( + 'Updating documents for %parentName% parent id %parentId% (%parentType%)', + array( + '%parentName%' => $event->getParentName(), + '%parentId%' => $event->getParentId(), + '%parentType%' => $event->getDocumentType() + ), + 'image' + ) + ); + + $fileManager = new FileManager($this->container); + // Copy and save file + if ($event->getUploadedFile()) { + // Remove old picture file from file storage + $url = $fileManager->getUploadDir($event->getDocumentType(), FileManager::FILE_TYPE_DOCUMENTS) . '/' . $event->getOldModelDocument()->getFile(); + unlink(str_replace('..', '', $url)); + + $newUploadedFile = $fileManager->copyUploadedFile( + $event->getModelDocument()->getParentId(), + $event->getDocumentType(), + $event->getModelDocument(), $event->getUploadedFile()); + $event->setUploadedFile($newUploadedFile); + } + + // Update document modifications + $event->getModelDocument()->save(); + $event->setModelDocument($event->getModelDocument()); + } + + /** + * Take care of deleting document in the database and file storage + * + * @param DocumentDeleteEvent $event Image event + * + * @throws \Exception + * @todo refactor make all documents using propel inheritance and factorise image behaviour into one single clean action + */ + public function deleteDocument(DocumentDeleteEvent $event) + { + $fileManager = new FileManager($this->container); + + try { + $fileManager->deleteFile($event->getDocumentToDelete(), $event->getDocumentType(), FileManager::FILE_TYPE_DOCUMENTS); + + $this->adminLogAppend( + $this->container->get('thelia.translator')->trans( + 'Deleting document for %id% with parent id %parentId%', + array( + '%id%' => $event->getDocumentToDelete()->getId(), + '%parentId%' => $event->getDocumentToDelete()->getParentId(), + ), + 'document' + ) + ); + } catch(\Exception $e) { + $this->adminLogAppend( + $this->container->get('thelia.translator')->trans( + 'Fail to delete document for %id% with parent id %parentId% (Exception : %e%)', + array( + '%id%' => $event->getDocumentToDelete()->getId(), + '%parentId%' => $event->getDocumentToDelete()->getParentId(), + '%e%' => $e->getMessage() + ), + 'document' + ) + ); + throw $e; + } + } + public static function getSubscribedEvents() { return array( TheliaEvents::DOCUMENT_PROCESS => array("processDocument", 128), TheliaEvents::DOCUMENT_CLEAR_CACHE => array("clearCache", 128), + TheliaEvents::DOCUMENT_DELETE => array("deleteDocument", 128), + TheliaEvents::DOCUMENT_SAVE => array("saveDocument", 128), + TheliaEvents::DOCUMENT_UPDATE => array("updateDocument", 128), ); } } diff --git a/core/lib/Thelia/Action/Image.php b/core/lib/Thelia/Action/Image.php index 989c9c516..da501eef1 100755 --- a/core/lib/Thelia/Action/Image.php +++ b/core/lib/Thelia/Action/Image.php @@ -334,7 +334,6 @@ class Image extends BaseCachedFile implements EventSubscriberInterface // Update image modifications $event->getModelImage()->save(); $event->setModelImage($event->getModelImage()); - } /** @@ -350,7 +349,7 @@ class Image extends BaseCachedFile implements EventSubscriberInterface $fileManager = new FileManager($this->container); try { - $fileManager->deleteImage($event->getImageToDelete(), $event->getImageType()); + $fileManager->deleteFile($event->getImageToDelete(), $event->getImageType(), FileManager::FILE_TYPE_IMAGES); $this->adminLogAppend( $this->container->get('thelia.translator')->trans( @@ -362,7 +361,7 @@ class Image extends BaseCachedFile implements EventSubscriberInterface 'image' ) ); - } catch(\Exception $e) { + } catch(\Exception $e){ $this->adminLogAppend( $this->container->get('thelia.translator')->trans( 'Fail to delete image for %id% with parent id %parentId% (Exception : %e%)', diff --git a/core/lib/Thelia/Config/Resources/action.xml b/core/lib/Thelia/Config/Resources/action.xml index 15839df95..f153a8de0 100755 --- a/core/lib/Thelia/Config/Resources/action.xml +++ b/core/lib/Thelia/Config/Resources/action.xml @@ -36,6 +36,10 @@ + + + + diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index 623067123..e1f3f9920 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -35,6 +35,7 @@ + @@ -59,19 +60,25 @@
+ + + - + + + + diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index 6127b2160..ed8f21214 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -63,7 +63,36 @@ \d+ - Thelia\Controller\Admin\FileController::deleteImagesAction + Thelia\Controller\Admin\FileController::deleteImageAction + .* + \d+ + + + + Thelia\Controller\Admin\FileController::saveDocumentAjaxAction + .* + \d+ + + + Thelia\Controller\Admin\FileController::getDocumentFormAjaxAction + .* + \d+ + + + Thelia\Controller\Admin\FileController::getDocumentListAjaxAction + .* + \d+ + + + Thelia\Controller\Admin\FileController::viewDocumentAction + \d+ + + + Thelia\Controller\Admin\FileController::updateDocumentAction + \d+ + + + Thelia\Controller\Admin\FileController::deleteDocumentAction .* \d+ diff --git a/core/lib/Thelia/Controller/Admin/FileController.php b/core/lib/Thelia/Controller/Admin/FileController.php index e0f469173..5485f6409 100755 --- a/core/lib/Thelia/Controller/Admin/FileController.php +++ b/core/lib/Thelia/Controller/Admin/FileController.php @@ -28,19 +28,21 @@ use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Router; -use Symfony\Component\Validator\Constraints\Image; -use Symfony\Component\Validator\Constraints\ImageValidator; -use Symfony\Component\Validator\Exception\ConstraintDefinitionException; +use Thelia\Core\Event\DocumentCreateOrUpdateEvent; +use Thelia\Core\Event\DocumentDeleteEvent; use Thelia\Core\Event\ImageCreateOrUpdateEvent; -use Thelia\Core\Event\ImagesCreateOrUpdateEvent; use Thelia\Core\Event\ImageDeleteEvent; use Thelia\Core\Event\TheliaEvents; use Thelia\Core\Translation\Translator; use Thelia\Form\Exception\FormValidationException; use Thelia\Log\Tlog; +use Thelia\Model\CategoryDocument; use Thelia\Model\CategoryImage; +use Thelia\Model\ContentDocument; use Thelia\Model\ContentImage; +use Thelia\Model\FolderDocument; use Thelia\Model\FolderImage; +use Thelia\Model\ProductDocument; use Thelia\Model\ProductImage; use Thelia\Tools\FileManager; use Thelia\Tools\Rest\ResponseRest; @@ -59,21 +61,8 @@ use Thelia\Tools\Rest\ResponseRest; */ class FileController extends BaseAdminController { - /** - * Manage how a file collection has to be saved - * - * @param int $parentId Parent id owning files being saved - * @param string $parentType Parent Type owning files being saved - * - * @return Response - */ - public function saveFilesAction($parentId, $parentType) - { - - } - /** * Manage how a image collection has to be saved * @@ -118,7 +107,7 @@ class FileController extends BaseAdminController return new ResponseRest($message, 'text', 415); } - $parentModel = $fileManager->getParentImageModel($parentType, $parentId); + $parentModel = $fileManager->getParentFIleModel($parentType, $parentId); $imageModel = $fileManager->getImageModel($parentType); if ($parentModel === null || $imageModel === null || $fileBeingUploaded === null) { @@ -152,6 +141,73 @@ class FileController extends BaseAdminController return new Response('', 404); } + /** + * Manage how a document collection has to be saved + * + * @param int $parentId Parent id owning documents being saved + * @param string $parentType Parent Type owning documents being saved + * + * @return Response + */ + public function saveDocumentAjaxAction($parentId, $parentType) + { + $this->checkAuth('ADMIN', 'admin.document.save'); + $this->checkXmlHttpRequest(); + + if ($this->isParentTypeValid($parentType)) { + if ($this->getRequest()->isMethod('POST')) { + + /** @var UploadedFile $fileBeingUploaded */ + $fileBeingUploaded = $this->getRequest()->files->get('file'); + + $fileManager = new FileManager($this->container); + + // Validate if file is too big + if ($fileBeingUploaded->getError() == 1) { + $message = $this->getTranslator() + ->trans( + 'File is too heavy, please retry with a file having a size less than %size%.', + array('%size%' => ini_get('post_max_size')), + 'document' + ); + + return new ResponseRest($message, 'text', 403); + } + + $parentModel = $fileManager->getParentFileModel($parentType, $parentId); + $documentModel = $fileManager->getDocumentModel($parentType); + + if ($parentModel === null || $documentModel === null || $fileBeingUploaded === null) { + return new Response('', 404); + } + + $defaultTitle = $parentModel->getTitle(); + $documentModel->setParentId($parentId); + $documentModel->setTitle($defaultTitle); + + $documentCreateOrUpdateEvent = new DocumentCreateOrUpdateEvent( + $parentType, + $parentId + ); + $documentCreateOrUpdateEvent->setModelDocument($documentModel); + $documentCreateOrUpdateEvent->setUploadedFile($fileBeingUploaded); + $documentCreateOrUpdateEvent->setParentName($parentModel->getTitle()); + + + // Dispatch Event to the Action + $this->dispatch( + TheliaEvents::DOCUMENT_SAVE, + $documentCreateOrUpdateEvent + ); + + + return new ResponseRest(array('status' => true, 'message' => '')); + } + } + + return new Response('', 404); + } + /** * Manage how a image list will be displayed in AJAX * @@ -169,6 +225,23 @@ class FileController extends BaseAdminController return $this->render('includes/image-upload-list-ajax', $args); } + /** + * Manage how a document list will be displayed in AJAX + * + * @param int $parentId Parent id owning documents being saved + * @param string $parentType Parent Type owning documents being saved + * + * @return Response + */ + public function getDocumentListAjaxAction($parentId, $parentType) + { + $this->checkAuth('ADMIN', 'admin.document.save'); + $this->checkXmlHttpRequest(); + $args = array('documentType' => $parentType, 'parentId' => $parentId); + + return $this->render('includes/document-upload-list-ajax', $args); + } + /** * Manage how an image list will be uploaded in AJAX * @@ -186,6 +259,23 @@ class FileController extends BaseAdminController return $this->render('includes/image-upload-form', $args); } + /** + * Manage how an document list will be uploaded in AJAX + * + * @param int $parentId Parent id owning documents being saved + * @param string $parentType Parent Type owning documents being saved + * + * @return Response + */ + public function getDocumentFormAjaxAction($parentId, $parentType) + { + $this->checkAuth('ADMIN', 'admin.document.save'); + $this->checkXmlHttpRequest(); + $args = array('documentType' => $parentType, 'parentId' => $parentId); + + return $this->render('includes/document-upload-form', $args); + } + /** * Manage how an image is viewed * @@ -209,7 +299,35 @@ class FileController extends BaseAdminController 'imageType' => $parentType, 'redirectUrl' => $redirectUrl )); - } catch (Exception $e) { + } catch (\Exception $e) { + $this->pageNotFound(); + } + } + + /** + * Manage how an document is viewed + * + * @param int $documentId Parent id owning images being saved + * @param string $parentType Parent Type owning images being saved + * + * @return Response + */ + public function viewDocumentAction($documentId, $parentType) + { + if (null !== $response = $this->checkAuth('admin.document.view')) { + return $response; + } + try { + $fileManager = new FileManager($this->container); + $document = $fileManager->getDocumentModelQuery($parentType)->findPk($documentId); + $redirectUrl = $fileManager->getRedirectionUrl($parentType, $document->getParentId()); + + return $this->render('document-edit', array( + 'documentId' => $documentId, + 'documentType' => $parentType, + 'redirectUrl' => $redirectUrl + )); + } catch (\Exception $e) { $this->pageNotFound(); } } @@ -237,12 +355,12 @@ class FileController extends BaseAdminController $image = $fileManager->getImageModelQuery($parentType)->findPk($imageId); $oldImage = clone $image; if (null === $image) { - throw new \InvalidArgumentException(sprintf('%d image id does not exists', $imageId)); + throw new \InvalidArgumentException(sprintf('%d image id does not exist', $imageId)); } $form = $this->validateForm($imageModification); - $event = $this->createEventInstance($parentType, $image, $form->getData()); + $event = $this->createImageEventInstance($parentType, $image, $form->getData()); $event->setOldModelImage($oldImage); $files = $this->getRequest()->files; @@ -288,14 +406,87 @@ class FileController extends BaseAdminController } /** - * Manage how a image has to be deleted (AJAX) + * Manage how an document is updated * - * @param int $imageId Parent id owning images being saved - * @param string $parentType Parent Type owning images being saved + * @param int $documentId Parent id owning documents being saved + * @param string $parentType Parent Type owning documents being saved * * @return Response */ - public function deleteImagesAction($imageId, $parentType) + public function updateDocumentAction($documentId, $parentType) + { + if (null !== $response = $this->checkAuth('admin.image.update')) { + return $response; + } + + $message = false; + + $fileManager = new FileManager($this->container); + $documentModification = $fileManager->getImageForm($parentType, $this->getRequest()); + + try { + $document = $fileManager->getDocumentModelQuery($parentType)->findPk($documentId); + $oldDocument = clone $document; + if (null === $document) { + throw new \InvalidArgumentException(sprintf('%d document id does not exist', $documentId)); + } + + $form = $this->validateForm($documentModification); + + $event = $this->createImageEventInstance($parentType, $document, $form->getData()); + $event->setOldModelImage($oldDocument); + + $files = $this->getRequest()->files; + $fileForm = $files->get($documentModification->getName()); + if (isset($fileForm['file'])) { + $event->setUploadedFile($fileForm['file']); + } + + $this->dispatch(TheliaEvents::DOCUMENT_UPDATE, $event); + + $documentUpdated = $event->getModelImage(); + + $this->adminLogAppend(sprintf('Document with Ref %s (ID %d) modified', $documentUpdated->getTitle(), $documentUpdated->getId())); + + if ($this->getRequest()->get('save_mode') == 'close') { + $this->redirectToRoute('admin.documents'); + } else { + $this->redirectSuccess($documentModification); + } + + } catch (FormValidationException $e) { + $message = sprintf('Please check your input: %s', $e->getMessage()); + } catch (PropelException $e) { + $message = $e->getMessage(); + } catch (\Exception $e) { + $message = sprintf('Sorry, an error occurred: %s', $e->getMessage().' '.$e->getFile()); + } + + if ($message !== false) { + Tlog::getInstance()->error(sprintf('Error during document editing : %s.', $message)); + + $documentModification->setErrorMessage($message); + + $this->getParserContext() + ->addForm($documentModification) + ->setGeneralError($message); + } + + return $this->render('document-edit', array( + 'documentId' => $documentId, + 'documentType' => $parentType + )); + } + + /** + * Manage how a image has to be deleted (AJAX) + * + * @param int $imageId Parent id owning image being deleted + * @param string $parentType Parent Type owning image being deleted + * + * @return Response + */ + public function deleteImageAction($imageId, $parentType) { $this->checkAuth('ADMIN', 'admin.image.delete'); $this->checkXmlHttpRequest(); @@ -330,6 +521,49 @@ class FileController extends BaseAdminController return new Response($message); } + /** + * Manage how a document has to be deleted (AJAX) + * + * @param int $documentId Parent id owning document being deleted + * @param string $parentType Parent Type owning document being deleted + * + * @return Response + */ + public function deleteDocumentAction($documentId, $parentType) + { + $this->checkAuth('ADMIN', 'admin.document.delete'); + $this->checkXmlHttpRequest(); + + $fileManager = new FileManager($this->container); + $documentModelQuery = $fileManager->getDocumentModelQuery($parentType); + $model = $documentModelQuery->findPk($documentId); + + if ($model == null) { + return $this->pageNotFound(); + } + + // Feed event + $documentDeleteEvent = new DocumentDeleteEvent( + $model, + $parentType + ); + + // Dispatch Event to the Action + $this->dispatch( + TheliaEvents::DOCUMENT_DELETE, + $documentDeleteEvent + ); + + $message = $this->getTranslator() + ->trans( + 'Document deleted successfully', + array(), + 'document' + ); + + return new Response($message); + } + /** * Log error message * @@ -362,11 +596,11 @@ class FileController extends BaseAdminController */ public function isParentTypeValid($parentType) { - return (in_array($parentType, ImagesCreateOrUpdateEvent::getAvailableType())); + return (in_array($parentType, FileManager::getAvailableTypes())); } /** - * Create Event instance + * Create Image Event instance * * @param string $parentType Parent Type owning images being saved * @param CategoryImage|ProductImage|ContentImage|FolderImage $model Image model @@ -374,7 +608,7 @@ class FileController extends BaseAdminController * * @return ImageCreateOrUpdateEvent */ - private function createEventInstance($parentType, $model, $data) + protected function createImageEventInstance($parentType, $model, $data) { $imageCreateEvent = new ImageCreateOrUpdateEvent($parentType, null); @@ -399,5 +633,39 @@ class FileController extends BaseAdminController return $imageCreateEvent; } + /** + * Create Document Event instance + * + * @param string $parentType Parent Type owning documents being saved + * @param CategoryDocument|ProductDocument|ContentDocument|FolderDocument $model Document model + * @param array $data Post data + * + * @return ImageCreateOrUpdateEvent + */ + protected function createDocumentEventInstance($parentType, $model, $data) + { + $documentCreateEvent = new DocumentCreateOrUpdateEvent($parentType, null); + + if (isset($data['title'])) { + $model->setTitle($data['title']); + } + if (isset($data['chapo'])) { + $model->setChapo($data['chapo']); + } + if (isset($data['description'])) { + $model->setDescription($data['description']); + } + if (isset($data['file'])) { + $model->setFile($data['file']); + } + if (isset($data['postscriptum'])) { + $model->setPostscriptum($data['postscriptum']); + } + + $documentCreateEvent->setModelDocument($model); + + return $documentCreateEvent; + } + } diff --git a/core/lib/Thelia/Core/Event/DocumentCreateOrUpdateEvent.php b/core/lib/Thelia/Core/Event/DocumentCreateOrUpdateEvent.php new file mode 100755 index 000000000..f19f9b23b --- /dev/null +++ b/core/lib/Thelia/Core/Event/DocumentCreateOrUpdateEvent.php @@ -0,0 +1,217 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; +use Symfony\Component\HttpFoundation\File\UploadedFile; +use Thelia\Model\CategoryDocument; +use Thelia\Model\ContentDocument; +use Thelia\Model\FolderDocument; +use Thelia\Model\ProductDocument; + +/** + * Created by JetBrains PhpStorm. + * Date: 9/18/13 + * Time: 3:56 PM + * + * Occurring when a Document is saved + * + * @package Document + * @author Guillaume MOREL + * + */ +class DocumentCreateOrUpdateEvent extends ActionEvent +{ + + /** @var CategoryDocument|ProductDocument|ContentDocument|FolderDocument model to save */ + protected $modelDocument = array(); + + /** @var CategoryDocument|ProductDocument|ContentDocument|FolderDocument model to save */ + protected $oldModelDocument = array(); + + /** @var UploadedFile Document file to save */ + protected $uploadedFile = null; + + /** @var int Document parent id */ + protected $parentId = null; + + /** @var string Document type */ + protected $documentType = null; + + /** @var string Parent name */ + protected $parentName = null; + + /** + * Constructor + * + * @param string $documentType Document type + * ex : FileManager::TYPE_CATEGORY + * @param int $parentId Document parent id + */ + public function __construct($documentType, $parentId) + { + $this->imageType = $documentType; + $this->parentId = $parentId; + } + + /** + * Set Document to save + * + * @param CategoryDocument|ProductDocument|ContentDocument|FolderDocument $document Document to save + * + * @return $this + */ + public function setModelDocument($document) + { + $this->modelDocument = $document; + + return $this; + } + + /** + * Get Document being saved + * + * @return CategoryDocument|ProductDocument|ContentDocument|FolderDocument + */ + public function getModelDocument() + { + return $this->modelDocument; + } + + /** + * Set document type + * + * @param string $documentType Document type + * + * @return $this + */ + public function setDocumentType($documentType) + { + $this->imageType = $documentType; + + return $this; + } + + /** + * Get document type + * + * @return string + */ + public function getDocumentType() + { + return $this->documentType; + } + + /** + * Set Document parent id + * + * @param int $parentId Document parent id + * + * @return $this + */ + public function setParentId($parentId) + { + $this->parentId = $parentId; + + return $this; + } + + /** + * Get Document parent id + * + * @return int + */ + public function getParentId() + { + return $this->parentId; + } + + /** + * Set uploaded file + * + * @param UploadedFile $uploadedFile File being uploaded + * + * @return $this + */ + public function setUploadedFile($uploadedFile) + { + $this->uploadedFile = $uploadedFile; + + return $this; + } + + /** + * Get uploaded file + * + * @return UploadedFile + */ + public function getUploadedFile() + { + return $this->uploadedFile; + } + + /** + * Set parent name + * + * @param string $parentName Parent name + * + * @return $this + */ + public function setParentName($parentName) + { + $this->parentName = $parentName; + + return $this; + } + + /** + * Get parent name + * + * @return string + */ + public function getParentName() + { + return $this->parentName; + } + + /** + * Set old model value + * + * @param CategoryDocument|ContentDocument|FolderDocument|ProductDocument $oldModelDocument + */ + public function setOldModelDocument($oldModelDocument) + { + $this->oldModelDocument = $oldModelDocument; + } + + /** + * Get old model value + * + * @return CategoryDocument|ContentDocument|FolderDocument|ProductDocument + */ + public function getOldModelDocument() + { + return $this->oldModelDocument; + } + + +} diff --git a/core/lib/Thelia/Core/Event/DocumentDeleteEvent.php b/core/lib/Thelia/Core/Event/DocumentDeleteEvent.php new file mode 100755 index 000000000..16bb86229 --- /dev/null +++ b/core/lib/Thelia/Core/Event/DocumentDeleteEvent.php @@ -0,0 +1,112 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; + +use Thelia\Model\CategoryDocument; +use Thelia\Model\ContentDocument; +use Thelia\Model\FolderDocument; +use Thelia\Model\ProductDocument; + +/** + * Created by JetBrains PhpStorm. + * Date: 9/18/13 + * Time: 3:56 PM + * + * Occurring when a Document is about to be deleted + * + * @package Document + * @author Guillaume MOREL + * + */ +class DocumentDeleteEvent extends ActionEvent +{ + /** @var string Document type */ + protected $documentType = null; + + /** @var CategoryDocument|ProductDocument|ContentDocument|FolderDocument Document about to be deleted */ + protected $documentToDelete = null; + + /** + * Constructor + * + * @param CategoryDocument|ProductDocument|ContentDocument|FolderDocument $documentToDelete Document about to be deleted + * @param string $documentType Document type + * ex : FileManager::TYPE_CATEGORY + */ + public function __construct($documentToDelete, $documentType) + { + $this->imageToDelete = $documentToDelete; + $this->documentType = $documentType; + } + + /** + * Set picture type + * + * @param string $documentType Document type + * + * @return $this + */ + public function setDocumentType($documentType) + { + $this->documentType = $documentType; + + return $this; + } + + /** + * Get picture type + * + * @return string + */ + public function getDocumentType() + { + return $this->documentType; + } + + /** + * Set Document about to be deleted + * + * @param CategoryDocument|ProductDocument|ContentDocument|FolderDocument $documentToDelete Document about to be deleted + * + * @return $this + */ + public function setDocumentToDelete($documentToDelete) + { + $this->imageToDelete = $documentToDelete; + + return $this; + } + + /** + * Get Document about to be deleted + * + * @return CategoryDocument|ProductDocument|ContentDocument|FolderDocument + */ + public function getDocumentToDelete() + { + return $this->documentToDelete; + } + + +} diff --git a/core/lib/Thelia/Core/Event/ImagesCreateOrUpdateEvent.php b/core/lib/Thelia/Core/Event/ImagesCreateOrUpdateEvent.php deleted file mode 100755 index 62c189fc5..000000000 --- a/core/lib/Thelia/Core/Event/ImagesCreateOrUpdateEvent.php +++ /dev/null @@ -1,184 +0,0 @@ -. */ -/* */ -/*************************************************************************************/ - -namespace Thelia\Core\Event; - -/** - * Created by JetBrains PhpStorm. - * Date: 9/18/13 - * Time: 3:56 PM - * - * Occurring when a Image list is saved - * - * @package Image - * @author Guillaume MOREL - * - */ -class ImagesCreateOrUpdateEvent extends ActionEvent -{ - CONST TYPE_PRODUCT = 'product'; - CONST TYPE_CATEGORY = 'category'; - CONST TYPE_CONTENT = 'content'; - CONST TYPE_FOLDER = 'folder'; - - /** @var array Images model to save */ - protected $modelImages = array(); - - /** @var array Images file to save */ - protected $uploadedFiles = array(); - - /** @var int Image parent id */ - protected $parentId = null; - - /** @var string Image type */ - protected $imageType = null; - - /** @var array Available image parent type */ - protected static $availableType = array( - self::TYPE_PRODUCT, - self::TYPE_CATEGORY, - self::TYPE_CONTENT, - self::TYPE_FOLDER, - ); - - /** - * Constructor - * - * @param string $pictureType Picture type - * ex : ImageCreateOrUpdateEvent::TYPE_CATEGORY - * @param int $parentId Image parent id - */ - public function __construct($pictureType, $parentId) - { - $this->imageType = $pictureType; - $this->parentId = $parentId; - } - - /** - * Set Images to save - * - * @param array $images Thelia\Model\CategoryImage Array - * - * @return $this - */ - public function setModelImages($images) - { - $this->modelImages = $images; - - return $this; - } - - /** - * Get Images being saved - * - * @return array Array of Thelia\Model\CategoryImage - */ - public function getModelImages() - { - return $this->modelImages; - } - - /** - * Set Images to save - * - * @param array $images Thelia\Model\CategoryImage Array - * - * @return $this - */ - public function setUploadedFiles($images) - { - $this->uploadedFiles = $images; - - return $this; - } - - /** - * Get Images being saved - * - * @return array Array of Thelia\Model\CategoryImage - */ - public function getUploadedFiles() - { - return $this->uploadedFiles; - } - - /** - * Set picture type - * - * @param string $pictureType Picture type - * - * @return $this - */ - public function setImageType($pictureType) - { - $this->imageType = $pictureType; - - return $this; - } - - /** - * Get picture type - * - * @return string - */ - public function getImageType() - { - return $this->imageType; - } - - /** - * Get all image parent type available - * - * @return array - */ - public static function getAvailableType() - { - return self::$availableType; - } - - /** - * Set Image parent id - * - * @param int $parentId Image parent id - * - * @return $this - */ - public function setParentId($parentId) - { - $this->parentId = $parentId; - - return $this; - } - - /** - * Get Image parent id - * - * @return int - */ - public function getParentId() - { - return $this->parentId; - } - - -} diff --git a/core/lib/Thelia/Core/Event/TheliaEvents.php b/core/lib/Thelia/Core/Event/TheliaEvents.php index faeed50f3..12e42831c 100755 --- a/core/lib/Thelia/Core/Event/TheliaEvents.php +++ b/core/lib/Thelia/Core/Event/TheliaEvents.php @@ -337,6 +337,26 @@ final class TheliaEvents */ const DOCUMENT_PROCESS = "action.processDocument"; + /** + * Sent on image cache clear request + */ + const DOCUMENT_CLEAR_CACHE = "action.clearDocumentCache"; + + /** + * Save given documents + */ + const DOCUMENT_SAVE = "action.saveDocument"; + + /** + * Save given documents + */ + const DOCUMENT_UPDATE = "action.updateDocument"; + + /** + * Delete given document + */ + const DOCUMENT_DELETE = "action.deleteDocument"; + /** * Sent on image cache clear request */ diff --git a/core/lib/Thelia/Form/Image/DocumentModification.php b/core/lib/Thelia/Form/Image/DocumentModification.php index 412da0660..39ba559be 100644 --- a/core/lib/Thelia/Form/Image/DocumentModification.php +++ b/core/lib/Thelia/Form/Image/DocumentModification.php @@ -69,7 +69,7 @@ abstract class DocumentModification extends BaseForm 'file', array( 'constraints' => array(), - 'label' => Translator::getInstance()->trans('File'), + 'label' => Translator::getInstance()->trans('Replace current document by this file'), 'label_attr' => array( 'for' => 'file' ) diff --git a/core/lib/Thelia/Form/Image/ImageModification.php b/core/lib/Thelia/Form/Image/ImageModification.php index 99e12d72c..c4d26378b 100644 --- a/core/lib/Thelia/Form/Image/ImageModification.php +++ b/core/lib/Thelia/Form/Image/ImageModification.php @@ -72,12 +72,12 @@ abstract class ImageModification extends BaseForm 'constraints' => array( new Image( array( - 'minWidth' => 200, - 'minHeight' => 200 +// 'minWidth' => 200, +// 'minHeight' => 200 ) ) ), - 'label' => Translator::getInstance()->trans('File'), + 'label' => Translator::getInstance()->trans('Replace current image by this file'), 'label_attr' => array( 'for' => 'file' ) diff --git a/core/lib/Thelia/Model/CategoryDocument.php b/core/lib/Thelia/Model/CategoryDocument.php index 5724e2df1..0917ab30c 100755 --- a/core/lib/Thelia/Model/CategoryDocument.php +++ b/core/lib/Thelia/Model/CategoryDocument.php @@ -25,4 +25,28 @@ class CategoryDocument extends BaseCategoryDocument return true; } + + /** + * Set Document parent id + * + * @param int $parentId parent id + * + * @return $this + */ + public function setParentId($parentId) + { + $this->setCategoryId($parentId); + + return $this; + } + + /** + * Get Document parent id + * + * @return int parent id + */ + public function getParentId() + { + return $this->getCategoryId(); + } } \ No newline at end of file diff --git a/core/lib/Thelia/Model/ContentDocument.php b/core/lib/Thelia/Model/ContentDocument.php index 8ecf3a3a9..1409b2713 100755 --- a/core/lib/Thelia/Model/ContentDocument.php +++ b/core/lib/Thelia/Model/ContentDocument.php @@ -25,4 +25,28 @@ class ContentDocument extends BaseContentDocument return true; } + + /** + * Set Document parent id + * + * @param int $parentId parent id + * + * @return $this + */ + public function setParentId($parentId) + { + $this->setContentId($parentId); + + return $this; + } + + /** + * Get Document parent id + * + * @return int parent id + */ + public function getParentId() + { + return $this->getContentId(); + } } diff --git a/core/lib/Thelia/Model/FolderDocument.php b/core/lib/Thelia/Model/FolderDocument.php index 0a86995d2..1d84d9e55 100755 --- a/core/lib/Thelia/Model/FolderDocument.php +++ b/core/lib/Thelia/Model/FolderDocument.php @@ -25,4 +25,28 @@ class FolderDocument extends BaseFolderDocument return true; } + + /** + * Set Document parent id + * + * @param int $parentId parent id + * + * @return $this + */ + public function setParentId($parentId) + { + $this->setFolderId($parentId); + + return $this; + } + + /** + * Get Document parent id + * + * @return int parent id + */ + public function getParentId() + { + return $this->getFolderId(); + } } diff --git a/core/lib/Thelia/Model/ProductDocument.php b/core/lib/Thelia/Model/ProductDocument.php index 53515ff3c..b0f8032da 100755 --- a/core/lib/Thelia/Model/ProductDocument.php +++ b/core/lib/Thelia/Model/ProductDocument.php @@ -26,4 +26,28 @@ class ProductDocument extends BaseProductDocument return true; } + /** + * Set Document parent id + * + * @param int $parentId parent id + * + * @return $this + */ + public function setParentId($parentId) + { + $this->setProductId($parentId); + + return $this; + } + + /** + * Get Document parent id + * + * @return int parent id + */ + public function getParentId() + { + return $this->getProductId(); + } + } diff --git a/core/lib/Thelia/Tools/FileManager.php b/core/lib/Thelia/Tools/FileManager.php index e18ef58d0..094af65e0 100644 --- a/core/lib/Thelia/Tools/FileManager.php +++ b/core/lib/Thelia/Tools/FileManager.php @@ -24,24 +24,38 @@ namespace Thelia\Tools; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\File\UploadedFile; -use Thelia\Core\Event\ImagesCreateOrUpdateEvent; +use Thelia\Core\Event\DocumentCreateOrUpdateEvent; +use Thelia\Core\Event\ImageCreateOrUpdateEvent; use Thelia\Core\HttpFoundation\Request; use Thelia\Core\Translation\Translator; use Thelia\Exception\ImageException; +use Thelia\Form\CategoryDocumentModification; use Thelia\Form\CategoryImageModification; +use Thelia\Form\ContentDocumentModification; use Thelia\Form\ContentImageModification; +use Thelia\Form\FolderDocumentModification; use Thelia\Form\FolderImageModification; +use Thelia\Form\ProductDocumentModification; use Thelia\Form\ProductImageModification; use Thelia\Model\AdminLog; +use Thelia\Model\CategoryDocument; +use Thelia\Model\CategoryDocumentQuery; use Thelia\Model\CategoryImage; use Thelia\Model\CategoryImageQuery; use Thelia\Model\CategoryQuery; +use Thelia\Model\ContentDocument; +use Thelia\Model\ContentDocumentQuery; use Thelia\Model\ContentImage; use Thelia\Model\ContentImageQuery; use Thelia\Model\ContentQuery; +use Thelia\Model\Exception\InvalidArgumentException; +use Thelia\Model\FolderDocument; +use Thelia\Model\FolderDocumentQuery; use Thelia\Model\FolderImage; use Thelia\Model\FolderImageQuery; use Thelia\Model\FolderQuery; +use Thelia\Model\ProductDocument; +use Thelia\Model\ProductDocumentQuery; use Thelia\Model\ProductImage; use Thelia\Model\ProductImageQuery; use Thelia\Model\ProductQuery; @@ -65,6 +79,9 @@ class FileManager CONST TYPE_FOLDER = 'folder'; CONST TYPE_MODULE = 'module'; + CONST FILE_TYPE_IMAGES = 'images'; + CONST FILE_TYPE_DOCUMENTS = 'documents'; + /** @var ContainerInterface Service Container */ protected $container = null; @@ -85,42 +102,45 @@ class FileManager /** * Copy UploadedFile into the server storage directory * - * @param int $parentId Parent id - * @param string $imageType Image type - * @param FolderImage|ContentImage|CategoryImage|ProductImage $modelImage Image saved - * @param UploadedFile $uploadedFile Ready to be uploaded file + * @param int $parentId Parent id + * @param string $fileType Image type + * @param FolderImage|ContentImage|CategoryImage|ProductImage|FolderDocument|ContentDocument|CategoryDocument|ProductDocument $model Model saved + * @param UploadedFile $uploadedFile Ready to be uploaded file * * @throws \Thelia\Exception\ImageException * @return UploadedFile */ - public function copyUploadedFile($parentId, $imageType, $modelImage, $uploadedFile) + public function copyUploadedFile($parentId, $fileType, $model, $uploadedFile) { + $newUploadedFile = null; if ($uploadedFile !== null) { - $directory = $this->getUploadDir($imageType); - $fileName = $this->renameFile($modelImage->getId(), $uploadedFile); + $directory = $this->getUploadDir($fileType, FileManager::FILE_TYPE_IMAGES); + $fileName = $this->renameFile($model->getId(), $uploadedFile); $this->adminLogAppend( $this->translator->trans( - 'Uploading picture %pictureName% to %directory% for parent_id %parentId% (%parentType%)', + 'Uploading %type% %fileName% to %directory% for parent_id %parentId% (%parentType%)', array( - '%pictureName%' => $uploadedFile->getClientOriginalName(), + '%type%' => $fileType, + '%fileName%' => $uploadedFile->getClientOriginalName(), '%directory%' => $directory . '/' . $fileName, '%parentId%' => $parentId, - '%parentType%' => $imageType + '%parentType%' => $fileType ), 'image' ) ); $newUploadedFile = $uploadedFile->move($directory, $fileName); - $modelImage->setFile($fileName); + $model->setFile($fileName); - if (!$modelImage->save()) { + if (!$model->save()) { throw new ImageException( sprintf( - 'Image %s (%s) failed to be saved (image file)', - $modelImage->getFile(), - $imageType + '*s %s (%s) failed to be saved (image file)', + ucfirst($fileType), + $model->getFile(), + $fileType ) ); } @@ -132,32 +152,32 @@ class FileManager /** * Save image into the database * - * @param ImagesCreateOrUpdateEvent $event Image event + * @param ImageCreateOrUpdateEvent $event Image event * @param FolderImage|ContentImage|CategoryImage|ProductImage $modelImage Image to save * * @return int Nb lines modified * @throws \Thelia\Exception\ImageException * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action */ - public function saveImage(ImagesCreateOrUpdateEvent $event, $modelImage) + public function saveImage(ImageCreateOrUpdateEvent $event, $modelImage) { $nbModifiedLines = 0; if ($modelImage->getFile() !== null) { switch ($event->getImageType()) { - case ImagesCreateOrUpdateEvent::TYPE_PRODUCT: + case self::TYPE_PRODUCT: /** @var ProductImage $modelImage */ $modelImage->setProductId($event->getParentId()); break; - case ImagesCreateOrUpdateEvent::TYPE_CATEGORY: + case self::TYPE_CATEGORY: /** @var CategoryImage $modelImage */ $modelImage->setCategoryId($event->getParentId()); break; - case ImagesCreateOrUpdateEvent::TYPE_CONTENT: + case self::TYPE_CONTENT: /** @var ContentImage $modelImage */ $modelImage->setContentId($event->getParentId()); break; - case ImagesCreateOrUpdateEvent::TYPE_FOLDER: + case self::TYPE_FOLDER: /** @var FolderImage $modelImage */ $modelImage->setFolderId($event->getParentId()); break; @@ -167,7 +187,7 @@ class FileManager 'Picture parent type is unknown (available types : %s)', implode( ',', - $event->getAvailableType() + self::getAvailableTypes() ) ) ); @@ -187,6 +207,64 @@ class FileManager return $nbModifiedLines; } + /** + * Save document into the database + * + * @param DocumentCreateOrUpdateEvent $event Image event + * @param FolderDocument|ContentDocument|CategoryDocument|ProductDocument $modelDocument Document to save + * + * @throws \Thelia\Model\Exception\InvalidArgumentException + * @return int Nb lines modified + * @todo refactor make all documents using propel inheritance and factorise image behaviour into one single clean action + */ + public function saveDocument(DocumentCreateOrUpdateEvent $event, $modelDocument) + { + $nbModifiedLines = 0; + + if ($modelDocument->getFile() !== null) { + switch ($event->getDocumentType()) { + case self::TYPE_PRODUCT: + /** @var ProductImage $modelImage */ + $modelDocument->setProductId($event->getParentId()); + break; + case self::TYPE_CATEGORY: + /** @var CategoryImage $modelImage */ + $modelDocument->setCategoryId($event->getParentId()); + break; + case self::TYPE_CONTENT: + /** @var ContentImage $modelImage */ + $modelDocument->setContentId($event->getParentId()); + break; + case self::TYPE_FOLDER: + /** @var FolderImage $modelImage */ + $modelDocument->setFolderId($event->getParentId()); + break; + default: + throw new InvalidArgumentException( + sprintf( + 'Document parent type is unknown (available types : %s)', + implode( + ',', + self::getAvailableTypes() + ) + ) + ); + } + + $nbModifiedLines = $modelDocument->save(); + if (!$nbModifiedLines) { + throw new InvalidArgumentException( + sprintf( + 'Document %s failed to be saved (document content)', + $modelDocument->getFile() + ) + ); + } + } + + return $nbModifiedLines; + } + /** * Sanitizes a filename replacing whitespace with dashes * @@ -226,14 +304,17 @@ class FileManager /** * Delete image from file storage and database * - * @param CategoryImage|ProductImage|ContentImage|FolderImage $imageModel Image being deleted - * @param string $parentType Parent type + * @param CategoryImage|ProductImage|ContentImage|FolderImage|CategoryDocument|ProductDocument|ContentDocument|FolderDocument $model File being deleted + * @param string $parentType Parent type + * @param string $fileType File type ex FileManager::FILE_TYPE_DOCUMENTS + * + * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action */ - public function deleteImage($imageModel, $parentType) + public function deleteFile($model, $parentType, $fileType) { - $url = $this->getUploadDir($parentType) . '/' . $imageModel->getFile(); + $url = $this->getUploadDir($parentType, $fileType) . '/' . $model->getFile(); unlink(str_replace('..', '', $url)); - $imageModel->delete(); + $model->delete(); } @@ -249,16 +330,16 @@ class FileManager public function getImageModel($parentType) { switch ($parentType) { - case ImagesCreateOrUpdateEvent::TYPE_PRODUCT: + case self::TYPE_PRODUCT: $model = new ProductImage(); break; - case ImagesCreateOrUpdateEvent::TYPE_CATEGORY: + case self::TYPE_CATEGORY: $model = new CategoryImage(); break; - case ImagesCreateOrUpdateEvent::TYPE_CONTENT: + case self::TYPE_CONTENT: $model = new ContentImage(); break; - case ImagesCreateOrUpdateEvent::TYPE_FOLDER: + case self::TYPE_FOLDER: $model = new FolderImage(); break; default: @@ -268,6 +349,37 @@ class FileManager return $model; } + /** + * Get document model from type + * + * @param string $parentType Parent type + * + * @return null|ProductDocument|CategoryDocument|ContentDocument|FolderDocument + * + * @todo refactor make all documents using propel inheritance and factorise image behaviour into one single clean action + */ + public function getDocumentModel($parentType) + { + switch ($parentType) { + case self::TYPE_PRODUCT: + $model = new ProductDocument(); + break; + case self::TYPE_CATEGORY: + $model = new CategoryDocument(); + break; + case self::TYPE_CONTENT: + $model = new ContentDocument(); + break; + case self::TYPE_FOLDER: + $model = new FolderDocument(); + break; + default: + $model = null; + } + + return $model; + } + /** * Get image model query from type * @@ -280,16 +392,16 @@ class FileManager public function getImageModelQuery($parentType) { switch ($parentType) { - case ImagesCreateOrUpdateEvent::TYPE_PRODUCT: + case self::TYPE_PRODUCT: $model = new ProductImageQuery(); break; - case ImagesCreateOrUpdateEvent::TYPE_CATEGORY: + case self::TYPE_CATEGORY: $model = new CategoryImageQuery(); break; - case ImagesCreateOrUpdateEvent::TYPE_CONTENT: + case self::TYPE_CONTENT: $model = new ContentImageQuery(); break; - case ImagesCreateOrUpdateEvent::TYPE_FOLDER: + case self::TYPE_FOLDER: $model = new FolderImageQuery(); break; default: @@ -299,6 +411,37 @@ class FileManager return $model; } + /** + * Get document model query from type + * + * @param string $parentType + * + * @return null|ProductDocumentQuery|CategoryDocumentQuery|ContentDocumentQuery|FolderDocumentQuery + * + * @todo refactor make all documents using propel inheritance and factorise image behaviour into one single clean action + */ + public function getDocumentModelQuery($parentType) + { + switch ($parentType) { + case self::TYPE_PRODUCT: + $model = new ProductDocumentQuery(); + break; + case self::TYPE_CATEGORY: + $model = new CategoryDocumentQuery(); + break; + case self::TYPE_CONTENT: + $model = new ContentDocumentQuery(); + break; + case self::TYPE_FOLDER: + $model = new FolderDocumentQuery(); + break; + default: + $model = null; + } + + return $model; + } + /** * Get image parent model from type * @@ -309,19 +452,19 @@ class FileManager * * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action */ - public function getParentImageModel($parentType, $parentId) + public function getParentFIleModel($parentType, $parentId) { switch ($parentType) { - case ImagesCreateOrUpdateEvent::TYPE_PRODUCT: + case self::TYPE_PRODUCT: $model = ProductQuery::create()->findPk($parentId); break; - case ImagesCreateOrUpdateEvent::TYPE_CATEGORY: + case self::TYPE_CATEGORY: $model = CategoryQuery::create()->findPk($parentId); break; - case ImagesCreateOrUpdateEvent::TYPE_CONTENT: + case self::TYPE_CONTENT: $model = ContentQuery::create()->findPk($parentId); break; - case ImagesCreateOrUpdateEvent::TYPE_FOLDER: + case self::TYPE_FOLDER: $model = FolderQuery::create()->findPk($parentId); break; default: @@ -343,20 +486,52 @@ class FileManager public function getImageForm($parentType, Request $request) { switch ($parentType) { - case ImagesCreateOrUpdateEvent::TYPE_PRODUCT: + case self::TYPE_PRODUCT: $form = new ProductImageModification($request); break; - case ImagesCreateOrUpdateEvent::TYPE_CATEGORY: + case self::TYPE_CATEGORY: $form = new CategoryImageModification($request); break; - case ImagesCreateOrUpdateEvent::TYPE_CONTENT: + case self::TYPE_CONTENT: $form = new ContentImageModification($request); break; - case ImagesCreateOrUpdateEvent::TYPE_FOLDER: + case self::TYPE_FOLDER: $form = new FolderImageModification($request); break; default: - $model = null; + $form = null; + } + + return $form; + + } + + /** + * Get document parent model from type + * + * @param string $parentType Parent type + * @param Request $request Request service + * + * @todo refactor make all document using propel inheritance and factorise image behaviour into one single clean action + * @return ProductDocumentModification|CategoryDocumentModification|ContentDocumentModification|FolderDocumentModification + */ + public function getDocumentForm($parentType, Request $request) + { + switch ($parentType) { + case self::TYPE_PRODUCT: + $form = new ProductDocumentModification($request); + break; + case self::TYPE_CATEGORY: + $form = new CategoryDocumentModification($request); + break; + case self::TYPE_CONTENT: + $form = new ContentDocumentModification($request); + break; + case self::TYPE_FOLDER: + $form = new FolderDocumentModification($request); + break; + default: + $form = null; } return $form; @@ -366,27 +541,32 @@ class FileManager /** * Get image upload dir * - * @param string $parentType Parent type + * @param string $parentType Parent type ex FileManager::TYPE_PRODUCT + * @param string $fileType File type * * @return string Uri */ - public function getUploadDir($parentType) + public function getUploadDir($parentType, $fileType) { + if (!in_array($fileType, self::$availableFileType)) { + return false; + } + switch ($parentType) { - case ImagesCreateOrUpdateEvent::TYPE_PRODUCT: - $uri = THELIA_LOCAL_DIR . 'media/images/' . ImagesCreateOrUpdateEvent::TYPE_PRODUCT; + case self::TYPE_PRODUCT: + $uri = THELIA_LOCAL_DIR . 'media/' . $fileType . '/' . self::TYPE_PRODUCT; break; - case ImagesCreateOrUpdateEvent::TYPE_CATEGORY: - $uri = THELIA_LOCAL_DIR . 'media/images/' . ImagesCreateOrUpdateEvent::TYPE_CATEGORY; + case self::TYPE_CATEGORY: + $uri = THELIA_LOCAL_DIR . 'media/' . $fileType . '/' . self::TYPE_CATEGORY; break; - case ImagesCreateOrUpdateEvent::TYPE_CONTENT: - $uri = THELIA_LOCAL_DIR . 'media/images/' . ImagesCreateOrUpdateEvent::TYPE_CONTENT; + case self::TYPE_CONTENT: + $uri = THELIA_LOCAL_DIR . 'media/' . $fileType . '/' . self::TYPE_CONTENT; break; - case ImagesCreateOrUpdateEvent::TYPE_FOLDER: - $uri = THELIA_LOCAL_DIR . 'media/images/' . ImagesCreateOrUpdateEvent::TYPE_FOLDER; + case self::TYPE_FOLDER: + $uri = THELIA_LOCAL_DIR . 'media/' . $fileType . '/' . self::TYPE_FOLDER; break; default: - $uri = null; + $uri = false; } return $uri; @@ -403,16 +583,16 @@ class FileManager public function getRedirectionUrl($parentType, $parentId) { switch ($parentType) { - case ImagesCreateOrUpdateEvent::TYPE_PRODUCT: + case self::TYPE_PRODUCT: $uri = '/admin/products/update?product_id=' . $parentId . '¤t_tab=images'; break; - case ImagesCreateOrUpdateEvent::TYPE_CATEGORY: + case self::TYPE_CATEGORY: $uri = '/admin/categories/update?category_id=' . $parentId . '¤t_tab=images'; break; - case ImagesCreateOrUpdateEvent::TYPE_CONTENT: + case self::TYPE_CONTENT: $uri = '/admin/content/update/' . $parentId . '¤t_tab=images'; break; - case ImagesCreateOrUpdateEvent::TYPE_FOLDER: + case self::TYPE_FOLDER: $uri = '/admin/folders/update/' . $parentId . '¤t_tab=images'; break; default: @@ -423,7 +603,7 @@ class FileManager } - /** @var array Available image parent type */ + /** @var array Available file parent type */ public static $availableType = array( self::TYPE_PRODUCT, self::TYPE_CATEGORY, @@ -432,6 +612,12 @@ class FileManager self::TYPE_MODULE ); + /** @var array Available file type type */ + public static $availableFileType = array( + self::FILE_TYPE_DOCUMENTS, + self::FILE_TYPE_IMAGES + ); + /** * Rename file with image model id * @@ -470,4 +656,20 @@ class FileManager return $isValid; } + + /** + * Return all document and image types + * + * @return array + */ + public static function getAvailableTypes() + { + return array( + self::TYPE_CATEGORY, + self::TYPE_CONTENT, + self::TYPE_FOLDER, + self::TYPE_PRODUCT, + self::TYPE_MODULE, + ); + } } \ No newline at end of file diff --git a/templates/admin/default/assets/js/document-upload.js b/templates/admin/default/assets/js/document-upload.js new file mode 100644 index 000000000..cd022cd93 --- /dev/null +++ b/templates/admin/default/assets/js/document-upload.js @@ -0,0 +1,99 @@ +$(function($){ + // Manage document upload + $.documentUploadManager = {}; + + Dropzone.autoDiscover = false; + + + + // Remove image on click + $.documentUploadManager.initDocumentDropZone = function() { + var documentDropzone = new Dropzone("#documents-dropzone", { + dictDefaultMessage : $('.btn-browse').html(), + uploadMultiple: false, + maxFilesize: 8 + }); + + var totalFiles = 0, + completedFiles = 0; + + documentDropzone.on("addedfile", function(file){ + totalFiles += 1; + + if(totalFiles == 1){ + $('.dz-message').hide(); + } + }); + + documentDropzone.on("complete", function(file){ + completedFiles += 1; + + if (completedFiles === totalFiles){ + $('.dz-message').slideDown(); + } + }); + + documentDropzone.on("success", function(file) { + documentDropzone.removeFile(file); + $.documentUploadManager.updateDocumentListAjax(); + $.documentUploadManager.onClickDeleteDocument(); + }); + + + + }; + + // Update picture list via AJAX call + $.documentUploadManager.updateDocumentListAjax = function() { + var $documentListArea = $(".document-manager .existing-document"); + $documentListArea.html('
'); + $.ajax({ + type: "POST", + url: documentListUrl, + statusCode: { + 404: function() { + $documentListArea.html( + documentListErrorMessage + ); + } + } + }).done(function(data) { + $documentListArea.html( + data + ); + $.documentUploadManager.onClickDeleteDocument(); + }); + }; + + // Remove image on click + $.documentUploadManager.onClickDeleteDocument = function() { + $('.document-manager .document-delete-btn').on('click', function (e) { + e.preventDefault(); + var $this = $(this); + var $parent = $this.parent(); + $parent.find('a').remove(); + $parent.append('
'); + var $url = $this.attr("href"); + var errorMessage = $this.attr("data-error-message"); + $.ajax({ + type: "POST", + url: $url, + statusCode: { + 404: function() { + $(".document-manager .message").html( + errorMessage + ); + } + } + }).done(function(data) { + $parent.parents('tr').remove(); + + $(".document-manager .message").html( + data + ); + }); + return false; + }); + }; + $.documentUploadManager.onClickDeleteDocument(); +}); diff --git a/templates/admin/default/category-edit.html b/templates/admin/default/category-edit.html index b7e1d9ed9..f8b564822 100755 --- a/templates/admin/default/category-edit.html +++ b/templates/admin/default/category-edit.html @@ -260,6 +260,7 @@
+ {include file='includes/document-upload-form.html' documentType='category' parentId=$category_id}
@@ -303,6 +304,9 @@ {javascripts file='assets/js/image-upload.js'} {/javascripts} + {javascripts file='assets/js/document-upload.js'} + + {/javascripts} @@ -327,6 +331,7 @@ $(function() { $.imageUploadManager.initImageDropZone(); + $.documentUploadManager.initDocumentDropZone(); $('.use_default_rewriten_url').click(function(ev) { alert("Not functionnal"); diff --git a/templates/admin/default/document-edit.html b/templates/admin/default/document-edit.html new file mode 100644 index 000000000..0039e7d29 --- /dev/null +++ b/templates/admin/default/document-edit.html @@ -0,0 +1,143 @@ +{extends file="admin-layout.tpl"} + +{block name="page-title"}{intl l='Edit a document'}{/block} + +{block name="check-permissions"}admin.document.edit{/block} + +{block name="main-content"} +
+ +
+ + {loop type="document" name="document_edit" source="{$documentType}" id="{$documentId}" backend_context="1" lang="$edit_language_id"} + + +
+
+
+ +
+ {intl l="Edit document $TITLE"} +
+ +
+
+ + {form name="thelia.admin.category.document.modification"} + + +
+
+ + {intl l='Close'} +
+
+ {form_hidden_fields form=$form} + + {form_field form=$form field='success_url'} + + {/form_field} + + {if $form_error}
{$form_error_message}
{/if} + +

{intl l="Document informations"}

+ +
+ +
+ {form_field form=$form field='file'} +
+ + +
+ {/form_field} + + {form_field form=$form field='title'} +
+ + +
+ {/form_field} + + {form_field form=$form field='chapo'} +
+ + +
+ {/form_field} + + {form_field form=$form field='postscriptum'} +
+ + +
+ {/form_field} +
+
+
+
+ {form_field form=$form field='description'} +
+ + +
+ {/form_field} +
+
+ + {/form} + +
+
+ +
+
+ +
+ + {/loop} + + {elseloop rel="document_edit"} +
+
+
+ {intl l="Sorry, document ID=$documentId was not found."} +
+
+
+ {/elseloop} + +
+
+{/block} + +{block name="javascript-initialization"} + {javascripts file='assets/js/main.js'} + + {/javascripts} + + + + +{/block} \ No newline at end of file diff --git a/templates/admin/default/folder-edit.html b/templates/admin/default/folder-edit.html index 7e5021d6e..bac087096 100644 --- a/templates/admin/default/folder-edit.html +++ b/templates/admin/default/folder-edit.html @@ -250,6 +250,7 @@
+ {include file='includes/document-upload-form.html' documentType='folder' parentId=$folder_id}
@@ -293,9 +294,14 @@ {javascripts file='assets/js/image-upload.js'} {/javascripts} + {javascripts file='assets/js/document-upload.js'} + + {/javascripts} + diff --git a/templates/admin/default/includes/document-upload-list-ajax.html b/templates/admin/default/includes/document-upload-list-ajax.html new file mode 100644 index 000000000..6dabb7c70 --- /dev/null +++ b/templates/admin/default/includes/document-upload-list-ajax.html @@ -0,0 +1,31 @@ +{* + +A generic document upload form + +Parameters: + documentType = Document type (category, product, folder, content, module) + parentId = Document parent id, ex: category id + +*} + +{ifloop rel="document"} + + {loop type="document" name="document" source="{$documentType}" order="manual-reverse" source_id="{$parentId}"} + + + + {/loop} +
+ {$TITLE} + + + +
+{/ifloop} \ No newline at end of file