# By Manuel Raynaud (80) and others
# Via Manuel Raynaud (16) and others
* 'master' of https://github.com/thelia/thelia: (179 commits)
  Working : images : enhance display
  fix missing } in password template
  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
  remove smarty cache
  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
  ...
This commit is contained in:
gmorel
2013-09-27 10:20:02 +02:00
763 changed files with 50632 additions and 4782 deletions

View File

@@ -35,10 +35,10 @@ Installation
------------
``` bash
$ git clone --recursive https://github.com/thelia/thelia.git
$ git clone https://github.com/thelia/thelia.git
$ cd thelia
$ curl -sS https://getcomposer.org/installer | php
$ php composer.phar install --optimize-autoloader
$ php composer.phar install --prefer-dist --optimize-autoloader
```
Finish the installation using cli tools :

View File

@@ -37,7 +37,8 @@
"imagine/imagine": "dev-master",
"symfony/icu": "1.0",
"swiftmailer/swiftmailer": "5.0.*"
"swiftmailer/swiftmailer": "5.0.*",
"symfony/serializer": "2.3.*"
},
"require-dev" : {
"phpunit/phpunit": "3.7.*",

67
composer.lock generated
View File

@@ -3,7 +3,7 @@
"This file locks the dependencies of your project to a known state",
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
],
"hash": "a40be01c82e68ba0c446dc204d2667da",
"hash": "097481390dc87b3482d895b3b6a65479",
"packages": [
{
"name": "imagine/imagine",
@@ -1456,6 +1456,53 @@
"homepage": "http://symfony.com",
"time": "2013-08-23 14:06:02"
},
{
"name": "symfony/serializer",
"version": "v2.3.4",
"target-dir": "Symfony/Component/Serializer",
"source": {
"type": "git",
"url": "https://github.com/symfony/Serializer.git",
"reference": "457ba76395955926a67ea692957b0872dead5278"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Serializer/zipball/457ba76395955926a67ea692957b0872dead5278",
"reference": "457ba76395955926a67ea692957b0872dead5278",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.3-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\Serializer\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony Serializer Component",
"homepage": "http://symfony.com",
"time": "2013-07-21 12:12:18"
},
{
"name": "symfony/translation",
"version": "v2.2.6",
@@ -1722,12 +1769,12 @@
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "1.2.12"
"reference": "0e9958c459d675fb497d8dc5001c91d335734e48"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/1.2.12",
"reference": "1.2.12",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/0e9958c459d675fb497d8dc5001c91d335734e48",
"reference": "0e9958c459d675fb497d8dc5001c91d335734e48",
"shasum": ""
},
"require": {
@@ -1916,12 +1963,12 @@
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
"reference": "1.2.0"
"reference": "31babf400e5b5868573bf49a000a3519d3978233"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/1.2.0",
"reference": "1.2.0",
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/31babf400e5b5868573bf49a000a3519d3978233",
"reference": "31babf400e5b5868573bf49a000a3519d3978233",
"shasum": ""
},
"require": {
@@ -1966,12 +2013,12 @@
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "3.7.24"
"reference": "af7b77ccb5c64458bdfca95665d29558d1df7d08"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3.7.24",
"reference": "3.7.24",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/af7b77ccb5c64458bdfca95665d29558d1df7d08",
"reference": "af7b77ccb5c64458bdfca95665d29558d1df7d08",
"shasum": ""
},
"require": {

View File

@@ -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)

View File

@@ -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);
}

View File

@@ -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()
);
}
}

View File

@@ -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) {
@@ -160,6 +148,7 @@ class Category extends BaseAction implements EventSubscriberInterface
$content = new CategoryAssociatedContent();
$content
->setDispatcher($this->getDispatcher())
->setCategory($event->getCategory())
->setContentId($event->getContentId())
->save()
@@ -174,7 +163,11 @@ class Category extends BaseAction implements EventSubscriberInterface
->filterByCategory($event->getCategory())->findOne()
;
if ($content !== null) $content->delete();
if ($content !== null) {
$content
->setDispatcher($this->getDispatcher())
->delete();
}
}

View File

@@ -0,0 +1,160 @@
<?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\Action;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Thelia\Core\Event\Content\ContentCreateEvent;
use Thelia\Core\Event\Content\ContentDeleteEvent;
use Thelia\Core\Event\Content\ContentToggleVisibilityEvent;
use Thelia\Core\Event\Content\ContentUpdateEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\Event\UpdatePositionEvent;
use Thelia\Model\ContentQuery;
use Thelia\Model\Content as ContentModel;
use Thelia\Model\FolderQuery;
/**
* Class Content
* @package Thelia\Action
* @author manuel raynaud <mraynaud@openstudio.fr>
*/
class Content extends BaseAction implements EventSubscriberInterface
{
public function create(ContentCreateEvent $event)
{
$content = new ContentModel();
$content
->setVisible($event->getVisible())
->setLocale($event->getLocale())
->setTitle($event->getTitle())
->create($event->getDefaultFolder())
;
$event->setContent($content);
}
/**
* process update content
*
* @param ContentUpdateEvent $event
*/
public function update(ContentUpdateEvent $event)
{
if (null !== $content = ContentQuery::create()->findPk($event->getContentId())) {
$content->setDispatcher($this->getDispatcher());
$content
->setVisible($event->getVisible())
->setLocale($event->getLocale())
->setTitle($event->getTitle())
->setDescription($event->getDescription())
->setChapo($event->getChapo())
->setPostscriptum($event->getPostscriptum())
->save()
;
$event->setContent($content);
}
}
public function updatePosition(UpdatePositionEvent $event)
{
if(null !== $content = ContentQuery::create()->findPk($event->getObjectId())) {
$content->setDispatcher($this->getDispatcher());
switch($event->getMode())
{
case UpdatePositionEvent::POSITION_ABSOLUTE:
$content->changeAbsolutePosition($event->getPosition());
break;
case UpdatePositionEvent::POSITION_DOWN:
$content->movePositionDown();
break;
case UpdatePositionEvent::POSITION_UP:
$content->movePositionUp();
break;
}
}
}
public function toggleVisibility(ContentToggleVisibilityEvent $event)
{
$content = $event->getContent();
$content
->setDispatcher($this->getDispatcher())
->setVisible(!$content->getVisible())
->save();
}
public function delete(ContentDeleteEvent $event)
{
if (null !== $content = ContentQuery::create()->findPk($event->getContentId())) {
$defaultFolderId = $content->getDefaultFolderId();
$content->setDispatcher($this->getDispatcher())
->delete();
$event->setDefaultFolderId($defaultFolderId);
$event->setContent($content);
}
}
/**
* Returns an array of event names this subscriber wants to listen to.
*
* The array keys are event names and the value can be:
*
* * The method name to call (priority defaults to 0)
* * An array composed of the method name to call and the priority
* * An array of arrays composed of the method names to call and respective
* priorities, or 0 if unset
*
* For instance:
*
* * array('eventName' => 'methodName')
* * array('eventName' => array('methodName', $priority))
* * array('eventName' => array(array('methodName1', $priority), array('methodName2'))
*
* @return array The event names to listen to
*
* @api
*/
public static function getSubscribedEvents()
{
return array(
TheliaEvents::CONTENT_CREATE => array("create", 128),
TheliaEvents::CONTENT_UPDATE => array("update", 128),
TheliaEvents::CONTENT_DELETE => array("delete", 128),
TheliaEvents::CONTENT_TOGGLE_VISIBILITY => array("toggleVisibility", 128),
TheliaEvents::CONTENT_UPDATE_POSITION => array("updatePosition", 128),
);
}
}

View File

@@ -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);
}
/**

View File

@@ -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),
);
}
}

View File

@@ -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)

View File

@@ -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);
}

View File

@@ -0,0 +1,155 @@
<?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\Action;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Thelia\Core\Event\FolderCreateEvent;
use Thelia\Core\Event\FolderDeleteEvent;
use Thelia\Core\Event\FolderToggleVisibilityEvent;
use Thelia\Core\Event\FolderUpdateEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\Event\UpdatePositionEvent;
use Thelia\Model\FolderQuery;
use Thelia\Model\Folder as FolderModel;
/**
* Class Folder
* @package Thelia\Action
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class Folder extends BaseAction implements EventSubscriberInterface {
public function update(FolderUpdateEvent $event)
{
if (null !== $folder = FolderQuery::create()->findPk($event->getFolderId())) {
$folder->setDispatcher($this->getDispatcher());
$folder
->setParent($event->getParent())
->setVisible($event->getVisible())
->setLocale($event->getLocale())
->setTitle($event->getTitle())
->setDescription($event->getDescription())
->setChapo($event->getChapo())
->setPostscriptum($event->getPostscriptum())
->save();
;
$event->setFolder($folder);
}
}
public function delete(FolderDeleteEvent $event)
{
if (null !== $folder = FolderQuery::create()->findPk($event->getFolderId())) {
$folder->setDispatcher($this->getDispatcher())
->delete();
$event->setFolder($folder);
}
}
/**
* @param FolderCreateEvent $event
*/
public function create(FolderCreateEvent $event)
{
$folder = new FolderModel();
$folder->setDispatcher($this->getDispatcher());
$folder
->setParent($event->getParent())
->setVisible($event->getVisible())
->setLocale($event->getLocale())
->setTitle($event->getTitle())
->save();
$event->setFolder($folder);
}
public function toggleVisibility(FolderToggleVisibilityEvent $event)
{
$folder = $event->getFolder();
$folder
->setDispatcher($this->getDispatcher())
->setVisible(!$folder->getVisible())
->save();
}
public function updatePosition(UpdatePositionEvent $event)
{
if(null !== $folder = FolderQuery::create()->findPk($event->getObjectId())) {
$folder->setDispatcher($this->getDispatcher());
switch($event->getMode())
{
case UpdatePositionEvent::POSITION_ABSOLUTE:
$folder->changeAbsolutePosition($event->getPosition());
break;
case UpdatePositionEvent::POSITION_DOWN:
$folder->movePositionDown();
break;
case UpdatePositionEvent::POSITION_UP:
$folder->movePositionUp();
break;
}
}
}
/**
* Returns an array of event names this subscriber wants to listen to.
*
* The array keys are event names and the value can be:
*
* * The method name to call (priority defaults to 0)
* * An array composed of the method name to call and the priority
* * An array of arrays composed of the method names to call and respective
* priorities, or 0 if unset
*
* For instance:
*
* * array('eventName' => 'methodName')
* * array('eventName' => array('methodName', $priority))
* * array('eventName' => array(array('methodName1', $priority), array('methodName2'))
*
* @return array The event names to listen to
*
* @api
*/
public static function getSubscribedEvents()
{
return array(
TheliaEvents::FOLDER_CREATE => array("create", 128),
TheliaEvents::FOLDER_UPDATE => array("update", 128),
TheliaEvents::FOLDER_DELETE => array("delete", 128),
TheliaEvents::FOLDER_TOGGLE_VISIBILITY => array("toggleVisibility", 128),
TheliaEvents::FOLDER_UPDATE_POSITION => array("updatePosition", 128),
);
}
}

View File

@@ -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),
);
}
}

View File

@@ -23,16 +23,23 @@
namespace Thelia\Action;
use Propel\Runtime\ActiveQuery\ModelCriteria;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Thelia\Core\Event\CartEvent;
use Thelia\Core\Event\OrderEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Model\ProductPrice;
use Thelia\Model\ProductPriceQuery;
use Thelia\Model\CartItem;
use Thelia\Model\CartItemQuery;
use Thelia\Exception\OrderException;
use Thelia\Exception\TheliaProcessException;
use Thelia\Model\AddressQuery;
use Thelia\Model\OrderProductAttributeCombination;
use Thelia\Model\ModuleQuery;
use Thelia\Model\OrderProduct;
use Thelia\Model\OrderStatus;
use Thelia\Model\Map\OrderTableMap;
use Thelia\Model\OrderAddress;
use Thelia\Model\OrderStatusQuery;
use Thelia\Model\ConfigQuery;
use Thelia\Tools\I18n;
/**
*
@@ -61,13 +68,224 @@ class Order extends BaseAction implements EventSubscriberInterface
{
$order = $event->getOrder();
$deliveryAddress = $event->getDeliveryAddress();
$order->setDeliveryModuleId($event->getDeliveryModule());
$order->setPostage($event->getPostage());
$event->setOrder($order);
}
/**
* @param \Thelia\Core\Event\OrderEvent $event
*/
public function setInvoiceAddress(OrderEvent $event)
{
$order = $event->getOrder();
$order->chosenInvoiceAddress = $event->getInvoiceAddress();
$event->setOrder($order);
}
/**
* @param \Thelia\Core\Event\OrderEvent $event
*/
public function setPaymentModule(OrderEvent $event)
{
$order = $event->getOrder();
$order->setPaymentModuleId($event->getPaymentModule());
$event->setOrder($order);
}
/**
* @param \Thelia\Core\Event\OrderEvent $event
*/
public function create(OrderEvent $event)
{
$con = \Propel\Runtime\Propel::getConnection(
OrderTableMap::DATABASE_NAME
);
$con->beginTransaction();
$sessionOrder = $event->getOrder();
/* use a copy to avoid errored reccord in session */
$placedOrder = $sessionOrder->copy();
$placedOrder->setDispatcher($this->getDispatcher());
$customer = $this->getSecurityContext()->getCustomerUser();
$currency = $this->getSession()->getCurrency();
$lang = $this->getSession()->getLang();
$deliveryAddress = AddressQuery::create()->findPk($sessionOrder->chosenDeliveryAddress);
$taxCountry = $deliveryAddress->getCountry();
$invoiceAddress = AddressQuery::create()->findPk($sessionOrder->chosenInvoiceAddress);
$cart = $this->getSession()->getCart();
$cartItems = $cart->getCartItems();
$paymentModule = ModuleQuery::create()->findPk($placedOrder->getPaymentModuleId());
/* fulfill order */
$placedOrder->setCustomerId($customer->getId());
$placedOrder->setCurrencyId($currency->getId());
$placedOrder->setCurrencyRate($currency->getRate());
$placedOrder->setLangId($lang->getId());
/* hard save the delivery and invoice addresses */
$deliveryOrderAddress = new OrderAddress();
$deliveryOrderAddress
->setCustomerTitleId($deliveryAddress->getTitleId())
->setCompany($deliveryAddress->getCompany())
->setFirstname($deliveryAddress->getFirstname())
->setLastname($deliveryAddress->getLastname())
->setAddress1($deliveryAddress->getAddress1())
->setAddress2($deliveryAddress->getAddress2())
->setAddress3($deliveryAddress->getAddress3())
->setZipcode($deliveryAddress->getZipcode())
->setCity($deliveryAddress->getCity())
->setPhone($deliveryAddress->getPhone())
->setCountryId($deliveryAddress->getCountryId())
->save($con)
;
$invoiceOrderAddress = new OrderAddress();
$invoiceOrderAddress
->setCustomerTitleId($invoiceAddress->getTitleId())
->setCompany($invoiceAddress->getCompany())
->setFirstname($invoiceAddress->getFirstname())
->setLastname($invoiceAddress->getLastname())
->setAddress1($invoiceAddress->getAddress1())
->setAddress2($invoiceAddress->getAddress2())
->setAddress3($invoiceAddress->getAddress3())
->setZipcode($invoiceAddress->getZipcode())
->setCity($invoiceAddress->getCity())
->setPhone($invoiceAddress->getPhone())
->setCountryId($invoiceAddress->getCountryId())
->save($con)
;
$placedOrder->setDeliveryOrderAddressId($deliveryOrderAddress->getId());
$placedOrder->setInvoiceOrderAddressId($invoiceOrderAddress->getId());
$placedOrder->setStatusId(
OrderStatusQuery::create()->findOneByCode(OrderStatus::CODE_NOT_PAID)->getId()
);
$placedOrder->save($con);
/* fulfill order_products and decrease stock */
foreach($cartItems as $cartItem) {
$product = $cartItem->getProduct();
/* get translation */
$productI18n = I18n::forceI18nRetrieving($this->getSession()->getLang()->getLocale(), 'Product', $product->getId());
$pse = $cartItem->getProductSaleElements();
/* check still in stock */
if($cartItem->getQuantity() > $pse->getQuantity()) {
throw new TheliaProcessException("Not enough stock", TheliaProcessException::CART_ITEM_NOT_ENOUGH_STOCK, $cartItem);
}
/* decrease stock */
$pse->setQuantity(
$pse->getQuantity() - $cartItem->getQuantity()
);
$pse->save($con);
/* get tax */
$taxRuleI18n = I18n::forceI18nRetrieving($this->getSession()->getLang()->getLocale(), 'TaxRule', $product->getTaxRuleId());
$taxDetail = $product->getTaxRule()->getTaxDetail(
$taxCountry,
$cartItem->getPromo() == 1 ? $cartItem->getPromoPrice() : $cartItem->getPrice(),
$this->getSession()->getLang()->getLocale()
);
$orderProduct = new OrderProduct();
$orderProduct
->setOrderId($placedOrder->getId())
->setProductRef($product->getRef())
->setProductSaleElementsRef($pse->getRef())
->setTitle($productI18n->getTitle())
->setChapo($productI18n->getChapo())
->setDescription($productI18n->getDescription())
->setPostscriptum($productI18n->getPostscriptum())
->setQuantity($cartItem->getQuantity())
->setPrice($cartItem->getPrice())
->setPromoPrice($cartItem->getPromoPrice())
->setWasNew($pse->getNewness())
->setWasInPromo($cartItem->getPromo())
->setWeight($pse->getWeight())
->setTaxRuleTitle($taxRuleI18n->getTitle())
->setTaxRuleDescription($taxRuleI18n->getDescription())
;
$orderProduct->setDispatcher($this->getDispatcher());
$orderProduct->save($con);
/* fulfill order_product_tax */
foreach($taxDetail as $tax) {
$tax->setOrderProductId($orderProduct->getId());
$tax->save($con);
}
/* fulfill order_attribute_combination and decrease stock */
foreach($pse->getAttributeCombinations() as $attributeCombination) {
$attribute = I18n::forceI18nRetrieving($this->getSession()->getLang()->getLocale(), 'Attribute', $attributeCombination->getAttributeId());
$attributeAv = I18n::forceI18nRetrieving($this->getSession()->getLang()->getLocale(), 'AttributeAv', $attributeCombination->getAttributeAvId());
$orderAttributeCombination = new OrderProductAttributeCombination();
$orderAttributeCombination
->setOrderProductId($orderProduct->getId())
->setAttributeTitle($attribute->getTitle())
->setAttributeChapo($attribute->getChapo())
->setAttributeDescription($attribute->getDescription())
->setAttributePostscriptumn($attribute->getPostscriptum())
->setAttributeAvTitle($attributeAv->getTitle())
->setAttributeAvChapo($attributeAv->getChapo())
->setAttributeAvDescription($attributeAv->getDescription())
->setAttributeAvPostscriptum($attributeAv->getPostscriptum())
;
$orderAttributeCombination->save($con);
}
}
/* discount @todo */
$con->commit();
$this->getDispatcher()->dispatch(TheliaEvents::ORDER_BEFORE_PAYMENT, new OrderEvent($placedOrder));
/* clear session */
/* but memorize placed order */
$sessionOrder = new \Thelia\Model\Order();
$event->setOrder($sessionOrder);
$event->setPlacedOrder($placedOrder);
$this->getSession()->setOrder($sessionOrder);
/* empty cart @todo */
/* call pay method */
$paymentModuleReflection = new \ReflectionClass($paymentModule->getFullNamespace());
$paymentModuleInstance = $paymentModuleReflection->newInstance();
$paymentModuleInstance->setRequest($this->getRequest());
$paymentModuleInstance->setDispatcher($this->getDispatcher());
$paymentModuleInstance->pay($placedOrder);
}
/**
* @param \Thelia\Core\Event\OrderEvent $event
*/
public function sendOrderEmail(OrderEvent $event)
{
/* @todo */
}
/**
* Returns an array of event names this subscriber wants to listen to.
*
@@ -93,6 +311,40 @@ class Order extends BaseAction implements EventSubscriberInterface
return array(
TheliaEvents::ORDER_SET_DELIVERY_ADDRESS => array("setDeliveryAddress", 128),
TheliaEvents::ORDER_SET_DELIVERY_MODULE => array("setDeliveryModule", 128),
TheliaEvents::ORDER_SET_INVOICE_ADDRESS => array("setInvoiceAddress", 128),
TheliaEvents::ORDER_SET_PAYMENT_MODULE => array("setPaymentModule", 128),
TheliaEvents::ORDER_PAY => array("create", 128),
TheliaEvents::ORDER_BEFORE_PAYMENT => array("sendOrderEmail", 128),
);
}
/**
* Return the security context
*
* @return SecurityContext
*/
protected function getSecurityContext()
{
return $this->container->get('thelia.securityContext');
}
/**
* @return \Symfony\Component\HttpFoundation\Request
*/
protected function getRequest()
{
return $this->container->get('request');
}
/**
* Returns the session from the current request
*
* @return \Thelia\Core\HttpFoundation\Session\Session
*/
protected function getSession()
{
$request = $this->getRequest();
return $request->getSession();
}
}

View File

@@ -40,6 +40,34 @@ use Thelia\Core\Event\ProductAddContentEvent;
use Thelia\Core\Event\ProductDeleteContentEvent;
use Thelia\Model\ProductAssociatedContent;
use Thelia\Model\ProductAssociatedContentQuery;
use Thelia\Model\ProductCategory;
use Thelia\Model\TaxRule;
use Thelia\Model\TaxRuleQuery;
use Thelia\Model\TaxQuery;
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
{
@@ -55,13 +83,24 @@ class Product extends BaseAction implements EventSubscriberInterface
$product
->setDispatcher($this->getDispatcher())
->setLocale($event->getLocale())
->setRef($event->getRef())
->setTitle($event->getTitle())
->setParent($event->getParent())
->setLocale($event->getLocale())
->setVisible($event->getVisible())
->save()
;
// Set the default tax rule to this product
->setTaxRule(TaxRuleQuery::create()->findOneByIsDefault(true))
//public function create($defaultCategoryId, $basePrice, $priceCurrencyId, $taxRuleId, $baseWeight) {
->create(
$event->getDefaultCategory(),
$event->getBasePrice(),
$event->getCurrencyId(),
$event->getTaxRuleId(),
$event->getBaseWeight()
);
;
$event->setProduct($product);
}
@@ -73,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
@@ -85,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);
}
@@ -136,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) {
@@ -160,6 +190,7 @@ class Product extends BaseAction implements EventSubscriberInterface
$content = new ProductAssociatedContent();
$content
->setDispatcher($this->getDispatcher())
->setProduct($event->getProduct())
->setContentId($event->getContentId())
->save()
@@ -174,9 +205,233 @@ class Product extends BaseAction implements EventSubscriberInterface
->filterByProduct($event->getProduct())->findOne()
;
if ($content !== null) $content->delete();
if ($content !== null)
$content
->setDispatcher($this->getDispatcher())
->delete()
;
}
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()
->filterByAccessory($event->getAccessoryId())
->filterByProductId($event->getProduct()->getId())->count() <= 0) {
$accessory = new Accessory();
$accessory
->setDispatcher($this->getDispatcher())
->setProductId($event->getProduct()->getId())
->setAccessory($event->getAccessoryId())
->save()
;
}
}
public function removeAccessory(ProductDeleteAccessoryEvent $event) {
$accessory = AccessoryQuery::create()
->filterByAccessory($event->getAccessoryId())
->filterByProductId($event->getProduct()->getId())->findOne()
;
if ($accessory !== null)
$accessory
->setDispatcher($this->getDispatcher())
->delete()
;
}
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 updateContentPosition(UpdatePositionEvent $event)
{
return $this->genericUpdatePosition(ProductAssociatedContentQuery::create(), $event);
}
public function updateFeatureProductValue(FeatureProductUpdateEvent $event) {
// 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.
$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();
}
}
/**
* {@inheritDoc}
@@ -191,8 +446,24 @@ class Product extends BaseAction implements EventSubscriberInterface
TheliaEvents::PRODUCT_UPDATE_POSITION => array("updatePosition", 128),
TheliaEvents::PRODUCT_ADD_CONTENT => array("addContent", 128),
TheliaEvents::PRODUCT_REMOVE_CONTENT => array("removeContent", 128),
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),
);
}

View File

@@ -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),
);
}
}

View File

@@ -139,4 +139,6 @@ trait CartTrait
return $id;
}
abstract public function getDispatcher();
}

View File

@@ -62,26 +62,34 @@ class CacheClear extends ContainerAwareCommand
$this->clearCache($cacheDir, $output);
if (!$input->getOption("without-assets")) {
$this->clearCache(THELIA_WEB_DIR . "/assets", $output);
$this->clearCache(THELIA_WEB_DIR . "assets", $output);
}
}
protected function clearCache($dir, OutputInterface $output)
{
if (!is_writable($dir)) {
throw new \RuntimeException(sprintf('Unable to write in the "%s" directory', $dir));
}
$output->writeln(sprintf("Clearing cache in <info>%s</info> directory", $dir));
try {
$directoryBrowser = new \DirectoryIterator($dir);
} catch(\UnexpectedValueException $e) {
// throws same exception code for does not exist and permission denied ...
if(!file_exists($dir)) {
$output->writeln(sprintf("<info>%s cache dir already clear</info>", $dir));
return;
}
throw $e;
}
$fs = new Filesystem();
try {
$fs->remove($dir);
$output->writeln(sprintf("<info>%s cache dir cleared successfully</info>", $dir));
} catch (IOException $e) {
$output->writeln(sprintf("error during clearing cache : %s", $e->getMessage()));
$output->writeln(sprintf("Error during clearing cache : %s", $e->getMessage()));
}
}
}

View File

@@ -0,0 +1,90 @@
<?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\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Filesystem\Exception\IOException;
use Thelia\Command\ContainerAwareCommand;
use Thelia\Model\ModuleQuery;
/**
* activates a module
*
* Class ModuleActivateCommand
* @package Thelia\Command
* @author Etienne Roudeix <eroudeix@openstudio.fr>
*
*/
class ModuleActivateCommand extends BaseModuleGenerate
{
protected function configure()
{
$this
->setName("module:activate")
->setDescription("Activates a module")
->addArgument(
"module" ,
InputArgument::REQUIRED,
"module to activate"
)
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$moduleCode = $this->formatModuleName($input->getArgument("module"));
$module = ModuleQuery::create()->findOneByCode($moduleCode);
if(null === $module) {
throw new \RuntimeException(sprintf("module %s not found", $moduleCode));
}
try {
new \TheliaDebugBar\TheliaDebugBar();
$moduleReflection = new \ReflectionClass($module->getFullNamespace());
$moduleInstance = $moduleReflection->newInstance();
$moduleInstance->activate();
} catch(\Exception $e) {
throw new \RuntimeException(sprintf("Activation fail with Exception : [%d] %s", $e->getCode(), $e->getMessage()));
}
//impossible to change output class in CommandTester...
if (method_exists($output, "renderBlock")) {
$output->renderBlock(array(
'',
sprintf("Activation succeed for module %s", $moduleCode),
''
), "bg=green;fg=black");
}
}
}

