WIP : Upload management (upload+save+delete done) need to finish integration and add all image fields

This commit is contained in:
gmorel
2013-09-20 16:51:34 +02:00
parent 3627d96175
commit ced7b5e6dc
24 changed files with 1838 additions and 168 deletions

View File

@@ -23,6 +23,7 @@
namespace Thelia\Action;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Thelia\Model\AdminLog;
class BaseAction
{
@@ -45,4 +46,18 @@ class BaseAction
{
return $this->container->get('event_dispatcher');
}
/**
* Helper to append a message to the admin log.
*
* @param string $message
*/
public function adminLogAppend($message)
{
AdminLog::append(
$message,
$this->container->get('request'),
$this->container->get('thelia.securityContext')->getAdminUser()
);
}
}

View File

@@ -23,10 +23,19 @@
namespace Thelia\Action;
use Propel\Runtime\ActiveRecord\ActiveRecordInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Thelia\Core\Event\ImageCreateOrUpdateEvent;
use Thelia\Core\Event\ImageDeleteEvent;
use Thelia\Core\Event\ImageEvent;
use Thelia\Model\CategoryImage;
use Thelia\Model\ConfigQuery;
use Thelia\Model\ContentImage;
use Thelia\Model\FolderImage;
use Thelia\Model\ProductImage;
use Thelia\Tools\FileManager;
use Thelia\Tools\URL;
use Imagine\Image\ImagineInterface;
@@ -39,10 +48,10 @@ use Thelia\Core\Event\TheliaEvents;
/**
*
* Image management actions. This class handles image processing an caching.
* Image management actions. This class handles image processing and caching.
*
* Basically, images are stored outside the web space (by default in local/media/images),
* and cached in the web space (by default in web/local/images).
* Basically, images are stored outside of the web space (by default in local/media/images),
* and cached inside the web space (by default in web/local/images).
*
* In the images caches directory, a subdirectory for images categories (eg. product, category, folder, etc.) is
* automatically created, and the cached image is created here. Plugin may use their own subdirectory as required.
@@ -78,6 +87,8 @@ class Image extends BaseCachedFile implements EventSubscriberInterface
const EXACT_RATIO_WITH_CROP = 2;
const KEEP_IMAGE_RATIO = 3;
/**
* @return string root of the image cache directory in web space
*/
@@ -240,6 +251,107 @@ class Image extends BaseCachedFile implements EventSubscriberInterface
$event->setOriginalFileUrl(URL::getInstance()->absoluteUrl($original_image_url, null, URL::PATH_TO_FILE));
}
/**
* Take care of saving images in the database and file storage
*
* @param ImageCreateOrUpdateEvent $event Image event
*
* @throws \Thelia\Exception\ImageException
* @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action
*/
public function saveImages(ImageCreateOrUpdateEvent $event)
{
$fileManager = new FileManager($this->container);
$this->adminLogAppend(
$this->container->get('thelia.translator')->trans(
'Saving images for parent id %parentId% (%parentType%)',
array(
'%parentId%' => $event->getParentId(),
'%parentType%' => $event->getImageType()
),
'image'
)
);
$newUploadedFiles = array();
$uploadedFiles = $event->getUploadedFiles();
foreach ($event->getModelImages() as $i => $modelImage) {
// Save image to database in order to get image id
$fileManager->saveImage($event, $modelImage);
if (isset($uploadedFiles) && isset($uploadedFiles[$i])) {
/** @var UploadedFile $uploadedFile */
$uploadedFile = $uploadedFiles[$i]['file'];
// Copy uploaded file into the storage directory
$newUploadedFiles = $fileManager->copyUploadedFile($event->getParentId(), $event->getImageType(), $modelImage, $uploadedFile, $newUploadedFiles);
} else {
throw new ImageException(
sprintf(
'File with name %s not found on the server',
$modelImage->getFile()
)
);
}
$event->setUploadedFiles($newUploadedFiles);
}
}
/**
* Take care of deleting image in the database and file storage
*
* @param ImageCreateOrUpdateEvent $event Image event
*
* @throws \Thelia\Exception\ImageException
* @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action
*/
public function deleteImage(ImageDeleteEvent $event)
{
$fileManager = new FileManager($this->container);
try {
$fileManager->deleteImage($event->getImageToDelete());
$this->adminLogAppend(
$this->container->get('thelia.translator')->trans(
'Deleting image for %id% with parent id %parentId%',
array(
'%id%' => $event->getImageToDelete()->getId(),
'%parentId%' => $event->getImageToDelete()->getParentId(),
),
'image'
)
);
} catch(\Exception $e) {
$this->adminLogAppend(
$this->container->get('thelia.translator')->trans(
'Fail to delete image for %id% with parent id %parentId% (Exception : %e%)',
array(
'%id%' => $event->getImageToDelete()->getId(),
'%parentId%' => $event->getImageToDelete()->getParentId(),
'%e%' => $e->getMessage()
),
'image'
)
);
}
}
/**
* The absolute directory path where uploaded
* documents should be saved
*
* @param $modelImage Image model
*
* @return string
*/
public function getUploadRootDir($modelImage)
{
return __DIR__.'/../../../../' . $modelImage->getUploadDir();
}
/**
* Process image resizing, with borders or cropping. If $dest_width and $dest_height
* are both null, no resize is performed.
@@ -362,6 +474,8 @@ class Image extends BaseCachedFile implements EventSubscriberInterface
return array(
TheliaEvents::IMAGE_PROCESS => array("processImage", 128),
TheliaEvents::IMAGE_CLEAR_CACHE => array("clearCache", 128),
TheliaEvents::IMAGE_SAVE => array("saveImages", 128),
TheliaEvents::IMAGE_DELETE => array("deleteImage", 128),
);
}
}

View File

@@ -54,7 +54,7 @@
<form name="thelia.admin.category.creation" class="Thelia\Form\CategoryCreationForm"/>
<form name="thelia.admin.category.modification" class="Thelia\Form\CategoryModificationForm"/>
<form name="thelia.admin.category.picture.creation" class="Thelia\Form\CategoryPictureCreationForm"/>
<form name="thelia.admin.category.image.creation" class="Thelia\Form\CategoryImageCreationForm"/>
<form name="thelia.admin.product.creation" class="Thelia\Form\ProductCreationForm"/>
<form name="thelia.admin.product.modification" class="Thelia\Form\ProductModificationForm"/>
@@ -225,6 +225,11 @@
<argument type="service" id="thelia.securityContext" />
</service>
<service id="smarty.plugin.flashMessage" class="Thelia\Core\Template\Smarty\Plugins\FlashMessage" scope="request">
<tag name="thelia.parser.register_plugin"/>
<argument type="service" id="request" />
</service>
<service id="http_kernel" class="Thelia\Core\TheliaHttpKernel">
<argument type="service" id="event_dispatcher" />

View File

@@ -31,6 +31,19 @@
<default key="_controller">Thelia\Controller\Admin\CategoryController::defaultAction</default>
</route>
<!-- Route to the file controller -->
<route id="admin.image.save" path="/admin/image/type/{parentType}/{parentId}/save">
<default key="_controller">Thelia\Controller\Admin\FileController::saveImagesAction</default>
<requirement key="parentType">.*</requirement>
<requirement key="parentId">\d+</requirement>
</route>
<route id="admin.image.delete" path="/admin/image/type/{parentType}/delete/{imageId}">
<default key="_controller">Thelia\Controller\Admin\FileController::deleteImagesAction</default>
<requirement key="parentType">.*</requirement>
<requirement key="parentId">\d+</requirement>
</route>
<!-- Customer rule management -->
<route id="admin.customers" path="/admin/customers">

View File

@@ -23,11 +23,13 @@
namespace Thelia\Controller\Admin;
use Symfony\Component\HttpFoundation\Response;
use Thelia\Core\Event\CategoryDeleteEvent;
use Thelia\Core\Event\ImageCreateOrUpdateEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\Event\CategoryUpdateEvent;
use Thelia\Core\Event\CategoryCreateEvent;
use Thelia\Form\CategoryPictureCreationForm;
use Thelia\Log\Tlog;
use Thelia\Model\CategoryQuery;
use Thelia\Form\CategoryModificationForm;
use Thelia\Form\CategoryCreationForm;
@@ -35,7 +37,6 @@ use Thelia\Core\Event\UpdatePositionEvent;
use Thelia\Core\Event\CategoryToggleVisibilityEvent;
use Thelia\Core\Event\CategoryDeleteContentEvent;
use Thelia\Core\Event\CategoryAddContentEvent;
use Thelia\Model\CategoryAssociatedContent;
use Thelia\Model\FolderQuery;
use Thelia\Model\ContentQuery;
use Propel\Runtime\ActiveQuery\Criteria;
@@ -366,29 +367,4 @@ class CategoryController extends AbstractCrudController
$this->redirectToEditionTemplate();
}
/**
* @todo remove
* @return Symfony\Component\HttpFoundation\Response|void
*/
public function updateAction()
{
var_dump('updateAction');
if ($this->getRequest()->isMethod('POST')) {
var_dump('getRequest', $this->getRequest()->files);
// Create the form from the request
$creationForm = new CategoryPictureCreationForm($this->getRequest());
// Check the form against constraints violations
$form = $this->validateForm($creationForm, 'POST');
var_dump('$form', $form);
// Get the form field values
$data = $form->getData();
var_dump('$data', $data);
}
return parent::updateAction();
}
}

