Merge branch 'master' of https://github.com/thelia/thelia into coupon
# By gmorel (24) and others # Via gmorel (12) and others * 'master' of https://github.com/thelia/thelia: (43 commits) Working : upload file/image : fix sanitizeFileName Working : images : enhance display Working : Fix : Unit test Working : Fix : Unit test Working : Fix : Image Management + Document Management Working : FileManager :Add some more unit tests Working : Add a link on documents Working : fix url document + refactor : naming conventions Working : refactor : naming conventions Working : upload : fix unit test WIP : upload documents : add action, ctrl, event Finished product combination basic function WIP : upload document : add forms Working : upload image : fix return URL to images tab Working : upload image : fix fallback and delete links on refresh Formatted combination table Impemented combination creation Working : Upload image : Fix upload validation - Image format allowed - manual-reverse order on image loop Upload allow only for images ... Conflicts: core/lib/Thelia/Model/Base/AttributeTemplate.php core/lib/Thelia/Model/Base/AttributeTemplateQuery.php core/lib/Thelia/Model/Map/AttributeTemplateTableMap.php install/faker.php install/thelia.sql local/config/schema.xml templates/admin/default/assets/js/coupon.js tests/functionnal/casperjs/exe/00_parameters.js tests/functionnal/casperjs/exe/31_coupons_rule.js
This commit is contained in:
@@ -123,19 +123,7 @@ class Attribute extends BaseAction implements EventSubscriberInterface
|
||||
*/
|
||||
public function updatePosition(UpdatePositionEvent $event)
|
||||
{
|
||||
if (null !== $attribute = AttributeQuery::create()->findPk($event->getObjectId())) {
|
||||
|
||||
$attribute->setDispatcher($this->getDispatcher());
|
||||
|
||||
$mode = $event->getMode();
|
||||
|
||||
if ($mode == UpdatePositionEvent::POSITION_ABSOLUTE)
|
||||
return $attribute->changeAbsolutePosition($event->getPosition());
|
||||
else if ($mode == UpdatePositionEvent::POSITION_UP)
|
||||
return $attribute->movePositionUp();
|
||||
else if ($mode == UpdatePositionEvent::POSITION_DOWN)
|
||||
return $attribute->movePositionDown();
|
||||
}
|
||||
return $this->genericUpdatePosition(AttributeQuery::create(), $event);
|
||||
}
|
||||
|
||||
protected function doAddToAllTemplates(AttributeModel $attribute)
|
||||
|
||||
@@ -112,19 +112,7 @@ class AttributeAv extends BaseAction implements EventSubscriberInterface
|
||||
*/
|
||||
public function updatePosition(UpdatePositionEvent $event)
|
||||
{
|
||||
if (null !== $attribute = AttributeAvQuery::create()->findPk($event->getObjectId())) {
|
||||
|
||||
$attribute->setDispatcher($this->getDispatcher());
|
||||
|
||||
$mode = $event->getMode();
|
||||
|
||||
if ($mode == UpdatePositionEvent::POSITION_ABSOLUTE)
|
||||
return $attribute->changeAbsolutePosition($event->getPosition());
|
||||
else if ($mode == UpdatePositionEvent::POSITION_UP)
|
||||
return $attribute->movePositionUp();
|
||||
else if ($mode == UpdatePositionEvent::POSITION_DOWN)
|
||||
return $attribute->movePositionDown();
|
||||
}
|
||||
return $this->genericUpdatePosition(AttributeAvQuery::create(), $event);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
namespace Thelia\Action;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Thelia\Model\AdminLog;
|
||||
use Propel\Runtime\ActiveQuery\PropelQuery;
|
||||
use Propel\Runtime\ActiveQuery\ModelCriteria;
|
||||
use Thelia\Core\Event\UpdatePositionEvent;
|
||||
|
||||
class BaseAction
|
||||
{
|
||||
@@ -45,4 +49,42 @@ class BaseAction
|
||||
{
|
||||
return $this->container->get('event_dispatcher');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Changes object position, selecting absolute ou relative change.
|
||||
*
|
||||
* @param $query the query to retrieve the object to move
|
||||
* @param UpdatePositionEvent $event
|
||||
*/
|
||||
protected function genericUpdatePosition(ModelCriteria $query, UpdatePositionEvent $event)
|
||||
{
|
||||
if (null !== $object = $query->findPk($event->getObjectId())) {
|
||||
|
||||
$object->setDispatcher($this->getDispatcher());
|
||||
|
||||
$mode = $event->getMode();
|
||||
|
||||
if ($mode == UpdatePositionEvent::POSITION_ABSOLUTE)
|
||||
return $object->changeAbsolutePosition($event->getPosition());
|
||||
else if ($mode == UpdatePositionEvent::POSITION_UP)
|
||||
return $object->movePositionUp();
|
||||
else if ($mode == UpdatePositionEvent::POSITION_DOWN)
|
||||
return $object->movePositionDown();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,19 +136,7 @@ class Category extends BaseAction implements EventSubscriberInterface
|
||||
*/
|
||||
public function updatePosition(UpdatePositionEvent $event)
|
||||
{
|
||||
if (null !== $category = CategoryQuery::create()->findPk($event->getObjectId())) {
|
||||
|
||||
$category->setDispatcher($this->getDispatcher());
|
||||
|
||||
$mode = $event->getMode();
|
||||
|
||||
if ($mode == UpdatePositionEvent::POSITION_ABSOLUTE)
|
||||
return $category->changeAbsolutePosition($event->getPosition());
|
||||
else if ($mode == UpdatePositionEvent::POSITION_UP)
|
||||
return $category->movePositionUp();
|
||||
else if ($mode == UpdatePositionEvent::POSITION_DOWN)
|
||||
return $category->movePositionDown();
|
||||
}
|
||||
return $this->genericUpdatePosition(CategoryQuery::create(), $event);
|
||||
}
|
||||
|
||||
public function addContent(CategoryAddContentEvent $event) {
|
||||
|
||||
@@ -166,20 +166,7 @@ class Currency extends BaseAction implements EventSubscriberInterface
|
||||
*/
|
||||
public function updatePosition(UpdatePositionEvent $event)
|
||||
{
|
||||
if (null !== $currency = CurrencyQuery::create()->findPk($event->getObjectId())) {
|
||||
|
||||
$currency->setDispatcher($this->getDispatcher());
|
||||
|
||||
$mode = $event->getMode();
|
||||
echo "loaded $mode !";
|
||||
|
||||
if ($mode == UpdatePositionEvent::POSITION_ABSOLUTE)
|
||||
return $currency->changeAbsolutePosition($event->getPosition());
|
||||
else if ($mode == UpdatePositionEvent::POSITION_UP)
|
||||
return $currency->movePositionUp();
|
||||
else if ($mode == UpdatePositionEvent::POSITION_DOWN)
|
||||
return $currency->movePositionDown();
|
||||
}
|
||||
return $this->genericUpdatePosition(CurrencyQuery::create(), $event);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,8 +25,12 @@ namespace Thelia\Action;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
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;
|
||||
@@ -88,45 +92,175 @@ class Document extends BaseCachedFile implements EventSubscriberInterface
|
||||
*
|
||||
* This method updates the cache_file_path and file_url attributes of the event
|
||||
*
|
||||
* @param DocumentEvent $event
|
||||
* @throws \InvalidArgumentException, DocumentException
|
||||
* @param DocumentEvent $event Event
|
||||
*
|
||||
* @throws \Thelia\Exception\DocumentException
|
||||
* @throws \InvalidArgumentException , DocumentException
|
||||
*/
|
||||
public function processDocument(DocumentEvent $event)
|
||||
{
|
||||
$subdir = $event->getCacheSubdirectory();
|
||||
$source_file = $event->getSourceFilepath();
|
||||
$sourceFile = $event->getSourceFilepath();
|
||||
|
||||
if (null == $subdir || null == $source_file) {
|
||||
if (null == $subdir || null == $sourceFile) {
|
||||
throw new \InvalidArgumentException("Cache sub-directory and source file path cannot be null");
|
||||
}
|
||||
|
||||
$originalDocumentPathInCache = $this->getCacheFilePath($subdir, $source_file, true);
|
||||
$originalDocumentPathInCache = $this->getCacheFilePath($subdir, $sourceFile, true);
|
||||
|
||||
if (! file_exists($originalDocumentPathInCache)) {
|
||||
|
||||
if (! file_exists($source_file)) {
|
||||
throw new DocumentException(sprintf("Source document file %s does not exists.", $source_file));
|
||||
if (! file_exists($sourceFile)) {
|
||||
throw new DocumentException(sprintf("Source document file %s does not exists.", $sourceFile));
|
||||
}
|
||||
|
||||
$mode = ConfigQuery::read('original_document_delivery_mode', 'symlink');
|
||||
|
||||
if ($mode == 'symlink') {
|
||||
if (false == symlink($source_file, $originalDocumentPathInCache)) {
|
||||
throw new DocumentException(sprintf("Failed to create symbolic link for %s in %s document cache directory", basename($source_file), $subdir));
|
||||
if (false == symlink($sourceFile, $originalDocumentPathInCache)) {
|
||||
throw new DocumentException(sprintf("Failed to create symbolic link for %s in %s document cache directory", basename($sourceFile), $subdir));
|
||||
}
|
||||
} else {// mode = 'copy'
|
||||
if (false == @copy($source_file, $originalDocumentPathInCache)) {
|
||||
throw new DocumentException(sprintf("Failed to copy %s in %s document cache directory", basename($source_file), $subdir));
|
||||
} else {
|
||||
// mode = 'copy'
|
||||
if (false == @copy($sourceFile, $originalDocumentPathInCache)) {
|
||||
throw new DocumentException(sprintf("Failed to copy %s in %s document cache directory", basename($sourceFile), $subdir));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the document URL
|
||||
$document_url = $this->getCacheFileURL($subdir, basename($originalDocumentPathInCache));
|
||||
$documentUrl = $this->getCacheFileURL($subdir, basename($originalDocumentPathInCache));
|
||||
|
||||
// Update the event with file path and file URL
|
||||
$event->setDocumentPath($originalDocumentPathInCache);
|
||||
$event->setDocumentUrl(URL::getInstance()->absoluteUrl($document_url, null, URL::PATH_TO_FILE));
|
||||
$event->setDocumentPath($documentUrl);
|
||||
$event->setDocumentUrl(URL::getInstance()->absoluteUrl($documentUrl, 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(), FileManager::FILE_TYPE_DOCUMENTS);
|
||||
$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'
|
||||
)
|
||||
);
|
||||
|
||||
if (null !== $event->getUploadedFile()) {
|
||||
$event->getModelDocument()->setTitle($event->getUploadedFile()->getClientOriginalName());
|
||||
}
|
||||
|
||||
$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->getParentId(), $event->getDocumentType(), $event->getModelDocument(), $event->getUploadedFile(), FileManager::FILE_TYPE_DOCUMENTS);
|
||||
$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()
|
||||
@@ -134,6 +268,9 @@ class Document extends BaseCachedFile implements EventSubscriberInterface
|
||||
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),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,19 +123,7 @@ class Feature extends BaseAction implements EventSubscriberInterface
|
||||
*/
|
||||
public function updatePosition(UpdatePositionEvent $event)
|
||||
{
|
||||
if (null !== $feature = FeatureQuery::create()->findPk($event->getObjectId())) {
|
||||
|
||||
$feature->setDispatcher($this->getDispatcher());
|
||||
|
||||
$mode = $event->getMode();
|
||||
|
||||
if ($mode == UpdatePositionEvent::POSITION_ABSOLUTE)
|
||||
return $feature->changeAbsolutePosition($event->getPosition());
|
||||
else if ($mode == UpdatePositionEvent::POSITION_UP)
|
||||
return $feature->movePositionUp();
|
||||
else if ($mode == UpdatePositionEvent::POSITION_DOWN)
|
||||
return $feature->movePositionDown();
|
||||
}
|
||||
return $this->genericUpdatePosition(FeatureQuery::create(), $event);
|
||||
}
|
||||
|
||||
protected function doAddToAllTemplates(FeatureModel $feature)
|
||||
|
||||
@@ -112,19 +112,7 @@ class FeatureAv extends BaseAction implements EventSubscriberInterface
|
||||
*/
|
||||
public function updatePosition(UpdatePositionEvent $event)
|
||||
{
|
||||
if (null !== $feature = FeatureAvQuery::create()->findPk($event->getObjectId())) {
|
||||
|
||||
$feature->setDispatcher($this->getDispatcher());
|
||||
|
||||
$mode = $event->getMode();
|
||||
|
||||
if ($mode == UpdatePositionEvent::POSITION_ABSOLUTE)
|
||||
return $feature->changeAbsolutePosition($event->getPosition());
|
||||
else if ($mode == UpdatePositionEvent::POSITION_UP)
|
||||
return $feature->movePositionUp();
|
||||
else if ($mode == UpdatePositionEvent::POSITION_DOWN)
|
||||
return $feature->movePositionDown();
|
||||
}
|
||||
return $this->genericUpdatePosition(FeatureAvQuery::create(), $event);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -23,10 +23,20 @@
|
||||
|
||||
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\ImagesCreateOrUpdateEvent;
|
||||
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 +49,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 +88,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 +252,128 @@ class Image extends BaseCachedFile implements EventSubscriberInterface
|
||||
$event->setOriginalFileUrl(URL::getInstance()->absoluteUrl($original_image_url, null, URL::PATH_TO_FILE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Take care of saving 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 saveImage(ImageCreateOrUpdateEvent $event)
|
||||
{
|
||||
$this->adminLogAppend(
|
||||
$this->container->get('thelia.translator')->trans(
|
||||
'Saving images for %parentName% parent id %parentId% (%parentType%)',
|
||||
array(
|
||||
'%parentName%' => $event->getParentName(),
|
||||
'%parentId%' => $event->getParentId(),
|
||||
'%parentType%' => $event->getImageType()
|
||||
),
|
||||
'image'
|
||||
)
|
||||
);
|
||||
|
||||
$fileManager = new FileManager($this->container);
|
||||
$model = $event->getModelImage();
|
||||
|
||||
$nbModifiedLines = $model->save();
|
||||
$event->setModelImage($model);
|
||||
|
||||
if (!$nbModifiedLines) {
|
||||
throw new ImageException(
|
||||
sprintf(
|
||||
'Image "%s" with parent id %s (%s) failed to be saved',
|
||||
$event->getParentName(),
|
||||
$event->getParentId(),
|
||||
$event->getImageType()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$newUploadedFile = $fileManager->copyUploadedFile($event->getParentId(), $event->getImageType(), $event->getModelImage(), $event->getUploadedFile(), FileManager::FILE_TYPE_IMAGES);
|
||||
$event->setUploadedFile($newUploadedFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Take care of updating 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 updateImage(ImageCreateOrUpdateEvent $event)
|
||||
{
|
||||
$this->adminLogAppend(
|
||||
$this->container->get('thelia.translator')->trans(
|
||||
'Updating images for %parentName% parent id %parentId% (%parentType%)',
|
||||
array(
|
||||
'%parentName%' => $event->getParentName(),
|
||||
'%parentId%' => $event->getParentId(),
|
||||
'%parentType%' => $event->getImageType()
|
||||
),
|
||||
'image'
|
||||
)
|
||||
);
|
||||
|
||||
$fileManager = new FileManager($this->container);
|
||||
// Copy and save file
|
||||
if ($event->getUploadedFile()) {
|
||||
// Remove old picture file from file storage
|
||||
$url = $fileManager->getUploadDir($event->getImageType(), FileManager::FILE_TYPE_IMAGES) . '/' . $event->getOldModelImage()->getFile();
|
||||
unlink(str_replace('..', '', $url));
|
||||
|
||||
$newUploadedFile = $fileManager->copyUploadedFile($event->getParentId(), $event->getImageType(), $event->getModelImage(), $event->getUploadedFile(), FileManager::FILE_TYPE_IMAGES);
|
||||
$event->setUploadedFile($newUploadedFile);
|
||||
}
|
||||
|
||||
// Update image modifications
|
||||
$event->getModelImage()->save();
|
||||
$event->setModelImage($event->getModelImage());
|
||||
}
|
||||
|
||||
/**
|
||||
* Take care of deleting image in the database and file storage
|
||||
*
|
||||
* @param ImageDeleteEvent $event Image event
|
||||
*
|
||||
* @throws \Exception
|
||||
* @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->deleteFile($event->getImageToDelete(), $event->getImageType(), FileManager::FILE_TYPE_IMAGES);
|
||||
|
||||
$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'
|
||||
)
|
||||
);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process image resizing, with borders or cropping. If $dest_width and $dest_height
|
||||
* are both null, no resize is performed.
|
||||
@@ -362,6 +496,9 @@ class Image extends BaseCachedFile implements EventSubscriberInterface
|
||||
return array(
|
||||
TheliaEvents::IMAGE_PROCESS => array("processImage", 128),
|
||||
TheliaEvents::IMAGE_CLEAR_CACHE => array("clearCache", 128),
|
||||
TheliaEvents::IMAGE_DELETE => array("deleteImage", 128),
|
||||
TheliaEvents::IMAGE_SAVE => array("saveImage", 128),
|
||||
TheliaEvents::IMAGE_UPDATE => array("updateImage", 128),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,26 @@ use Thelia\Model\AccessoryQuery;
|
||||
use Thelia\Model\Accessory;
|
||||
use Thelia\Core\Event\ProductAddAccessoryEvent;
|
||||
use Thelia\Core\Event\ProductDeleteAccessoryEvent;
|
||||
use Thelia\Core\Event\FeatureProductUpdateEvent;
|
||||
use Thelia\Model\FeatureProduct;
|
||||
use Thelia\Model\FeatureQuery;
|
||||
use Thelia\Core\Event\FeatureProductDeleteEvent;
|
||||
use Thelia\Model\FeatureProductQuery;
|
||||
use Thelia\Model\ProductCategoryQuery;
|
||||
use Thelia\Core\Event\ProductSetTemplateEvent;
|
||||
use Thelia\Model\AttributeCombinationQuery;
|
||||
use Thelia\Model\ProductSaleElementsQuery;
|
||||
use Propel\Runtime\ActiveQuery\PropelQuery;
|
||||
use Thelia\Core\Event\ProductDeleteCategoryEvent;
|
||||
use Thelia\Core\Event\ProductAddCategoryEvent;
|
||||
use Thelia\Model\AttributeAvQuery;
|
||||
use Thelia\Model\AttributeCombination;
|
||||
use Thelia\Core\Event\ProductCreateCombinationEvent;
|
||||
use Propel\Runtime\Propel;
|
||||
use Thelia\Model\Map\ProductTableMap;
|
||||
use Thelia\Core\Event\ProductDeleteCombinationEvent;
|
||||
use Thelia\Model\ProductPrice;
|
||||
use Thelia\Model\ProductSaleElements;
|
||||
|
||||
class Product extends BaseAction implements EventSubscriberInterface
|
||||
{
|
||||
@@ -71,7 +91,15 @@ class Product extends BaseAction implements EventSubscriberInterface
|
||||
// Set the default tax rule to this product
|
||||
->setTaxRule(TaxRuleQuery::create()->findOneByIsDefault(true))
|
||||
|
||||
->create($event->getDefaultCategory())
|
||||
//public function create($defaultCategoryId, $basePrice, $priceCurrencyId, $taxRuleId, $baseWeight) {
|
||||
|
||||
->create(
|
||||
$event->getDefaultCategory(),
|
||||
$event->getBasePrice(),
|
||||
$event->getCurrencyId(),
|
||||
$event->getTaxRuleId(),
|
||||
$event->getBaseWeight()
|
||||
);
|
||||
;
|
||||
|
||||
$event->setProduct($product);
|
||||
@@ -84,8 +112,6 @@ class Product extends BaseAction implements EventSubscriberInterface
|
||||
*/
|
||||
public function update(ProductUpdateEvent $event)
|
||||
{
|
||||
$search = ProductQuery::create();
|
||||
|
||||
if (null !== $product = ProductQuery::create()->findPk($event->getProductId())) {
|
||||
|
||||
$product
|
||||
@@ -96,11 +122,16 @@ class Product extends BaseAction implements EventSubscriberInterface
|
||||
->setDescription($event->getDescription())
|
||||
->setChapo($event->getChapo())
|
||||
->setPostscriptum($event->getPostscriptum())
|
||||
|
||||
->setParent($event->getParent())
|
||||
->setVisible($event->getVisible())
|
||||
|
||||
->save();
|
||||
->save()
|
||||
;
|
||||
|
||||
// Update the rewriten URL, if required
|
||||
$product->setRewrittenUrl($event->getLocale(), $event->getUrl());
|
||||
|
||||
// Update default category (ifd required)
|
||||
$product->updateDefaultCategory($event->getDefaultCategory());
|
||||
|
||||
$event->setProduct($product);
|
||||
}
|
||||
@@ -147,19 +178,7 @@ class Product extends BaseAction implements EventSubscriberInterface
|
||||
*/
|
||||
public function updatePosition(UpdatePositionEvent $event)
|
||||
{
|
||||
if (null !== $product = ProductQuery::create()->findPk($event->getObjectId())) {
|
||||
|
||||
$product->setDispatcher($this->getDispatcher());
|
||||
|
||||
$mode = $event->getMode();
|
||||
|
||||
if ($mode == UpdatePositionEvent::POSITION_ABSOLUTE)
|
||||
return $product->changeAbsolutePosition($event->getPosition());
|
||||
else if ($mode == UpdatePositionEvent::POSITION_UP)
|
||||
return $product->movePositionUp();
|
||||
else if ($mode == UpdatePositionEvent::POSITION_DOWN)
|
||||
return $product->movePositionDown();
|
||||
}
|
||||
return $this->genericUpdatePosition(ProductQuery::create(), $event);
|
||||
}
|
||||
|
||||
public function addContent(ProductAddContentEvent $event) {
|
||||
@@ -193,6 +212,34 @@ class Product extends BaseAction implements EventSubscriberInterface
|
||||
;
|
||||
}
|
||||
|
||||
public function addCategory(ProductAddCategoryEvent $event) {
|
||||
|
||||
if (ProductCategoryQuery::create()
|
||||
->filterByProduct($event->getProduct())
|
||||
->filterByCategoryId($event->getCategoryId())
|
||||
->count() <= 0) {
|
||||
|
||||
$productCategory = new ProductCategory();
|
||||
|
||||
$productCategory
|
||||
->setProduct($event->getProduct())
|
||||
->setCategoryId($event->getCategoryId())
|
||||
->setDefaultCategory(false)
|
||||
->save()
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
public function removeCategory(ProductDeleteCategoryEvent $event) {
|
||||
|
||||
$productCategory = ProductCategoryQuery::create()
|
||||
->filterByProduct($event->getProduct())
|
||||
->filterByCategoryId($event->getCategoryId())
|
||||
->findOne();
|
||||
|
||||
if ($productCategory != null) $productCategory->delete();
|
||||
}
|
||||
|
||||
public function addAccessory(ProductAddAccessoryEvent $event) {
|
||||
|
||||
if (AccessoryQuery::create()
|
||||
@@ -224,26 +271,165 @@ class Product extends BaseAction implements EventSubscriberInterface
|
||||
;
|
||||
}
|
||||
|
||||
public function setProductTemplate(ProductSetTemplateEvent $event) {
|
||||
|
||||
$product = $event->getProduct();
|
||||
|
||||
// Delete all product feature relations
|
||||
FeatureProductQuery::create()->filterByProduct($product)->delete();
|
||||
|
||||
// Delete all product attributes sale elements
|
||||
ProductSaleElementsQuery::create()->filterByProduct($product)->delete();
|
||||
|
||||
// Update the product template
|
||||
$template_id = $event->getTemplateId();
|
||||
|
||||
// Set it to null if it's zero.
|
||||
if ($template_id <= 0) $template_id = NULL;
|
||||
|
||||
$product->setTemplateId($template_id)->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes accessry position, selecting absolute ou relative change.
|
||||
*
|
||||
* @param ProductChangePositionEvent $event
|
||||
*/
|
||||
public function updateAccessoryPosition(UpdatePositionEvent $event)
|
||||
{
|
||||
return $this->genericUpdatePosition(AccessoryQuery::create(), $event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes position, selecting absolute ou relative change.
|
||||
*
|
||||
* @param ProductChangePositionEvent $event
|
||||
*/
|
||||
public function updateAccessoryPosition(UpdatePositionEvent $event)
|
||||
public function updateContentPosition(UpdatePositionEvent $event)
|
||||
{
|
||||
if (null !== $accessory = AccessoryQuery::create()->findPk($event->getObjectId())) {
|
||||
return $this->genericUpdatePosition(ProductAssociatedContentQuery::create(), $event);
|
||||
}
|
||||
|
||||
$accessory->setDispatcher($this->getDispatcher());
|
||||
public function updateFeatureProductValue(FeatureProductUpdateEvent $event) {
|
||||
|
||||
$mode = $event->getMode();
|
||||
// If the feature is not free text, it may have one ore more values.
|
||||
// If the value exists, we do not change it
|
||||
// If the value does not exists, we create it.
|
||||
//
|
||||
// If the feature is free text, it has only a single value.
|
||||
// Etiher create or update it.
|
||||
|
||||
if ($mode == UpdatePositionEvent::POSITION_ABSOLUTE)
|
||||
return $accessory->changeAbsolutePosition($event->getPosition());
|
||||
else if ($mode == UpdatePositionEvent::POSITION_UP)
|
||||
return $accessory->movePositionUp();
|
||||
else if ($mode == UpdatePositionEvent::POSITION_DOWN)
|
||||
return $accessory->movePositionDown();
|
||||
$featureProductQuery = FeatureProductQuery::create()
|
||||
->filterByFeatureId($event->getFeatureId())
|
||||
->filterByProductId($event->getProductId())
|
||||
;
|
||||
|
||||
if ($event->getIsTextValue() !== true) {
|
||||
$featureProductQuery->filterByFeatureAvId($event->getFeatureValue());
|
||||
}
|
||||
|
||||
$featureProduct = $featureProductQuery->findOne();
|
||||
|
||||
if ($featureProduct == null) {
|
||||
$featureProduct = new FeatureProduct();
|
||||
|
||||
$featureProduct
|
||||
->setDispatcher($this->getDispatcher())
|
||||
|
||||
->setProductId($event->getProductId())
|
||||
->setFeatureId($event->getFeatureId())
|
||||
;
|
||||
}
|
||||
|
||||
if ($event->getIsTextValue() == true) {
|
||||
$featureProduct->setFreeTextValue($event->getFeatureValue());
|
||||
}
|
||||
else {
|
||||
$featureProduct->setFeatureAvId($event->getFeatureValue());
|
||||
}
|
||||
|
||||
$featureProduct->save();
|
||||
|
||||
$event->setFeatureProduct($featureProduct);
|
||||
}
|
||||
|
||||
public function deleteFeatureProductValue(FeatureProductDeleteEvent $event) {
|
||||
|
||||
$featureProduct = FeatureProductQuery::create()
|
||||
->filterByProductId($event->getProductId())
|
||||
->filterByFeatureId($event->getFeatureId())
|
||||
->delete()
|
||||
;
|
||||
}
|
||||
|
||||
public function createProductCombination(ProductCreateCombinationEvent $event) {
|
||||
|
||||
$con = Propel::getWriteConnection(ProductTableMap::DATABASE_NAME);
|
||||
|
||||
$con->beginTransaction();
|
||||
|
||||
try {
|
||||
$product = $event->getProduct();
|
||||
|
||||
// Create an empty product sale element
|
||||
$salesElement = new ProductSaleElements();
|
||||
|
||||
$salesElement
|
||||
->setProduct($product)
|
||||
->setRef($product->getRef())
|
||||
->setPromo(0)
|
||||
->setNewness(0)
|
||||
->setWeight(0)
|
||||
->setIsDefault(false)
|
||||
->save($con)
|
||||
;
|
||||
|
||||
// Create an empty product price in the default currency
|
||||
$product_price = new ProductPrice();
|
||||
|
||||
$product_price
|
||||
->setProductSaleElements($salesElement)
|
||||
->setPromoPrice(0)
|
||||
->setPrice(0)
|
||||
->setCurrencyId($event->getCurrencyId())
|
||||
->save($con)
|
||||
;
|
||||
|
||||
$combinationAttributes = $event->getAttributeAvList();
|
||||
|
||||
if (count($combinationAttributes) > 0) {
|
||||
|
||||
foreach($combinationAttributes as $attributeAvId) {
|
||||
|
||||
$attributeAv = AttributeAvQuery::create()->findPk($attributeAvId);
|
||||
|
||||
if ($attributeAv !== null) {
|
||||
$attributeCombination = new AttributeCombination();
|
||||
|
||||
$attributeCombination
|
||||
->setAttributeAvId($attributeAvId)
|
||||
->setAttribute($attributeAv->getAttribute())
|
||||
->setProductSaleElements($salesElement)
|
||||
->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Store all the stuff !
|
||||
$con->commit();
|
||||
}
|
||||
catch(\Exception $ex) {
|
||||
|
||||
$con->rollback();
|
||||
|
||||
throw $ex;
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteProductCombination(ProductDeleteCombinationEvent $event) {
|
||||
|
||||
if (null !== $pse = ProductSaleElementsQuery::create()->findPk($event->getProductSaleElementId())) {
|
||||
$pse->delete();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,9 +449,22 @@ class Product extends BaseAction implements EventSubscriberInterface
|
||||
TheliaEvents::PRODUCT_ADD_CONTENT => array("addContent", 128),
|
||||
TheliaEvents::PRODUCT_REMOVE_CONTENT => array("removeContent", 128),
|
||||
TheliaEvents::PRODUCT_UPDATE_ACCESSORY_POSITION => array("updateAccessoryPosition", 128),
|
||||
TheliaEvents::PRODUCT_UPDATE_CONTENT_POSITION => array("updateContentPosition", 128),
|
||||
|
||||
TheliaEvents::PRODUCT_ADD_COMBINATION => array("createProductCombination", 128),
|
||||
TheliaEvents::PRODUCT_DELETE_COMBINATION => array("deleteProductCombination", 128),
|
||||
|
||||
TheliaEvents::PRODUCT_ADD_ACCESSORY => array("addAccessory", 128),
|
||||
TheliaEvents::PRODUCT_REMOVE_ACCESSORY => array("removeAccessory", 128),
|
||||
|
||||
TheliaEvents::PRODUCT_ADD_CATEGORY => array("addCategory", 128),
|
||||
TheliaEvents::PRODUCT_REMOVE_CATEGORY => array("removeCategory", 128),
|
||||
|
||||
TheliaEvents::PRODUCT_SET_TEMPLATE => array("setProductTemplate", 128),
|
||||
|
||||
TheliaEvents::PRODUCT_FEATURE_UPDATE_VALUE => array("updateFeatureProductValue", 128),
|
||||
TheliaEvents::PRODUCT_FEATURE_DELETE_VALUE => array("deleteFeatureProductValue", 128),
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,6 +135,26 @@ class Template extends BaseAction implements EventSubscriberInterface
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes position, selecting absolute ou relative change.
|
||||
*
|
||||
* @param CategoryChangePositionEvent $event
|
||||
*/
|
||||
public function updateAttributePosition(UpdatePositionEvent $event)
|
||||
{
|
||||
return $this->genericUpdatePosition(AttributeTemplateQuery::create(), $event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes position, selecting absolute ou relative change.
|
||||
*
|
||||
* @param CategoryChangePositionEvent $event
|
||||
*/
|
||||
public function updateFeaturePosition(UpdatePositionEvent $event)
|
||||
{
|
||||
return $this->genericUpdatePosition(FeatureTemplateQuery::create(), $event);
|
||||
}
|
||||
|
||||
public function deleteAttribute(TemplateDeleteAttributeEvent $event) {
|
||||
|
||||
$attribute_template = AttributeTemplateQuery::create()
|
||||
@@ -185,6 +205,9 @@ class Template extends BaseAction implements EventSubscriberInterface
|
||||
TheliaEvents::TEMPLATE_ADD_FEATURE => array("addFeature", 128),
|
||||
TheliaEvents::TEMPLATE_DELETE_FEATURE => array("deleteFeature", 128),
|
||||
|
||||
TheliaEvents::TEMPLATE_CHANGE_ATTRIBUTE_POSITION => array('updateAttributePosition', 128),
|
||||
TheliaEvents::TEMPLATE_CHANGE_FEATURE_POSITION => array('updateFeaturePosition', 128),
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user