View File

@@ -54,6 +54,13 @@ class ReloadDatabaseCommand extends BaseModuleGenerate
$connection = Propel::getConnection(\Thelia\Model\Map\ProductTableMap::DATABASE_NAME);
$connection = $connection->getWrappedConnection();
$tables = $connection->query("SHOW TABLES");
$connection->query("SET FOREIGN_KEY_CHECKS = 0");
foreach($tables as $table) {
$connection->query(sprintf("DROP TABLE `%s`", $table[0]));
}
$connection->query("SET FOREIGN_KEY_CHECKS = 1");
$database = new Database($connection);
$output->writeln(array(
'',

View File

@@ -36,6 +36,10 @@
<argument type="service" id="service_container"/>
<tag name="kernel.event_subscriber"/>
</service>
<service id="thelia.action.document" class="Thelia\Action\Document">
<argument type="service" id="service_container"/>
<tag name="kernel.event_subscriber"/>
</service>
<service id="thelia.action.category" class="Thelia\Action\Category">
<argument type="service" id="service_container"/>
@@ -97,6 +101,16 @@
<tag name="kernel.event_subscriber"/>
</service>
<service id="thelia.action.folder" class="Thelia\Action\Folder">
<argument type="service" id="service_container"/>
<tag name="kernel.event_subscriber"/>
</service>
<service id="thelia.action.content" class="Thelia\Action\Content">
<argument type="service" id="service_container"/>
<tag name="kernel.event_subscriber"/>
</service>
</services>
</config>

View File

@@ -18,25 +18,30 @@
<loop class="Thelia\Core\Template\Loop\Currency" name="currency"/>
<loop class="Thelia\Core\Template\Loop\Customer" name="customer"/>
<loop class="Thelia\Core\Template\Loop\Feature" name="feature"/>
<loop class="Thelia\Core\Template\Loop\FeatureAvailability" name="feature_availability"/>
<loop class="Thelia\Core\Template\Loop\FeatureAvailability" name="feature-availability"/>
<loop class="Thelia\Core\Template\Loop\FeatureValue" name="feature_value"/>
<loop class="Thelia\Core\Template\Loop\Folder" name="folder"/>
<loop class="Thelia\Core\Template\Loop\Module" name="module"/>
<loop class="Thelia\Core\Template\Loop\Order" name="order"/>
<loop class="Thelia\Core\Template\Loop\OrderStatus" name="order-status"/>
<loop class="Thelia\Core\Template\Loop\CategoryPath" name="category-path"/>
<loop class="Thelia\Core\Template\Loop\Payment" name="payment"/>
<loop class="Thelia\Core\Template\Loop\Product" name="product"/>
<loop class="Thelia\Core\Template\Loop\ProductSaleElements" name="product_sale_elements"/>
<loop class="Thelia\Core\Template\Loop\Feed" name="feed"/>
<loop class="Thelia\Core\Template\Loop\Title" name="title"/>
<loop class="Thelia\Core\Template\Loop\Lang" name="lang"/>
<loop class="Thelia\Core\Template\Loop\CategoryTree" name="category-tree"/>
<loop class="Thelia\Core\Template\Loop\FolderTree" name="folder-tree"/>
<loop class="Thelia\Core\Template\Loop\Cart" name="cart"/>
<loop class="Thelia\Core\Template\Loop\Image" name="image"/>
<loop class="Thelia\Core\Template\Loop\Document" name="document"/>
<loop class="Thelia\Core\Template\Loop\Config" name="config"/>
<loop class="Thelia\Core\Template\Loop\Coupon" name="coupon"/>
<loop class="Thelia\Core\Template\Loop\Message" name="message"/>
<loop class="Thelia\Core\Template\Loop\Delivery" name="delivery"/>
<loop class="Thelia\Core\Template\Loop\Template" name="template"/> <!-- This is product templates ;-) -->
<loop class="Thelia\Core\Template\Loop\TaxRule" name="tax-rule"/>
</loops>
<forms>
@@ -54,16 +59,31 @@
<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.image.modification" class="Thelia\Form\CategoryImageModification"/>
<form name="thelia.admin.category.document.modification" class="Thelia\Form\CategoryDocumentModification"/>
<form name="thelia.admin.product.creation" class="Thelia\Form\ProductCreationForm"/>
<form name="thelia.admin.product.modification" class="Thelia\Form\ProductModificationForm"/>
<form name="thelia.admin.product.details.modification" class="Thelia\Form\ProductDetailsModificationForm"/>
<form name="thelia.admin.product.image.modification" class="Thelia\Form\ProductImageModification"/>
<form name="thelia.admin.product.document.modification" class="Thelia\Form\ProductDocumentModification"/>
<form name="thelia.admin.product.creation" class="Thelia\Form\ProductCreationForm"/>
<form name="thelia.admin.product.deletion" class="Thelia\Form\ProductModificationForm"/>
<form name="thelia.admin.folder.creation" class="Thelia\Form\FolderCreationForm"/>
<form name="thelia.admin.folder.modification" class="Thelia\Form\FolderModificationForm"/>
<form name="thelia.admin.folder.image.modification" class="Thelia\Form\FolderImageModification"/>
<form name="thelia.admin.folder.document.modification" class="Thelia\Form\FolderDocumentModification"/>
<form name="thelia.admin.content.creation" class="Thelia\Form\ContentCreationForm"/>
<form name="thelia.admin.content.modification" class="Thelia\Form\ContentModificationForm"/>
<form name="thelia.admin.content.image.modification" class="Thelia\Form\ContentImageModification"/>
<form name="thelia.admin.content.document.modification" class="Thelia\Form\ContentDocumentModification"/>
<form name="thelia.cart.add" class="Thelia\Form\CartAdd"/>
<form name="thelia.order.delivery" class="Thelia\Form\OrderDelivery"/>
<form name="thelia.order.payment" class="Thelia\Form\OrderPayment"/>
<form name="thelia.admin.config.creation" class="Thelia\Form\ConfigCreationForm"/>
<form name="thelia.admin.config.modification" class="Thelia\Form\ConfigModificationForm"/>
@@ -92,6 +112,8 @@
<form name="thelia.admin.country.creation" class="Thelia\Form\CountryCreationForm"/>
<form name="thelia.admin.country.modification" class="Thelia\Form\CountryModificationForm"/>
<form name="thelia.admin.profile.modification" class="Thelia\Form\ProfileModificationForm"/>
</forms>
@@ -102,6 +124,7 @@
<command class="Thelia\Command\ModuleGenerateCommand"/>
<command class="Thelia\Command\ModuleGenerateModelCommand"/>
<command class="Thelia\Command\ModuleGenerateSqlCommand"/>
<command class="Thelia\Command\ModuleActivateCommand"/>
<command class="Thelia\Command\CreateAdminUser"/>
<command class="Thelia\Command\ReloadDatabaseCommand"/>
</commands>
@@ -217,6 +240,7 @@
<argument type="service" id="request" />
<argument type="service" id="thelia.securityContext" />
<argument type="service" id="thelia.parser.context"/>
<argument type="service" id="event_dispatcher"/>
</service>
<service id="smarty.plugin.adminUtilities" class="Thelia\Core\Template\Smarty\Plugins\AdminUtilities" scope="request">
@@ -224,6 +248,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

@@ -24,6 +24,12 @@
<default key="_controller">Thelia\Controller\Admin\SessionController::checkLoginAction</default>
</route>
<!-- Route to edit admin profile -->
<route id="admin.profile.update.view" path="/admin/profile/update" methods="get">
<default key="_controller">Thelia\Controller\Admin\AdminController::updateAction</default>
</route>
<!-- Route to the catalog controller -->
@@ -31,6 +37,70 @@
<default key="_controller">Thelia\Controller\Admin\CategoryController::defaultAction</default>
</route>
<!-- Route to the file controller -->
<route id="admin.image.save-ajax" path="/admin/image/type/{parentType}/{parentId}/save-ajax">
<default key="_controller">Thelia\Controller\Admin\FileController::saveImageAjaxAction</default>
<requirement key="parentType">.*</requirement>
<requirement key="parentId">\d+</requirement>
</route>
<route id="admin.image.form-ajax" path="/admin/image/type/{parentType}/{parentId}/form-ajax">
<default key="_controller">Thelia\Controller\Admin\FileController::getImageFormAjaxAction</default>
<requirement key="parentType">.*</requirement>
<requirement key="parentId">\d+</requirement>
</route>
<route id="admin.image.list-ajax" path="/admin/image/type/{parentType}/{parentId}/list-ajax">
<default key="_controller">Thelia\Controller\Admin\FileController::getImageListAjaxAction</default>
<requirement key="parentType">.*</requirement>
<requirement key="parentId">\d+</requirement>
</route>
<route id="admin.image.update.view" path="/admin/image/type/{parentType}/{imageId}/update" methods="get">
<default key="_controller">Thelia\Controller\Admin\FileController::viewImageAction</default>
<requirement key="parentType">.*</requirement>
<requirement key="imageId">\d+</requirement>
</route>
<route id="admin.image.update.process" path="/admin/image/type/{parentType}/{imageId}/update" methods="post">
<default key="_controller">Thelia\Controller\Admin\FileController::updateImageAction</default>
<requirement key="parentType">.*</requirement>
<requirement key="imageId">\d+</requirement>
</route>
<route id="admin.image.delete" path="/admin/image/type/{parentType}/delete/{imageId}">
<default key="_controller">Thelia\Controller\Admin\FileController::deleteImageAction</default>
<requirement key="parentType">.*</requirement>
<requirement key="imageId">\d+</requirement>
</route>
<route id="admin.document.save-ajax" path="/admin/document/type/{parentType}/{parentId}/save-ajax">
<default key="_controller">Thelia\Controller\Admin\FileController::saveDocumentAjaxAction</default>
<requirement key="parentType">.*</requirement>
<requirement key="parentId">\d+</requirement>
</route>
<route id="admin.document.form-ajax" path="/admin/document/type/{parentType}/{parentId}/form-ajax">
<default key="_controller">Thelia\Controller\Admin\FileController::getDocumentFormAjaxAction</default>
<requirement key="parentType">.*</requirement>
<requirement key="parentId">\d+</requirement>
</route>
<route id="admin.document.list-ajax" path="/admin/document/type/{parentType}/{parentId}/list-ajax">
<default key="_controller">Thelia\Controller\Admin\FileController::getDocumentListAjaxAction</default>
<requirement key="parentType">.*</requirement>
<requirement key="parentId">\d+</requirement>
</route>
<route id="admin.document.update.view" path="/admin/document/type/{parentType}/{documentId}/update" methods="get">
<default key="_controller">Thelia\Controller\Admin\FileController::viewDocumentAction</default>
<requirement key="parentType">.*</requirement>
<requirement key="documentId">\d+</requirement>
</route>
<route id="admin.document.update.process" path="/admin/document/type/{parentType}/{documentId}/update" methods="post">
<default key="_controller">Thelia\Controller\Admin\FileController::updateDocumentAction</default>
<requirement key="parentType">.*</requirement>
<requirement key="documentId">\d+</requirement>
</route>
<route id="admin.document.delete" path="/admin/document/type/{parentType}/delete/{documentId}">
<default key="_controller">Thelia\Controller\Admin\FileController::deleteDocumentAction</default>
<requirement key="parentType">.*</requirement>
<requirement key="documentId">\d+</requirement>
</route>
<!-- Customer rule management -->
<route id="admin.customers" path="/admin/customers">
@@ -100,6 +170,10 @@
<default key="_controller">Thelia\Controller\Admin\CategoryController::addRelatedContentAction</default>
</route>
<route id="admin.categories.related-content.add" path="/admin/categories/related-picture/add">
<default key="_controller">Thelia\Controller\Admin\CategoryController::addRelatedPictureAction</default>
</route>
<route id="admin.categories.related-content.delete" path="/admin/categories/related-content/delete">
<default key="_controller">Thelia\Controller\Admin\CategoryController::deleteRelatedContentAction</default>
</route>
@@ -144,19 +218,167 @@
<default key="_controller">Thelia\Controller\Admin\ProductController::updatePositionAction</default>
</route>
<route id="admin.products.related-content.add" path="/admin/products/related-content/add">
<route id="admin.products.general.tab" path="/admin/products/general/tab">
<default key="_controller">Thelia\Controller\Admin\ProductController::loadGeneralAjaxTabAction</default>
</route>
<!-- Product categories, content and accessories -->
<route id="admin.products.related.tab" path="/admin/products/related/tab">
<default key="_controller">Thelia\Controller\Admin\ProductController::loadRelatedAjaxTabAction</default>
</route>
<!-- categories -->
<route id="admin.products.additional-category.add" path="/admin/products/category/add">
<default key="_controller">Thelia\Controller\Admin\ProductController::addAdditionalCategoryAction</default>
</route>
<route id="admin.products.additional-category.delete" path="/admin/products/category/delete">
<default key="_controller">Thelia\Controller\Admin\ProductController::deleteAdditionalCategoryAction</default>
</route>
<!-- content -->
<route id="admin.products.related-content.add" path="/admin/products/content/add">
<default key="_controller">Thelia\Controller\Admin\ProductController::addRelatedContentAction</default>
</route>
<route id="admin.products.related-content.delete" path="/admin/products/related-content/delete">
<route id="admin.products.related-content.delete" path="/admin/products/content/delete">
<default key="_controller">Thelia\Controller\Admin\ProductController::deleteRelatedContentAction</default>
</route>
<route id="admin.product.available-related-content" path="/admin/product/{productId}/available-related-content/{folderId}.{_format}" methods="GET">
<route id="admin.product.available-related-content" path="/admin/product/{productId}/available-content/{folderId}.{_format}" methods="GET">
<default key="_controller">Thelia\Controller\Admin\ProductController::getAvailableRelatedContentAction</default>
<requirement key="_format">xml|json</requirement>
</route>
<route id="admin.product.update-content-position" path="/admin/product/update-content-position">
<default key="_controller">Thelia\Controller\Admin\ProductController::updateContentPositionAction</default>
</route>
<!-- accessories -->
<route id="admin.products.accessories.add" path="/admin/products/accessory/add">
<default key="_controller">Thelia\Controller\Admin\ProductController::addAccessoryAction</default>
</route>
<route id="admin.products.accessories.delete" path="/admin/products/accessory/delete">
<default key="_controller">Thelia\Controller\Admin\ProductController::deleteAccessoryAction</default>
</route>
<route id="admin.product.accessories-content" path="/admin/product/{productId}/available-accessories/{categoryId}.{_format}" methods="GET">
<default key="_controller">Thelia\Controller\Admin\ProductController::getAvailableAccessoriesAction</default>
<requirement key="_format">xml|json</requirement>
</route>
<route id="admin.product.update-accessory-position" path="/admin/product/update-accessory-position">
<default key="_controller">Thelia\Controller\Admin\ProductController::updateAccessoryPositionAction</default>
</route>
<!--Product Features and attributes -->
<route id="admin.products.attributes.tab" path="/admin/products/attributes/tab">
<default key="_controller">Thelia\Controller\Admin\ProductController::loadAttributesAjaxTabAction</default>
</route>
<route id="admin.products.set-product-template" path="/admin/product/{productId}/set-product-template">
<default key="_controller">Thelia\Controller\Admin\ProductController::setProductTemplateAction</default>
</route>
<route id="admin.products.update-attributes-and-features" path="/admin/product/{productId}/update-attributes-and-features">
<default key="_controller">Thelia\Controller\Admin\ProductController::updateAttributesAndFeaturesAction</default>
</route>
<!-- Combinations -->
<route id="admin.product.attribute-values" path="/admin/product/{productId}/attribute-values/{attributeId}.{_format}" methods="GET">
<default key="_controller">Thelia\Controller\Admin\ProductController::getAttributeValuesAction</default>
<requirement key="_format">xml|json</requirement>
</route>
<route id="admin.product.add-attribute-value-to-combination" path="/admin/product/{productId}/add-attribute-value-to-combination/{attributeAvId}/{combination}.{_format}" methods="GET">
<default key="_controller">Thelia\Controller\Admin\ProductController::addAttributeValueToCombinationAction</default>
<requirement key="_format">xml|json</requirement>
</route>
<route id="admin.product.combination.add" path="/admin/product/combination/add">
<default key="_controller">Thelia\Controller\Admin\ProductController::addCombinationAction</default>
</route>
<route id="admin.product.combination.delete" path="/admin/product/combination/delete">
<default key="_controller">Thelia\Controller\Admin\ProductController::deleteCombinationAction</default>
</route>
<route id="admin.product.combination.update" path="/admin/product/combination/update">
<default key="_controller">Thelia\Controller\Admin\ProductController::updateCombinationAction</default>
</route>
<route id="admin.product.combination.defaut-price.update" path="/admin/product/default-price/update">
<default key="_controller">Thelia\Controller\Admin\ProductController::updateDefaultPriceAction</default>
</route>
<!-- Folder routes management -->
<route id="admin.folders.default" path="/admin/folders">
<default key="_controller">Thelia\Controller\Admin\FolderController::defaultAction</default>
</route>
<route id="admin.folders.create" path="/admin/folders/create">
<default key="_controller">Thelia\Controller\Admin\FolderController::createAction</default>
</route>
<route id="admin.folders.update" path="/admin/folders/update/{folder_id}">
<default key="_controller">Thelia\Controller\Admin\FolderController::updateAction</default>
<requirement key="folder_id">\d+</requirement>
</route>
<route id="admin.folders.toggle-online" path="/admin/folders/toggle-online">
<default key="_controller">Thelia\Controller\Admin\FolderController::setToggleVisibilityAction</default>
</route>
<route id="admin.folders.save" path="/admin/folders/save">
<default key="_controller">Thelia\Controller\Admin\FolderController::processUpdateAction</default>
</route>
<route id="admin.folders.delete" path="/admin/folders/delete">
<default key="_controller">Thelia\Controller\Admin\FolderController::deleteAction</default>
</route>
<route id="admin.folders.update-position" path="/admin/folders/update-position">
<default key="_controller">Thelia\Controller\Admin\FolderController::updatePositionAction</default>
</route>
<!-- content routes management -->
<route id="admin.folders.create" path="/admin/content/create">
<default key="_controller">Thelia\Controller\Admin\ContentController::createAction</default>
</route>
<route id="admin.content.update" path="admin/content/update/{content_id}">
<default key="_controller">Thelia\Controller\Admin\ContentController::updateAction</default>
<requirement key="content_id">\d+</requirement>
</route>
<route id="admin.content.save" path="/admin/content/save">
<default key="_controller">Thelia\Controller\Admin\ContentController::processUpdateAction</default>
</route>
<route id="admin.content.update-position" path="/admin/content/update-position">
<default key="_controller">Thelia\Controller\Admin\ContentController::updatePositionAction</default>
</route>
<route id="admin.content.toggle-online" path="/admin/content/toggle-online">
<default key="_controller">Thelia\Controller\Admin\ContentController::setToggleVisibilityAction</default>
</route>
<route id="admin.content.delete" path="/admin/content/delete">
<default key="_controller">Thelia\Controller\Admin\ContentController::deleteAction</default>
</route>
<!-- Route to the Coupon controller (process Coupon browsing) -->
@@ -303,6 +525,10 @@
<default key="_controller">Thelia\Controller\Admin\TemplateController::deleteFeatureAction</default>
</route>
<route id="admin.configuration.templates.attributes.update-feature-position" path="/admin/template/update-feature-position">
<default key="_controller">Thelia\Controller\Admin\TemplateController::updateFeaturePositionAction</default>
</route>
<route id="admin.configuration.templates.attributes.list" path="/admin/configuration/templates/attributes/list">
<default key="_controller">Thelia\Controller\Admin\TemplateController::getAjaxAttributesAction</default>
</route>
@@ -315,6 +541,10 @@
<default key="_controller">Thelia\Controller\Admin\TemplateController::deleteAttributeAction</default>
</route>
<route id="admin.configuration.templates.attributes.update-attribute-position" path="/admin/template/update-attribute-position">
<default key="_controller">Thelia\Controller\Admin\TemplateController::updateAttributePositionAction</default>
</route>
<!-- attribute and attributes value management -->
@@ -388,7 +618,34 @@
<requirement key="country_id">\d+</requirement>
</route>
<!-- end countries routes management -->
<!-- end countries routes management -->
<!-- Shipping zones routes management -->
<route id="admin.configuration.shipping-zones.default" path="/admin/configuration/shipping_zones">
<default key="_controller">Thelia\Controller\Admin\ShippingZoneController::indexAction</default>
</route>
<route id="admin.configuration.shipping-zones.update.view" path="/admin/configuration/shipping_zones/update/{shipping_zones_id}" methods="get">
<default key="_controller">Thelia\Controller\Admin\ShippingZoneController::updateAction</default>
<requirement key="shipping_zones_id">\d+</requirement>
</route>
<!-- end shipping routes management -->
<!-- Shipping zones routes management -->
<route id="admin.configuration.shipping-configuration.default" path="/admin/configuration/shipping_configuration">
<default key="_controller">Thelia\Controller\Admin\ShippingConfigurationController::indexAction</default>
</route>
<route id="admin.configuration.shipping-configuration.update.view" path="/admin/configuration/shipping_configuration/update/{shipping_configuration_id}" methods="get">
<default key="_controller">Thelia\Controller\Admin\ShippingConfigurationController::updateAction</default>
<requirement key="shipping_configuration_id">\d+</requirement>
</route>
<!-- end shipping routes management -->
<!-- feature and features value management -->
@@ -447,6 +704,15 @@
<!-- end feature and feature routes management -->
<!-- Modules rule management -->
<route id="admin.module" path="/admin/modules">
<default key="_controller">Thelia\Controller\Admin\ModuleController::indexAction</default>
</route>
<!-- end Modules rule management -->
<!-- The default route, to display a template -->
<route id="admin.processTemplate" path="/admin/{template}">

View File

@@ -112,27 +112,36 @@
<default key="_view">cart</default>
</route>
<route id="order.delivery" path="/order/delivery" methods="post">
<!-- end cart routes -->
<!-- order management process -->
<route id="order.delivery.process" path="/order/delivery" methods="post">
<default key="_controller">Thelia\Controller\Front\OrderController::deliver</default>
<default key="_view">order_delivery</default>
</route>
<route id="order.delivery.process" path="/order/delivery">
<route id="order.delivery" path="/order/delivery">
<default key="_controller">Thelia\Controller\Front\DefaultController::noAction</default>
<default key="_view">order_delivery</default>
</route>
<route id="order.invoice.process" path="/order/invoice" methods="post">
<default key="_controller">Thelia\Controller\Front\OrderController::invoice</default>
<default key="_view">order_invoice</default>
</route>
<route id="order.invoice" path="/order/invoice">
<default key="_controller">Thelia\Controller\Front\DefaultController::noAction</default>
<default key="_view">order_invoice</default>
</route>
<!-- end cart routes -->
<route id="order.payment.process" path="/order/pay">
<default key="_controller">Thelia\Controller\Front\OrderController::pay</default>
</route>
<!-- order management process -->
<route id="order.delivery.add" path="/delivery/choose/{delivery_id}">
<default key="_controller">Thelia\Controller\Front\DeliveryController::select</default>
<requirement key="delivery_id">\d+</requirement>
<route id="order.placed" path="/order/placed/{order_id}">
<default key="_controller">Thelia\Controller\Front\OrderController::orderPlaced</default>
<default key="_view">order_placed</default>
</route>
<!-- end order management process -->

View File

@@ -58,6 +58,7 @@ abstract class AbstractCrudController extends BaseAdminController
* @param string $objectName the lower case object name. Example. "message"
*
* @param string $defaultListOrder the default object list order, or null if list is not sortable. Example: manual
* @param string $orderRequestParameterName Name of the request parameter that set the list order (null if list is not sortable)
*
* @param string $viewPermissionIdentifier the 'view' permission identifier. Example: "admin.configuration.message.view"
* @param string $createPermissionIdentifier the 'create' permission identifier. Example: "admin.configuration.message.create"
@@ -445,6 +446,8 @@ abstract class AbstractCrudController extends BaseAdminController
/**
* Update object position (only for objects whichsupport that)
*
* FIXME: integrate with genericUpdatePositionAction
*/
public function updatePositionAction()
{
@@ -482,6 +485,38 @@ abstract class AbstractCrudController extends BaseAdminController
}
}
protected function genericUpdatePositionAction($object, $eventName, $doFinalRedirect = true) {
// Check current user authorization
if (null !== $response = $this->checkAuth($this->updatePermissionIdentifier)) return $response;
if ($object != null) {
try {
$mode = $this->getRequest()->get('mode', null);
if ($mode == 'up')
$mode = UpdatePositionEvent::POSITION_UP;
else if ($mode == 'down')
$mode = UpdatePositionEvent::POSITION_DOWN;
else
$mode = UpdatePositionEvent::POSITION_ABSOLUTE;
$position = $this->getRequest()->get('position', null);
$event = new UpdatePositionEvent($object->getId(), $mode, $position);
$this->dispatch($eventName, $event);
}
catch (\Exception $ex) {
// Any error
return $this->errorPage($ex);
}
}
if ($doFinalRedirect) $this->redirectToEditionTemplate();
}
/**
* Online status toggle (only for object which support it)
*/
@@ -492,9 +527,6 @@ abstract class AbstractCrudController extends BaseAdminController
$changeEvent = $this->createToggleVisibilityEvent($this->getRequest());
// Create and dispatch the change event
$changeEvent->setIsDefault(true);
try {
$this->dispatch($this->visibilityToggleEventIdentifier, $changeEvent);
} catch (\Exception $ex) {
@@ -502,7 +534,7 @@ abstract class AbstractCrudController extends BaseAdminController
return $this->errorPage($ex);
}
$this->redirectToListTemplate();
return $this->nullResponse();
}
/**

View File

@@ -33,4 +33,9 @@ class AdminController extends BaseAdminController
{
return $this->render("home");
}
public function updateAction()
{
return $this->render("profile-edit");
}
}

View File

@@ -42,6 +42,7 @@ use Thelia\Log\Tlog;
use Symfony\Component\Routing\Router;
use Thelia\Model\Admin;
use Thelia\Core\Security\Token\CookieTokenProvider;
use Thelia\Model\CurrencyQuery;
class BaseAdminController extends BaseController
{
@@ -250,6 +251,23 @@ class BaseAdminController extends BaseController
$this->redirect(URL::getInstance()->absoluteUrl($this->getRoute($routeId), $urlParameters));
}
/**
* Get the current edition currency ID, checking if a change was requested in the current request.
*/
protected function getCurrentEditionCurrency()
{
// Return the new language if a change is required.
if (null !== $edit_currency_id = $this->getRequest()->get('edit_currency_id', null)) {
if (null !== $edit_currency = CurrencyQuery::create()->findOneById($edit_currency_id)) {
return $edit_currency;
}
}
// Otherwise return the lang stored in session.
return $this->getSession()->getAdminEditionCurrency();
}
/**
* Get the current edition lang ID, checking if a change was requested in the current request.
*/
@@ -376,6 +394,9 @@ class BaseAdminController extends BaseController
// Find the current edit language ID
$edition_language = $this->getCurrentEditionLang();
// Find the current edit currency ID
$edition_currency = $this->getCurrentEditionCurrency();
// Prepare common template variables
$args = array_merge($args, array(
'locale' => $session->getLang()->getLocale(),
@@ -385,11 +406,16 @@ class BaseAdminController extends BaseController
'edit_language_id' => $edition_language->getId(),
'edit_language_locale' => $edition_language->getLocale(),
'edit_currency_id' => $edition_currency->getId(),
'current_url' => $this->getRequest()->getUri()
));
// Update the current edition language in session
$this->getSession()->setAdminEditionLang($edition_language);
// Update the current edition language & currency in session
$this->getSession()
->setAdminEditionLang($edition_language)
->setAdminEditionCurrency($edition_currency)
;
// Render the template.
try {

View File

@@ -23,10 +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\Log\Tlog;
use Thelia\Model\CategoryQuery;
use Thelia\Form\CategoryModificationForm;
use Thelia\Form\CategoryCreationForm;
@@ -34,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;
@@ -133,7 +135,7 @@ class CategoryController extends AbstractCrudController
'description' => $object->getDescription(),
'postscriptum' => $object->getPostscriptum(),
'visible' => $object->getVisible(),
'url' => $object->getRewritenUrl($this->getCurrentEditionLocale()),
'url' => $object->getRewrittenUrl($this->getCurrentEditionLocale()),
'parent' => $object->getParent()
);
@@ -306,6 +308,39 @@ class CategoryController extends AbstractCrudController
$this->redirectToEditionTemplate();
}
/**
* Add category pictures
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function addRelatedPictureAction()
{
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.categories.update")) {
return $response;
}
// $content_id = intval($this->getRequest()->get('content_id'));
//
// if ($content_id > 0) {
//
// $event = new CategoryAddContentEvent(
// $this->getExistingObject(),
// $content_id
// );
//
// try {
// $this->dispatch(TheliaEvents::CATEGORY_ADD_CONTENT, $event);
// }
// catch (\Exception $ex) {
// // Any error
// return $this->errorPage($ex);
// }
// }
$this->redirectToEditionTemplate();
}
public function deleteRelatedContentAction() {
// Check current user authorization
@@ -331,4 +366,5 @@ class CategoryController extends AbstractCrudController
$this->redirectToEditionTemplate();
}
}

View File

@@ -0,0 +1,347 @@
<?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 Thelia\Core\Event\Content\ContentCreateEvent;
use Thelia\Core\Event\Content\ContentDeleteEvent;
use Thelia\Core\Event\Content\ContentToggleVisibilityEvent;
use Thelia\Core\Event\Content\ContentUpdateEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\Event\UpdatePositionEvent;
use Thelia\Form\ContentCreationForm;
use Thelia\Form\ContentModificationForm;
use Thelia\Model\ContentQuery;
/**
* Class ContentController
* @package Thelia\Controller\Admin
* @author manuel raynaud <mraynaud@openstudio.fr>
*/
class ContentController extends AbstractCrudController
{
public function __construct()
{
parent::__construct(
'content',
'manual',
'content_order',
'admin.content.default',
'admin.content.create',
'admin.content.update',
'admin.content.delete',
TheliaEvents::CONTENT_CREATE,
TheliaEvents::CONTENT_UPDATE,
TheliaEvents::CONTENT_DELETE,
TheliaEvents::CONTENT_TOGGLE_VISIBILITY,
TheliaEvents::CONTENT_UPDATE_POSITION
);
}
/**
* Return the creation form for this object
*/
protected function getCreationForm()
{
return new ContentCreationForm($this->getRequest());
}
/**
* Return the update form for this object
*/
protected function getUpdateForm()
{
return new ContentModificationForm($this->getRequest());
}
/**
* Hydrate the update form for this object, before passing it to the update template
*
* @param \Thelia\Form\ContentModificationForm $object
*/
protected function hydrateObjectForm($object)
{
// Prepare the data that will hydrate the form
$data = array(
'id' => $object->getId(),
'locale' => $object->getLocale(),
'title' => $object->getTitle(),
'chapo' => $object->getChapo(),
'description' => $object->getDescription(),
'postscriptum' => $object->getPostscriptum(),
'visible' => $object->getVisible(),
'url' => $object->getRewrittenUrl($this->getCurrentEditionLocale()),
);
// Setup the object form
return new ContentModificationForm($this->getRequest(), "form", $data);
}
/**
* Creates the creation event with the provided form data
*
* @param unknown $formData
*/
protected function getCreationEvent($formData)
{
$contentCreateEvent = new ContentCreateEvent();
$contentCreateEvent
->setLocale($formData['locale'])
->setDefaultFolder($formData['default_folder'])
->setTitle($formData['title'])
->setVisible($formData['visible'])
;
return $contentCreateEvent;
}
/**
* Creates the update event with the provided form data
*
* @param unknown $formData
*/
protected function getUpdateEvent($formData)
{
$contentUpdateEvent = new ContentUpdateEvent($formData['id']);
$contentUpdateEvent
->setLocale($formData['locale'])
->setTitle($formData['title'])
->setChapo($formData['chapo'])
->setDescription($formData['description'])
->setPostscriptum($formData['postscriptum'])
->setVisible($formData['visible'])
->setUrl($formData['url'])
->setDefaultFolder($formData['default_folder']);
return $contentUpdateEvent;
}
/**
* Creates the delete event with the provided form data
*/
protected function getDeleteEvent()
{
return new ContentDeleteEvent($this->getRequest()->get('content_id'));
}
/**
* Return true if the event contains the object, e.g. the action has updated the object in the event.
*
* @param \Thelia\Core\Event\Content\ContentEvent $event
*/
protected function eventContainsObject($event)
{
return $event->hasContent();
}
/**
* Get the created object from an event.
*
* @param $event \Thelia\Core\Event\Content\ContentEvent
*
* @return null|\Thelia\Model\Content
*/
protected function getObjectFromEvent($event)
{
return $event->getContent();
}
/**
* Load an existing object from the database
*
* @return \Thelia\Model\Content
*/
protected function getExistingObject()
{
return ContentQuery::create()
->joinWithI18n($this->getCurrentEditionLocale())
->findOneById($this->getRequest()->get('content_id', 0));
}
/**
* Returns the object label form the object event (name, title, etc.)
*
* @param $object \Thelia\Model\Content
*
* @return string content title
*
*/
protected function getObjectLabel($object)
{
return $object->getTitle();
}
/**
* Returns the object ID from the object
*
* @param $object \Thelia\Model\Content
*
* @return int content id
*/
protected function getObjectId($object)
{
return $object->getId();
}
protected function getFolderId()
{
$folderId = $this->getRequest()->get('folder_id', null);
if(null === $folderId) {
$content = $this->getExistingObject();
if($content) {
$folderId = $content->getDefaultFolderId();
}
}
return $folderId ?: 0;
}
/**
* Render the main list template
*
* @param unknown $currentOrder, if any, null otherwise.
*/
protected function renderListTemplate($currentOrder)
{
$this->getListOrderFromSession('content', 'content_order', 'manual');
return $this->render('folders',
array(
'content_order' => $currentOrder,
'parent' => $this->getFolderId()
));
}
protected function getEditionArguments()
{
return array(
'content_id' => $this->getRequest()->get('content_id', 0),
'current_tab' => $this->getRequest()->get('current_tab', 'general')
);
}
/**
* Render the edition template
*/
protected function renderEditionTemplate()
{
return $this->render('content-edit', $this->getEditionArguments());
}
/**
* Redirect to the edition template
*/
protected function redirectToEditionTemplate()
{
$this->redirect($this->getRoute('admin.content.update', $this->getEditionArguments()));
}
/**
* Redirect to the list template
*/
protected function redirectToListTemplate()
{
$this->redirectToRoute(
'admin.content.default',
array('parent' => $this->getFolderId())
);
}
/**
* @param \Thelia\Core\Event\Content\ContentUpdateEvent $updateEvent
* @return Response|void
*/
protected function performAdditionalUpdateAction($updateEvent)
{
if ($this->getRequest()->get('save_mode') != 'stay') {
// Redirect to parent category list
$this->redirectToRoute(
'admin.folders.default',
array('parent' => $this->getFolderId())
);
}
}
/**
* Put in this method post object delete processing if required.
*
* @param \Thelia\Core\Event\Content\ContentDeleteEvent $deleteEvent the delete event
* @return Response a response, or null to continue normal processing
*/
protected function performAdditionalDeleteAction($deleteEvent)
{
// Redirect to parent category list
$this->redirectToRoute(
'admin.folders.default',
array('parent' => $deleteEvent->getDefaultFolderId())
);
}
/**
* @param $event \Thelia\Core\Event\UpdatePositionEvent
* @return null|Response
*/
protected function performAdditionalUpdatePositionAction($event)
{
if (null !== $content = ContentQuery::create()->findPk($event->getObjectId())) {
// Redirect to parent category list
$this->redirectToRoute(
'admin.folders.default',
array('parent' => $content->getDefaultFolderId())
);
}
return null;
}
/**
* @param $positionChangeMode
* @param $positionValue
* @return UpdatePositionEvent|void
*/
protected function createUpdatePositionEvent($positionChangeMode, $positionValue)
{
return new UpdatePositionEvent(
$this->getRequest()->get('content_id', null),
$positionChangeMode,
$positionValue
);
}
/**
* @return ContentToggleVisibilityEvent|void
*/
protected function createToggleVisibilityEvent()
{
return new ContentToggleVisibilityEvent($this->getExistingObject());
}
}