View File

@@ -0,0 +1,290 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Controller\Admin;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Router;
use Thelia\Core\Event\ImageCreateOrUpdateEvent;
use Thelia\Core\Event\ImageDeleteEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\Translation\Translator;
use Thelia\Form\CategoryImageCreationForm;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Log\Tlog;
use Thelia\Model\CategoryImageQuery;
use Thelia\Model\ContentImageQuery;
use Thelia\Model\FolderImageQuery;
use Thelia\Model\ProductImageQuery;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* Control View and Action (Model) via Events
* Control Files and Images
*
* @package File
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
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
* @param string $successUrl Success URL to be redirected to
*
* @return Response
*/
public function saveFilesAction($parentId, $parentType, $successUrl)
{
}
/**
* Manage how a image collection has to be saved
*
* @param int $parentId Parent id owning images being saved
* @param string $parentType Parent Type owning images being saved
*
* @return Response
*/
public function saveImagesAction($parentId, $parentType)
{
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.image.save")) {
return $response;
}
$message = $this->getTranslator()
->trans(
'Images saved successfully',
array(),
'image'
);
if ($this->isParentTypeValid($parentType)) {
if ($this->getRequest()->isMethod('POST')) {
// Create the form from the request
$creationForm = $this->getImageForm($parentType, $this->getRequest());
try {
// Check the form against constraints violations
$form = $this->validateForm($creationForm, 'POST');
// Get the form field values
$data = $form->getData();
// Feed event
$imageCreateOrUpdateEvent = new ImageCreateOrUpdateEvent(
$parentType,
$parentId
);
if (isset($data) && isset($data['pictures'])) {
$imageCreateOrUpdateEvent->setModelImages($data['pictures']);
$imageCreateOrUpdateEvent->setUploadedFiles($this->getRequest()->files->get($creationForm->getName())['pictures']);
}
// Dispatch Event to the Action
$this->dispatch(
TheliaEvents::IMAGE_SAVE,
$imageCreateOrUpdateEvent
);
} catch (FormValidationException $e) {
// Invalid data entered
$message = 'Please check your input:';
$this->logError($parentType, 'image saving', $message, $e);
} catch (\Exception $e) {
// Any other error
$message = 'Sorry, an error occurred:';
$this->logError($parentType, 'image saving', $message, $e);
}
if ($message !== false) {
// Mark the form as with error
$creationForm->setErrorMessage($message);
// Send the form and the error to the parser
$this->getParserContext()
->addForm($creationForm)
->setGeneralError($message);
// Set flash message to be displayed
$flashMessage = $this->getSession()->get('flashMessage');
$flashMessage['imageMessage'] = $message;
$this->getSession()->set('flashMessage', $flashMessage);
}
}
}
$this->redirectSuccess($creationForm);
}
/**
* Manage how a image has to be deleted (AJAX)
*
* @param int $imageId Parent id owning images being saved
* @param string $parentType Parent Type owning images being saved
*
* @return Response
*/
public function deleteImagesAction($imageId, $parentType)
{
$this->checkAuth('ADMIN', 'admin.image.delete');
$this->checkXmlHttpRequest();
$model = $this->getImageModel($parentType, $imageId);
if ($model == null) {
return $this->pageNotFound();
}
// Feed event
$imageDeleteEvent = new ImageDeleteEvent(
$model
);
// Dispatch Event to the Action
$this->dispatch(
TheliaEvents::IMAGE_DELETE,
$imageDeleteEvent
);
$message = $this->getTranslator()
->trans(
'Images deleted successfully',
array(),
'image'
);
return new Response($message);
}
/**
* Log error message
*
* @param string $parentType Parent type
* @param string $action Creation|Update|Delete
* @param string $message Message to log
* @param \Exception $e Exception to log
*
* @return $this
*/
protected function logError($parentType, $action, $message, $e)
{
Tlog::getInstance()->error(
sprintf(
'Error during ' . $parentType . ' ' . $action . ' process : %s. Exception was %s',
$message,
$e->getMessage()
)
);
return $this;
}
/**
* Check if parent type is valid or not
*
* @param string $parentType Parent type
*
* @return bool
*/
public function isParentTypeValid($parentType)
{
return (in_array($parentType, ImageCreateOrUpdateEvent::getAvailableType()));
}
/**
* Get Image form
*
* @param string $parentType Parent type
* @param Request $request Request Service
*
* @return null|CategoryImageCreationForm|ContentImageCreationForm|FolderImageCreationForm|ProductImageCreationForm
*
* @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action
*/
public function getImageForm($parentType, Request $request)
{
// @todo implement other forms
switch ($parentType) {
// case ImageCreateOrUpdateEvent::TYPE_PRODUCT:
// $creationForm = new ProductImageCreationForm($request);
// break;
case ImageCreateOrUpdateEvent::TYPE_CATEGORY:
$creationForm = new CategoryImageCreationForm($request);
break;
// case ImageCreateOrUpdateEvent::TYPE_CONTENT:
// $creationForm = new ContentImageCreationForm($request);
// break;
// case ImageCreateOrUpdateEvent::TYPE_FOLDER:
// $creationForm = new FolderImageCreationForm($request);
// break;
default:
$creationForm = null;
}
return $creationForm;
}
/**
* Get image model from type
*
* @param string $parentType
* @param int $imageId
*
* @return null|\Thelia\Model\CategoryImage|\Thelia\Model\ContentImage|\Thelia\Model\FolderImage|\Thelia\Model\ProductImage
*
* @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action
*/
public function getImageModel($parentType, $imageId)
{
switch ($parentType) {
case ImageCreateOrUpdateEvent::TYPE_PRODUCT:
$model = ProductImageQuery::create()->findPk($imageId);
break;
case ImageCreateOrUpdateEvent::TYPE_CATEGORY:
$model = CategoryImageQuery::create()->findPk($imageId);
break;
case ImageCreateOrUpdateEvent::TYPE_CONTENT:
$model = ContentImageQuery::create()->findPk($imageId);
break;
case ImageCreateOrUpdateEvent::TYPE_FOLDER:
$model = FolderImageQuery::create()->findPk($imageId);
break;
default:
$model = null;
}
return $model;
}
}