View File

@@ -0,0 +1,680 @@
<?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 Propel\Runtime\Exception\PropelException;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Router;
use Thelia\Core\Event\DocumentCreateOrUpdateEvent;
use Thelia\Core\Event\DocumentDeleteEvent;
use Thelia\Core\Event\ImageCreateOrUpdateEvent;
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;
/**
* 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 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 saveImageAjaxAction($parentId, $parentType)
{
$this->checkAuth('ADMIN', 'admin.image.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')),
'image'
);
return new ResponseRest($message, 'text', 403);
}
// Validate if it is a image or file
if (!$fileManager->isImage($fileBeingUploaded->getMimeType())) {
$message = $this->getTranslator()
->trans(
'You can only upload images (.png, .jpg, .jpeg, .gif)',
array(),
'image'
);
return new ResponseRest($message, 'text', 415);
}
$parentModel = $fileManager->getParentFileModel($parentType, $parentId);
$imageModel = $fileManager->getImageModel($parentType);
if ($parentModel === null || $imageModel === null || $fileBeingUploaded === null) {
return new Response('', 404);
}
$defaultTitle = $parentModel->getTitle();
$imageModel->setParentId($parentId);
$imageModel->setTitle($defaultTitle);
$imageCreateOrUpdateEvent = new ImageCreateOrUpdateEvent(
$parentType,
$parentId
);
$imageCreateOrUpdateEvent->setModelImage($imageModel);
$imageCreateOrUpdateEvent->setUploadedFile($fileBeingUploaded);
$imageCreateOrUpdateEvent->setParentName($parentModel->getTitle());
// Dispatch Event to the Action
$this->dispatch(
TheliaEvents::IMAGE_SAVE,
$imageCreateOrUpdateEvent
);
return new ResponseRest(array('status' => true, 'message' => ''));
}
}
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);
}
$documentModel->setParentId($parentId);
$documentModel->setTitle($fileBeingUploaded->getClientOriginalName());
$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
*
* @param int $parentId Parent id owning images being saved
* @param string $parentType Parent Type owning images being saved
*
* @return Response
*/
public function getImageListAjaxAction($parentId, $parentType)
{
$this->checkAuth('ADMIN', 'admin.image.save');
$this->checkXmlHttpRequest();
$args = array('imageType' => $parentType, 'parentId' => $parentId);
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
*
* @param int $parentId Parent id owning images being saved
* @param string $parentType Parent Type owning images being saved
*
* @return Response
*/
public function getImageFormAjaxAction($parentId, $parentType)
{
$this->checkAuth('ADMIN', 'admin.image.save');
$this->checkXmlHttpRequest();
$args = array('imageType' => $parentType, 'parentId' => $parentId);
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
*
* @param int $imageId Parent id owning images being saved
* @param string $parentType Parent Type owning images being saved
*
* @return Response
*/
public function viewImageAction($imageId, $parentType)
{
if (null !== $response = $this->checkAuth('admin.image.view')) {
return $response;
}
try {
$fileManager = new FileManager($this->container);
$image = $fileManager->getImageModelQuery($parentType)->findPk($imageId);
$redirectUrl = $fileManager->getRedirectionUrl($parentType, $image->getParentId(), FileManager::FILE_TYPE_IMAGES);
return $this->render('image-edit', array(
'imageId' => $imageId,
'imageType' => $parentType,
'redirectUrl' => $redirectUrl,
'formId' => $fileManager->getFormId($parentType, FileManager::FILE_TYPE_IMAGES)
));
} 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(), FileManager::FILE_TYPE_DOCUMENTS);
return $this->render('document-edit', array(
'documentId' => $documentId,
'documentType' => $parentType,
'redirectUrl' => $redirectUrl,
'formId' => $fileManager->getFormId($parentType, FileManager::FILE_TYPE_DOCUMENTS)
));
} catch (\Exception $e) {
$this->pageNotFound();
}
}
/**
* Manage how an image is updated
*
* @param int $imageId Parent id owning images being saved
* @param string $parentType Parent Type owning images being saved
*
* @return Response
*/
public function updateImageAction($imageId, $parentType)
{
if (null !== $response = $this->checkAuth('admin.image.update')) {
return $response;
}
$message = false;
$fileManager = new FileManager($this->container);
$imageModification = $fileManager->getImageForm($parentType, $this->getRequest());
try {
$image = $fileManager->getImageModelQuery($parentType)->findPk($imageId);
$oldImage = clone $image;
if (null === $image) {
throw new \InvalidArgumentException(sprintf('%d image id does not exist', $imageId));
}
$form = $this->validateForm($imageModification);
$event = $this->createImageEventInstance($parentType, $image, $form->getData());
$event->setOldModelImage($oldImage);
$files = $this->getRequest()->files;
$fileForm = $files->get($imageModification->getName());
if (isset($fileForm['file'])) {
$event->setUploadedFile($fileForm['file']);
}
$this->dispatch(TheliaEvents::IMAGE_UPDATE, $event);
$imageUpdated = $event->getModelImage();
$this->adminLogAppend(sprintf('Image with Ref %s (ID %d) modified', $imageUpdated->getTitle(), $imageUpdated->getId()));
if ($this->getRequest()->get('save_mode') == 'close') {
$this->redirectToRoute('admin.images');
} else {
$this->redirectSuccess($imageModification);
}
} 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 image editing : %s.', $message));
$imageModification->setErrorMessage($message);
$this->getParserContext()
->addForm($imageModification)
->setGeneralError($message);
}
$redirectUrl = $fileManager->getRedirectionUrl($parentType, $image->getParentId(), FileManager::FILE_TYPE_IMAGES);
return $this->render('image-edit', array(
'imageId' => $imageId,
'imageType' => $parentType,
'redirectUrl' => $redirectUrl,
'formId' => $fileManager->getFormId($parentType, FileManager::FILE_TYPE_IMAGES)
));
}
/**
* Manage how an document is updated
*
* @param int $documentId Parent id owning documents being saved
* @param string $parentType Parent Type owning documents being saved
*
* @return Response
*/
public function updateDocumentAction($documentId, $parentType)
{
if (null !== $response = $this->checkAuth('admin.document.update')) {
return $response;
}
$message = false;
$fileManager = new FileManager($this->container);
$documentModification = $fileManager->getDocumentForm($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->createDocumentEventInstance($parentType, $document, $form->getData());
$event->setOldModelDocument($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->getModelDocument();
$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);
}
$redirectUrl = $fileManager->getRedirectionUrl($parentType, $document->getParentId(), FileManager::FILE_TYPE_DOCUMENTS);
return $this->render('document-edit', array(
'documentId' => $documentId,
'documentType' => $parentType,
'redirectUrl' => $redirectUrl,
'formId' => $fileManager->getFormId($parentType, FileManager::FILE_TYPE_DOCUMENTS)
));
}
/**
* 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();
$fileManager = new FileManager($this->container);
$imageModelQuery = $fileManager->getImageModelQuery($parentType);
$model = $imageModelQuery->findPk($imageId);
if ($model == null) {
return $this->pageNotFound();
}
// Feed event
$imageDeleteEvent = new ImageDeleteEvent(
$model,
$parentType
);
// Dispatch Event to the Action
$this->dispatch(
TheliaEvents::IMAGE_DELETE,
$imageDeleteEvent
);
$message = $this->getTranslator()
->trans(
'Images deleted successfully',
array(),
'image'
);
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
*
* @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, FileManager::getAvailableTypes()));
}
/**
* Create Image Event instance
*
* @param string $parentType Parent Type owning images being saved
* @param CategoryImage|ProductImage|ContentImage|FolderImage $model Image model
* @param array $data Post data
*
* @return ImageCreateOrUpdateEvent
*/
protected function createImageEventInstance($parentType, $model, $data)
{
$imageCreateEvent = new ImageCreateOrUpdateEvent($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']);
}
$imageCreateEvent->setModelImage($model);
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 DocumentCreateOrUpdateEvent
*/
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;
}
}

View File

@@ -0,0 +1,328 @@
<?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 Thelia\Core\Event\FolderCreateEvent;
use Thelia\Core\Event\FolderDeleteEvent;
use Thelia\Core\Event\FolderToggleVisibilityEvent;
use Thelia\Core\Event\FolderUpdateEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\Event\UpdatePositionEvent;
use Thelia\Form\FolderCreationForm;
use Thelia\Form\FolderModificationForm;
use Thelia\Model\FolderQuery;
/**
* Class FolderController
* @package Thelia\Controller\Admin
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class FolderController extends AbstractCrudController
{
public function __construct()
{
parent::__construct(
'folder',
'manual',
'folder_order',
'admin.folder.default',
'admin.folder.create',
'admin.folder.update',
'admin.folder.delete',
TheliaEvents::FOLDER_CREATE,
TheliaEvents::FOLDER_UPDATE,
TheliaEvents::FOLDER_DELETE,
TheliaEvents::FOLDER_TOGGLE_VISIBILITY,
TheliaEvents::FOLDER_UPDATE_POSITION
);
}
/**
* Return the creation form for this object
*/
protected function getCreationForm()
{
return new FolderCreationForm($this->getRequest());
}
/**
* Return the update form for this object
*/
protected function getUpdateForm()
{
return new FolderModificationForm($this->getRequest());
}
/**
* Hydrate the update form for this object, before passing it to the update template
*
* @param \Thelia\Model\Folder $object
*/
protected function hydrateObjectForm($object) {
// Prepare the data that will hydrate the form
$data = array(
'id' => $object->getId(),
'locale' => $object->getLocale(),
'title' => $object->getTitle(),
'chapo' => $object->getChapo(),
'description' => $object->getDescription(),
'postscriptum' => $object->getPostscriptum(),
'visible' => $object->getVisible(),
'url' => $object->getRewrittenUrl($this->getCurrentEditionLocale()),
'parent' => $object->getParent()
);
// Setup the object form
return new FolderModificationForm($this->getRequest(), "form", $data);
}
/**
* Creates the creation event with the provided form data
*
* @param unknown $formData
*/
protected function getCreationEvent($formData)
{
$creationEvent = new FolderCreateEvent();
$creationEvent
->setLocale($formData['locale'])
->setTitle($formData['title'])
->setVisible($formData['visible'])
->setParent($formData['parent']);
return $creationEvent;
}
/**
* Creates the update event with the provided form data
*
* @param unknown $formData
*/
protected function getUpdateEvent($formData)
{
$updateEvent = new FolderUpdateEvent($formData['id']);
$updateEvent
->setLocale($formData['locale'])
->setTitle($formData['title'])
->setChapo($formData['chapo'])
->setDescription($formData['description'])
->setPostscriptum($formData['postscriptum'])
->setVisible($formData['visible'])
->setUrl($formData['url'])
->setParent($formData['parent'])
;
return $updateEvent;
}
/**
* Creates the delete event with the provided form data
*/
protected function getDeleteEvent()
{
return new FolderDeleteEvent($this->getRequest()->get('folder_id'), 0);
}
/**
* @return FolderToggleVisibilityEvent|void
*/
protected function createToggleVisibilityEvent()
{
return new FolderToggleVisibilityEvent($this->getExistingObject());
}
/**
* @param $positionChangeMode
* @param $positionValue
* @return UpdatePositionEvent|void
*/
protected function createUpdatePositionEvent($positionChangeMode, $positionValue) {
return new UpdatePositionEvent(
$this->getRequest()->get('folder_id', null),
$positionChangeMode,
$positionValue
);
}
/**
* Return true if the event contains the object, e.g. the action has updated the object in the event.
*
* @param \Thelia\Core\Event\FolderEvent $event
*/
protected function eventContainsObject($event)
{
return $event->hasFolder();
}
/**
* Get the created object from an event.
*
* @param $event \Thelia\Core\Event\FolderEvent $event
*
* @return null|\Thelia\Model\Folder
*/
protected function getObjectFromEvent($event)
{
return $event->hasFolder() ? $event->getFolder() : null;
}
/**
* Load an existing object from the database
*/
protected function getExistingObject() {
return FolderQuery::create()
->joinWithI18n($this->getCurrentEditionLocale())
->findOneById($this->getRequest()->get('folder_id', 0));
}
/**
* Returns the object label form the object event (name, title, etc.)
*
* @param unknown $object
*/
protected function getObjectLabel($object) {
return $object->getTitle();
}
/**
* Returns the object ID from the object
*
* @param unknown $object
*/
protected function getObjectId($object)
{
return $object->getId();
}
/**
* Render the main list template
*
* @param unknown $currentOrder, if any, null otherwise.
*/
protected function renderListTemplate($currentOrder) {
// Get content order
$content_order = $this->getListOrderFromSession('content', 'content_order', 'manual');
return $this->render('folders',
array(
'folder_order' => $currentOrder,
'content_order' => $content_order,
'parent' => $this->getRequest()->get('parent', 0)
));
}
/**
* Render the edition template
*/
protected function renderEditionTemplate() {
return $this->render('folder-edit', $this->getEditionArguments());
}
protected function getEditionArguments()
{
return array(
'folder_id' => $this->getRequest()->get('folder_id', 0),
'current_tab' => $this->getRequest()->get('current_tab', 'general')
);
}
/**
* @param \Thelia\Core\Event\FolderUpdateEvent $updateEvent
* @return Response|void
*/
protected function performAdditionalUpdateAction($updateEvent)
{
if ($this->getRequest()->get('save_mode') != 'stay') {
// Redirect to parent category list
$this->redirectToRoute(
'admin.folders.default',
array('parent' => $updateEvent->getFolder()->getParent())
);
}
}
/**
* Put in this method post object delete processing if required.
*
* @param \Thelia\Core\Event\FolderDeleteEvent $deleteEvent the delete event
* @return Response a response, or null to continue normal processing
*/
protected function performAdditionalDeleteAction($deleteEvent)
{
// Redirect to parent category list
$this->redirectToRoute(
'admin.folders.default',
array('parent' => $deleteEvent->getFolder()->getParent())
);
}
/**
* @param $event \Thelia\Core\Event\UpdatePositionEvent
* @return null|Response
*/
protected function performAdditionalUpdatePositionAction($event)
{
$folder = FolderQuery::create()->findPk($event->getObjectId());
if ($folder != null) {
// Redirect to parent category list
$this->redirectToRoute(
'admin.folders.default',
array('parent' => $folder->getParent())
);
}
return null;
}
/**
* Redirect to the edition template
*/
protected function redirectToEditionTemplate()
{
$this->redirect($this->getRoute('admin.folders.update', $this->getEditionArguments()));
}
/**
* Redirect to the list template
*/
protected function redirectToListTemplate()
{
$this->redirectToRoute(
'admin.folders.default',
array('parent' => $this->getRequest()->get('parent', 0))
);
}
}

View File

@@ -0,0 +1,46 @@
<?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;
/**
* Class ModuleController
* @package Thelia\Controller\Admin
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class ModuleController extends BaseAdminController
{
public function indexAction()
{
if (null !== $response = $this->checkAuth("admin.module.view")) return $response;
return $this->render("modules", array("display_module" => 20));
}
public function updateAction($module_id)
{
return $this->render("module-edit", array(
"module_id" => $module_id
));
}
}

View File

@@ -39,6 +39,24 @@ use Thelia\Model\FolderQuery;
use Thelia\Model\ContentQuery;
use Propel\Runtime\ActiveQuery\Criteria;
use Thelia\Model\ProductAssociatedContentQuery;
use Thelia\Model\AccessoryQuery;
use Thelia\Model\CategoryQuery;
use Thelia\Core\Event\ProductAddAccessoryEvent;
use Thelia\Core\Event\ProductDeleteAccessoryEvent;
use Thelia\Core\Event\FeatureProductUpdateEvent;
use Thelia\Model\FeatureQuery;
use Thelia\Core\Event\FeatureProductDeleteEvent;
use Thelia\Model\FeatureTemplateQuery;
use Thelia\Core\Event\ProductSetTemplateEvent;
use Thelia\Core\Event\ProductAddCategoryEvent;
use Thelia\Core\Event\ProductDeleteCategoryEvent;
use Thelia\Model\AttributeQuery;
use Thelia\Model\AttributeAvQuery;
use Thelia\Model\ProductSaleElementsQuery;
use Thelia\Model\AttributeCombination;
use Thelia\Model\AttributeAv;
use Thelia\Core\Event\ProductCreateCombinationEvent;
use Thelia\Core\Event\ProductDeleteCombinationEvent;
/**
* Manages products
@@ -68,6 +86,35 @@ class ProductController extends AbstractCrudController
);
}
/**
* Attributes ajax tab loading
*/
public function loadAttributesAjaxTabAction() {
return $this->render(
'ajax/product-attributes-tab',
array(
'product_id' => $this->getRequest()->get('product_id', 0),
)
);
}
/**
* Related information ajax tab loading
*/
public function loadRelatedAjaxTabAction() {
return $this->render(
'ajax/product-related-tab',
array(
'product_id' => $this->getRequest()->get('product_id', 0),
'folder_id' => $this->getRequest()->get('folder_id', 0),
'accessory_category_id' => $this->getRequest()->get('accessory_category_id', 0)
)
);
}
protected function getCreationForm()
{
return new ProductCreationForm($this->getRequest());
@@ -83,10 +130,15 @@ class ProductController extends AbstractCrudController
$createEvent = new ProductCreateEvent();
$createEvent
->setRef($formData['ref'])
->setTitle($formData['title'])
->setLocale($formData["locale"])
->setParent($formData['parent'])
->setLocale($formData['locale'])
->setDefaultCategory($formData['default_category'])
->setVisible($formData['visible'])
->setBasePrice($formData['price'])
->setBaseWeight($formData['weight'])
->setCurrencyId($formData['currency'])
->setTaxRuleId($formData['tax_rule'])
;
return $createEvent;
@@ -105,8 +157,8 @@ class ProductController extends AbstractCrudController
->setPostscriptum($formData['postscriptum'])
->setVisible($formData['visible'])
->setUrl($formData['url'])
->setParent($formData['parent'])
;
->setDefaultCategory($formData['default_category'])
;
return $changeEvent;
}
@@ -132,17 +184,25 @@ class ProductController extends AbstractCrudController
protected function hydrateObjectForm($object)
{
// Get the default produc sales element
$salesElement = ProductSaleElementsQuery::create()->filterByProduct($object)->filterByIsDefault(true)->findOne();
// $prices = $salesElement->getProductPrices();
// Prepare the data that will hydrate the form
$data = array(
'id' => $object->getId(),
'locale' => $object->getLocale(),
'title' => $object->getTitle(),
'chapo' => $object->getChapo(),
'description' => $object->getDescription(),
'postscriptum' => $object->getPostscriptum(),
'visible' => $object->getVisible(),
'url' => $object->getRewritenUrl($this->getCurrentEditionLocale()),
'parent' => $object->getParent()
'id' => $object->getId(),
'ref' => $object->getRef(),
'locale' => $object->getLocale(),
'title' => $object->getTitle(),
'chapo' => $object->getChapo(),
'description' => $object->getDescription(),
'postscriptum' => $object->getPostscriptum(),
'visible' => $object->getVisible(),
'url' => $object->getRewrittenUrl($this->getCurrentEditionLocale()),
'default_category' => $object->getDefaultCategoryId()
// A terminer pour les prix
);
// Setup the object form
@@ -174,12 +234,27 @@ class ProductController extends AbstractCrudController
protected function getEditionArguments()
{
return array(
'product_id' => $this->getRequest()->get('product_id', 0),
'folder_id' => $this->getRequest()->get('folder_id', 0),
'current_tab' => $this->getRequest()->get('current_tab', 'general')
'category_id' => $this->getCategoryId(),
'product_id' => $this->getRequest()->get('product_id', 0),
'folder_id' => $this->getRequest()->get('folder_id', 0),
'accessory_category_id' => $this->getRequest()->get('accessory_category_id', 0),
'current_tab' => $this->getRequest()->get('current_tab', 'general')
);
}
protected function getCategoryId() {
// Trouver le category_id, soit depuis la reques, souit depuis le produit courant
$category_id = $this->getRequest()->get('category_id', null);
if ($category_id == null) {
$product = $this->getExistingObject();
if ($product !== null) $category_id = $product->getDefaultCategoryId();
}
return $category_id != null ? $category_id : 0;
}
protected function renderListTemplate($currentOrder)
{
$this->getListOrderFromSession('product', 'product_order', 'manual');
@@ -187,18 +262,15 @@ class ProductController extends AbstractCrudController
return $this->render('categories',
array(
'product_order' => $currentOrder,
'product_id' => $this->getRequest()->get('product_id', 0)
'category_id' => $this->getCategoryId()
));
}
protected function redirectToListTemplate()
{
// Redirect to the product default category list
$product = $this->getExistingObject();
$this->redirectToRoute(
'admin.products.default',
array('category_id' => $product != null ? $product->getDefaultCategory() : 0)
array('category_id' => $this->getCategoryId())
);
}
@@ -238,7 +310,7 @@ class ProductController extends AbstractCrudController
// Redirect to parent product list
$this->redirectToRoute(
'admin.products.default',
array('category_id' => $deleteEvent->getProduct()->getDefaultCategory())
array('category_id' => $this->getCategoryId())
);
}
@@ -249,26 +321,22 @@ class ProductController extends AbstractCrudController
// Redirect to parent product list
$this->redirectToRoute(
'admin.categories.default',
array('category_id' => $product->getDefaultCategory())
array('category_id' => $this->getCategoryId())
);
}
}
protected function performAdditionalUpdatePositionAction($event)
protected function performAdditionalUpdatePositionAction($positionEvent)
{
$product = ProductQuery::create()->findPk($event->getObjectId());
if ($product != null) {
// Redirect to parent product list
$this->redirectToRoute(
'admin.categories.default',
array('category_id' => $product->getDefaultCategory())
);
}
return null;
// Redirect to parent product list
$this->redirectToRoute(
'admin.categories.default',
array('category_id' => $this->getCategoryId())
);
}
// -- Related content management -------------------------------------------
public function getAvailableRelatedContentAction($productId, $folderId)
{
$result = array();
@@ -347,4 +415,383 @@ class ProductController extends AbstractCrudController
$this->redirectToEditionTemplate();
}
// -- Accessories management ----------------------------------------------
public function getAvailableAccessoriesAction($productId, $categoryId)
{
$result = array();
$categories = CategoryQuery::create()->filterById($categoryId)->find();
if ($categories !== null) {
$list = ProductQuery::create()
->joinWithI18n($this->getCurrentEditionLocale())
->filterByCategory($categories, Criteria::IN)
->filterById(AccessoryQuery::create()->select('accessory')->findByProductId($productId), Criteria::NOT_IN)
->find();
;
if ($list !== null) {
foreach($list as $item) {
$result[] = array('id' => $item->getId(), 'title' => $item->getTitle());
}
}
}
return $this->jsonResponse(json_encode($result));
}
public function addAccessoryAction()
{
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.products.update")) return $response;
$accessory_id = intval($this->getRequest()->get('accessory_id'));
if ($accessory_id > 0) {
$event = new ProductAddAccessoryEvent(
$this->getExistingObject(),
$accessory_id
);
try {
$this->dispatch(TheliaEvents::PRODUCT_ADD_ACCESSORY, $event);
}
catch (\Exception $ex) {
// Any error
return $this->errorPage($ex);
}
}
$this->redirectToEditionTemplate();
}
public function deleteAccessoryAction()
{
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.products.update")) return $response;
$accessory_id = intval($this->getRequest()->get('accessory_id'));
if ($accessory_id > 0) {
$event = new ProductDeleteAccessoryEvent(
$this->getExistingObject(),
$accessory_id
);
try {
$this->dispatch(TheliaEvents::PRODUCT_REMOVE_ACCESSORY, $event);
}
catch (\Exception $ex) {
// Any error
return $this->errorPage($ex);
}
}
$this->redirectToEditionTemplate();
}
/**
* Update accessory position
*/
public function updateAccessoryPositionAction()
{
$accessory = AccessoryQuery::create()->findPk($this->getRequest()->get('accessory_id', null));
return $this->genericUpdatePositionAction(
$accessory,
TheliaEvents::PRODUCT_UPDATE_ACCESSORY_POSITION
);
}
/**
* Update related content position
*/
public function updateContentPositionAction()
{
$content = ProductAssociatedContentQuery::create()->findPk($this->getRequest()->get('content_id', null));
return $this->genericUpdatePositionAction(
$content,
TheliaEvents::PRODUCT_UPDATE_CONTENT_POSITION
);
}
/**
* Change product template for a given product.
*
* @param unknown $productId
*/
public function setProductTemplateAction($productId) {
// Check current user authorization
if (null !== $response = $this->checkAuth('admin.products.update')) return $response;
$product = ProductQuery::create()->findPk($productId);
if ($product != null) {
$template_id = intval($this->getRequest()->get('template_id', 0));
$this->dispatch(
TheliaEvents::PRODUCT_SET_TEMPLATE,
new ProductSetTemplateEvent($product, $template_id)
);
}
$this->redirectToEditionTemplate();
}
/**
* Update product attributes and features
*/
public function updateAttributesAndFeaturesAction($productId) {
$product = ProductQuery::create()->findPk($productId);
if ($product != null) {
$featureTemplate = FeatureTemplateQuery::create()->filterByTemplateId($product->getTemplateId())->find();
if ($featureTemplate !== null) {
// Get all features for the template attached to this product
$allFeatures = FeatureQuery::create()
->filterByFeatureTemplate($featureTemplate)
->find();
$updatedFeatures = array();
// Update all features values, starting with feature av. values
$featureValues = $this->getRequest()->get('feature_value', array());
foreach($featureValues as $featureId => $featureValueList) {
// Delete all features av. for this feature.
$event = new FeatureProductDeleteEvent($productId, $featureId);
$this->dispatch(TheliaEvents::PRODUCT_FEATURE_DELETE_VALUE, $event);
// Add then all selected values
foreach($featureValueList as $featureValue) {
$event = new FeatureProductUpdateEvent($productId, $featureId, $featureValue);
$this->dispatch(TheliaEvents::PRODUCT_FEATURE_UPDATE_VALUE, $event);
}
$updatedFeatures[] = $featureId;
}
// Update then features text values
$featureTextValues = $this->getRequest()->get('feature_text_value', array());
foreach($featureTextValues as $featureId => $featureValue) {
// considere empty text as empty feature value (e.g., we will delete it)
if (empty($featureValue)) continue;
$event = new FeatureProductUpdateEvent($productId, $featureId, $featureValue, true);
$this->dispatch(TheliaEvents::PRODUCT_FEATURE_UPDATE_VALUE, $event);
$updatedFeatures[] = $featureId;
}
// Delete features which don't have any values
foreach($allFeatures as $feature) {
if (! in_array($feature->getId(), $updatedFeatures)) {
$event = new FeatureProductDeleteEvent($productId, $feature->getId());
$this->dispatch(TheliaEvents::PRODUCT_FEATURE_DELETE_VALUE, $event);
}
}
}
}
// If we have to stay on the same page, do not redirect to the succesUrl,
// just redirect to the edit page again.
if ($this->getRequest()->get('save_mode') == 'stay') {
$this->redirectToEditionTemplate($this->getRequest());
}
// Redirect to the category/product list
$this->redirectToListTemplate();
}
public function addAdditionalCategoryAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.products.update")) return $response;
$category_id = intval($this->getRequest()->get('additional_category_id'));
if ($category_id > 0) {
$event = new ProductAddCategoryEvent(
$this->getExistingObject(),
$category_id
);
try {
$this->dispatch(TheliaEvents::PRODUCT_ADD_CATEGORY, $event);
}
catch (\Exception $ex) {
// Any error
return $this->errorPage($ex);
}
}
$this->redirectToEditionTemplate();
}
public function deleteAdditionalCategoryAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.products.update")) return $response;
$category_id = intval($this->getRequest()->get('additional_category_id'));
if ($category_id > 0) {
$event = new ProductDeleteCategoryEvent(
$this->getExistingObject(),
$category_id
);
try {
$this->dispatch(TheliaEvents::PRODUCT_REMOVE_CATEGORY, $event);
}
catch (\Exception $ex) {
// Any error
return $this->errorPage($ex);
}
}
$this->redirectToEditionTemplate();
}
// -- Product combination management ---------------------------------------
public function getAttributeValuesAction($productId, $attributeId) {
$result = array();
// Get attribute for this product
$attribute = AttributeQuery::create()->findPk($attributeId);
if ($attribute !== null) {
$values = AttributeAvQuery::create()
->joinWithI18n($this->getCurrentEditionLocale())
->filterByAttribute($attribute)
->find();
;
if ($values !== null) {
foreach($values as $value) {
$result[] = array('id' => $value->getId(), 'title' => $value->getTitle());
}
}
}
return $this->jsonResponse(json_encode($result));
}
public function addAttributeValueToCombinationAction($productId, $attributeAvId, $combination) {
$result = array();
// Get attribute for this product
$attributeAv = AttributeAvQuery::create()->joinWithI18n($this->getCurrentEditionLocale())->findPk($attributeAvId);
if ($attributeAv !== null) {
$addIt = true;
$attribute = $attributeAv->getAttribute();
// Check if this attribute is not already present
$combinationArray = explode(',', $combination);
foreach ($combinationArray as $id) {
$attrAv = AttributeAvQuery::create()->joinWithI18n($this->getCurrentEditionLocale())->findPk($id);
if ($attrAv !== null) {
if ($attrAv->getAttributeId() == $attribute->getId()) {
$result['error'] = $this->getTranslator()->trans(
'A value for attribute "%name" is already present in the combination',
array('%name' => $attribute->getTitle())
);
$addIt = false;
}
$result[] = array('id' => $attrAv->getId(), 'title' => $attrAv->getAttribute()->getTitle() . " : " . $attrAv->getTitle());
}
}
if ($addIt) $result[] = array('id' => $attributeAv->getId(), 'title' => $attribute->getTitle() . " : " . $attributeAv->getTitle());
}
return $this->jsonResponse(json_encode($result));
}
/**
* A a new combination to a product
*/
public function addCombinationAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.products.update")) return $response;
$event = new ProductCreateCombinationEvent(
$this->getExistingObject(),
$this->getRequest()->get('combination_attributes', array()),
$this->getCurrentEditionCurrency()->getId()
);
try {
$this->dispatch(TheliaEvents::PRODUCT_ADD_COMBINATION, $event);
}
catch (\Exception $ex) {
// Any error
return $this->errorPage($ex);
}
$this->redirectToEditionTemplate();
}
/**
* A a new combination to a product
*/
public function deleteCombinationAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.products.update")) return $response;
$event = new ProductDeleteCombinationEvent(
$this->getExistingObject(),
$this->getRequest()->get('product_sale_element_id',0)
);
try {
$this->dispatch(TheliaEvents::PRODUCT_DELETE_COMBINATION, $event);
}
catch (\Exception $ex) {
// Any error
return $this->errorPage($ex);
}
$this->redirectToEditionTemplate();
}
}

View File