View File

@@ -0,0 +1,184 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
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 <gmorel@openstudio.fr>
*
*/
class ImageCreateOrUpdateEvent 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;
}
}

View File

@@ -0,0 +1,82 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Core\Event;
use Thelia\Model\CategoryImage;
use Thelia\Model\ContentImage;
use Thelia\Model\FolderImage;
use Thelia\Model\ProductImage;
/**
* Created by JetBrains PhpStorm.
* Date: 9/18/13
* Time: 3:56 PM
*
* Occurring when a Image is about to be deleted
*
* @package Image
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class ImageDeleteEvent extends ActionEvent
{
/** @var CategoryImage|ProductImage|ContentImage|FolderImage Image about to be deleted */
protected $imageToDelete = null;
/**
* Constructor
*
* @param CategoryImage|ProductImage|ContentImage|FolderImage $imageToDelete Image about to be deleted
*/
public function __construct($imageToDelete)
{
$this->imageToDelete = $imageToDelete;
}
/**
* Set Image about to be deleted
*
* @param CategoryImage|ProductImage|ContentImage|FolderImage $imageToDelete Image about to be deleted
*
* @return $this
*/
public function setImageToDelete($imageToDelete)
{
$this->imageToDelete = $imageToDelete;
return $this;
}
/**
* Get Image about to be deleted
*
* @return CategoryImage|ProductImage|ContentImage|FolderImage
*/
public function getImageToDelete()
{
return $this->imageToDelete;
}
}