@@ -0,0 +1,46 @@
<?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;
/**
* Class ShippingConfigurationController
* @package Thelia\Controller\Admin
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class ShippingConfigurationController extends BaseAdminController
{
public function indexAction()
{
if (null !== $response = $this->checkAuth("admin.shipping-configuration.view")) return $response;
return $this->render("shipping-configuration", array("display_shipping_configuration" => 20));
}
public function updateAction($shipping_configuration_id)
{
return $this->render("shipping-configuration-edit", array(
"shipping_configuration_id" => $shipping_configuration_id
));
}
}

View File

@@ -0,0 +1,46 @@
<?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;
/**
* Class ShippingZoneController
* @package Thelia\Controller\Admin
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class ShippingZoneController extends BaseAdminController
{
public function indexAction()
{
if (null !== $response = $this->checkAuth("admin.shipping-zones.view")) return $response;
return $this->render("shipping-zones", array("display_shipping_zone" => 20));
}
public function updateAction($shipping_zones_id)
{
return $this->render("shipping-zones-edit", array(
"shipping_zones_id" => $shipping_zones_id
));
}
}

View File

@@ -39,6 +39,8 @@ use Thelia\Core\Event\TemplateDeleteAttributeEvent;
use Thelia\Core\Event\TemplateAddAttributeEvent;
use Thelia\Core\Event\TemplateAddFeatureEvent;
use Thelia\Core\Event\TemplateDeleteFeatureEvent;
use Thelia\Model\FeatureTemplateQuery;
use Thelia\Model\AttributeTemplateQuery;
/**
* Manages product templates
@@ -255,6 +257,21 @@ class TemplateController extends AbstractCrudController
$this->redirectToEditionTemplate();
}
public function updateAttributePositionAction() {
// Find attribute_template
$attributeTemplate = AttributeTemplateQuery::create()
->filterByTemplateId($this->getRequest()->get('template_id', null))
->filterByAttributeId($this->getRequest()->get('attribute_id', null))
->findOne()
;
return $this->genericUpdatePositionAction(
$attributeTemplate,
TheliaEvents::TEMPLATE_CHANGE_ATTRIBUTE_POSITION
);
}
public function addFeatureAction() {
// Check current user authorization
@@ -299,4 +316,18 @@ class TemplateController extends AbstractCrudController
$this->redirectToEditionTemplate();
}
public function updateFeaturePositionAction() {
// Find feature_template
$featureTemplate = FeatureTemplateQuery::create()
->filterByTemplateId($this->getRequest()->get('template_id', null))
->filterByFeatureId($this->getRequest()->get('feature_id', null))
->findOne()
;
return $this->genericUpdatePositionAction(
$featureTemplate,
TheliaEvents::TEMPLATE_CHANGE_FEATURE_POSITION
);
}
}

View File

@@ -24,6 +24,8 @@ namespace Thelia\Controller\Front;
use Symfony\Component\Routing\Router;
use Thelia\Controller\BaseController;
use Thelia\Model\AddressQuery;
use Thelia\Model\ModuleQuery;
use Thelia\Tools\URL;
class BaseFrontController extends BaseController
@@ -65,4 +67,20 @@ class BaseFrontController extends BaseController
$this->redirectToRoute("cart.view");
}
}
protected function checkValidDelivery()
{
$order = $this->getSession()->getOrder();
if(null === $order || null === $order->chosenDeliveryAddress || null === $order->getDeliveryModuleId() || null === AddressQuery::create()->findPk($order->chosenDeliveryAddress) || null === ModuleQuery::create()->findPk($order->getDeliveryModuleId())) {
$this->redirectToRoute("order.delivery");
}
}
protected function checkValidInvoice()
{
$order = $this->getSession()->getOrder();
if(null === $order || null === $order->chosenInvoiceAddress || null === $order->getPaymentModuleId() || null === AddressQuery::create()->findPk($order->chosenInvoiceAddress) || null === ModuleQuery::create()->findPk($order->getPaymentModuleId())) {
$this->redirectToRoute("order.invoice");
}
}
}

View File

@@ -23,15 +23,21 @@
namespace Thelia\Controller\Front;
use Propel\Runtime\Exception\PropelException;
use Thelia\Exception\TheliaProcessException;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Core\Event\OrderEvent;
use Thelia\Core\Event\TheliaEvents;
use Symfony\Component\HttpFoundation\Request;
use Thelia\Form\OrderDelivery;
use Thelia\Form\OrderPayment;
use Thelia\Log\Tlog;
use Thelia\Model\AddressQuery;
use Thelia\Model\AreaDeliveryModuleQuery;
use Thelia\Model\Base\OrderQuery;
use Thelia\Model\CountryQuery;
use Thelia\Model\ModuleQuery;
use Thelia\Model\Order;
use Thelia\Tools\URL;
/**
* Class OrderController
@@ -41,7 +47,6 @@ use Thelia\Model\Order;
class OrderController extends BaseFrontController
{
/**
* set billing address
* set delivery address
* set delivery module
*/
@@ -59,25 +64,32 @@ class OrderController extends BaseFrontController
$deliveryAddressId = $form->get("delivery-address")->getData();
$deliveryModuleId = $form->get("delivery-module")->getData();
$deliveryAddress = AddressQuery::create()->findPk($deliveryAddressId);
$deliveryModule = ModuleQuery::create()->findPk($deliveryModuleId);
/* check that the delivery address belong to the current customer */
/* check that the delivery address belongs to the current customer */
$deliveryAddress = AddressQuery::create()->findPk($deliveryAddressId);
if($deliveryAddress->getCustomerId() !== $this->getSecurityContext()->getCustomerUser()->getId()) {
throw new \Exception("Address does not belong to the current customer");
throw new \Exception("Delivery address does not belong to the current customer");
}
/* check that the delivery module fetch the delivery address area */
/* check that the delivery module fetches the delivery address area */
if(AreaDeliveryModuleQuery::create()
->filterByAreaId($deliveryAddress->getCountry()->getAreaId())
->filterByDeliveryModuleId()
->filterByDeliveryModuleId($deliveryModuleId)
->count() == 0) {
throw new \Exception("PUKE");
throw new \Exception("Delivery module cannot be use with selected delivery address");
}
/* get postage amount */
$moduleReflection = new \ReflectionClass($deliveryModule->getFullNamespace());
$moduleInstance = $moduleReflection->newInstance();
$postage = $moduleInstance->getPostage($deliveryAddress->getCountry());
$orderEvent = $this->getOrderEvent();
$orderEvent->setDeliveryAddress($deliveryAddressId);
$orderEvent->setDeliveryModule($deliveryModuleId);
$orderEvent->setPostage($postage);
$this->getDispatcher()->dispatch(TheliaEvents::ORDER_SET_DELIVERY_ADDRESS, $orderEvent);
$this->getDispatcher()->dispatch(TheliaEvents::ORDER_SET_DELIVERY_MODULE, $orderEvent);
@@ -105,6 +117,111 @@ class OrderController extends BaseFrontController
}
/**
* set invoice address
* set payment module
*/
public function invoice()
{
$this->checkAuth();
$this->checkCartNotEmpty();
$this->checkValidDelivery();
$message = false;
$orderPayment = new OrderPayment($this->getRequest());
try {
$form = $this->validateForm($orderPayment, "post");
$invoiceAddressId = $form->get("invoice-address")->getData();
$paymentModuleId = $form->get("payment-module")->getData();
/* check that the invoice address belongs to the current customer */
$invoiceAddress = AddressQuery::create()->findPk($invoiceAddressId);
if($invoiceAddress->getCustomerId() !== $this->getSecurityContext()->getCustomerUser()->getId()) {
throw new \Exception("Invoice address does not belong to the current customer");
}
$orderEvent = $this->getOrderEvent();
$orderEvent->setInvoiceAddress($invoiceAddressId);
$orderEvent->setPaymentModule($paymentModuleId);
$this->getDispatcher()->dispatch(TheliaEvents::ORDER_SET_INVOICE_ADDRESS, $orderEvent);
$this->getDispatcher()->dispatch(TheliaEvents::ORDER_SET_PAYMENT_MODULE, $orderEvent);
$this->redirectToRoute("order.payment.process");
} catch (FormValidationException $e) {
$message = sprintf("Please check your input: %s", $e->getMessage());
} catch (PropelException $e) {
$this->getParserContext()->setGeneralError($e->getMessage());
} catch (\Exception $e) {
$message = sprintf("Sorry, an error occured: %s", $e->getMessage());
}
if ($message !== false) {
Tlog::getInstance()->error(sprintf("Error during order payment process : %s. Exception was %s", $message, $e->getMessage()));
$orderPayment->setErrorMessage($message);
$this->getParserContext()
->addForm($orderPayment)
->setGeneralError($message)
;
}
}
public function pay()
{
/* check customer */
$this->checkAuth();
/* check cart count */
$this->checkCartNotEmpty();
/* check delivery address and module */
$this->checkValidDelivery();
/* check invoice address and payment module */
$this->checkValidInvoice();
$orderEvent = $this->getOrderEvent();
$this->getDispatcher()->dispatch(TheliaEvents::ORDER_PAY, $orderEvent);
$placedOrder = $orderEvent->getPlacedOrder();
if(null !== $placedOrder && null !== $placedOrder->getId()) {
/* order has been placed */
$this->redirect(URL::getInstance()->absoluteUrl($this->getRoute('order.placed', array('order_id' => $orderEvent->getPlacedOrder()->getId()))));
} else {
/* order has not been placed */
$this->redirectToRoute("cart.view");
}
}
public function orderPlaced($order_id)
{
/* check if the placed order matched the customer */
$placedOrder = OrderQuery::create()->findPk(
$this->getRequest()->attributes->get('order_id')
);
if(null === $placedOrder) {
throw new TheliaProcessException("No placed order", TheliaProcessException::NO_PLACED_ORDER, $placedOrder);
}
$customer = $this->getSecurityContext()->getCustomerUser();
if(null === $customer || $placedOrder->getCustomerId() !== $customer->getId()) {
throw new TheliaProcessException("Received placed order id does not belong to the current customer", TheliaProcessException::PLACED_ORDER_ID_BAD_CURRENT_CUSTOMER, $placedOrder);
}
$this->getParserContext()->set("placed_order_id", $placedOrder->getId());
}
protected function getOrderEvent()
{
$order = $this->getOrder($this->getRequest());

View File

@@ -0,0 +1,54 @@
<?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\Accessory;
use Thelia\Core\Event\ActionEvent;
class AccessoryEvent extends ActionEvent
{
public $accessory = null;
public function __construct(Accessory $accessory = null)
{
$this->accessory = $accessory;
}
public function hasAccessory()
{
return ! is_null($this->accessory);
}
public function getAccessory()
{
return $this->accessory;
}
public function setAccessory(Accessory $accessory)
{
$this->accessory = $accessory;
return $this;
}
}

View File

@@ -0,0 +1,54 @@
<?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\CategoryAssociatedContent;
use Thelia\Core\Event\ActionEvent;
class CategoryAssociatedContentEvent extends ActionEvent
{
public $content = null;
public function __construct(CategoryAssociatedContent $content = null)
{
$this->content = $content;
}
public function hasCategoryAssociatedContent()
{
return ! is_null($this->content);
}
public function getCategoryAssociatedContent()
{
return $this->content;
}
public function setCategoryAssociatedContent(CategoryAssociatedContent $content)
{
$this->content = $content;
return $this;
}
}

View File

@@ -0,0 +1,124 @@
<?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\Content;
/**
* Class ContentCreateEvent
* @package Thelia\Core\Event\Content
* @author manuel raynaud <mraynaud@openstudio.fr>
*/
class ContentCreateEvent extends ContentEvent
{
protected $title;
protected $default_folder;
protected $locale;
protected $visible;
/**
* @param mixed $locale
*
* @return $this
*/
public function setLocale($locale)
{
$this->locale = $locale;
return $this;
}
/**
* @return mixed
*/
public function getLocale()
{
return $this->locale;
}
/**
* @param mixed $default_folder
*
* @return $this
*/
public function setDefaultFolder($default_folder)
{
$this->default_folder = $default_folder;
return $this;
}
/**
* @return mixed
*/
public function getDefaultFolder()
{
return $this->default_folder;
}
/**
* @param mixed $visible
*
* @return $this
*/
public function setVisible($visible)
{
$this->visible = $visible;
return $this;
}
/**
* @return mixed
*/
public function getVisible()
{
return $this->visible;
}
/**
* @param mixed $title
*
* @return $this
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* @return mixed
*/
public function getTitle()
{
return $this->title;
}
}

View File

@@ -0,0 +1,74 @@
<?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\Content;
/**
* Class ContentDeleteEvent
* @package Thelia\Core\Event\Content
* @author manuel raynaud <mraynaud@openstudio.fr>
*/
class ContentDeleteEvent extends ContentEvent
{
protected $content_id;
protected $folder_id;
function __construct($content_id)
{
$this->content_id = $content_id;
}
/**
* @param mixed $content_id
*
* @return $this
*/
public function setContentId($content_id)
{
$this->content_id = $content_id;
return $this;
}
/**
* @return mixed
*/
public function getContentId()
{
return $this->content_id;
}
public function setDefaultFolderId($folderid)
{
$this->folder_id = $folderid;
}
public function getDefaultFolderId()
{
return $this->folder_id;
}
}

View File

@@ -0,0 +1,73 @@
<?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\Content;
use Thelia\Core\Event\ActionEvent;
use Thelia\Model\Content;
/**
* Class ContentEvent
* @package Thelia\Core\Event\Content
* @author manuel raynaud <mraynaud@openstudio.fr>
*/
class ContentEvent extends ActionEvent
{
/**
* @var \Thelia\Model\Content
*/
protected $content;
function __construct(Content $content = null)
{
$this->content = $content;
}
/**
* @param \Thelia\Model\Content $content
*/
public function setContent(Content $content)
{
$this->content = $content;
return $this;
}
/**
* @return \Thelia\Model\Content
*/
public function getContent()
{
return $this->content;
}
/**
* check if content exists
*
* @return bool
*/
public function hasContent()
{
return null !== $this->content;
}
}

View File

@@ -0,0 +1,35 @@
<?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\Content;
/**
* Class ContentToggleVisibilityEvent
* @package Thelia\Core\Event\Content
* @author manuel raynaud <mraynaud@openstudio.fr>
*/
class ContentToggleVisibilityEvent extends ContentEvent
{
}

View File

@@ -0,0 +1,150 @@
<?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\Content;
/**
* Class ContentUpdateEvent
* @package Thelia\Core\Event\Content
* @author manuel raynaud <mraynaud@openstudio.fr>
*/
class ContentUpdateEvent extends ContentCreateEvent
{
protected $content_id;
protected $chapo;
protected $description;
protected $postscriptum;
protected $url;
function __construct($content_id)
{
$this->content_id = $content_id;
}
/**
* @param mixed $chapo
*
* @return $this
*/
public function setChapo($chapo)
{
$this->chapo = $chapo;
return $this;
}
/**
* @return mixed
*/
public function getChapo()
{
return $this->chapo;
}
/**
* @param mixed $content_id
*
* @return $this
*/
public function setContentId($content_id)
{
$this->content_id = $content_id;
return $this;
}
/**
* @return mixed
*/
public function getContentId()
{
return $this->content_id;
}
/**
* @param mixed $description
*
* @return $this
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* @return mixed
*/
public function getDescription()
{
return $this->description;
}
/**
* @param mixed $postscriptum
*
* @return $this
*/
public function setPostscriptum($postscriptum)
{
$this->postscriptum = $postscriptum;
return $this;
}
/**
* @return mixed
*/
public function getPostscriptum()
{
return $this->postscriptum;
}
/**
* @param mixed $url
*
* @return $this
*/
public function setUrl($url)
{
$this->url = $url;
return $this;
}
/**
* @return mixed
*/
public function getUrl()
{
return $this->url;
}
}

View File

@@ -0,0 +1,217 @@
<?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 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 <gmorel@openstudio.fr>
*
*/
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->documentType = $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->documentType = $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;
}
}

View File

@@ -0,0 +1,112 @@
<?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\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 <gmorel@openstudio.fr>
*
*/
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->documentToDelete = $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->documentToDelete = $documentToDelete;
return $this;
}
/**
* Get Document about to be deleted
*
* @return CategoryDocument|ProductDocument|ContentDocument|FolderDocument
*/
public function getDocumentToDelete()
{
return $this->documentToDelete;
}
}

View File

@@ -23,43 +23,60 @@
namespace Thelia\Core\Event;
/**
* Class DocumentEvent
*
* @package Thelia\Core\Event
*/
class DocumentEvent extends CachedFileEvent
{
protected $document_path;
protected $document_url;
protected $documentPath;
protected $documentUrl;
/**
* @return the document file path
* Get Document path
*
* @return string The document file path
*/
public function getDocumentPath()
{
return $this->document_path;
return $this->documentPath;
}
/**
* @param string $document_path the document file path
* Set Document path
*
* @param string $documentPath the document file path
*
* @return $this
*/
public function setDocumentPath($document_path)
public function setDocumentPath($documentPath)
{
$this->document_path = $document_path;
$this->documentPath = $documentPath;
return $this;
}
/**
* @return the document URL
* Get Document URL
*
* @return string The document URL
*/
public function getDocumentUrl()
{
return $this->document_url;
return $this->documentUrl;
}
/**
* @param string $document_url the document URL
* Set Document URL
*
* @param string $documentUrl the document URL
*
* @return $this
*/
public function setDocumentUrl($document_url)
public function setDocumentUrl($documentUrl)
{
$this->document_url = $document_url;
$this->documentUrl = $documentUrl;
return $this;
}

View File

@@ -0,0 +1,61 @@
<?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\FeatureProduct;
class FeatureProductDeleteEvent extends FeatureProductEvent
{
protected $product_id;
protected $feature_id;
public function __construct($product_id, $feature_id)
{
$this->product_id = $product_id;
$this->feature_id = $feature_id;
}
public function getProductId()
{
return $this->product_id;
}
public function setProductId($product_id)
{
$this->product_id = $product_id;
return $this;
}
public function getFeatureId()
{
return $this->feature_id;
}
public function setFeatureId($feature_id)
{
$this->feature_id = $feature_id;
return $this;
}
}

View File

@@ -0,0 +1,52 @@
<?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\FeatureProduct;
class FeatureProductEvent extends ActionEvent
{
protected $featureProduct = null;
public function __construct(FeatureProduct $featureProduct = null)
{
$this->featureProduct = $featureProduct;
}
public function hasFeatureProduct()
{
return ! is_null($this->featureProduct);
}
public function getFeatureProduct()
{
return $this->featureProduct;
}
public function setFeatureProduct($featureProduct)
{
$this->featureProduct = $featureProduct;
return $this;
}
}

View File

@@ -0,0 +1,89 @@
<?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\FeatureProduct;
class FeatureProductUpdateEvent extends FeatureProductEvent
{
protected $product_id;
protected $feature_id;
protected $feature_value;
protected $is_text_value;
public function __construct($product_id, $feature_id, $feature_value, $is_text_value = false)
{
$this->product_id = $product_id;
$this->feature_id = $feature_id;
$this->feature_value = $feature_value;
$this->is_text_value = $is_text_value;
}
public function getProductId()
{
return $this->product_id;
}
public function setProductId($product_id)
{
$this->product_id = $product_id;
return $this;
}
public function getFeatureId()
{
return $this->feature_id;
}
public function setFeatureId($feature_id)
{
$this->feature_id = $feature_id;
return $this;
}
public function getFeatureValue()
{
return $this->feature_value;
}
public function setFeatureValue($feature_value)
{
$this->feature_value = $feature_value;
return $this;
}
public function getIsTextValue()
{
return $this->is_text_value;
}
public function setIsTextValue($is_text_value)
{
$this->is_text_value = $is_text_value;
return $this;
}
}

View File

@@ -0,0 +1,120 @@
<?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;
/**
* Class FolderCreateEvent
* @package Thelia\Core\Event
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class FolderCreateEvent extends FolderEvent {
protected $title;
protected $parent;
protected $locale;
protected $visible;
/**
* @param mixed $locale
*
* @return $this
*/
public function setLocale($locale)
{
$this->locale = $locale;
return $this;
}
/**
* @return mixed
*/
public function getLocale()
{
return $this->locale;
}
/**
* @param mixed $parent
*
*
* @return $this
*/
public function setParent($parent)
{
$this->parent = $parent;
return $this;
}
/**
* @return mixed
*/
public function getParent()
{
return $this->parent;
}
/**
* @param mixed $title
*
* @return $this
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* @return mixed
*/
public function getTitle()
{
return $this->title;
}
/**
* @param mixed $visible
*
* @return $this
*/
public function setVisible($visible)
{
$this->visible = $visible;
return $this;
}
/**
* @return mixed
*/
public function getVisible()
{
return $this->visible;
}
}

View File

@@ -21,35 +21,44 @@
/* */
/*************************************************************************************/
namespace Thelia\Controller\Front;
use Thelia\Model\ModuleQuery;
use Thelia\Tools\URL;
namespace Thelia\Core\Event;
/**
* Class DeliveryController
* @package Thelia\Controller\Front
* Class FolderDeleteEvent
* @package Thelia\Core\Event
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class DeliveryController extends BaseFrontController
{
public function select($delivery_id)
class FolderDeleteEvent extends FolderEvent{
/**
* @var int folder id
*/
protected $folder_id;
/**
* @param int $folder_id
*/
function __construct($folder_id)
{
if ($this->getSecurityContext()->hasCustomerUser() === false) {
$this->redirect(URL::getInstance()->getIndexPage());
}
$request = $this->getRequest();
$deliveryModule = ModuleQuery::create()
->filterById($delivery_id)
->filterByActivate(1)
->findOne()
;
if ($deliveryModule) {
$request->getSession()->setDelivery($delivery_id);
} else {
$this->pageNotFound();
}
$this->folder_id = $folder_id;
}
}
/**
* @param int $folder_id
*/
public function setFolderId($folder_id)
{
$this->folder_id = $folder_id;
}
/**
* @return int
*/
public function getFolderId()
{
return $this->folder_id;
}
}

View File

@@ -0,0 +1,73 @@
<?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\Folder;
/**
* Class FolderEvent
* @package Thelia\Core\Event
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class FolderEvent extends ActionEvent {
/**
* @var \Thelia\Model\Folder
*/
protected $folder;
function __construct(Folder $folder = null)
{
$this->folder = $folder;
}
/**
* @param \Thelia\Model\Folder $folder
*/
public function setFolder(Folder $folder)
{
$this->folder = $folder;
return $this;
}
/**
* @return \Thelia\Model\Folder
*/
public function getFolder()
{
return $this->folder;
}
/**
* test if a folder object exists
*
* @return bool
*/
public function hasFolder()
{
return null !== $this->folder;
}
}

View File

@@ -0,0 +1,34 @@
<?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;
/**
* Class FolderToggleVisibilityEvent
* @package Thelia\Core\Event
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class FolderToggleVisibilityEvent extends FolderEvent {
}

View File

@@ -0,0 +1,136 @@
<?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;
/**
* Class FolderUpdateEvent
* @package Thelia\Core\Event
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class FolderUpdateEvent extends FolderCreateEvent {
protected $folder_id;
protected $chapo;
protected $description;
protected $postscriptum;
protected $url;
function __construct($folder_id)
{
$this->folder_id = $folder_id;
}
/**
* @param mixed $chapo
*/
public function setChapo($chapo)
{
$this->chapo = $chapo;
return $this;
}
/**
* @return mixed
*/
public function getChapo()
{
return $this->chapo;
}
/**
* @param mixed $description
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* @return mixed
*/
public function getDescription()
{
return $this->description;
}
/**
* @param mixed $folder_id
*/
public function setFolderId($folder_id)
{
$this->folder_id = $folder_id;
return $this;
}
/**
* @return mixed
*/
public function getFolderId()
{
return $this->folder_id;
}
/**
* @param mixed $postscriptum
*/
public function setPostscriptum($postscriptum)
{
$this->postscriptum = $postscriptum;
return $this;
}
/**
* @return mixed
*/
public function getPostscriptum()
{
return $this->postscriptum;
}
/**
* @param mixed $url
*/
public function setUrl($url)
{
$this->url = $url;
return $this;
}
/**
* @return mixed
*/
public function getUrl()
{
return $this->url;
}
}

View File

@@ -0,0 +1,60 @@
<?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;
/**
* Class GenerateRewrittenUrlEvent
* @package Thelia\Core\Event
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class GenerateRewrittenUrlEvent extends ActionEvent {
protected $object;
protected $locale;
protected $url;
public function __construct($object, $locale)
{
$this->object;
$this->locale;
}
public function setUrl($url)
{
$this->url = $url;
}
public function isRewritten()
{
return null !== $this->url;
}
public function getUrl()
{
return $this->url;
}
}

View File

@@ -0,0 +1,213 @@
<?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 Symfony\Component\HttpFoundation\File\UploadedFile;
/**
* Created by JetBrains PhpStorm.
* Date: 9/18/13
* Time: 3:56 PM
*
* Occurring when an Image is saved
*
* @package Image
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class ImageCreateOrUpdateEvent extends ActionEvent
{
/** @var \Thelia\Model\CategoryImage|\Thelia\Model\ProductImage|\Thelia\Model\ContentImage|\Thelia\Model\FolderImage model to save */
protected $modelImage = array();
/** @var \Thelia\Model\CategoryImage|\Thelia\Model\ProductImage|\Thelia\Model\ContentImage|\Thelia\Model\FolderImage model to save */
protected $oldModelImage = array();
/** @var UploadedFile Image file to save */
protected $uploadedFile = null;
/** @var int Image parent id */
protected $parentId = null;
/** @var string Image type */
protected $imageType = null;
/** @var string Parent name */
protected $parentName = null;
/**
* Constructor
*
* @param string $imageType Image type
* ex : FileManager::TYPE_CATEGORY
* @param int $parentId Image parent id
*/
public function __construct($imageType, $parentId)
{
$this->imageType = $imageType;
$this->parentId = $parentId;
}
/**
* Set Image to save
*
* @param $image \Thelia\Model\CategoryImage|\Thelia\Model\ProductImage|\Thelia\Model\ContentImage|\Thelia\Model\FolderImage
*
* @return $this
*/
public function setModelImage($image)
{
$this->modelImage = $image;
return $this;
}
/**
* Get Image being saved
*
* @return \Thelia\Model\CategoryImage|\Thelia\Model\ProductImage|\Thelia\Model\ContentImage|\Thelia\Model\FolderImage
*/
public function getModelImage()
{
return $this->modelImage;
}
/**
* Set picture type
*
* @param string $imageType Image type
*
* @return $this
*/
public function setImageType($imageType)
{
$this->imageType = $imageType;
return $this;
}
/**
* Get picture type
*
* @return string
*/
public function getImageType()
{
return $this->imageType;
}
/**
* 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;
}
/**
* 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 \Thelia\Model\CategoryImage|\Thelia\Model\ContentImage|\Thelia\Model\FolderImage|\Thelia\Model\ProductImage $oldModelImage
*/
public function setOldModelImage($oldModelImage)
{
$this->oldModelImage = $oldModelImage;
}
/**
* Get old model value
*
* @return \Thelia\Model\CategoryImage|\Thelia\Model\ContentImage|\Thelia\Model\FolderImage|\Thelia\Model\ProductImage
*/
public function getOldModelImage()
{
return $this->oldModelImage;
}
}

View File

@@ -0,0 +1,112 @@
<?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 string Image type */
protected $imageType = null;
/** @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
* @param string $imageType Image type
* ex : FileManager::TYPE_CATEGORY
*/
public function __construct($imageToDelete, $imageType)
{
$this->imageToDelete = $imageToDelete;
$this->imageType = $imageType;
}
/**
* Set picture type
*
* @param string $imageType Image type
*
* @return $this
*/
public function setImageType($imageType)
{
$this->imageType = $imageType;
return $this;
}
/**
* Get picture type
*
* @return string
*/
public function getImageType()
{
return $this->imageType;
}
/**
* 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

@@ -23,17 +23,18 @@
namespace Thelia\Core\Event;
use Thelia\Model\Address;
use Thelia\Model\AddressQuery;
use Thelia\Model\Module;
use Thelia\Model\Order;
class OrderEvent extends ActionEvent
{
protected $order = null;
protected $billingAddress = null;
protected $placedOrder = null;
protected $invoiceAddress = null;
protected $deliveryAddress = null;
protected $deliveryModule = null;
protected $paymentModule = null;
protected $postage = null;
protected $ref = null;
/**
* @param Order $order
@@ -51,12 +52,20 @@ class OrderEvent extends ActionEvent
$this->order = $order;
}
/**
* @param Order $order
*/
public function setPlacedOrder(Order $order)
{
$this->placedOrder = $order;
}
/**
* @param $address
*/
public function setBillingAddress($address)
public function setInvoiceAddress($address)
{
$this->deliveryAddress = $address;
$this->invoiceAddress = $address;
}
/**
@@ -75,6 +84,30 @@ class OrderEvent extends ActionEvent
$this->deliveryModule = $module;
}
/**
* @param $module
*/
public function setPaymentModule($module)
{
$this->paymentModule = $module;
}
/**
* @param $postage
*/
public function setPostage($postage)
{
$this->postage = $postage;
}
/**
* @param $ref
*/
public function setRef($ref)
{
$this->ref = $ref;
}
/**
* @return null|Order
*/
@@ -84,15 +117,23 @@ class OrderEvent extends ActionEvent
}
/**
* @return array|mixed|Address
* @return null|Order
*/
public function getBillingAddress()
public function getPlacedOrder()
{
return $this->billingAddress;
return $this->placedOrder;
}
/**
* @return array|mixed|Address
* @return null|int
*/
public function getInvoiceAddress()
{
return $this->invoiceAddress;
}
/**
* @return null|int
*/
public function getDeliveryAddress()
{
@@ -100,10 +141,34 @@ class OrderEvent extends ActionEvent
}
/**
* @return array|mixed|Address
* @return null|int
*/
public function getDeliveryModule()
{
return $this->deliveryModule;
}
/**
* @return null|int
*/
public function getPaymentModule()
{
return $this->paymentModule;
}
/**
* @return null|int
*/
public function getPostage()
{
return $this->postage;
}
/**
* @return null|int
*/
public function getRef()
{
return $this->ref;
}
}

View File

@@ -0,0 +1,48 @@
<?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\Product;
class ProductAddAccessoryEvent extends ProductEvent
{
protected $accessory_id;
public function __construct(Product $product, $accessory_id)
{
parent::__construct($product);
$this->accessory_id = $accessory_id;
}
public function getAccessoryId()
{
return $this->accessory_id;
}
public function setAccessoryId($accessory_id)
{
$this->accessory_id = $accessory_id;
}
}

View File

@@ -0,0 +1,48 @@
<?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\Product;
class ProductAddCategoryEvent extends ProductEvent
{
protected $category_id;
public function __construct(Product $product, $category_id)
{
parent::__construct($product);
$this->category_id = $category_id;
}
public function getCategoryId()
{
return $this->category_id;
}
public function setCategoryId($category_id)
{
$this->category_id = $category_id;
}
}

View File

@@ -0,0 +1,54 @@
<?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\ProductAssociatedContent;
use Thelia\Core\Event\ActionEvent;
class ProductAssociatedContentEvent extends ActionEvent
{
public $content = null;
public function __construct(ProductAssociatedContent $content = null)
{
$this->content = $content;
}
public function hasProductAssociatedContent()
{
return ! is_null($this->content);
}
public function getProductAssociatedContent()
{
return $this->content;
}
public function setProductAssociatedContent(ProductAssociatedContent $content)
{
$this->content = $content;
return $this;
}
}

View File

@@ -0,0 +1,64 @@
<?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\Product;
class ProductCreateCombinationEvent extends ProductEvent
{
protected $attribute_av_list;
protected $currency_id;
public function __construct(Product $product, $attribute_av_list, $currency_id)
{
parent::__construct($product);
$this->attribute_av_list = $attribute_av_list;
$this->currency_id = $currency_id;
}
public function getAttributeAvList()
{
return $this->attribute_av_list;
}
public function setAttributeAvList($attribute_av_list)
{
$this->attribute_av_list = $attribute_av_list;
return $this;
}
public function getCurrencyId()
{
return $this->currency_id;
}
public function setCurrencyId($currency_id)
{
$this->currency_id = $currency_id;
return $this;
}
}

View File

@@ -25,11 +25,28 @@ namespace Thelia\Core\Event;
class ProductCreateEvent extends ProductEvent
{
protected $ref;
protected $title;
protected $parent;
protected $locale;
protected $default_category;
protected $visible;
protected $basePrice;
protected $baseWeight;
protected $taxRuleId;
protected $currencyId;
public function getRef()
{
return $this->ref;
}
public function setRef($ref)
{
$this->ref = $ref;
return $this;
}
public function getTitle()
{
return $this->title;
@@ -38,19 +55,6 @@ class ProductCreateEvent extends ProductEvent
public function setTitle($title)
{
$this->title = $title;
return $this;
}
public function getParent()
{
return $this->parent;
}
public function setParent($parent)
{
$this->parent = $parent;
return $this;
}
@@ -62,7 +66,17 @@ class ProductCreateEvent extends ProductEvent
public function setLocale($locale)
{
$this->locale = $locale;
return $this;
}
public function getDefaultCategory()
{
return $this->default_category;
}
public function setDefaultCategory($default_category)
{
$this->default_category = $default_category;
return $this;
}
@@ -74,7 +88,50 @@ class ProductCreateEvent extends ProductEvent
public function setVisible($visible)
{
$this->visible = $visible;
return $this;
}
public function getBasePrice()
{
return $this->basePrice;
}
public function setBasePrice($basePrice)
{
$this->basePrice = $basePrice;
return $this;
}
public function getBaseWeight()
{
return $this->baseWeight;
}
public function setBaseWeight($baseWeight)
{
$this->baseWeight = $baseWeight;
return $this;
}
public function getTaxRuleId()
{
return $this->taxRuleId;
}
public function setTaxRuleId($taxRuleId)
{
$this->taxRuleId = $taxRuleId;
return $this;
}
public function getCurrencyId()
{
return $this->currencyId;
}
public function setCurrencyId($currencyId)
{
$this->currencyId = $currencyId;
return $this;
}
}

View File

@@ -0,0 +1,48 @@
<?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\Product;
class ProductDeleteAccessoryEvent extends ProductEvent
{
protected $accessory_id;
public function __construct(Product $product, $accessory_id)
{
parent::__construct($product);
$this->accessory_id = $accessory_id;
}
public function getAccessoryId()
{
return $this->accessory_id;
}
public function setAccessoryId($accessory_id)
{
$this->accessory_id = $accessory_id;
}
}

View File

@@ -0,0 +1,50 @@
<?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\Product;
class ProductDeleteCategoryEvent extends ProductEvent
{
protected $category_id;
public function __construct(Product $product, $category_id)
{
parent::__construct($product);
$this->category_id = $category_id;
}
public function getCategoryId()
{
return $this->category_id;
}
public function setCategoryId($category_id)
{
$this->category_id = $category_id;
return $this;
}
}

View File

@@ -0,0 +1,47 @@
<?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\Product;
class ProductDeleteCombinationEvent extends ProductEvent
{
protected $product_sale_element_id;
public function __construct(Product $product, $product_sale_element_id)
{
parent::__construct($product);
$this->product_sale_element_id = $product_sale_element_id;
}
public function getProductSaleElementId()
{
return $this->product_sale_element_id;
}
public function setProductSaleElementId($product_sale_element_id)
{
$this->product_sale_element_id = $product_sale_element_id;
}
}

View File

@@ -0,0 +1,51 @@
<?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\Product;
use Thelia\Core\Event\ActionEvent;
class ProductSetTemplateEvent extends ProductEvent
{
public $template_id = null;
public function __construct(Product $product = null, $template_id)
{
parent::__construct($product);
$this->template_id = $template_id;
}
public function getTemplateId()
{
return $this->template_id;
}
public function setTemplateId($template_id)
{
$this->template_id = $template_id;
return $this;
}
}

View File

@@ -165,6 +165,57 @@ final class TheliaEvents
const BEFORE_UPDATECATEGORY = "action.before_updateCategory";
const AFTER_UPDATECATEGORY = "action.after_updateCategory";
// -- folder management -----------------------------------------------
const FOLDER_CREATE = "action.createFolder";
const FOLDER_UPDATE = "action.updateFolder";
const FOLDER_DELETE = "action.deleteFolder";
const FOLDER_TOGGLE_VISIBILITY = "action.toggleFolderVisibility";
const FOLDER_UPDATE_POSITION = "action.updateFolderPosition";
// const FOLDER_ADD_CONTENT = "action.categoryAddContent";
// const FOLDER_REMOVE_CONTENT = "action.categoryRemoveContent";
const BEFORE_CREATEFOLDER = "action.before_createFolder";
const AFTER_CREATEFOLDER = "action.after_createFolder";
const BEFORE_DELETEFOLDER = "action.before_deleteFolder";
const AFTER_DELETEFOLDER = "action.after_deleteFolder";
const BEFORE_UPDATEFOLDER = "action.before_updateFolder";
const AFTER_UPDATEFOLDER = "action.after_updateFolder";
// -- content management -----------------------------------------------
const CONTENT_CREATE = "action.createContent";
const CONTENT_UPDATE = "action.updateContent";
const CONTENT_DELETE = "action.deleteContent";
const CONTENT_TOGGLE_VISIBILITY = "action.toggleContentVisibility";
const CONTENT_UPDATE_POSITION = "action.updateContentPosition";
// const FOLDER_ADD_CONTENT = "action.categoryAddContent";
// const FOLDER_REMOVE_CONTENT = "action.categoryRemoveContent";
const BEFORE_CREATECONTENT = "action.before_createContent";
const AFTER_CREATECONTENT = "action.after_createContent";
const BEFORE_DELETECONTENT = "action.before_deleteContent";
const AFTER_DELETECONTENT = "action.after_deleteContent";
const BEFORE_UPDATECONTENT = "action.before_updateContent";
const AFTER_UPDATECONTENT = "action.after_updateContent";
// -- Categories Associated Content ----------------------------------------
const BEFORE_CREATECATEGORY_ASSOCIATED_CONTENT = "action.before_createCategoryAssociatedContent";
const AFTER_CREATECATEGORY_ASSOCIATED_CONTENT = "action.after_createCategoryAssociatedContent";
const BEFORE_DELETECATEGORY_ASSOCIATED_CONTENT = "action.before_deleteCategoryAssociatedContent";
const AFTER_DELETECATEGORY_ASSOCIATED_CONTENT = "action.after_deleteCategoryAssociatedContent";
const BEFORE_UPDATECATEGORY_ASSOCIATED_CONTENT = "action.before_updateCategoryAssociatedContent";
const AFTER_UPDATECATEGORY_ASSOCIATED_CONTENT = "action.after_updateCategoryAssociatedContent";
// -- Product management -----------------------------------------------
const PRODUCT_CREATE = "action.createProduct";
@@ -173,8 +224,24 @@ final class TheliaEvents
const PRODUCT_TOGGLE_VISIBILITY = "action.toggleProductVisibility";
const PRODUCT_UPDATE_POSITION = "action.updateProductPosition";
const PRODUCT_ADD_CONTENT = "action.productAddContent";
const PRODUCT_REMOVE_CONTENT = "action.productRemoveContent";
const PRODUCT_ADD_CONTENT = "action.productAddContent";
const PRODUCT_REMOVE_CONTENT = "action.productRemoveContent";
const PRODUCT_UPDATE_CONTENT_POSITION = "action.updateProductContentPosition";
const PRODUCT_ADD_COMBINATION = "action.productAddCombination";
const PRODUCT_DELETE_COMBINATION = "action.productDeleteCombination";
const PRODUCT_SET_TEMPLATE = "action.productSetTemplate";
const PRODUCT_ADD_ACCESSORY = "action.productAddProductAccessory";
const PRODUCT_REMOVE_ACCESSORY = "action.productRemoveProductAccessory";
const PRODUCT_UPDATE_ACCESSORY_POSITION = "action.updateProductAccessoryPosition";
const PRODUCT_FEATURE_UPDATE_VALUE = "action.updateProductFeatureValue";
const PRODUCT_FEATURE_DELETE_VALUE = "action.deleteProductFeatureValue";
const PRODUCT_ADD_CATEGORY = "action.addProductCategory";
const PRODUCT_REMOVE_CATEGORY = "action.deleteProductCategory";
const BEFORE_CREATEPRODUCT = "action.before_createproduct";
const AFTER_CREATEPRODUCT = "action.after_createproduct";
@@ -185,6 +252,39 @@ final class TheliaEvents
const BEFORE_UPDATEPRODUCT = "action.before_updateProduct";
const AFTER_UPDATEPRODUCT = "action.after_updateProduct";
// -- Product Accessories --------------------------------------------------
const BEFORE_CREATEACCESSORY = "action.before_createAccessory";
const AFTER_CREATEACCESSORY = "action.after_createAccessory";
const BEFORE_DELETEACCESSORY = "action.before_deleteAccessory";
const AFTER_DELETEACCESSORY = "action.after_deleteAccessory";
const BEFORE_UPDATEACCESSORY = "action.before_updateAccessory";
const AFTER_UPDATEACCESSORY = "action.after_updateAccessory";
// -- Product Associated Content -------------------------------------------
const BEFORE_CREATEPRODUCT_ASSOCIATED_CONTENT = "action.before_createProductAssociatedContent";
const AFTER_CREATEPRODUCT_ASSOCIATED_CONTENT = "action.after_createProductAssociatedContent";
const BEFORE_DELETEPRODUCT_ASSOCIATED_CONTENT = "action.before_deleteProductAssociatedContent";
const AFTER_DELETEPRODUCT_ASSOCIATED_CONTENT = "action.after_deleteProductAssociatedContent";
const BEFORE_UPDATEPRODUCT_ASSOCIATED_CONTENT = "action.before_updateProductAssociatedContent";
const AFTER_UPDATEPRODUCT_ASSOCIATED_CONTENT = "action.after_updateProductAssociatedContent";
// -- Feature product ------------------------------------------------------
const BEFORE_CREATEFEATURE_PRODUCT = "action.before_createFeatureProduct";
const AFTER_CREATEFEATURE_PRODUCT = "action.after_createFeatureProduct";
const BEFORE_DELETEFEATURE_PRODUCT = "action.before_deleteFeatureProduct";
const AFTER_DELETEFEATURE_PRODUCT = "action.after_deleteFeatureProduct";
const BEFORE_UPDATEFEATURE_PRODUCT = "action.before_updateFeatureProduct";
const AFTER_UPDATEFEATURE_PRODUCT = "action.after_updateFeatureProduct";
/**
* sent when a new existing cat id duplicated. This append when current customer is different from current cart
*/
@@ -215,9 +315,17 @@ final class TheliaEvents
/**
* Order linked event
*/
const ORDER_SET_BILLING_ADDRESS = "action.order.setBillingAddress";
const ORDER_SET_DELIVERY_ADDRESS = "action.order.setDeliveryAddress";
const ORDER_SET_DELIVERY_MODULE = "action.order.setDeliveryModule";
const ORDER_SET_INVOICE_ADDRESS = "action.order.setInvoiceAddress";
const ORDER_SET_PAYMENT_MODULE = "action.order.setPaymentModule";
const ORDER_PAY = "action.order.pay";
const ORDER_BEFORE_CREATE = "action.order.beforeCreate";
const ORDER_AFTER_CREATE = "action.order.afterCreate";
const ORDER_BEFORE_PAYMENT = "action.order.beforePayment";
const ORDER_PRODUCT_BEFORE_CREATE = "action.orderProduct.beforeCreate";
const ORDER_PRODUCT_AFTER_CREATE = "action.orderProduct.afterCreate";
/**
* Sent on image processing
@@ -229,11 +337,46 @@ 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
*/
const IMAGE_CLEAR_CACHE = "action.clearImageCache";
/**
* Save given images
*/
const IMAGE_SAVE = "action.saveImages";
/**
* Save given images
*/
const IMAGE_UPDATE = "action.updateImages";
/**
* Delete given image
*/
const IMAGE_DELETE = "action.deleteImage";
/**
* Sent when creating a Coupon
*/
@@ -344,6 +487,7 @@ final class TheliaEvents
const AFTER_DELETECURRENCY = "action.after_deleteCurrency";
const CHANGE_DEFAULT_CURRENCY = 'action.changeDefaultCurrency';
// -- Product templates management -----------------------------------------
const TEMPLATE_CREATE = "action.createTemplate";
@@ -356,6 +500,9 @@ final class TheliaEvents
const TEMPLATE_ADD_FEATURE = "action.templateAddFeature";
const TEMPLATE_DELETE_FEATURE = "action.templateDeleteFeature";
const TEMPLATE_CHANGE_FEATURE_POSITION = "action.templateChangeAttributePosition";
const TEMPLATE_CHANGE_ATTRIBUTE_POSITION = "action.templateChangeFeaturePosition";
const BEFORE_CREATETEMPLATE = "action.before_createTemplate";
const AFTER_CREATETEMPLATE = "action.after_createTemplate";
@@ -441,4 +588,9 @@ final class TheliaEvents
*/
const MAILTRANSPORTER_CONFIG = 'action.mailertransporter.config';
/**
* sent when Thelia try to generate a rewriten url
*/
const GENERATE_REWRITTENURL = 'action.generate_rewritenurl';
}

View File

@@ -28,8 +28,10 @@ use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Router;
use Thelia\Core\Template\Exception\ResourceNotFoundException;
use Thelia\Core\Template\ParserInterface;
use Thelia\Exception\OrderException;
use Thelia\Tools\Redirect;
use Thelia\Tools\URL;
use Thelia\Core\Security\Exception\AuthenticationException;
@@ -77,16 +79,39 @@ class ViewListener implements EventSubscriberInterface
$content = $parser->getContent();
if ($content instanceof Response) {
$event->setResponse($content);
$response = $content;$event->setResponse($content);
} else {
$event->setResponse(new Response($content, $parser->getStatus() ?: 200));
$response = new Response($content, $parser->getStatus() ?: 200);
}
$response->setCache(array(
'last_modified' => new \DateTime(),
'max_age' => 600,
's_maxage' => 600,
'private' => false,
'public' => true,
));
$event->setResponse($response);
} catch (ResourceNotFoundException $e) {
$event->setResponse(new Response($e->getMessage(), 404));
} catch (AuthenticationException $ex) {
// Redirect to the login template
Redirect::exec($this->container->get('thelia.url.manager')->viewUrl($ex->getLoginTemplate()));
} catch (OrderException $e) {
switch($e->getCode()) {
case OrderException::CART_EMPTY:
// Redirect to the cart template
Redirect::exec($this->container->get('router.chainRequest')->generate($e->cartRoute, $e->arguments, Router::ABSOLUTE_URL));
break;
case OrderException::UNDEFINED_DELIVERY:
// Redirect to the delivery choice template
Redirect::exec($this->container->get('router.chainRequest')->generate($e->orderDeliveryRoute, $e->arguments, Router::ABSOLUTE_URL));
break;
}
throw $e;
}
}

View File

@@ -65,23 +65,6 @@ class Session extends BaseSession
return $this;
}
public function getAdminEditionLang()
{
$lang = $this->get('thelia.admin.edition.lang');
if (null === $lang) {
$lang = Lang::getDefaultLanguage();
}
return $lang;
}
public function setAdminEditionLang($langId)
{
$this->set('thelia.admin.edition.lang', $langId);
return $this;
}
public function setCurrency(Currency $currency)
{
$this->set("thelia.current.currency", $currency);
@@ -98,6 +81,43 @@ class Session extends BaseSession
return $currency;
}
// -- Admin lang and currency ----------------------------------------------
public function getAdminEditionCurrency()
{
$currency = $this->get('thelia.admin.edition.currency', null);
if (null === $currency) {
$currency = Currency::getDefaultCurrency();
}
return $currency;
}
public function setAdminEditionCurrency($currencyId)
{
$this->set('thelia.admin.edition.currency', $currencyId);
return $this;
}
public function getAdminEditionLang()
{
$lang = $this->get('thelia.admin.edition.lang');
if (null === $lang) {
$lang = Lang::getDefaultLanguage();
}
return $lang;
}
public function setAdminEditionLang($lang)
{
$this->set('thelia.admin.edition.lang', $lang);
return $this;
}
// -- Customer user --------------------------------------------------------
public function setCustomerUser(UserInterface $user)
@@ -218,6 +238,9 @@ class Session extends BaseSession
return $this;
}
/**
* @return Order
*/
public function getOrder()
{
return $this->get("thelia.order");

View File

@@ -128,7 +128,7 @@ class RewritingRouter implements RouterInterface, RequestMatcherInterface
*/
public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH)
{
// TODO: Implement generate() method.
throw new RouteNotFoundException();
}
/**

View File

@@ -65,6 +65,8 @@ abstract class BaseI18nLoop extends BaseLoop
{
/* manage translations */
$fr = $this->getForce_return();
return ModelCriteriaTools::getI18n(
$this->getBackend_context(),
$this->getLang(),

View File

@@ -74,6 +74,7 @@ class Accessory extends Product
$search = AccessoryQuery::create();
$product = $this->getProduct();
$search->filterByProductId($product, Criteria::IN);
$order = $this->getOrder();
@@ -93,8 +94,16 @@ class Accessory extends Product
$accessories = $this->search($search);
$accessoryIdList = array(0);
$accessoryPosition = $accessoryId = array();
foreach ($accessories as $accessory) {
array_push($accessoryIdList, $accessory->getAccessory());
$accessoryProductId = $accessory->getAccessory();
array_push($accessoryIdList, $accessoryProductId);
$accessoryPosition[$accessoryProductId] = $accessory->getPosition();
$accessoryId[$accessoryProductId] = $accessory->getId();
}
$receivedIdList = $this->getId();
@@ -106,7 +115,18 @@ class Accessory extends Product
$this->args->get('id')->setValue( implode(',', array_intersect($receivedIdList, $accessoryIdList)) );
}
return parent::exec($pagination);
}
$loopResult = parent::exec($pagination);
foreach($loopResult as $loopResultRow) {
$accessoryProductId = $loopResultRow->get('ID');
$loopResultRow
->set("ID" , $accessoryId[$accessoryProductId])
->set("POSITION", $accessoryPosition[$accessoryProductId])
;
}
return $loopResult;
}
}

View File