View File

@@ -234,6 +234,16 @@ final class TheliaEvents
*/
const IMAGE_CLEAR_CACHE = "action.clearImageCache";
/**
* Save given images
*/
const IMAGE_SAVE = "action.saveImages";
/**
* Delete given image
*/
const IMAGE_DELETE = "action.deleteImage";
/**
* Sent when creating a Coupon
*/

View File

@@ -0,0 +1,103 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Core\Template\Smarty\Plugins;
use Symfony\Component\Form\FormView;
use Thelia\Form\BaseForm;
use Thelia\Core\Template\Element\Exception\ElementNotFoundException;
use Symfony\Component\HttpFoundation\Request;
use Thelia\Core\Template\Smarty\SmartyPluginDescriptor;
use Thelia\Core\Template\Smarty\AbstractSmartyPlugin;
use Thelia\Core\Template\ParserContext;
/**
* Created by JetBrains PhpStorm.
* Date: 9/18/13
* Time: 3:56 PM
*
* Plugin for smarty defining blocks allowing to get flash message
* A flash message is a variable, array, object stored in session under the flashMessage key
* ex $SESSION['flashMessage']['myKey']
*
* blocks :
* - {flashMessage key="myKey"} ... {/flashMessage}
*
* Class Form
*
* @package Thelia\Core\Template\Smarty\Plugins
* @author Guillaume MOREL <gmorel@openstudio.fr>
*/
class FlashMessage extends AbstractSmartyPlugin
{
/** @var Request Request service */
protected $request;
/**
* Constructor
*
* @param Request $request Request service
*/
public function __construct(Request $request)
{
$this->request = $request;
}
/**
* Get FlashMessage
* And clean session from this key
*
* @param array $params Block parameters
* @param mixed $content Block content
* @param \Smarty_Internal_Template $template Template
* @param bool $repeat Control how many times
* the block is displayed
*
* @return mixed
*/
public function getFlashMessage($params, $content, \Smarty_Internal_Template $template, &$repeat)
{
if ($repeat) {
$key = $params['key'];
$flashBag = $this->request->getSession()->get('flashMessage');
$template->assign('value', $flashBag[$key]);
// Reset flash message (can be read once)
unset($flashBag[$key]);
$this->request->getSession()->set('flashMessage', $flashBag);
} else {
return $content;
}
}
/**
* @return array an array of SmartyPluginDescriptor
*/
public function getPluginDescriptors()
{
return array(
new SmartyPluginDescriptor("block", "flashMessage", $this, "getFlashMessage")
);
}
}

View File

@@ -0,0 +1,71 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Form;
use Thelia\Core\Translation\Translator;
use Thelia\Form\Type\ImageCategoryType;
/**
* Created by JetBrains PhpStorm.
* Date: 9/18/13
* Time: 3:56 PM
*
* Form allowing to process an image collection
*
* @package Image
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class CategoryImageCreationForm extends BaseForm
{
/**
* Allow to build a form
*/
protected function buildForm()
{
$this->formBuilder
->add('pictures',
'collection',
array(
'type' => new ImageCategoryType(),
'options' => array(
'required' => false
),
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
)
)
->add('formSuccessUrl');
}
/**
* Get form name
*
* @return string
*/
public function getName()
{
return 'thelia_category_image_creation';
}
}

View File

@@ -1,100 +0,0 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Form;
use Symfony\Component\Validator\Constraints\Image;
use Symfony\Component\Validator\Constraints\NotBlank;
use Thelia\Core\Translation\Translator;
class CategoryPictureCreationForm extends BaseForm
{
protected function buildForm()
{
$this->formBuilder
// ->add('alt')
->add('file', 'file', array(
'constraints' => array(
new NotBlank(),
new Image(
array(
'minWidth' => 200,
'maxWidth' => 400,
'minHeight' => 200,
'maxHeight' => 400,
)
)
)))
// ->add('category_id', 'model', array(
// 'disabled' => false,
// 'class' => 'Thelia\Model\ProductImage'
// ))
// ->add('position', 'integer', array(
// 'constraints' => array(
// new NotBlank()
// )
// ))
->add('title', 'text', array(
'constraints' => array(
// new NotBlank()
),
// 'label' => Translator::getInstance()->trans('Category picture title *'),
// 'label_attr' => array(
// 'for' => 'title'
// )
))
// ->add('description', 'text', array(
// 'constraints' => array(
// new NotBlank()
// ),
// 'label' => Translator::getInstance()->trans('Category picture description *'),
// 'label_attr' => array(
// 'for' => 'description'
// )
// ))
// ->add('chapo', 'text', array(
// 'constraints' => array(
// new NotBlank()
// ),
// 'label' => Translator::getInstance()->trans('Category picture chapo *'),
// 'label_attr' => array(
// 'for' => 'chapo'
// )
// ))
// ->add('postscriptum', 'text', array(
// 'constraints' => array(
// new NotBlank()
// ),
// 'label' => Translator::getInstance()->trans('Category picture postscriptum *'),
// 'label_attr' => array(
// 'for' => 'postscriptum'
// )
// ))
;
}
public function getName()
{
return 'thelia_category_picture_creation';
}
}

View File

@@ -0,0 +1,79 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Form\Type;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Thelia\Form\Type\ImageType;
/**
* Created by JetBrains PhpStorm.
* Date: 9/18/13
* Time: 3:56 PM
*
* Form allowing to process a category picture
*
* @package Image
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class ImageCategoryType extends ImageType
{
/**
* Build a Picture form
*
* @param FormBuilderInterface $builder Form builder
* @param array $options Form options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('category_id', 'integer');
parent::buildForm($builder, $options);
}
/**
* Set default options
* Map the form to the given Model
*
* @param OptionsResolverInterface $resolver Option resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(
array(
'data_class' => 'Thelia\Model\CategoryImage'
)
);
}
/**
* Get form name
*
* @return string
*/
public function getName()
{
return 'thelia_category_picture_creation_type';
}
}

View File

@@ -0,0 +1,82 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints\Image;
use Symfony\Component\Validator\Constraints\NotBlank;
/**
* Created by JetBrains PhpStorm.
* Date: 9/18/13
* Time: 3:56 PM
*
* Form allowing to process a picture
*
* @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action
*
* @package Image
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
abstract class ImageType extends AbstractType
{
/**
* Build a Picture form
*
* @param FormBuilderInterface $builder Form builder
* @param array $options Form options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
// $builder->add('position');
$builder->add(
'title',
'text',
array(
'constraints' => new NotBlank()
)
);
$builder->add(
'file',
'file',
array(
'constraints' => array(
new NotBlank(),
new Image(
array(
'minWidth' => 200,
// 'maxWidth' => 400,
'minHeight' => 200,
// 'maxHeight' => 400,
)
)
)
)
);
// $builder->add('description');
// $builder->add('chapo');
// $builder->add('postscriptum');
}
}

View File

@@ -2,6 +2,8 @@
namespace Thelia\Model;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Thelia\Model\Base\CategoryImage as BaseCategoryImage;
use Propel\Runtime\Connection\ConnectionInterface;
@@ -28,6 +30,7 @@ class CategoryImage extends BaseCategoryImage
/**
* Get picture absolute path
* @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action
*
* @return null|string
*/
@@ -35,11 +38,12 @@ class CategoryImage extends BaseCategoryImage
{
return null === $this->file
? null
: $this->getUploadRootDir().'/'.$this->file;
: $this->getUploadDir().'/'.$this->file;
}
/**
* Get picture web path
* @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action
*
* @return null|string
*/
@@ -50,23 +54,25 @@ class CategoryImage extends BaseCategoryImage
: $this->getUploadDir().'/'.$this->file;
}
/**
* The absolute directory path where uploaded
* documents should be saved
* @return string
*/
protected function getUploadRootDir()
{
return __DIR__.'/../../../../../'.$this->getUploadDir();
}
/**
* Get rid of the __DIR__ so it doesn't screw up
* when displaying uploaded doc/image in the view.
* @return string
*/
protected function getUploadDir()
public function getUploadDir()
{
return 'local/media/images/category';
return THELIA_LOCAL_DIR . 'media/images/category';
}
/**
* Get Image parent id
*
* @return int parent id
*/
public function getParentId()
{
return $this->getCategoryId();
}
}

View File

@@ -25,4 +25,14 @@ class ContentImage extends BaseContentImage
return true;
}
/**
* Get Image parent id
*
* @return int parent id
*/
public function getParentId()
{
return $this->getContentId();
}
}

View File

@@ -25,4 +25,14 @@ class FolderImage extends BaseFolderImage
return true;
}
/**
* Get Image parent id
*
* @return int parent id
*/
public function getParentId()
{
return $this->getFolderId();
}
}

View File

@@ -25,4 +25,14 @@ class ProductImage extends BaseProductImage
return true;
}
/**
* Get Image parent id
*
* @return int parent id
*/
public function getParentId()
{
return $this->getProductId();
}
}

View File