@@ -54,7 +54,13 @@ class Address extends BaseLoop
protected function getArgDefinitions()
{
return new ArgumentCollection(
Argument::createIntListTypeArgument('id'),
new Argument(
'id',
new TypeCollection(
new Type\IntListType(),
new Type\EnumType(array('*', 'any'))
)
),
new Argument(
'customer',
new TypeCollection(
@@ -63,8 +69,14 @@ class Address extends BaseLoop
),
'current'
),
Argument::createBooleanTypeArgument('default'),
Argument::createIntListTypeArgument('exclude')
Argument::createBooleanOrBothTypeArgument('default'),
new Argument(
'exclude',
new TypeCollection(
new Type\IntListType(),
new Type\EnumType(array('none'))
)
)
);
}
@@ -79,7 +91,7 @@ class Address extends BaseLoop
$id = $this->getId();
if (null !== $id) {
if (null !== $id && !in_array($id, array('*', 'any'))) {
$search->filterById($id, Criteria::IN);
}
@@ -106,7 +118,7 @@ class Address extends BaseLoop
$exclude = $this->getExclude();
if (!is_null($exclude)) {
if (null !== $exclude && 'none' !== $exclude) {
$search->filterById($exclude, Criteria::NOT_IN);
}

View File

@@ -58,7 +58,19 @@ class Argument
public function setValue($value)
{
$this->value = $value === null ? null : (string) $value;
$x = $value === null;
if($value === null) {
$this->value = null;
} else {
if(false === $value) {
/* (string) $value = "" */
$this->value = 0;
} else {
$this->value = (string) $value;
}
}
//$this->value = $value === null ? null : (string) $value;
}
public static function createAnyTypeArgument($name, $default=null, $mandatory=false, $empty=true)

View File

@@ -97,9 +97,9 @@ class AssociatedContent extends Content
$exclude_product = $this->getExcludeProduct();
// If we have to filter by template, find all attributes assigned to this template, and filter by found IDs
// If we have to filter by product, find all products assigned to this product, and filter by found IDs
if (null !== $exclude_product) {
// Exclure tous les attribut qui sont attachés aux templates indiqués
// Exclude all contents related to the given product
$search->filterById(
ProductAssociatedContentQuery::create()->filterByProductId($exclude_product)->select('product_id')->find(),
Criteria::NOT_IN
@@ -108,7 +108,7 @@ class AssociatedContent extends Content
$exclude_category = $this->getExcludeCategory();
// If we have to filter by template, find all attributes assigned to this template, and filter by found IDs
// If we have to filter by category, find all contents assigned to this category, and filter by found IDs
if (null !== $exclude_category) {
// Exclure tous les attribut qui sont attachés aux templates indiqués
$search->filterById(
@@ -135,8 +135,17 @@ class AssociatedContent extends Content
$associatedContents = $this->search($search);
$associatedContentIdList = array(0);
$contentIdList = array(0);
$contentPosition = $contentId = array();
foreach ($associatedContents as $associatedContent) {
array_push($associatedContentIdList, $associatedContent->getContentId());
$associatedContentId = $associatedContent->getContentId();
array_push($associatedContentIdList, $associatedContentId);
$contentPosition[$associatedContentId] = $associatedContent->getPosition();
$contentId[$associatedContentId] = $associatedContent->getId();
}
$receivedIdList = $this->getId();
@@ -148,7 +157,18 @@ class AssociatedContent extends Content
$this->args->get('id')->setValue( implode(',', array_intersect($receivedIdList, $associatedContentIdList)) );
}
return parent::exec($pagination);
}
$loopResult = parent::exec($pagination);
foreach($loopResult as $loopResultRow) {
$relatedContentId = $loopResultRow->get('ID');
$loopResultRow
->set("ID" , $contentId[$relatedContentId])
->set("POSITION", $contentPosition[$relatedContentId])
;
}
return $loopResult;
}
}

View File

@@ -41,7 +41,8 @@ use Thelia\Type\BooleanOrBothType;
use Thelia\Model\ProductQuery;
use Thelia\Model\TemplateQuery;
use Thelia\Model\AttributeTemplateQuery;
use Thelia\Core\Translation\Translator;
use Thelia\Model\Map\AttributeTemplateTableMap;
/**
*
* Attribute loop
@@ -106,33 +107,50 @@ class Attribute extends BaseI18nLoop
$product = $this->getProduct();
$template = $this->getTemplate();
if (null !== $product) {
// Find the template assigned to the product.
$productObj = ProductQuery::create()->findPk($product);
// Ignore if the product cannot be found.
if ($productObj !== null)
$template = $productObj->getTemplate();
}
// If we have to filter by template, find all attributes assigned to this template, and filter by found IDs
if (null !== $template) {
$search->filterById(
AttributeTemplateQuery::create()->filterByTemplateId($template)->select('attribute_id')->find(),
Criteria::IN
);
}
$exclude_template = $this->getExcludeTemplate();
// If we have to filter by template, find all attributes assigned to this template, and filter by found IDs
if (null !== $exclude_template) {
// Exclure tous les attribut qui sont attachés aux templates indiqués
$search->filterById(
AttributeTemplateQuery::create()->filterByTemplateId($exclude_template)->select('attribute_id')->find(),
Criteria::NOT_IN
);
$use_attribute_pos = true;
if (null !== $product) {
// Find all template assigned to the products.
$products = ProductQuery::create()->findById($product);
// Ignore if the product cannot be found.
if ($products !== null) {
// Create template array
if ($template == null) $template = array();
foreach($products as $product) {
$tpl_id = $product->getTemplateId();
if (! is_null($tpl_id)) $template[] = $tpl_id;
}
}
}
if (! empty($template)) {
// Join with feature_template table to get position
$search
->withColumn(AttributeTemplateTableMap::POSITION, 'position')
->filterByTemplate(TemplateQuery::create()->findById($template), Criteria::IN)
;
$use_attribute_pos = false;
}
else if (null !== $exclude_template) {
// Join with attribute_template table to get position
$exclude_attributes = AttributeTemplateQuery::create()->filterByTemplateId($exclude_template)->select('attribute_id')->find();
$search
->joinAttributeTemplate(null, Criteria::LEFT_JOIN)
->withColumn(AttributeTemplateTableMap::POSITION, 'position')
->filterById($exclude_attributes, Criteria::NOT_IN)
;
$use_attribute_pos = false;
}
$orders = $this->getOrder();
@@ -152,10 +170,16 @@ class Attribute extends BaseI18nLoop
$search->addDescendingOrderByColumn('i18n_TITLE');
break;
case "manual":
$search->orderByPosition(Criteria::ASC);
if ($use_attribute_pos)
$search->orderByPosition(Criteria::ASC);
else
$search->addAscendingOrderByColumn(AttributeTemplateTableMap::POSITION);
break;
case "manual_reverse":
$search->orderByPosition(Criteria::DESC);
if ($use_attribute_pos)
$search->orderByPosition(Criteria::DESC);
else
$search->addDescendingOrderByColumn(AttributeTemplateTableMap::POSITION);
break;
}
}
@@ -174,7 +198,8 @@ class Attribute extends BaseI18nLoop
->set("CHAPO", $attribute->getVirtualColumn('i18n_CHAPO'))
->set("DESCRIPTION", $attribute->getVirtualColumn('i18n_DESCRIPTION'))
->set("POSTSCRIPTUM", $attribute->getVirtualColumn('i18n_POSTSCRIPTUM'))
->set("POSITION", $attribute->getPosition());
->set("POSITION", $use_attribute_pos ? $attribute->getPosition() : $attribute->getVirtualColumn('position'))
;
$loopResult->addRow($loopResultRow);
}

View File

@@ -29,7 +29,6 @@ use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
use Thelia\Model\ModuleQuery;
/**
* Class Delivery
* @package Thelia\Core\Template\Loop
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
@@ -93,6 +92,8 @@ class BaseSpecificModule extends BaseI18nLoop
{
$search = ModuleQuery::create();
$search->filterByActivate(1);
if (null !== $id = $this->getId()) {
$search->filterById($id);
}

View File

@@ -81,6 +81,8 @@ class Cart extends BaseLoop
return $result;
}
$taxCountry = CountryQuery::create()->findPk(64); // @TODO : make it magic;
foreach ($cartItems as $cartItem) {
$product = $cartItem->getProduct();
$productSaleElement = $cartItem->getProductSaleElements();
@@ -97,12 +99,8 @@ class Cart extends BaseLoop
->set("STOCK", $productSaleElement->getQuantity())
->set("PRICE", $cartItem->getPrice())
->set("PROMO_PRICE", $cartItem->getPromoPrice())
->set("TAXED_PRICE", $cartItem->getTaxedPrice(
CountryQuery::create()->findOneById(64) // @TODO : make it magic
))
->set("PROMO_TAXED_PRICE", $cartItem->getTaxedPromoPrice(
CountryQuery::create()->findOneById(64) // @TODO : make it magic
))
->set("TAXED_PRICE", $cartItem->getTaxedPrice($taxCountry))
->set("PROMO_TAXED_PRICE", $cartItem->getTaxedPromoPrice($taxCountry))
->set("IS_PROMO", $cartItem->getPromo() === 1 ? 1 : 0);
$result->addRow($loopResultRow);
}
@@ -110,4 +108,13 @@ class Cart extends BaseLoop
return $result;
}
/**
* Return the event dispatcher,
*
* @return \Symfony\Component\EventDispatcher\EventDispatcher
*/
public function getDispatcher()
{
return $this->dispatcher;
}
}

View File

@@ -35,6 +35,7 @@ use Thelia\Model\CategoryQuery;
use Thelia\Type\TypeCollection;
use Thelia\Type;
use Thelia\Type\BooleanOrBothType;
use Thelia\Model\ProductQuery;
/**
*
@@ -73,6 +74,8 @@ class Category extends BaseI18nLoop
return new ArgumentCollection(
Argument::createIntListTypeArgument('id'),
Argument::createIntTypeArgument('parent'),
Argument::createIntTypeArgument('product'),
Argument::createIntTypeArgument('exclude_product'),
Argument::createBooleanTypeArgument('current'),
Argument::createBooleanTypeArgument('not_empty', 0),
Argument::createBooleanOrBothTypeArgument('visible', 1),
@@ -128,6 +131,22 @@ class Category extends BaseI18nLoop
if ($this->getVisible() != BooleanOrBothType::ANY)
$search->filterByVisible($this->getVisible() ? 1 : 0);
$product = $this->getProduct();
if ($product != null) {
$obj = ProductQuery::create()->findPk($product);
if ($obj != null) $search->filterByProduct($obj, Criteria::IN);
}
$exclude_product = $this->getExclude_product();
if ($exclude_product != null) {
$obj = ProductQuery::create()->findPk($exclude_product);
if ($obj != null) $search->filterByProduct($obj, Criteria::NOT_IN);
}
$orders = $this->getOrder();
foreach ($orders as $order) {
@@ -206,7 +225,8 @@ class Category extends BaseI18nLoop
->set("POSTSCRIPTUM", $category->getVirtualColumn('i18n_POSTSCRIPTUM'))
->set("PARENT", $category->getParent())
->set("URL", $category->getUrl($locale))
->set("PRODUCT_COUNT", $category->countChild())
->set("PRODUCT_COUNT", $category->countAllProducts())
->set("CHILD_COUNT", $category->countChild())
->set("VISIBLE", $category->getVisible() ? "1" : "0")
->set("POSITION", $category->getPosition())

View File

@@ -59,7 +59,7 @@ class CategoryTree extends BaseI18nLoop
}
// changement de rubrique
protected function buildCategoryTree($parent, $visible, $level, $max_level, $exclude, LoopResult &$loopResult)
protected function buildCategoryTree($parent, $visible, $level, $previousLevel, $max_level, $exclude, LoopResult &$loopResult)
{
if ($level > $max_level) return;
@@ -87,11 +87,12 @@ class CategoryTree extends BaseI18nLoop
->set("ID", $result->getId())->set("TITLE", $result->getVirtualColumn('i18n_TITLE'))
->set("PARENT", $result->getParent())->set("URL", $result->getUrl($locale))
->set("VISIBLE", $result->getVisible() ? "1" : "0")->set("LEVEL", $level)
->set('CHILD_COUNT', $result->countChild())->set('PREV_LEVEL', $previousLevel)
;
$loopResult->addRow($loopResultRow);
$this->buildCategoryTree($result->getId(), $visible, 1 + $level, $max_level, $exclude, $loopResult);
$this->buildCategoryTree($result->getId(), $visible, 1 + $level, $level, $max_level, $exclude, $loopResult);
}
}
@@ -109,7 +110,7 @@ class CategoryTree extends BaseI18nLoop
$loopResult = new LoopResult();
$this->buildCategoryTree($id, $visible, 0, $depth, $exclude, $loopResult);
$this->buildCategoryTree($id, $visible, 0, 0, $depth, $exclude, $loopResult);
return $loopResult;
}

View File

@@ -234,7 +234,9 @@ class Content extends BaseI18nLoop
->set("DESCRIPTION", $content->getVirtualColumn('i18n_DESCRIPTION'))
->set("POSTSCRIPTUM", $content->getVirtualColumn('i18n_POSTSCRIPTUM'))
->set("POSITION", $content->getPosition())
->set("DEFAULT_FOLDER", $content->getDefaultFolderId())
->set("URL", $content->getUrl($locale))
->set("VISIBLE", $content->getVisible())
;
$loopResult->addRow($loopResultRow);

View File

@@ -87,7 +87,7 @@ class Country extends BaseI18nLoop
if (true === $withArea) {
$search->filterByAreaId(null, Criteria::ISNOTNULL);
} elseif (false == $withArea) {
} elseif (false === $withArea) {
$search->filterByAreaId(null, Criteria::ISNULL);
}

View File

@@ -89,7 +89,7 @@ class Delivery extends BaseSpecificModule
->set('CHAPO', $deliveryModule->getVirtualColumn('i18n_CHAPO'))
->set('DESCRIPTION', $deliveryModule->getVirtualColumn('i18n_DESCRIPTION'))
->set('POSTSCRIPTUM', $deliveryModule->getVirtualColumn('i18n_POSTSCRIPTUM'))
->set('PRICE', $moduleInstance->calculate($country))
->set('POSTAGE', $moduleInstance->getPostage($country))
;
$loopResult->addRow($loopResultRow);

View File

@@ -251,9 +251,9 @@ class Document extends BaseI18nLoop
$loopResultRow
->set("ID" , $result->getId())
->set("LOCALE" ,$locale)
->set("LOCALE" , $locale)
->set("DOCUMENT_URL" , $event->getFileUrl())
->set("DOCUMENT_PATH" , $event->getCacheFilepath())
->set("DOCUMENT_PATH" , $event->getDocumentPath())
->set("ORIGINAL_DOCUMENT_PATH", $source_filepath)
->set("TITLE" , $result->getVirtualColumn('i18n_TITLE'))
->set("CHAPO" , $result->getVirtualColumn('i18n_CHAPO'))

View File

@@ -31,14 +31,18 @@ use Thelia\Core\Template\Element\LoopResultRow;
use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Model\Base\CategoryQuery;
use Thelia\Model\Base\ProductCategoryQuery;
use Thelia\Model\Base\FeatureQuery;
use Thelia\Model\CategoryQuery;
use Thelia\Model\FeatureI18nQuery;
use Thelia\Model\ProductCategoryQuery;
use Thelia\Model\FeatureQuery;
use Thelia\Model\Map\ProductCategoryTableMap;
use Thelia\Model\ProductQuery;
use Thelia\Type\TypeCollection;
use Thelia\Type;
use Thelia\Type\BooleanOrBothType;
use Thelia\Model\FeatureTemplateQuery;
use Thelia\Model\TemplateQuery;
use Thelia\Model\Map\FeatureTemplateTableMap;
/**
*
@@ -68,10 +72,11 @@ class Feature extends BaseI18nLoop
new Argument(
'order',
new TypeCollection(
new Type\EnumListType(array('alpha', 'alpha-reverse', 'manual', 'manual_reverse'))
new Type\EnumListType(array('id', 'id_reverse', 'alpha', 'alpha-reverse', 'manual', 'manual_reverse'))
),
'manual'
)
),
Argument::createAnyTypeArgument('title')
);
}
@@ -105,39 +110,78 @@ class Feature extends BaseI18nLoop
$product = $this->getProduct();
$template = $this->getTemplate();
if (null !== $product) {
// Find the template assigned to the product.
$productObj = ProductQuery::create()->findPk($product);
// Ignore if the product cannot be found.
if ($productObj !== null)
$template = $productObj->getTemplate();
}
// If we have to filter by template, find all features assigned to this template, and filter by found IDs
if (null !== $template) {
$search->filterById(
FeatureTemplateQuery::create()->filterByTemplateId($template)->select('feature_id')->find(),
Criteria::IN
);
}
$exclude_template = $this->getExcludeTemplate();
// If we have to filter by template, find all features assigned to this template, and filter by found IDs
$use_feature_pos = true;
if (null !== $product) {
// Find all template assigned to the products.
$products = ProductQuery::create()->findById($product);
// Ignore if the product cannot be found.
if ($products !== null) {
// Create template array
if ($template == null) $template = array();
foreach($products as $product) {
$tpl_id = $product->getTemplateId();
if (! is_null($tpl_id)) $template[] = $tpl_id;
}
}
}
if (! empty($template)) {
// Join with feature_template table to get position
$search
->withColumn(FeatureTemplateTableMap::POSITION, 'position')
->filterByTemplate(TemplateQuery::create()->findById($template), Criteria::IN)
;
$use_feature_pos = false;
}
if (null !== $exclude_template) {
// Exclure tous les attribut qui sont attachés aux templates indiqués
$search->filterById(
FeatureTemplateQuery::create()->filterByTemplateId($exclude_template)->select('feature_id')->find(),
Criteria::NOT_IN
);
$exclude_features = FeatureTemplateQuery::create()->filterByTemplateId($exclude_template)->select('feature_id')->find();
$search
->joinFeatureTemplate(null, Criteria::LEFT_JOIN)
->withColumn(FeatureTemplateTableMap::POSITION, 'position')
->filterById($exclude_features, Criteria::NOT_IN)
;
$use_feature_pos = false;
}
$title = $this->getTitle();
if (null !== $title) {
//find all feature that match exactly this title and find with all locales.
$features = FeatureI18nQuery::create()
->filterByTitle($title, Criteria::LIKE)
->select('id')
->find();
if($features) {
$search->filterById(
$features,
Criteria::IN
);
}
}
$orders = $this->getOrder();
foreach ($orders as $order) {
switch ($order) {
case "id":
$search->orderById(Criteria::ASC);
break;
case "id_reverse":
$search->orderById(Criteria::DESC);
break;
case "alpha":
$search->addAscendingOrderByColumn('i18n_TITLE');
break;
@@ -145,14 +189,22 @@ class Feature extends BaseI18nLoop
$search->addDescendingOrderByColumn('i18n_TITLE');
break;
case "manual":
$search->orderByPosition(Criteria::ASC);
if ($use_feature_pos)
$search->orderByPosition(Criteria::ASC);
else
$search->addAscendingOrderByColumn(FeatureTemplateTableMap::POSITION);
break;
case "manual_reverse":
$search->orderByPosition(Criteria::DESC);
if ($use_feature_pos)
$search->orderByPosition(Criteria::DESC);
else
$search->addDescendingOrderByColumn(FeatureTemplateTableMap::POSITION);
break;
}
}
/* perform search */
$features = $this->search($search, $pagination);
@@ -167,7 +219,8 @@ class Feature extends BaseI18nLoop
->set("CHAPO", $feature->getVirtualColumn('i18n_CHAPO'))
->set("DESCRIPTION", $feature->getVirtualColumn('i18n_DESCRIPTION'))
->set("POSTSCRIPTUM", $feature->getVirtualColumn('i18n_POSTSCRIPTUM'))
->set("POSITION", $feature->getPosition());
->set("POSITION", $use_feature_pos ? $feature->getPosition() : $feature->getVirtualColumn('position'))
;
$loopResult->addRow($loopResultRow);
}

View File