@@ -0,0 +1,361 @@
<?php
/**
* Created by JetBrains PhpStorm.
* Date: 9/18/13
* Time: 8:47 PM
*
* @author Guillaume MOREL <gmorel@openstudio.fr>
*/
namespace Thelia\Tests\Type;
use Thelia\Core\Event\ImageCreateOrUpdateEvent;
use Thelia\Exception\ImageException;
use Thelia\Model\Admin;
use Thelia\Model\ProductImage;
use Thelia\Tools\FileManager;
class FileManagerTest extends \PHPUnit_Framework_TestCase {
/**
* @covers Thelia\Tools\FileManager::copyUploadedFile
*/
public function testCopyUploadedFile()
{
$this->markTestIncomplete(
'Mock issue'
);
$stubTranslator = $this->getMockBuilder('\Thelia\Core\Translation\Translator')
->disableOriginalConstructor()
->getMock();
$stubTranslator->expects($this->any())
->method('trans')
->will($this->returnValue('translated'));
$stubRequest = $this->getMockBuilder('\Thelia\Core\HttpFoundation\Request')
->disableOriginalConstructor()
->getMock();
$stubSecurity = $this->getMockBuilder('\Thelia\Core\Security\SecurityContext')
->disableOriginalConstructor()
->getMock();
$stubSecurity->expects($this->any())
->method('getAdminUser')
->will($this->returnValue(new Admin()));
// Create a map of arguments to return values.
$map = array(
array('thelia.translator', $stubTranslator),
array('request', $stubRequest),
array('thelia.securityContext', $stubSecurity)
);
$stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface')
->disableOriginalConstructor()
->getMock();
$stubContainer->expects($this->any())
->method('get')
->will($this->returnValueMap($map));
$stubProductImage = $this->getMockBuilder('\Thelia\Model\ProductImage')
->disableOriginalConstructor()
->getMock();
$stubProductImage->expects($this->any())
->method('getUploadDir')
->will($this->returnValue(THELIA_LOCAL_DIR . 'media/images/product'));
$stubProductImage->expects($this->any())
->method('getId')
->will($this->returnValue(42));
$stubProductImage->expects($this->any())
->method('setFile')
->will($this->returnValue(true));
$stubProductImage->expects($this->any())
->method('save')
->will($this->returnValue(0));
$stubUploadedFile = $this->getMockBuilder('\Symfony\Component\HttpFoundation\File\UploadedFile')
->disableOriginalConstructor()
->getMock();
$stubUploadedFile->expects($this->any())
->method('getClientOriginalName')
->will($this->returnValue('goodName'));
$stubUploadedFile->expects($this->any())
->method('getClientOriginalExtension')
->will($this->returnValue('png'));
$stubUploadedFile->expects($this->any())
->method('move')
->will($this->returnValue($stubUploadedFile));
$fileManager = new FileManager($stubContainer);
$newUploadedFiles = array();
$actual = $fileManager->copyUploadedFile(24, ImageCreateOrUpdateEvent::TYPE_PRODUCT, $stubProductImage, $stubUploadedFile, $newUploadedFiles);
$this->assertCount(1, $actual);
}
/**
* @covers Thelia\Tools\FileManager::copyUploadedFile
* @expectedException \Thelia\Exception\ImageException
*/
public function testCopyUploadedFileExceptionImageException()
{
$this->markTestIncomplete(
'Mock issue'
);
$stubTranslator = $this->getMockBuilder('\Thelia\Core\Translation\Translator')
->disableOriginalConstructor()
->getMock();
$stubTranslator->expects($this->any())
->method('trans')
->will($this->returnValue('translated'));
$stubRequest = $this->getMockBuilder('\Thelia\Core\HttpFoundation\Request')
->disableOriginalConstructor()
->getMock();
$stubSecurity = $this->getMockBuilder('\Thelia\Core\Security\SecurityContext')
->disableOriginalConstructor()
->getMock();
$stubSecurity->expects($this->any())
->method('getAdminUser')
->will($this->returnValue(new Admin()));
// Create a map of arguments to return values.
$map = array(
array('thelia.translator', $stubTranslator),
array('request', $stubRequest),
array('thelia.securityContext', $stubSecurity)
);
$stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface')
->disableOriginalConstructor()
->getMock();
$stubContainer->expects($this->any())
->method('get')
->will($this->returnValueMap($map));
$stubProductImage = $this->getMockBuilder('\Thelia\Model\ProductImage')
->disableOriginalConstructor()
->getMock();
$stubProductImage->expects($this->any())
->method('getUploadDir')
->will($this->returnValue(THELIA_LOCAL_DIR . 'media/images/product'));
$stubProductImage->expects($this->any())
->method('getId')
->will($this->returnValue(42));
$stubProductImage->expects($this->any())
->method('setFile')
->will($this->returnValue(true));
$stubProductImage->expects($this->any())
->method('save')
->will($this->returnValue(0));
$stubUploadedFile = $this->getMockBuilder('\Symfony\Component\HttpFoundation\File\UploadedFile')
->disableOriginalConstructor()
->getMock();
$stubUploadedFile->expects($this->any())
->method('getClientOriginalName')
->will($this->returnValue('goodName'));
$stubUploadedFile->expects($this->any())
->method('getClientOriginalExtension')
->will($this->returnValue('png'));
$stubUploadedFile->expects($this->any())
->method('move')
->will($this->returnValue($stubUploadedFile));
$fileManager = new FileManager($stubContainer);
$newUploadedFiles = array();
$actual = $fileManager->copyUploadedFile(24, ImageCreateOrUpdateEvent::TYPE_PRODUCT, $stubProductImage, $stubUploadedFile, $newUploadedFiles);
}
/**
* @covers Thelia\Tools\FileManager::saveImage
*/
public function testSaveImageProductImage()
{
$stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface')
->disableOriginalConstructor()
->getMock();
$stubProductImage = $this->getMockBuilder('\Thelia\Model\ProductImage')
->disableOriginalConstructor()
->getMock();
$stubProductImage->expects($this->any())
->method('save')
->will($this->returnValue(10));
$fileManager = new FileManager($stubContainer);
$event = new ImageCreateOrUpdateEvent(ImageCreateOrUpdateEvent::TYPE_PRODUCT, 24);
$expected = 10;
$actual = $fileManager->saveImage($event, $stubProductImage);
$this->assertEquals($expected, $actual);
}
/**
* @covers Thelia\Tools\FileManager::saveImage
*/
public function testSaveImageCategoryImage()
{
$stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface')
->disableOriginalConstructor()
->getMock();
$stubCategoryImage = $this->getMockBuilder('\Thelia\Model\CategoryImage')
->disableOriginalConstructor()
->getMock();
$stubCategoryImage->expects($this->any())
->method('save')
->will($this->returnValue(10));
$fileManager = new FileManager($stubContainer);
$event = new ImageCreateOrUpdateEvent(ImageCreateOrUpdateEvent::TYPE_CATEGORY, 24);
$expected = 10;
$actual = $fileManager->saveImage($event, $stubCategoryImage);
$this->assertEquals($expected, $actual);
}
/**
* @covers Thelia\Tools\FileManager::saveImage
*/
public function testSaveImageFolderImage()
{
$stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface')
->disableOriginalConstructor()
->getMock();
$stubFolderImage = $this->getMockBuilder('\Thelia\Model\FolderImage')
->disableOriginalConstructor()
->getMock();
$stubFolderImage->expects($this->any())
->method('save')
->will($this->returnValue(10));
$fileManager = new FileManager($stubContainer);
$event = new ImageCreateOrUpdateEvent(ImageCreateOrUpdateEvent::TYPE_FOLDER, 24);
$expected = 10;
$actual = $fileManager->saveImage($event, $stubFolderImage);
$this->assertEquals($expected, $actual);
}
/**
* @covers Thelia\Tools\FileManager::saveImage
*/
public function testSaveImageContentImage()
{
$stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface')
->disableOriginalConstructor()
->getMock();
$stubContentImage = $this->getMockBuilder('\Thelia\Model\ContentImage')
->disableOriginalConstructor()
->getMock();
$stubContentImage->expects($this->any())
->method('save')
->will($this->returnValue(10));
$fileManager = new FileManager($stubContainer);
$event = new ImageCreateOrUpdateEvent(ImageCreateOrUpdateEvent::TYPE_CONTENT, 24);
$expected = 10;
$actual = $fileManager->saveImage($event, $stubContentImage);
$this->assertEquals($expected, $actual);
}
/**
* @covers Thelia\Tools\FileManager::saveImage
* @expectedException \Thelia\Exception\ImageException
*/
public function testSaveImageExceptionImageException()
{
$stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface')
->disableOriginalConstructor()
->getMock();
$fileManager = new FileManager($stubContainer);
$stubProductImage = $this->getMockBuilder('\Thelia\Model\ProductImage')
->disableOriginalConstructor()
->getMock();
$stubProductImage->expects($this->any())
->method('save')
->will($this->returnValue(10));
$event = new ImageCreateOrUpdateEvent('bad', 24);
$modelImage = new ProductImage();
$fileManager->saveImage($event, $modelImage);
}
/**
* @covers Thelia\Tools\FileManager::saveImage
* @expectedException \Thelia\Exception\ImageException
*/
public function testSaveImageExceptionImageException2()
{
$stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface')
->disableOriginalConstructor()
->getMock();
$fileManager = new FileManager($stubContainer);
$stubProductImage = $this->getMockBuilder('\Thelia\Model\ProductImage')
->disableOriginalConstructor()
->getMock();
$stubProductImage->expects($this->any())
->method('save')
->will($this->returnValue(0));
$event = new ImageCreateOrUpdateEvent(ImageCreateOrUpdateEvent::TYPE_PRODUCT, 24);
$fileManager->saveImage($event, $stubProductImage);
}
/**
* @covers Thelia\Tools\FileManager::sanitizeFileName
*/
public function testSanitizeFileName()
{
$stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface')
->disableOriginalConstructor()
->getMock();
$fileManager = new FileManager($stubContainer);
$badFileName = 'azeéràçè§^"$*+-_°)(&é<>@#ty';
$expected = 'azeyryZyy-_yty';
$actual = $fileManager->sanitizeFileName($badFileName);
$this->assertEquals($expected, $actual);
}
/**
* @covers Thelia\Tools\FileManager::adminLogAppend
*/
public function testAdminLogAppend()
{
$this->markTestIncomplete(
'This test has not been implemented yet.'
);
}
}

View File

@@ -0,0 +1,222 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Tools;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Thelia\Core\Event\ImageCreateOrUpdateEvent;
use Thelia\Core\Event\ImageDeleteEvent;
use Thelia\Exception\ImageException;
use Thelia\Model\AdminLog;
use Thelia\Model\Base\CategoryImage;
use Thelia\Model\ContentImage;
use Thelia\Model\FolderImage;
use Thelia\Model\ProductImage;
/**
* Created by JetBrains PhpStorm.
* Date: 9/19/13
* Time: 3:24 PM
*
* File Manager
*
* @package File
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class FileManager
{
/** @var ContainerInterface Service Container */
protected $container = null;
/** @var Translator Service Translator */
protected $translator = null;
/**
* Constructor
*
* @param ContainerInterface $container Service container
*/
public function __construct(ContainerInterface $container)
{
$this->container = $container;
$this->translator = $this->container->get('thelia.translator');
}
/**
* 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 array $newUploadedFiles UploadedFile array to update
*
* @throws \Thelia\Exception\ImageException
* @return array Updated UploadedFile array
*/
public function copyUploadedFile($parentId, $imageType, $modelImage, $uploadedFile, $newUploadedFiles)
{
if ($uploadedFile !== null) {
$directory = $modelImage->getUploadDir();
$fileName = $this->sanitizeFileName(
$uploadedFile->getClientOriginalName() . "-" . $modelImage->getId() . "." . strtolower(
$uploadedFile->getClientOriginalExtension()
)
);
$this->adminLogAppend(
$this->translator->trans(
'Uploading picture %pictureName% to %directory% for parent_id %parentId% (%parentType%)',
array(
'%pictureName%' => $uploadedFile->getClientOriginalName(),
'%directory%' => $directory . '/' . $fileName,
'%parentId%' => $parentId,
'%parentType%' => $imageType
),
'image'
)
);
$newUploadedFiles[] = array('file' => $uploadedFile->move($directory, $fileName));
$modelImage->setFile($fileName);
if (!$modelImage->save()) {
throw new ImageException(
sprintf(
'Image %s (%s) failed to be saved (image file)',
$modelImage->getFile(),
$imageType
)
);
}
}
return $newUploadedFiles;
}
/**
* Save image into the database
*
* @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(ImageCreateOrUpdateEvent $event, $modelImage)
{
$nbModifiedLines = 0;
if ($modelImage->getFile() !== null) {
switch ($event->getImageType()) {
case ImageCreateOrUpdateEvent::TYPE_PRODUCT:
/** @var ProductImage $modelImage */
$modelImage->setProductId($event->getParentId());
break;
case ImageCreateOrUpdateEvent::TYPE_CATEGORY:
/** @var CategoryImage $modelImage */
$modelImage->setCategoryId($event->getParentId());
break;
case ImageCreateOrUpdateEvent::TYPE_CONTENT:
/** @var ContentImage $modelImage */
$modelImage->setContentId($event->getParentId());
break;
case ImageCreateOrUpdateEvent::TYPE_FOLDER:
/** @var FolderImage $modelImage */
$modelImage->setFolderId($event->getParentId());
break;
default:
throw new ImageException(
sprintf(
'Picture parent type is unknown (available types : %s)',
implode(
',',
$event->getAvailableType()
)
)
);
}
$nbModifiedLines = $modelImage->save();
if (!$nbModifiedLines) {
throw new ImageException(
sprintf(
'Image %s failed to be saved (image content)',
$modelImage->getFile()
)
);
}
}
return $nbModifiedLines;
}
/**
* Sanitizes a filename replacing whitespace with dashes
*
* Removes special characters that are illegal in filenames on certain
* operating systems and special characters requiring special escaping
* to manipulate at the command line.
*
* @param string $string The filename to be sanitized
*
* @return string The sanitized filename
*/
public function sanitizeFileName($string)
{
$cleanName = strtr($string, 'ŠŽšžŸÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖØÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöøùúûüýÿ', 'SZszYAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy');
$cleanName = strtr($cleanName, array('Þ' => 'TH', 'þ' => 'th', 'Ð' => 'DH', 'ð' => 'dh', 'ß' => 'ss', 'Œ' => 'OE', 'œ' => 'oe', 'Æ' => 'AE', 'æ' => 'ae', 'µ' => 'u'));
$cleanName = preg_replace(array('/\s/', '/\.[\.]+/', '/[^\w_\.\-]/'), array('_', '.', ''), $cleanName);
return $cleanName;
}
/**
* Helper to append a message to the admin log.
*
* @param string $message
*/
public function adminLogAppend($message)
{
AdminLog::append(
$message,
$this->container->get('request'),
$this->container->get('thelia.securityContext')->getAdminUser()
);
}
/**
* Delete image from file storage and database
*
* @param CategoryImage|ProductImage|ContentImage|FolderImage $imageModel Image being deleted
*/
public function deleteImage($imageModel)
{
unlink($imageModel->getAbsolutePath());
$imageModel->delete();
}
}

View File

@@ -54,4 +54,5 @@ class I18n
return \DateTime::createFromFormat($currentDateFormat, $date);
}
}