@@ -59,7 +59,7 @@ class FeatureValue extends BaseI18nLoop
Argument::createIntTypeArgument('product', null, true),
Argument::createIntListTypeArgument('feature_availability'),
Argument::createBooleanTypeArgument('exclude_feature_availability', 0),
Argument::createBooleanTypeArgument('exclude_personal_values', 0),
Argument::createBooleanTypeArgument('exclude_free_text', 0),
new Argument(
'order',
new TypeCollection(
@@ -79,7 +79,7 @@ class FeatureValue extends BaseI18nLoop
{
$search = FeatureProductQuery::create();
/* manage featureAv translations */
// manage featureAv translations
$locale = $this->configureI18nProcessing(
$search,
array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'),
@@ -103,13 +103,9 @@ class FeatureValue extends BaseI18nLoop
}
$excludeFeatureAvailability = $this->getExclude_feature_availability();
if ($excludeFeatureAvailability == true) {
$search->filterByFeatureAvId(null, Criteria::NULL);
}
$excludeDefaultValues = $this->getExclude_personal_values();
if ($excludeDefaultValues == true) {
$search->filterByByDefault(null, Criteria::NULL);
if ($excludeFeatureAvailability == true) {
$search->filterByFeatureAvId(null, Criteria::ISNULL);
}
$orders = $this->getOrder();
@@ -136,17 +132,26 @@ class FeatureValue extends BaseI18nLoop
$loopResult = new LoopResult($featureValues);
foreach ($featureValues as $featureValue) {
$loopResultRow = new LoopResultRow($loopResult, $featureValue, $this->versionable, $this->timestampable, $this->countable);
$loopResultRow->set("ID", $featureValue->getId());
$loopResultRow
->set("LOCALE",$locale)
->set("PERSONAL_VALUE", $featureValue->getByDefault())
->set("TITLE",$featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_TITLE'))
->set("CHAPO", $featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_CHAPO'))
->set("DESCRIPTION", $featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_DESCRIPTION'))
->set("POSTSCRIPTUM", $featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_POSTSCRIPTUM'))
->set("POSITION", $featureValue->getPosition());
->set("ID" , $featureValue->getId())
->set("PRODUCT" , $featureValue->getProductId())
->set("FEATURE_AV_ID" , $featureValue->getFeatureAvId())
->set("FREE_TEXT_VALUE" , $featureValue->getFreeTextValue())
->set("IS_FREE_TEXT" , is_null($featureValue->getFeatureAvId()) ? 1 : 0)
->set("IS_FEATURE_AV" , is_null($featureValue->getFeatureAvId()) ? 0 : 1)
->set("LOCALE" , $locale)
->set("TITLE" , $featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_TITLE'))
->set("CHAPO" , $featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_CHAPO'))
->set("DESCRIPTION" , $featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_DESCRIPTION'))
->set("POSTSCRIPTUM" , $featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_POSTSCRIPTUM'))
->set("POSITION" , $featureValue->getPosition())
;
$loopResult->addRow($loopResultRow);
}

View File

@@ -162,7 +162,8 @@ class Folder extends BaseI18nLoop
->set("POSTSCRIPTUM", $folder->getVirtualColumn('i18n_POSTSCRIPTUM'))
->set("PARENT", $folder->getParent())
->set("URL", $folder->getUrl($locale))
->set("CONTENT_COUNT", $folder->countChild())
->set("CHILD_COUNT", $folder->countChild())
->set("CONTENT_COUNT", $folder->countAllContents())
->set("VISIBLE", $folder->getVisible() ? "1" : "0")
->set("POSITION", $folder->getPosition())
;

View File

@@ -0,0 +1,118 @@
<?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\Loop;
use Propel\Runtime\ActiveQuery\Criteria;
use Thelia\Core\Template\Element\LoopResult;
use Thelia\Core\Template\Element\LoopResultRow;
use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Model\FolderQuery;
use Thelia\Type;
use Thelia\Type\BooleanOrBothType;
use Thelia\Core\Template\Element\BaseI18nLoop;
/**
*
* Folder tree loop, to get a folder tree from a given folder to a given depth.
*
* - folder is the folder id
* - depth is the maximum depth to go, default unlimited
* - visible if true or missing, only visible categories will be displayed. If false, all categories (visible or not) are returned.
*
* @package Thelia\Core\Template\Loop
* @author Franck Allimant <franck@cqfdev.fr>
*/
class FolderTree extends BaseI18nLoop
{
/**
* @return ArgumentCollection
*/
protected function getArgDefinitions()
{
return new ArgumentCollection(
Argument::createIntTypeArgument('folder', null, true),
Argument::createIntTypeArgument('depth', PHP_INT_MAX),
Argument::createBooleanOrBothTypeArgument('visible', true, false),
Argument::createIntListTypeArgument('exclude', array())
);
}
// changement de rubrique
protected function buildFolderTree($parent, $visible, $level, $max_level, $exclude, LoopResult &$loopResult)
{
if ($level > $max_level) return;
$search = FolderQuery::create();
$locale = $this->configureI18nProcessing($search, array(
'TITLE'
));
$search->filterByParent($parent);
if ($visible != BooleanOrBothType::ANY) $search->filterByVisible($visible);
if ($exclude != null) $search->filterById($exclude, Criteria::NOT_IN);
$search->orderByPosition(Criteria::ASC);
$results = $search->find();
foreach ($results as $result) {
$loopResultRow = new LoopResultRow();
$loopResultRow
->set("ID", $result->getId())->set("TITLE", $result->getVirtualColumn('i18n_TITLE'))
->set("PARENT", $result->getParent())->set("URL", $result->getUrl($locale))
->set("VISIBLE", $result->getVisible() ? "1" : "0")->set("LEVEL", $level)
;
$loopResult->addRow($loopResultRow);
$this->buildFolderTree($result->getId(), $visible, 1 + $level, $max_level, $exclude, $loopResult);
}
}
/**
* @param $pagination (ignored)
*
* @return \Thelia\Core\Template\Element\LoopResult
*/
public function exec(&$pagination)
{
$id = $this->getFolder();
$depth = $this->getDepth();
$visible = $this->getVisible();
$exclude = $this->getExclude();
$loopResult = new LoopResult();
$this->buildFolderTree($id, $visible, 0, $depth, $exclude, $loopResult);
return $loopResult;
}
}

View File

@@ -48,7 +48,7 @@ class Image extends BaseI18nLoop
/**
* @var array Possible image sources
*/
protected $possible_sources = array('category', 'product', 'folder', 'content');
protected $possible_sources = array('category', 'product', 'folder', 'content', 'module');
/**
* @return \Thelia\Core\Template\Loop\Argument\ArgumentCollection
@@ -93,7 +93,8 @@ class Image extends BaseI18nLoop
new EnumType($this->possible_sources)
)
),
Argument::createIntTypeArgument('source_id')
Argument::createIntTypeArgument('source_id'),
Argument::createBooleanTypeArgument('force_return', true)
);
// Add possible image sources
@@ -175,7 +176,7 @@ class Image extends BaseI18nLoop
$source_id = $this->getSourceId();
$id = $this->getId();
//echo "source = ".$this->getSource()."source_id=$source_id, id=$id<br />";
//echo "source = ".$this->getSourceId()."source_id=$source_id, id=$id<br />";
if (is_null($source_id) && is_null($id)) {
throw new \InvalidArgumentException("If 'source' argument is specified, 'id' or 'source_id' argument should be specified");
@@ -214,6 +215,7 @@ class Image extends BaseI18nLoop
*/
public function exec(&$pagination)
{
// Select the proper query to use, and get the object type
$object_type = $object_id = null;
@@ -262,13 +264,14 @@ class Image extends BaseI18nLoop
}
//echo "sql=".$search->toString();
// echo "sql=".$search->toString();
$results = $this->search($search, $pagination);
$loopResult = new LoopResult($results);
foreach ($results as $result) {
// Create image processing event
$event = new ImageEvent($this->request);
@@ -315,7 +318,8 @@ class Image extends BaseI18nLoop
;
$loopResult->addRow($loopResultRow);
} catch (\Exception $ex) {
}
catch (\Exception $ex) {
// Ignore the result and log an error
Tlog::getInstance()->addError("Failed to process image in image loop: ", $this->args);
}

View File

@@ -0,0 +1,137 @@
<?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\Loop;
use Propel\Runtime\ActiveQuery\Criteria;
use Thelia\Core\Template\Element\BaseI18nLoop;
use Thelia\Core\Template\Element\LoopResult;
use Thelia\Core\Template\Element\LoopResultRow;
use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Model\ModuleQuery;
use Thelia\Module\BaseModule;
use Thelia\Type;
/**
*
* Module loop
*
*
* Class Module
* @package Thelia\Core\Template\Loop
* @author Etienne Roudeix <eroudeix@openstudio.fr>
*/
class Module extends BaseI18nLoop
{
public $timestampable = true;
/**
* @return ArgumentCollection
*/
protected function getArgDefinitions()
{
return new ArgumentCollection(
Argument::createIntListTypeArgument('id'),
new Argument(
'module_type',
new Type\TypeCollection(
new Type\EnumListType(array(
BaseModule::CLASSIC_MODULE_TYPE,
BaseModule::DELIVERY_MODULE_TYPE,
BaseModule::PAYMENT_MODULE_TYPE,
))
)
),
Argument::createIntListTypeArgument('exclude'),
Argument::createBooleanOrBothTypeArgument('active', Type\BooleanOrBothType::ANY)
);
}
/**
* @param $pagination
*
* @return \Thelia\Core\Template\Element\LoopResult
*/
public function exec(&$pagination)
{
$search = ModuleQuery::create();
/* manage translations */
$locale = $this->configureI18nProcessing($search);
$id = $this->getId();
if (null !== $id) {
$search->filterById($id, Criteria::IN);
}
$moduleType = $this->getModule_type();
if (null !== $moduleType) {
$search->filterByType($moduleType, Criteria::IN);
}
$exclude = $this->getExclude();
if (!is_null($exclude)) {
$search->filterById($exclude, Criteria::NOT_IN);
}
$active = $this->getActive();
if($active !== Type\BooleanOrBothType::ANY) {
$search->filterByActivate($active ? 1 : 0, Criteria::EQUAL);
}
$search->orderByPosition();
/* perform search */
$modules = $this->search($search, $pagination);
$loopResult = new LoopResult($modules);
foreach ($modules as $module) {
$loopResultRow = new LoopResultRow($loopResult, $module, $this->versionable, $this->timestampable, $this->countable);
$loopResultRow->set("ID", $module->getId())
->set("IS_TRANSLATED",$module->getVirtualColumn('IS_TRANSLATED'))
->set("LOCALE",$locale)
->set("TITLE",$module->getVirtualColumn('i18n_TITLE'))
->set("CHAPO", $module->getVirtualColumn('i18n_CHAPO'))
->set("DESCRIPTION", $module->getVirtualColumn('i18n_DESCRIPTION'))
->set("POSTSCRIPTUM", $module->getVirtualColumn('i18n_POSTSCRIPTUM'))
->set("CODE", $module->getCode())
->set("TYPE", $module->getType())
->set("ACTIVE", $module->getActivate())
->set("CLASS", $module->getFullNamespace())
->set("POSITION", $module->getPosition());
$loopResult->addRow($loopResultRow);
}
return $loopResult;
}
}

View File

@@ -23,12 +23,16 @@
namespace Thelia\Core\Template\Loop;
use Propel\Runtime\ActiveQuery\Criteria;
use Thelia\Core\Template\Element\BaseLoop;
use Thelia\Core\Template\Element\LoopResult;
use Thelia\Core\Template\Element\LoopResultRow;
use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Model\OrderQuery;
use Thelia\Type\TypeCollection;
use Thelia\Type;
/**
*
* @package Thelia\Core\Template\Loop
@@ -37,19 +41,94 @@ use Thelia\Core\Template\Loop\Argument\Argument;
*/
class Order extends BaseLoop
{
public $countable = true;
public $timestampable = true;
public $versionable = false;
public function getArgDefinitions()
{
return new ArgumentCollection();
return new ArgumentCollection(
Argument::createIntListTypeArgument('id'),
new Argument(
'customer',
new TypeCollection(
new Type\IntType(),
new Type\EnumType(array('current'))
),
'current'
),
Argument::createIntListTypeArgument('status')
);
}
/**
* @param $pagination
*
*
* @return \Thelia\Core\Template\Element\LoopResult
* @return LoopResult
*/
public function exec(&$pagination)
{
// TODO : a coder !
return new LoopResult();
$search = OrderQuery::create();
$id = $this->getId();
if (null !== $id) {
$search->filterById($id, Criteria::IN);
}
$customer = $this->getCustomer();
if ($customer === 'current') {
$currentCustomer = $this->securityContext->getCustomerUser();
if ($currentCustomer === null) {
return new LoopResult();
} else {
$search->filterByCustomerId($currentCustomer->getId(), Criteria::EQUAL);
}
} else {
$search->filterByCustomerId($customer, Criteria::EQUAL);
}
$status = $this->getStatus();
if (null !== $status) {
$search->filterByStatusId($status, Criteria::IN);
}
$orders = $this->search($search, $pagination);
$loopResult = new LoopResult($orders);
foreach ($orders as $order) {
$tax = 0;
$amount = $order->getTotalAmount($tax);
$loopResultRow = new LoopResultRow($loopResult, $order, $this->versionable, $this->timestampable, $this->countable);
$loopResultRow
->set("ID", $order->getId())
->set("REF", $order->getRef())
->set("CUSTOMER", $order->getCustomerId())
->set("DELIVERY_ADDRESS", $order->getDeliveryOrderAddressId())
->set("INVOICE_ADDRESS", $order->getInvoiceOrderAddressId())
->set("INVOICE_DATE", $order->getInvoiceDate())
->set("CURRENCY", $order->getCurrencyId())
->set("CURRENCY_RATE", $order->getCurrencyRate())
->set("TRANSACTION_REF", $order->getTransactionRef())
->set("DELIVERY_REF", $order->getDeliveryRef())
->set("INVOICE_REF", $order->getInvoiceRef())
->set("POSTAGE", $order->getPostage())
->set("PAYMENT_MODULE", $order->getPaymentModuleId())
->set("DELIVERY_MODULE", $order->getDeliveryModuleId())
->set("STATUS", $order->getStatusId())
->set("LANG", $order->getLangId())
->set("POSTAGE", $order->getPostage())
->set("TOTAL_TAX", $tax)
->set("TOTAL_AMOUNT", $amount - $tax)
->set("TOTAL_TAXED_AMOUNT", $amount)
;
$loopResult->addRow($loopResultRow);
}
return $loopResult;
}
}

View File

@@ -0,0 +1,84 @@
<?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\Loop;
use Propel\Runtime\ActiveQuery\Criteria;
use Thelia\Core\Template\Element\LoopResult;
use Thelia\Core\Template\Element\LoopResultRow;
use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Module\BaseModule;
/**
* Class Payment
* @package Thelia\Core\Template\Loop
* @author Etienne Roudeix <eroudeix@gmail.com>
*/
class Payment extends BaseSpecificModule
{
public function getArgDefinitions()
{
$collection = parent::getArgDefinitions();
return $collection;
}
public function exec(&$pagination)
{
$search = parent::exec($pagination);
/* manage translations */
$locale = $this->configureI18nProcessing($search);
$search->filterByType(BaseModule::PAYMENT_MODULE_TYPE, Criteria::EQUAL);
/* perform search */
$paymentModules = $this->search($search, $pagination);
$loopResult = new LoopResult($paymentModules);
foreach ($paymentModules as $paymentModule) {
$loopResultRow = new LoopResultRow($loopResult, $paymentModule, $this->versionable, $this->timestampable, $this->countable);
$moduleReflection = new \ReflectionClass($paymentModule->getFullNamespace());
if ($moduleReflection->isSubclassOf("Thelia\Module\PaymentModuleInterface") === false) {
throw new \RuntimeException(sprintf("payment module %s is not a Thelia\Module\PaymentModuleInterface", $paymentModule->getCode()));
}
$moduleInstance = $moduleReflection->newInstance();
$moduleInstance->setRequest($this->request);
$moduleInstance->setDispatcher($this->dispatcher);
$loopResultRow
->set('ID', $paymentModule->getId())
->set('TITLE', $paymentModule->getVirtualColumn('i18n_TITLE'))
->set('CHAPO', $paymentModule->getVirtualColumn('i18n_CHAPO'))
->set('DESCRIPTION', $paymentModule->getVirtualColumn('i18n_DESCRIPTION'))
->set('POSTSCRIPTUM', $paymentModule->getVirtualColumn('i18n_POSTSCRIPTUM'))
;
$loopResult->addRow($loopResultRow);
}
return $loopResult;
}
}

View File

@@ -32,6 +32,7 @@ use Thelia\Core\Template\Element\LoopResultRow;
use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Exception\TaxEngineException;
use Thelia\Model\CategoryQuery;
use Thelia\Model\CountryQuery;
use Thelia\Model\CurrencyQuery;
@@ -597,32 +598,67 @@ class Product extends BaseI18nLoop
$loopResult = new LoopResult($products);
$taxCountry = CountryQuery::create()->findPk(64); // @TODO : make it magic
foreach ($products as $product) {
$loopResultRow = new LoopResultRow($loopResult, $product, $this->versionable, $this->timestampable, $this->countable);
$price = $product->getRealLowestPrice();
$taxedPrice = $product->getTaxedPrice(
CountryQuery::create()->findOneById(64) // @TODO : make it magic
);
try {
$taxedPrice = $product->getTaxedPrice(
$taxCountry
);
} catch(TaxEngineException $e) {
$taxedPrice = null;
}
$loopResultRow->set("ID", $product->getId())
->set("REF",$product->getRef())
->set("IS_TRANSLATED",$product->getVirtualColumn('IS_TRANSLATED'))
->set("LOCALE",$locale)
->set("TITLE",$product->getVirtualColumn('i18n_TITLE'))
->set("CHAPO", $product->getVirtualColumn('i18n_CHAPO'))
->set("DESCRIPTION", $product->getVirtualColumn('i18n_DESCRIPTION'))
->set("POSTSCRIPTUM", $product->getVirtualColumn('i18n_POSTSCRIPTUM'))
->set("URL", $product->getUrl($locale))
->set("BEST_PRICE", $price)
->set("BEST_PRICE_TAX", $taxedPrice - $price)
->set("BEST_TAXED_PRICE", $taxedPrice)
->set("IS_PROMO", $product->getVirtualColumn('main_product_is_promo'))
->set("IS_NEW", $product->getVirtualColumn('main_product_is_new'))
->set("POSITION", $product->getPosition())
// Find previous and next product, in the default category.
$default_category_id = $product->getDefaultCategoryId();
$previous = ProductQuery::create()
->joinProductCategory()
->where('ProductCategory.category_id = ?', $default_category_id)
->filterByPosition($product->getPosition(), Criteria::LESS_THAN)
->orderByPosition(Criteria::DESC)
->findOne()
;
$next = ProductQuery::create()
->joinProductCategory()
->where('ProductCategory.category_id = ?', $default_category_id)
->filterByPosition($product->getPosition(), Criteria::GREATER_THAN)
->orderByPosition(Criteria::ASC)
->findOne()
;
$loopResultRow
->set("ID" , $product->getId())
->set("REF" , $product->getRef())
->set("IS_TRANSLATED" , $product->getVirtualColumn('IS_TRANSLATED'))
->set("LOCALE" , $locale)
->set("TITLE" , $product->getVirtualColumn('i18n_TITLE'))
->set("CHAPO" , $product->getVirtualColumn('i18n_CHAPO'))
->set("DESCRIPTION" , $product->getVirtualColumn('i18n_DESCRIPTION'))
->set("POSTSCRIPTUM" , $product->getVirtualColumn('i18n_POSTSCRIPTUM'))
->set("URL" , $product->getUrl($locale))
->set("BEST_PRICE" , $price)
->set("BEST_PRICE_TAX" , $taxedPrice - $price)
->set("BEST_TAXED_PRICE" , $taxedPrice)
->set("IS_PROMO" , $product->getVirtualColumn('main_product_is_promo'))
->set("IS_NEW" , $product->getVirtualColumn('main_product_is_new'))
->set("POSITION" , $product->getPosition())
->set("VISIBLE" , $product->getVisible() ? "1" : "0")
->set("TEMPLATE" , $product->getTemplateId())
->set("HAS_PREVIOUS" , $previous != null ? 1 : 0)
->set("HAS_NEXT" , $next != null ? 1 : 0)
->set("PREVIOUS" , $previous != null ? $previous->getId() : -1)
->set("NEXT" , $next != null ? $next->getId() : -1)
->set("DEFAULT_CATEGORY" , $default_category_id)
;
$loopResult->addRow($loopResultRow);
}

View File

@@ -31,6 +31,7 @@ use Thelia\Core\Template\Element\LoopResultRow;
use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Exception\TaxEngineException;
use Thelia\Model\Base\ProductSaleElementsQuery;
use Thelia\Model\CountryQuery;
use Thelia\Model\CurrencyQuery;
@@ -147,29 +148,41 @@ class ProductSaleElements extends BaseLoop
$loopResult = new LoopResult($PSEValues);
$taxCountry = CountryQuery::create()->findPk(64); // @TODO : make it magic
foreach ($PSEValues as $PSEValue) {
$loopResultRow = new LoopResultRow($loopResult, $PSEValue, $this->versionable, $this->timestampable, $this->countable);
$price = $PSEValue->getPrice();
$taxedPrice = $PSEValue->getTaxedPrice(
CountryQuery::create()->findOneById(64) // @TODO : make it magic
);
try {
$taxedPrice = $PSEValue->getTaxedPrice(
$taxCountry
);
} catch(TaxEngineException $e) {
$taxedPrice = null;
}
$promoPrice = $PSEValue->getPromoPrice();
$taxedPromoPrice = $PSEValue->getTaxedPromoPrice(
CountryQuery::create()->findOneById(64) // @TODO : make it magic
);
try {
$taxedPromoPrice = $PSEValue->getTaxedPromoPrice(
$taxCountry
);
} catch(TaxEngineException $e) {
$taxedPromoPrice = null;
}
$loopResultRow->set("ID", $PSEValue->getId())
->set("QUANTITY", $PSEValue->getQuantity())
->set("IS_PROMO", $PSEValue->getPromo() === 1 ? 1 : 0)
->set("IS_NEW", $PSEValue->getNewness() === 1 ? 1 : 0)
->set("WEIGHT", $PSEValue->getWeight())
->set("PRICE", $price)
->set("PRICE_TAX", $taxedPrice - $price)
->set("TAXED_PRICE", $taxedPrice)
->set("PROMO_PRICE", $promoPrice)
->set("PROMO_PRICE_TAX", $taxedPromoPrice - $promoPrice)
->set("TAXED_PROMO_PRICE", $taxedPromoPrice);
$loopResultRow
->set("ID" , $PSEValue->getId())
->set("QUANTITY" , $PSEValue->getQuantity())
->set("IS_PROMO" , $PSEValue->getPromo() === 1 ? 1 : 0)
->set("IS_NEW" , $PSEValue->getNewness() === 1 ? 1 : 0)
->set("IS_DEFAULT" , $PSEValue->getIsDefault() === 1 ? 1 : 0)
->set("WEIGHT" , $PSEValue->getWeight())
->set("PRICE" , $price)
->set("PRICE_TAX" , $taxedPrice - $price)
->set("TAXED_PRICE" , $taxedPrice)
->set("PROMO_PRICE" , $promoPrice)
->set("PROMO_PRICE_TAX" , $taxedPromoPrice - $promoPrice)
->set("TAXED_PROMO_PRICE" , $taxedPromoPrice);
$loopResult->addRow($loopResultRow);
}

View File

@@ -0,0 +1,135 @@
<?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\Loop;
use Propel\Runtime\ActiveQuery\Criteria;
use Thelia\Core\Template\Element\BaseI18nLoop;
use Thelia\Core\Template\Element\LoopResult;
use Thelia\Core\Template\Element\LoopResultRow;
use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Type\TypeCollection;
use Thelia\Type;
use Thelia\Model\TaxRuleQuery;
/**
*
* TaxRule loop
*
*
* Class TaxRule
* @package Thelia\Core\Template\Loop
* @author Etienne Roudeix <eroudeix@openstudio.fr>
*/
class TaxRule extends BaseI18nLoop
{
public $timestampable = true;
/**
* @return ArgumentCollection
*/
protected function getArgDefinitions()
{
return new ArgumentCollection(
Argument::createIntListTypeArgument('id'),
Argument::createIntListTypeArgument('exclude'),
new Argument(
'order',
new TypeCollection(
new Type\EnumListType(array('id', 'id_reverse', 'alpha', 'alpha_reverse'))
),
'alpha'
)
);
}
/**
* @param $pagination
*
* @return \Thelia\Core\Template\Element\LoopResult
*/
public function exec(&$pagination)
{
$search = TaxRuleQuery::create();
/* manage translations */
$locale = $this->configureI18nProcessing($search, array('TITLE', 'DESCRIPTION'));
$id = $this->getId();
if (null !== $id) {
$search->filterById($id, Criteria::IN);
}
$exclude = $this->getExclude();
if (null !== $exclude) {
$search->filterById($exclude, Criteria::NOT_IN);
}
$orders = $this->getOrder();
foreach ($orders as $order) {
switch ($order) {
case "id":
$search->orderById(Criteria::ASC);
break;
case "id_reverse":
$search->orderById(Criteria::DESC);
break;
case "alpha":
$search->addAscendingOrderByColumn('i18n_TITLE');
break;
case "alpha_reverse":
$search->addDescendingOrderByColumn('i18n_TITLE');
break;
}
}
/* perform search */
$tax_rules = $this->search($search, $pagination);
$loopResult = new LoopResult($tax_rules);
foreach ($tax_rules as $tax_rule) {
$loopResultRow = new LoopResultRow($loopResult, $tax_rule, $this->versionable, $this->timestampable, $this->countable);
$loopResultRow
->set("ID" , $tax_rule->getId())
->set("IS_TRANSLATED" , $tax_rule->getVirtualColumn('IS_TRANSLATED'))
->set("LOCALE" , $locale)
->set("TITLE" , $tax_rule->getVirtualColumn('i18n_TITLE'))
->set("DESCRIPTION" , $tax_rule->getVirtualColumn('i18n_DESCRIPTION'))
->set("IS_DEFAULT" , $tax_rule->getIsDefault() ? '1' : '0')
;
$loopResult->addRow($loopResultRow);
}
return $loopResult;
}
}

View File

@@ -24,6 +24,7 @@
namespace Thelia\Core\Template\Smarty\Plugins;
use Propel\Runtime\ActiveQuery\ModelCriteria;
use Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher;
use Symfony\Component\HttpFoundation\Request;
use Thelia\Core\Template\Smarty\AbstractSmartyPlugin;
use Thelia\Core\Security\SecurityContext;
@@ -53,12 +54,16 @@ class DataAccessFunctions extends AbstractSmartyPlugin
private $securityContext;
protected $parserContext;
protected $request;
protected $dispatcher;
public function __construct(Request $request, SecurityContext $securityContext, ParserContext $parserContext)
private static $dataAccessCache = array();
public function __construct(Request $request, SecurityContext $securityContext, ParserContext $parserContext, ContainerAwareEventDispatcher $dispatcher)
{
$this->securityContext = $securityContext;
$this->parserContext = $parserContext;
$this->request = $request;
$this->dispatcher = $dispatcher;
}
/**
@@ -157,7 +162,12 @@ class DataAccessFunctions extends AbstractSmartyPlugin
public function countryDataAccess($params, $smarty)
{
$defaultCountry = CountryQuery::create()->findOneByByDefault(1);
if(array_key_exists('defaultCountry', self::$dataAccessCache)) {
$defaultCountry = self::$dataAccessCache['defaultCountry'];
} else {
$defaultCountry = CountryQuery::create()->findOneByByDefault(1);
self::$dataAccessCache['defaultCountry'] = $defaultCountry;
}
switch($params["attr"]) {
case "default":
@@ -167,6 +177,13 @@ class DataAccessFunctions extends AbstractSmartyPlugin
public function cartDataAccess($params, $smarty)
{
if(array_key_exists('currentCountry', self::$dataAccessCache)) {
$currentCountry = self::$dataAccessCache['currentCountry'];
} else {
$currentCountry = CountryQuery::create()->findOneById(64); // @TODO : make it magic
self::$dataAccessCache['currentCountry'] = $currentCountry;
}
$cart = $this->getCart($this->request);
$result = "";
switch($params["attr"]) {
@@ -177,9 +194,7 @@ class DataAccessFunctions extends AbstractSmartyPlugin
$result = $cart->getTotalAmount();
break;
case "total_taxed_price":
$result = $cart->getTaxedAmount(
CountryQuery::create()->findOneById(64) // @TODO : make it magic
);
$result = $cart->getTaxedAmount($currentCountry);
break;
}
@@ -188,7 +203,22 @@ class DataAccessFunctions extends AbstractSmartyPlugin
public function orderDataAccess($params, &$smarty)
{
return $this->dataAccess("Order", $params, $this->request->getSession()->getOrder());
$order = $this->request->getSession()->getOrder();
$attribute = $this->getNormalizedParam($params, array('attribute', 'attrib', 'attr'));
switch($attribute) {
case 'postage':
return $order->getPostage();
case 'delivery_address':
return $order->chosenDeliveryAddress;
case 'invoice_address':
return $order->chosenInvoiceAddress;
case 'delivery_module':
return $order->getDeliveryModuleId();
case 'payment_module':
return $order->getPaymentModuleId();
}
throw new \InvalidArgumentException(sprintf("%s has no '%s' attribute", 'Order', $attribute));
}
/**
@@ -196,6 +226,8 @@ class DataAccessFunctions extends AbstractSmartyPlugin
*
* @param $params
* @param $smarty
*
* @return string
*/
public function langDataAccess($params, $smarty)
{
@@ -214,24 +246,30 @@ class DataAccessFunctions extends AbstractSmartyPlugin
*/
protected function dataAccessWithI18n($objectLabel, $params, ModelCriteria $search, $columns = array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), $foreignTable = null, $foreignKey = 'ID')
{
$lang = $this->getNormalizedParam($params, array('lang'));
if ($lang === null) {
$lang = $this->request->getSession()->getLang()->getId();
if(array_key_exists('data_' . $objectLabel, self::$dataAccessCache)) {
$data = self::$dataAccessCache['data_' . $objectLabel];
} else {
$lang = $this->getNormalizedParam($params, array('lang'));
if ($lang === null) {
$lang = $this->request->getSession()->getLang()->getId();
}
ModelCriteriaTools::getI18n(
false,
$lang,
$search,
$this->request->getSession()->getLang()->getLocale(),
$columns,
$foreignTable,
$foreignKey,
true
);
$data = $search->findOne();
self::$dataAccessCache['data_' . $objectLabel] = $data;
}
ModelCriteriaTools::getI18n(
false,
$lang,
$search,
$this->request->getSession()->getLang()->getLocale(),
$columns,
$foreignTable,
$foreignKey,
true
);
$data = $search->findOne();
$noGetterData = array();
foreach ($columns as $column) {
$noGetterData[$column] = $data->getVirtualColumn('i18n_' . $column);
@@ -294,6 +332,7 @@ class DataAccessFunctions extends AbstractSmartyPlugin
*/
public function getPluginDescriptors()
{
return array(
new SmartyPluginDescriptor('function', 'admin', $this, 'adminDataAccess'),
new SmartyPluginDescriptor('function', 'customer', $this, 'customerDataAccess'),
@@ -308,4 +347,14 @@ class DataAccessFunctions extends AbstractSmartyPlugin
new SmartyPluginDescriptor('function', 'order', $this, 'orderDataAccess'),
);
}
/**
* Return the event dispatcher,
*
* @return \Symfony\Component\EventDispatcher\EventDispatcher
*/
public function getDispatcher()
{
return $this->dispatcher;
}
}

Some files were not shown because too many files have changed in this diff Show More