diff --git a/Readme.md b/Readme.md index ac0862dae..ed4edf9ef 100755 --- a/Readme.md +++ b/Readme.md @@ -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 : diff --git a/composer.json b/composer.json index 4a3798384..afef9e30b 100755 --- a/composer.json +++ b/composer.json @@ -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.*", diff --git a/composer.lock b/composer.lock index b0310c075..f90373a84 100755 --- a/composer.lock +++ b/composer.lock @@ -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": { diff --git a/core/lib/Thelia/Action/Attribute.php b/core/lib/Thelia/Action/Attribute.php index 44c5968a4..12478e8a1 100644 --- a/core/lib/Thelia/Action/Attribute.php +++ b/core/lib/Thelia/Action/Attribute.php @@ -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) diff --git a/core/lib/Thelia/Action/AttributeAv.php b/core/lib/Thelia/Action/AttributeAv.php index a6b442fa2..0a72739d1 100644 --- a/core/lib/Thelia/Action/AttributeAv.php +++ b/core/lib/Thelia/Action/AttributeAv.php @@ -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); } diff --git a/core/lib/Thelia/Action/BaseAction.php b/core/lib/Thelia/Action/BaseAction.php index 56565ddc6..d371919eb 100755 --- a/core/lib/Thelia/Action/BaseAction.php +++ b/core/lib/Thelia/Action/BaseAction.php @@ -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() + ); + } } diff --git a/core/lib/Thelia/Action/Category.php b/core/lib/Thelia/Action/Category.php index 64254d734..8429a7c4e 100755 --- a/core/lib/Thelia/Action/Category.php +++ b/core/lib/Thelia/Action/Category.php @@ -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(); + } } diff --git a/core/lib/Thelia/Action/Content.php b/core/lib/Thelia/Action/Content.php new file mode 100644 index 000000000..4e59cafad --- /dev/null +++ b/core/lib/Thelia/Action/Content.php @@ -0,0 +1,160 @@ +. */ +/* */ +/*************************************************************************************/ + +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 + */ +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), + ); + } + +} \ No newline at end of file diff --git a/core/lib/Thelia/Action/Currency.php b/core/lib/Thelia/Action/Currency.php index 946fee375..3c428683b 100644 --- a/core/lib/Thelia/Action/Currency.php +++ b/core/lib/Thelia/Action/Currency.php @@ -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); } /** diff --git a/core/lib/Thelia/Action/Document.php b/core/lib/Thelia/Action/Document.php index 86fc51ac5..6b5188ba8 100644 --- a/core/lib/Thelia/Action/Document.php +++ b/core/lib/Thelia/Action/Document.php @@ -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), ); } } diff --git a/core/lib/Thelia/Action/Feature.php b/core/lib/Thelia/Action/Feature.php index a746ce4e2..01799510c 100644 --- a/core/lib/Thelia/Action/Feature.php +++ b/core/lib/Thelia/Action/Feature.php @@ -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) diff --git a/core/lib/Thelia/Action/FeatureAv.php b/core/lib/Thelia/Action/FeatureAv.php index 2bd117b4b..25f9ae5f2 100644 --- a/core/lib/Thelia/Action/FeatureAv.php +++ b/core/lib/Thelia/Action/FeatureAv.php @@ -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); } diff --git a/core/lib/Thelia/Action/Folder.php b/core/lib/Thelia/Action/Folder.php new file mode 100644 index 000000000..b830947cc --- /dev/null +++ b/core/lib/Thelia/Action/Folder.php @@ -0,0 +1,155 @@ +. */ +/* */ +/*************************************************************************************/ + +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 + */ +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), + ); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Action/Image.php b/core/lib/Thelia/Action/Image.php index 4660f93b8..9de87182b 100755 --- a/core/lib/Thelia/Action/Image.php +++ b/core/lib/Thelia/Action/Image.php @@ -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), ); } } diff --git a/core/lib/Thelia/Action/Order.php b/core/lib/Thelia/Action/Order.php index a0d98265e..f93733da3 100755 --- a/core/lib/Thelia/Action/Order.php +++ b/core/lib/Thelia/Action/Order.php @@ -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(); + } } diff --git a/core/lib/Thelia/Action/Product.php b/core/lib/Thelia/Action/Product.php index d2deb7688..cecc1df39 100644 --- a/core/lib/Thelia/Action/Product.php +++ b/core/lib/Thelia/Action/Product.php @@ -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), ); } diff --git a/core/lib/Thelia/Action/Template.php b/core/lib/Thelia/Action/Template.php index 18174dd26..47d5d7a4d 100644 --- a/core/lib/Thelia/Action/Template.php +++ b/core/lib/Thelia/Action/Template.php @@ -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), + ); } } \ No newline at end of file diff --git a/core/lib/Thelia/Cart/CartTrait.php b/core/lib/Thelia/Cart/CartTrait.php index 8589f25b5..8ced1b6c1 100755 --- a/core/lib/Thelia/Cart/CartTrait.php +++ b/core/lib/Thelia/Cart/CartTrait.php @@ -139,4 +139,6 @@ trait CartTrait return $id; } + + abstract public function getDispatcher(); } diff --git a/core/lib/Thelia/Command/CacheClear.php b/core/lib/Thelia/Command/CacheClear.php index 72b7571d2..1126f99a6 100755 --- a/core/lib/Thelia/Command/CacheClear.php +++ b/core/lib/Thelia/Command/CacheClear.php @@ -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 %s 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("%s cache dir already clear", $dir)); + return; + } + + throw $e; + } + $fs = new Filesystem(); try { $fs->remove($dir); $output->writeln(sprintf("%s cache dir cleared successfully", $dir)); } catch (IOException $e) { - $output->writeln(sprintf("error during clearing cache : %s", $e->getMessage())); + $output->writeln(sprintf("Error during clearing cache : %s", $e->getMessage())); } } } diff --git a/core/lib/Thelia/Command/ModuleActivateCommand.php b/core/lib/Thelia/Command/ModuleActivateCommand.php new file mode 100755 index 000000000..cddfd5290 --- /dev/null +++ b/core/lib/Thelia/Command/ModuleActivateCommand.php @@ -0,0 +1,90 @@ +. */ +/* */ +/*************************************************************************************/ + +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 + * + */ +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"); + } + } +} diff --git a/core/lib/Thelia/Command/ReloadDatabaseCommand.php b/core/lib/Thelia/Command/ReloadDatabaseCommand.php index 70fab56d9..311b20552 100644 --- a/core/lib/Thelia/Command/ReloadDatabaseCommand.php +++ b/core/lib/Thelia/Command/ReloadDatabaseCommand.php @@ -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( '', diff --git a/core/lib/Thelia/Config/Resources/action.xml b/core/lib/Thelia/Config/Resources/action.xml index f7ef4806d..f153a8de0 100755 --- a/core/lib/Thelia/Config/Resources/action.xml +++ b/core/lib/Thelia/Config/Resources/action.xml @@ -36,6 +36,10 @@ + + + + @@ -97,6 +101,16 @@ + + + + + + + + + + diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index 41e49d7d7..2f06e9606 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -18,25 +18,30 @@ - + + + + + + @@ -54,16 +59,31 @@
+ + + + + - + + + + + + + + + + + @@ -92,6 +112,8 @@ + + @@ -102,6 +124,7 @@ + @@ -217,6 +240,7 @@ + @@ -224,6 +248,11 @@ + + + + + diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index af7c950af..a305edda8 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -24,6 +24,12 @@ Thelia\Controller\Admin\SessionController::checkLoginAction + + + Thelia\Controller\Admin\AdminController::updateAction + + + @@ -31,6 +37,70 @@ Thelia\Controller\Admin\CategoryController::defaultAction + + + + Thelia\Controller\Admin\FileController::saveImageAjaxAction + .* + \d+ + + + Thelia\Controller\Admin\FileController::getImageFormAjaxAction + .* + \d+ + + + Thelia\Controller\Admin\FileController::getImageListAjaxAction + .* + \d+ + + + Thelia\Controller\Admin\FileController::viewImageAction + .* + \d+ + + + Thelia\Controller\Admin\FileController::updateImageAction + .* + \d+ + + + Thelia\Controller\Admin\FileController::deleteImageAction + .* + \d+ + + + + Thelia\Controller\Admin\FileController::saveDocumentAjaxAction + .* + \d+ + + + Thelia\Controller\Admin\FileController::getDocumentFormAjaxAction + .* + \d+ + + + Thelia\Controller\Admin\FileController::getDocumentListAjaxAction + .* + \d+ + + + Thelia\Controller\Admin\FileController::viewDocumentAction + .* + \d+ + + + Thelia\Controller\Admin\FileController::updateDocumentAction + .* + \d+ + + + Thelia\Controller\Admin\FileController::deleteDocumentAction + .* + \d+ + + @@ -100,6 +170,10 @@ Thelia\Controller\Admin\CategoryController::addRelatedContentAction + + Thelia\Controller\Admin\CategoryController::addRelatedPictureAction + + Thelia\Controller\Admin\CategoryController::deleteRelatedContentAction @@ -144,19 +218,167 @@ Thelia\Controller\Admin\ProductController::updatePositionAction - + + + Thelia\Controller\Admin\ProductController::loadGeneralAjaxTabAction + + + + + + Thelia\Controller\Admin\ProductController::loadRelatedAjaxTabAction + + + + + + Thelia\Controller\Admin\ProductController::addAdditionalCategoryAction + + + + Thelia\Controller\Admin\ProductController::deleteAdditionalCategoryAction + + + + + Thelia\Controller\Admin\ProductController::addRelatedContentAction - + Thelia\Controller\Admin\ProductController::deleteRelatedContentAction - + Thelia\Controller\Admin\ProductController::getAvailableRelatedContentAction xml|json + + Thelia\Controller\Admin\ProductController::updateContentPositionAction + + + + + + Thelia\Controller\Admin\ProductController::addAccessoryAction + + + + Thelia\Controller\Admin\ProductController::deleteAccessoryAction + + + + Thelia\Controller\Admin\ProductController::getAvailableAccessoriesAction + xml|json + + + + Thelia\Controller\Admin\ProductController::updateAccessoryPositionAction + + + + + + Thelia\Controller\Admin\ProductController::loadAttributesAjaxTabAction + + + + Thelia\Controller\Admin\ProductController::setProductTemplateAction + + + + Thelia\Controller\Admin\ProductController::updateAttributesAndFeaturesAction + + + + + + Thelia\Controller\Admin\ProductController::getAttributeValuesAction + xml|json + + + + Thelia\Controller\Admin\ProductController::addAttributeValueToCombinationAction + xml|json + + + + Thelia\Controller\Admin\ProductController::addCombinationAction + + + + Thelia\Controller\Admin\ProductController::deleteCombinationAction + + + + Thelia\Controller\Admin\ProductController::updateCombinationAction + + + + Thelia\Controller\Admin\ProductController::updateDefaultPriceAction + + + + + + + + + Thelia\Controller\Admin\FolderController::defaultAction + + + + Thelia\Controller\Admin\FolderController::createAction + + + + Thelia\Controller\Admin\FolderController::updateAction + \d+ + + + + Thelia\Controller\Admin\FolderController::setToggleVisibilityAction + + + + Thelia\Controller\Admin\FolderController::processUpdateAction + + + + Thelia\Controller\Admin\FolderController::deleteAction + + + + Thelia\Controller\Admin\FolderController::updatePositionAction + + + + + Thelia\Controller\Admin\ContentController::createAction + + + + Thelia\Controller\Admin\ContentController::updateAction + \d+ + + + + Thelia\Controller\Admin\ContentController::processUpdateAction + + + + Thelia\Controller\Admin\ContentController::updatePositionAction + + + + Thelia\Controller\Admin\ContentController::setToggleVisibilityAction + + + + Thelia\Controller\Admin\ContentController::deleteAction + + @@ -303,6 +525,10 @@ Thelia\Controller\Admin\TemplateController::deleteFeatureAction + + Thelia\Controller\Admin\TemplateController::updateFeaturePositionAction + + Thelia\Controller\Admin\TemplateController::getAjaxAttributesAction @@ -315,6 +541,10 @@ Thelia\Controller\Admin\TemplateController::deleteAttributeAction + + Thelia\Controller\Admin\TemplateController::updateAttributePositionAction + + @@ -388,7 +618,34 @@ \d+ - + + + + + + Thelia\Controller\Admin\ShippingZoneController::indexAction + + + + Thelia\Controller\Admin\ShippingZoneController::updateAction + \d+ + + + + + + + + Thelia\Controller\Admin\ShippingConfigurationController::indexAction + + + + Thelia\Controller\Admin\ShippingConfigurationController::updateAction + \d+ + + + + @@ -447,6 +704,15 @@ + + + + Thelia\Controller\Admin\ModuleController::indexAction + + + + + diff --git a/core/lib/Thelia/Config/Resources/routing/front.xml b/core/lib/Thelia/Config/Resources/routing/front.xml index 7705c81cc..5b26a6ed6 100755 --- a/core/lib/Thelia/Config/Resources/routing/front.xml +++ b/core/lib/Thelia/Config/Resources/routing/front.xml @@ -112,27 +112,36 @@ cart - + + + + Thelia\Controller\Front\OrderController::deliver order_delivery - + Thelia\Controller\Front\DefaultController::noAction order_delivery + + Thelia\Controller\Front\OrderController::invoice + order_invoice + + Thelia\Controller\Front\DefaultController::noAction order_invoice - + + Thelia\Controller\Front\OrderController::pay + - - - Thelia\Controller\Front\DeliveryController::select - \d+ + + Thelia\Controller\Front\OrderController::orderPlaced + order_placed diff --git a/core/lib/Thelia/Controller/Admin/AbstractCrudController.php b/core/lib/Thelia/Controller/Admin/AbstractCrudController.php index 7b9550610..d2e7e5508 100644 --- a/core/lib/Thelia/Controller/Admin/AbstractCrudController.php +++ b/core/lib/Thelia/Controller/Admin/AbstractCrudController.php @@ -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(); } /** diff --git a/core/lib/Thelia/Controller/Admin/AdminController.php b/core/lib/Thelia/Controller/Admin/AdminController.php index 2c252258d..2d3d80df1 100755 --- a/core/lib/Thelia/Controller/Admin/AdminController.php +++ b/core/lib/Thelia/Controller/Admin/AdminController.php @@ -33,4 +33,9 @@ class AdminController extends BaseAdminController { return $this->render("home"); } + + public function updateAction() + { + return $this->render("profile-edit"); + } } diff --git a/core/lib/Thelia/Controller/Admin/BaseAdminController.php b/core/lib/Thelia/Controller/Admin/BaseAdminController.php index 1e0f65055..fa505b5c3 100755 --- a/core/lib/Thelia/Controller/Admin/BaseAdminController.php +++ b/core/lib/Thelia/Controller/Admin/BaseAdminController.php @@ -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 { diff --git a/core/lib/Thelia/Controller/Admin/CategoryController.php b/core/lib/Thelia/Controller/Admin/CategoryController.php index 8c74c31ec..0b2b310ef 100755 --- a/core/lib/Thelia/Controller/Admin/CategoryController.php +++ b/core/lib/Thelia/Controller/Admin/CategoryController.php @@ -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(); } + } diff --git a/core/lib/Thelia/Controller/Admin/ContentController.php b/core/lib/Thelia/Controller/Admin/ContentController.php new file mode 100644 index 000000000..10bfe07e0 --- /dev/null +++ b/core/lib/Thelia/Controller/Admin/ContentController.php @@ -0,0 +1,347 @@ +. */ +/* */ +/*************************************************************************************/ + +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 + */ +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()); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Controller/Admin/FileController.php b/core/lib/Thelia/Controller/Admin/FileController.php new file mode 100755 index 000000000..f43f30fe6 --- /dev/null +++ b/core/lib/Thelia/Controller/Admin/FileController.php @@ -0,0 +1,680 @@ +. */ +/* */ +/**********************************************************************************/ + +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 + * + */ +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; + } + + +} diff --git a/core/lib/Thelia/Controller/Admin/FolderController.php b/core/lib/Thelia/Controller/Admin/FolderController.php new file mode 100644 index 000000000..9f2190442 --- /dev/null +++ b/core/lib/Thelia/Controller/Admin/FolderController.php @@ -0,0 +1,328 @@ +. */ +/* */ +/*************************************************************************************/ + +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 + */ +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)) + ); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Controller/Admin/ModuleController.php b/core/lib/Thelia/Controller/Admin/ModuleController.php new file mode 100644 index 000000000..fe794abf9 --- /dev/null +++ b/core/lib/Thelia/Controller/Admin/ModuleController.php @@ -0,0 +1,46 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Controller\Admin; + +/** + * Class ModuleController + * @package Thelia\Controller\Admin + * @author Manuel Raynaud + */ +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 + )); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Controller/Admin/ProductController.php b/core/lib/Thelia/Controller/Admin/ProductController.php index e1b651e60..342af6b14 100644 --- a/core/lib/Thelia/Controller/Admin/ProductController.php +++ b/core/lib/Thelia/Controller/Admin/ProductController.php @@ -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(); + } + } diff --git a/core/lib/Thelia/Controller/Admin/ShippingConfigurationController.php b/core/lib/Thelia/Controller/Admin/ShippingConfigurationController.php new file mode 100644 index 000000000..71aa0ba2f --- /dev/null +++ b/core/lib/Thelia/Controller/Admin/ShippingConfigurationController.php @@ -0,0 +1,46 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Controller\Admin; + +/** + * Class ShippingConfigurationController + * @package Thelia\Controller\Admin + * @author Manuel Raynaud + */ +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 + )); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Controller/Admin/ShippingZoneController.php b/core/lib/Thelia/Controller/Admin/ShippingZoneController.php new file mode 100644 index 000000000..ee34d11bd --- /dev/null +++ b/core/lib/Thelia/Controller/Admin/ShippingZoneController.php @@ -0,0 +1,46 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Controller\Admin; + +/** + * Class ShippingZoneController + * @package Thelia\Controller\Admin + * @author Manuel Raynaud + */ +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 + )); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Controller/Admin/TemplateController.php b/core/lib/Thelia/Controller/Admin/TemplateController.php index c9e30612c..fb32e4231 100644 --- a/core/lib/Thelia/Controller/Admin/TemplateController.php +++ b/core/lib/Thelia/Controller/Admin/TemplateController.php @@ -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 + ); + } } \ No newline at end of file diff --git a/core/lib/Thelia/Controller/Front/BaseFrontController.php b/core/lib/Thelia/Controller/Front/BaseFrontController.php index 69ea8553d..152c2c10e 100755 --- a/core/lib/Thelia/Controller/Front/BaseFrontController.php +++ b/core/lib/Thelia/Controller/Front/BaseFrontController.php @@ -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"); + } + } } diff --git a/core/lib/Thelia/Controller/Front/OrderController.php b/core/lib/Thelia/Controller/Front/OrderController.php index f34715894..1f2c716ae 100755 --- a/core/lib/Thelia/Controller/Front/OrderController.php +++ b/core/lib/Thelia/Controller/Front/OrderController.php @@ -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()); diff --git a/core/lib/Thelia/Core/Event/AccessoryEvent.php b/core/lib/Thelia/Core/Event/AccessoryEvent.php new file mode 100644 index 000000000..1e14e6fb7 --- /dev/null +++ b/core/lib/Thelia/Core/Event/AccessoryEvent.php @@ -0,0 +1,54 @@ +. */ +/* */ +/*************************************************************************************/ + +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; + } +} diff --git a/core/lib/Thelia/Core/Event/CategoryAssociatedContentEvent.php b/core/lib/Thelia/Core/Event/CategoryAssociatedContentEvent.php new file mode 100644 index 000000000..1984a042c --- /dev/null +++ b/core/lib/Thelia/Core/Event/CategoryAssociatedContentEvent.php @@ -0,0 +1,54 @@ +. */ +/* */ +/*************************************************************************************/ + +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; + } +} diff --git a/core/lib/Thelia/Core/Event/Content/ContentCreateEvent.php b/core/lib/Thelia/Core/Event/Content/ContentCreateEvent.php new file mode 100644 index 000000000..5e2e7f0ea --- /dev/null +++ b/core/lib/Thelia/Core/Event/Content/ContentCreateEvent.php @@ -0,0 +1,124 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event\Content; + + +/** + * Class ContentCreateEvent + * @package Thelia\Core\Event\Content + * @author manuel raynaud + */ +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; + } + + + +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/Content/ContentDeleteEvent.php b/core/lib/Thelia/Core/Event/Content/ContentDeleteEvent.php new file mode 100644 index 000000000..3b5e5423b --- /dev/null +++ b/core/lib/Thelia/Core/Event/Content/ContentDeleteEvent.php @@ -0,0 +1,74 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event\Content; + + +/** + * Class ContentDeleteEvent + * @package Thelia\Core\Event\Content + * @author manuel raynaud + */ +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; + } + + +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/Content/ContentEvent.php b/core/lib/Thelia/Core/Event/Content/ContentEvent.php new file mode 100644 index 000000000..0949348e3 --- /dev/null +++ b/core/lib/Thelia/Core/Event/Content/ContentEvent.php @@ -0,0 +1,73 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event\Content; +use Thelia\Core\Event\ActionEvent; +use Thelia\Model\Content; + + +/** + * Class ContentEvent + * @package Thelia\Core\Event\Content + * @author manuel raynaud + */ +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; + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/Content/ContentToggleVisibilityEvent.php b/core/lib/Thelia/Core/Event/Content/ContentToggleVisibilityEvent.php new file mode 100644 index 000000000..55176635c --- /dev/null +++ b/core/lib/Thelia/Core/Event/Content/ContentToggleVisibilityEvent.php @@ -0,0 +1,35 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event\Content; + + +/** + * Class ContentToggleVisibilityEvent + * @package Thelia\Core\Event\Content + * @author manuel raynaud + */ +class ContentToggleVisibilityEvent extends ContentEvent +{ + +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/Content/ContentUpdateEvent.php b/core/lib/Thelia/Core/Event/Content/ContentUpdateEvent.php new file mode 100644 index 000000000..f7c75a01f --- /dev/null +++ b/core/lib/Thelia/Core/Event/Content/ContentUpdateEvent.php @@ -0,0 +1,150 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event\Content; + + +/** + * Class ContentUpdateEvent + * @package Thelia\Core\Event\Content + * @author manuel raynaud + */ +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; + } + + + + +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/DocumentCreateOrUpdateEvent.php b/core/lib/Thelia/Core/Event/DocumentCreateOrUpdateEvent.php new file mode 100755 index 000000000..81e52257e --- /dev/null +++ b/core/lib/Thelia/Core/Event/DocumentCreateOrUpdateEvent.php @@ -0,0 +1,217 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; +use Symfony\Component\HttpFoundation\File\UploadedFile; +use Thelia\Model\CategoryDocument; +use Thelia\Model\ContentDocument; +use Thelia\Model\FolderDocument; +use Thelia\Model\ProductDocument; + +/** + * Created by JetBrains PhpStorm. + * Date: 9/18/13 + * Time: 3:56 PM + * + * Occurring when a Document is saved + * + * @package Document + * @author Guillaume MOREL + * + */ +class DocumentCreateOrUpdateEvent extends ActionEvent +{ + + /** @var CategoryDocument|ProductDocument|ContentDocument|FolderDocument model to save */ + protected $modelDocument = array(); + + /** @var CategoryDocument|ProductDocument|ContentDocument|FolderDocument model to save */ + protected $oldModelDocument = array(); + + /** @var UploadedFile Document file to save */ + protected $uploadedFile = null; + + /** @var int Document parent id */ + protected $parentId = null; + + /** @var string Document type */ + protected $documentType = null; + + /** @var string Parent name */ + protected $parentName = null; + + /** + * Constructor + * + * @param string $documentType Document type + * ex : FileManager::TYPE_CATEGORY + * @param int $parentId Document parent id + */ + public function __construct($documentType, $parentId) + { + $this->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; + } + + +} diff --git a/core/lib/Thelia/Core/Event/DocumentDeleteEvent.php b/core/lib/Thelia/Core/Event/DocumentDeleteEvent.php new file mode 100755 index 000000000..d9e2b7161 --- /dev/null +++ b/core/lib/Thelia/Core/Event/DocumentDeleteEvent.php @@ -0,0 +1,112 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; + +use Thelia\Model\CategoryDocument; +use Thelia\Model\ContentDocument; +use Thelia\Model\FolderDocument; +use Thelia\Model\ProductDocument; + +/** + * Created by JetBrains PhpStorm. + * Date: 9/18/13 + * Time: 3:56 PM + * + * Occurring when a Document is about to be deleted + * + * @package Document + * @author Guillaume MOREL + * + */ +class DocumentDeleteEvent extends ActionEvent +{ + /** @var string Document type */ + protected $documentType = null; + + /** @var CategoryDocument|ProductDocument|ContentDocument|FolderDocument Document about to be deleted */ + protected $documentToDelete = null; + + /** + * Constructor + * + * @param CategoryDocument|ProductDocument|ContentDocument|FolderDocument $documentToDelete Document about to be deleted + * @param string $documentType Document type + * ex : FileManager::TYPE_CATEGORY + */ + public function __construct($documentToDelete, $documentType) + { + $this->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; + } + + +} diff --git a/core/lib/Thelia/Core/Event/DocumentEvent.php b/core/lib/Thelia/Core/Event/DocumentEvent.php index f58d51083..6248b8d9a 100644 --- a/core/lib/Thelia/Core/Event/DocumentEvent.php +++ b/core/lib/Thelia/Core/Event/DocumentEvent.php @@ -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; } diff --git a/core/lib/Thelia/Core/Event/FeatureProductDeleteEvent.php b/core/lib/Thelia/Core/Event/FeatureProductDeleteEvent.php new file mode 100644 index 000000000..5c74c6287 --- /dev/null +++ b/core/lib/Thelia/Core/Event/FeatureProductDeleteEvent.php @@ -0,0 +1,61 @@ +. */ +/* */ +/*************************************************************************************/ + +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; + } +} diff --git a/core/lib/Thelia/Core/Event/FeatureProductEvent.php b/core/lib/Thelia/Core/Event/FeatureProductEvent.php new file mode 100644 index 000000000..0acf48569 --- /dev/null +++ b/core/lib/Thelia/Core/Event/FeatureProductEvent.php @@ -0,0 +1,52 @@ +. */ +/* */ +/*************************************************************************************/ + +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; + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/FeatureProductUpdateEvent.php b/core/lib/Thelia/Core/Event/FeatureProductUpdateEvent.php new file mode 100644 index 000000000..5493c55a7 --- /dev/null +++ b/core/lib/Thelia/Core/Event/FeatureProductUpdateEvent.php @@ -0,0 +1,89 @@ +. */ +/* */ +/*************************************************************************************/ + +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; + } +} diff --git a/core/lib/Thelia/Core/Event/FolderCreateEvent.php b/core/lib/Thelia/Core/Event/FolderCreateEvent.php new file mode 100644 index 000000000..609fea6f8 --- /dev/null +++ b/core/lib/Thelia/Core/Event/FolderCreateEvent.php @@ -0,0 +1,120 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; + + +/** + * Class FolderCreateEvent + * @package Thelia\Core\Event + * @author Manuel Raynaud + */ +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; + } + + +} \ No newline at end of file diff --git a/core/lib/Thelia/Controller/Front/DeliveryController.php b/core/lib/Thelia/Core/Event/FolderDeleteEvent.php similarity index 72% rename from core/lib/Thelia/Controller/Front/DeliveryController.php rename to core/lib/Thelia/Core/Event/FolderDeleteEvent.php index ef5913bc9..1ef83ef51 100644 --- a/core/lib/Thelia/Controller/Front/DeliveryController.php +++ b/core/lib/Thelia/Core/Event/FolderDeleteEvent.php @@ -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 */ -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; + } + + +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/FolderEvent.php b/core/lib/Thelia/Core/Event/FolderEvent.php new file mode 100644 index 000000000..8ae8223b5 --- /dev/null +++ b/core/lib/Thelia/Core/Event/FolderEvent.php @@ -0,0 +1,73 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; +use Thelia\Model\Folder; + + +/** + * Class FolderEvent + * @package Thelia\Core\Event + * @author Manuel Raynaud + */ +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; + } + +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/FolderToggleVisibilityEvent.php b/core/lib/Thelia/Core/Event/FolderToggleVisibilityEvent.php new file mode 100644 index 000000000..9d7c53ab7 --- /dev/null +++ b/core/lib/Thelia/Core/Event/FolderToggleVisibilityEvent.php @@ -0,0 +1,34 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; + + +/** + * Class FolderToggleVisibilityEvent + * @package Thelia\Core\Event + * @author Manuel Raynaud + */ +class FolderToggleVisibilityEvent extends FolderEvent { + +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/FolderUpdateEvent.php b/core/lib/Thelia/Core/Event/FolderUpdateEvent.php new file mode 100644 index 000000000..47c3b28cf --- /dev/null +++ b/core/lib/Thelia/Core/Event/FolderUpdateEvent.php @@ -0,0 +1,136 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; + + +/** + * Class FolderUpdateEvent + * @package Thelia\Core\Event + * @author Manuel Raynaud + */ +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; + } + +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/GenerateRewrittenUrlEvent.php b/core/lib/Thelia/Core/Event/GenerateRewrittenUrlEvent.php new file mode 100644 index 000000000..7ee22cddd --- /dev/null +++ b/core/lib/Thelia/Core/Event/GenerateRewrittenUrlEvent.php @@ -0,0 +1,60 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; + + +/** + * Class GenerateRewrittenUrlEvent + * @package Thelia\Core\Event + * @author Manuel Raynaud + */ +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; + } + +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/ImageCreateOrUpdateEvent.php b/core/lib/Thelia/Core/Event/ImageCreateOrUpdateEvent.php new file mode 100755 index 000000000..e7d5f3449 --- /dev/null +++ b/core/lib/Thelia/Core/Event/ImageCreateOrUpdateEvent.php @@ -0,0 +1,213 @@ +. */ +/* */ +/*************************************************************************************/ + +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 + * + */ +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; + } + + +} diff --git a/core/lib/Thelia/Core/Event/ImageDeleteEvent.php b/core/lib/Thelia/Core/Event/ImageDeleteEvent.php new file mode 100755 index 000000000..9e890e999 --- /dev/null +++ b/core/lib/Thelia/Core/Event/ImageDeleteEvent.php @@ -0,0 +1,112 @@ +. */ +/* */ +/*************************************************************************************/ + +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 + * + */ +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; + } + + +} diff --git a/core/lib/Thelia/Core/Event/OrderEvent.php b/core/lib/Thelia/Core/Event/OrderEvent.php index 6c2b5ff4b..7089141bb 100755 --- a/core/lib/Thelia/Core/Event/OrderEvent.php +++ b/core/lib/Thelia/Core/Event/OrderEvent.php @@ -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; + } } diff --git a/core/lib/Thelia/Core/Event/ProductAddAccessoryEvent.php b/core/lib/Thelia/Core/Event/ProductAddAccessoryEvent.php new file mode 100644 index 000000000..d3f2ba19b --- /dev/null +++ b/core/lib/Thelia/Core/Event/ProductAddAccessoryEvent.php @@ -0,0 +1,48 @@ +. */ +/* */ +/*************************************************************************************/ + +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; + } +} diff --git a/core/lib/Thelia/Core/Event/ProductAddCategoryEvent.php b/core/lib/Thelia/Core/Event/ProductAddCategoryEvent.php new file mode 100644 index 000000000..215b61f99 --- /dev/null +++ b/core/lib/Thelia/Core/Event/ProductAddCategoryEvent.php @@ -0,0 +1,48 @@ +. */ +/* */ +/*************************************************************************************/ + +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; + } +} diff --git a/core/lib/Thelia/Core/Event/ProductAssociatedContentEvent.php b/core/lib/Thelia/Core/Event/ProductAssociatedContentEvent.php new file mode 100644 index 000000000..ba41b5ede --- /dev/null +++ b/core/lib/Thelia/Core/Event/ProductAssociatedContentEvent.php @@ -0,0 +1,54 @@ +. */ +/* */ +/*************************************************************************************/ + +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; + } +} diff --git a/core/lib/Thelia/Core/Event/ProductCreateCombinationEvent.php b/core/lib/Thelia/Core/Event/ProductCreateCombinationEvent.php new file mode 100644 index 000000000..322451199 --- /dev/null +++ b/core/lib/Thelia/Core/Event/ProductCreateCombinationEvent.php @@ -0,0 +1,64 @@ +. */ +/* */ +/*************************************************************************************/ + +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; + } + +} diff --git a/core/lib/Thelia/Core/Event/ProductCreateEvent.php b/core/lib/Thelia/Core/Event/ProductCreateEvent.php index 51be86e25..012d29793 100644 --- a/core/lib/Thelia/Core/Event/ProductCreateEvent.php +++ b/core/lib/Thelia/Core/Event/ProductCreateEvent.php @@ -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; } } diff --git a/core/lib/Thelia/Core/Event/ProductDeleteAccessoryEvent.php b/core/lib/Thelia/Core/Event/ProductDeleteAccessoryEvent.php new file mode 100644 index 000000000..9644cdacc --- /dev/null +++ b/core/lib/Thelia/Core/Event/ProductDeleteAccessoryEvent.php @@ -0,0 +1,48 @@ +. */ +/* */ +/*************************************************************************************/ + +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; + } +} diff --git a/core/lib/Thelia/Core/Event/ProductDeleteCategoryEvent.php b/core/lib/Thelia/Core/Event/ProductDeleteCategoryEvent.php new file mode 100644 index 000000000..4fcfeee92 --- /dev/null +++ b/core/lib/Thelia/Core/Event/ProductDeleteCategoryEvent.php @@ -0,0 +1,50 @@ +. */ +/* */ +/*************************************************************************************/ + +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; + } + +} diff --git a/core/lib/Thelia/Core/Event/ProductDeleteCombinationEvent.php b/core/lib/Thelia/Core/Event/ProductDeleteCombinationEvent.php new file mode 100644 index 000000000..3cc9a25ce --- /dev/null +++ b/core/lib/Thelia/Core/Event/ProductDeleteCombinationEvent.php @@ -0,0 +1,47 @@ +. */ +/* */ +/*************************************************************************************/ + +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; + } +} diff --git a/core/lib/Thelia/Core/Event/ProductSetTemplateEvent.php b/core/lib/Thelia/Core/Event/ProductSetTemplateEvent.php new file mode 100644 index 000000000..c7c6dc760 --- /dev/null +++ b/core/lib/Thelia/Core/Event/ProductSetTemplateEvent.php @@ -0,0 +1,51 @@ +. */ +/* */ +/*************************************************************************************/ + +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; + } + +} diff --git a/core/lib/Thelia/Core/Event/TheliaEvents.php b/core/lib/Thelia/Core/Event/TheliaEvents.php index dab2db208..12e42831c 100755 --- a/core/lib/Thelia/Core/Event/TheliaEvents.php +++ b/core/lib/Thelia/Core/Event/TheliaEvents.php @@ -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'; + } diff --git a/core/lib/Thelia/Core/EventListener/ViewListener.php b/core/lib/Thelia/Core/EventListener/ViewListener.php index c723c2112..dac1f943d 100755 --- a/core/lib/Thelia/Core/EventListener/ViewListener.php +++ b/core/lib/Thelia/Core/EventListener/ViewListener.php @@ -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; } } diff --git a/core/lib/Thelia/Core/HttpFoundation/Session/Session.php b/core/lib/Thelia/Core/HttpFoundation/Session/Session.php index 5edd007b3..798a9c7fd 100755 --- a/core/lib/Thelia/Core/HttpFoundation/Session/Session.php +++ b/core/lib/Thelia/Core/HttpFoundation/Session/Session.php @@ -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"); diff --git a/core/lib/Thelia/Core/Routing/RewritingRouter.php b/core/lib/Thelia/Core/Routing/RewritingRouter.php index 2b663a979..9b736a614 100644 --- a/core/lib/Thelia/Core/Routing/RewritingRouter.php +++ b/core/lib/Thelia/Core/Routing/RewritingRouter.php @@ -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(); } /** diff --git a/core/lib/Thelia/Core/Template/Element/BaseI18nLoop.php b/core/lib/Thelia/Core/Template/Element/BaseI18nLoop.php index 283aad797..557c64901 100644 --- a/core/lib/Thelia/Core/Template/Element/BaseI18nLoop.php +++ b/core/lib/Thelia/Core/Template/Element/BaseI18nLoop.php @@ -65,6 +65,8 @@ abstract class BaseI18nLoop extends BaseLoop { /* manage translations */ + $fr = $this->getForce_return(); + return ModelCriteriaTools::getI18n( $this->getBackend_context(), $this->getLang(), diff --git a/core/lib/Thelia/Core/Template/Loop/Accessory.php b/core/lib/Thelia/Core/Template/Loop/Accessory.php index 69b2e09d9..34d674c10 100755 --- a/core/lib/Thelia/Core/Template/Loop/Accessory.php +++ b/core/lib/Thelia/Core/Template/Loop/Accessory.php @@ -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; + } } diff --git a/core/lib/Thelia/Core/Template/Loop/Address.php b/core/lib/Thelia/Core/Template/Loop/Address.php index 1321592f4..9ca4352e9 100755 --- a/core/lib/Thelia/Core/Template/Loop/Address.php +++ b/core/lib/Thelia/Core/Template/Loop/Address.php @@ -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); } diff --git a/core/lib/Thelia/Core/Template/Loop/Argument/Argument.php b/core/lib/Thelia/Core/Template/Loop/Argument/Argument.php index 54c2e3bf2..418a76220 100755 --- a/core/lib/Thelia/Core/Template/Loop/Argument/Argument.php +++ b/core/lib/Thelia/Core/Template/Loop/Argument/Argument.php @@ -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) diff --git a/core/lib/Thelia/Core/Template/Loop/AssociatedContent.php b/core/lib/Thelia/Core/Template/Loop/AssociatedContent.php index d85f75fa6..78794b715 100755 --- a/core/lib/Thelia/Core/Template/Loop/AssociatedContent.php +++ b/core/lib/Thelia/Core/Template/Loop/AssociatedContent.php @@ -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; + } } diff --git a/core/lib/Thelia/Core/Template/Loop/Attribute.php b/core/lib/Thelia/Core/Template/Loop/Attribute.php index e2ea7cf0f..9a9aa6ff3 100755 --- a/core/lib/Thelia/Core/Template/Loop/Attribute.php +++ b/core/lib/Thelia/Core/Template/Loop/Attribute.php @@ -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); } diff --git a/core/lib/Thelia/Core/Template/Loop/BaseSpecificModule.php b/core/lib/Thelia/Core/Template/Loop/BaseSpecificModule.php index 2aaa173dc..6f5f23707 100644 --- a/core/lib/Thelia/Core/Template/Loop/BaseSpecificModule.php +++ b/core/lib/Thelia/Core/Template/Loop/BaseSpecificModule.php @@ -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 */ @@ -93,6 +92,8 @@ class BaseSpecificModule extends BaseI18nLoop { $search = ModuleQuery::create(); + $search->filterByActivate(1); + if (null !== $id = $this->getId()) { $search->filterById($id); } diff --git a/core/lib/Thelia/Core/Template/Loop/Cart.php b/core/lib/Thelia/Core/Template/Loop/Cart.php index 3c8724d68..5c08b2896 100755 --- a/core/lib/Thelia/Core/Template/Loop/Cart.php +++ b/core/lib/Thelia/Core/Template/Loop/Cart.php @@ -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; + } } diff --git a/core/lib/Thelia/Core/Template/Loop/Category.php b/core/lib/Thelia/Core/Template/Loop/Category.php index bd1c32de2..9c9ddab7d 100755 --- a/core/lib/Thelia/Core/Template/Loop/Category.php +++ b/core/lib/Thelia/Core/Template/Loop/Category.php @@ -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()) diff --git a/core/lib/Thelia/Core/Template/Loop/CategoryTree.php b/core/lib/Thelia/Core/Template/Loop/CategoryTree.php index 712767954..009e2204f 100755 --- a/core/lib/Thelia/Core/Template/Loop/CategoryTree.php +++ b/core/lib/Thelia/Core/Template/Loop/CategoryTree.php @@ -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; } diff --git a/core/lib/Thelia/Core/Template/Loop/Content.php b/core/lib/Thelia/Core/Template/Loop/Content.php index a29cb2e60..ce966bf5c 100755 --- a/core/lib/Thelia/Core/Template/Loop/Content.php +++ b/core/lib/Thelia/Core/Template/Loop/Content.php @@ -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); diff --git a/core/lib/Thelia/Core/Template/Loop/Country.php b/core/lib/Thelia/Core/Template/Loop/Country.php index f14b97efc..3a05b684a 100755 --- a/core/lib/Thelia/Core/Template/Loop/Country.php +++ b/core/lib/Thelia/Core/Template/Loop/Country.php @@ -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); } diff --git a/core/lib/Thelia/Core/Template/Loop/Delivery.php b/core/lib/Thelia/Core/Template/Loop/Delivery.php index dea302797..5d33d398d 100644 --- a/core/lib/Thelia/Core/Template/Loop/Delivery.php +++ b/core/lib/Thelia/Core/Template/Loop/Delivery.php @@ -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); diff --git a/core/lib/Thelia/Core/Template/Loop/Document.php b/core/lib/Thelia/Core/Template/Loop/Document.php index 0e7e979c9..d60aaf7b2 100644 --- a/core/lib/Thelia/Core/Template/Loop/Document.php +++ b/core/lib/Thelia/Core/Template/Loop/Document.php @@ -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')) diff --git a/core/lib/Thelia/Core/Template/Loop/Feature.php b/core/lib/Thelia/Core/Template/Loop/Feature.php index f5c66d2e6..f542b2e8d 100755 --- a/core/lib/Thelia/Core/Template/Loop/Feature.php +++ b/core/lib/Thelia/Core/Template/Loop/Feature.php @@ -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); } diff --git a/core/lib/Thelia/Core/Template/Loop/FeatureValue.php b/core/lib/Thelia/Core/Template/Loop/FeatureValue.php index 30a8dcf27..8ae8b0f4f 100755 --- a/core/lib/Thelia/Core/Template/Loop/FeatureValue.php +++ b/core/lib/Thelia/Core/Template/Loop/FeatureValue.php @@ -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); } diff --git a/core/lib/Thelia/Core/Template/Loop/Folder.php b/core/lib/Thelia/Core/Template/Loop/Folder.php index cfd54db4f..5c56dff94 100755 --- a/core/lib/Thelia/Core/Template/Loop/Folder.php +++ b/core/lib/Thelia/Core/Template/Loop/Folder.php @@ -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()) ; diff --git a/core/lib/Thelia/Core/Template/Loop/FolderTree.php b/core/lib/Thelia/Core/Template/Loop/FolderTree.php new file mode 100644 index 000000000..9549f2467 --- /dev/null +++ b/core/lib/Thelia/Core/Template/Loop/FolderTree.php @@ -0,0 +1,118 @@ +. */ +/* */ +/*************************************************************************************/ + +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 + */ +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; + } +} diff --git a/core/lib/Thelia/Core/Template/Loop/Image.php b/core/lib/Thelia/Core/Template/Loop/Image.php index c85d41fc7..a62f23702 100755 --- a/core/lib/Thelia/Core/Template/Loop/Image.php +++ b/core/lib/Thelia/Core/Template/Loop/Image.php @@ -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
"; + //echo "source = ".$this->getSourceId()."source_id=$source_id, id=$id
"; 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); } diff --git a/core/lib/Thelia/Core/Template/Loop/Module.php b/core/lib/Thelia/Core/Template/Loop/Module.php new file mode 100755 index 000000000..1c4f91b4d --- /dev/null +++ b/core/lib/Thelia/Core/Template/Loop/Module.php @@ -0,0 +1,137 @@ +. */ +/* */ +/*************************************************************************************/ + +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 + */ +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; + } +} diff --git a/core/lib/Thelia/Core/Template/Loop/Order.php b/core/lib/Thelia/Core/Template/Loop/Order.php index fd11d8d4c..41d49c4f8 100755 --- a/core/lib/Thelia/Core/Template/Loop/Order.php +++ b/core/lib/Thelia/Core/Template/Loop/Order.php @@ -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; } } diff --git a/core/lib/Thelia/Core/Template/Loop/Payment.php b/core/lib/Thelia/Core/Template/Loop/Payment.php new file mode 100644 index 000000000..542ffb590 --- /dev/null +++ b/core/lib/Thelia/Core/Template/Loop/Payment.php @@ -0,0 +1,84 @@ +. */ +/* */ +/*************************************************************************************/ + +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 + */ +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; + } +} diff --git a/core/lib/Thelia/Core/Template/Loop/Product.php b/core/lib/Thelia/Core/Template/Loop/Product.php index 59f83f8fc..7c812d81f 100755 --- a/core/lib/Thelia/Core/Template/Loop/Product.php +++ b/core/lib/Thelia/Core/Template/Loop/Product.php @@ -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); } diff --git a/core/lib/Thelia/Core/Template/Loop/ProductSaleElements.php b/core/lib/Thelia/Core/Template/Loop/ProductSaleElements.php index e27626129..e25164456 100755 --- a/core/lib/Thelia/Core/Template/Loop/ProductSaleElements.php +++ b/core/lib/Thelia/Core/Template/Loop/ProductSaleElements.php @@ -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); } diff --git a/core/lib/Thelia/Core/Template/Loop/TaxRule.php b/core/lib/Thelia/Core/Template/Loop/TaxRule.php new file mode 100644 index 000000000..5851f631d --- /dev/null +++ b/core/lib/Thelia/Core/Template/Loop/TaxRule.php @@ -0,0 +1,135 @@ +. */ +/* */ +/*************************************************************************************/ + +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 + */ +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; + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php index 41341f789..f39c2a768 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php @@ -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; + } } diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/FlashMessage.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/FlashMessage.php new file mode 100755 index 000000000..569aedb84 --- /dev/null +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/FlashMessage.php @@ -0,0 +1,103 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Core\Template\Smarty\Plugins; + +use Symfony\Component\Form\FormView; +use Thelia\Form\BaseForm; +use Thelia\Core\Template\Element\Exception\ElementNotFoundException; +use Symfony\Component\HttpFoundation\Request; +use Thelia\Core\Template\Smarty\SmartyPluginDescriptor; +use Thelia\Core\Template\Smarty\AbstractSmartyPlugin; +use Thelia\Core\Template\ParserContext; + +/** + * Created by JetBrains PhpStorm. + * Date: 9/18/13 + * Time: 3:56 PM + * + * Plugin for smarty defining blocks allowing to get flash message + * A flash message is a variable, array, object stored in session under the flashMessage key + * ex $SESSION['flashMessage']['myKey'] + * + * blocks : + * - {flashMessage key="myKey"} ... {/flashMessage} + * + * Class Form + * + * @package Thelia\Core\Template\Smarty\Plugins + * @author Guillaume MOREL + */ +class FlashMessage extends AbstractSmartyPlugin +{ + + /** @var Request Request service */ + protected $request; + + /** + * Constructor + * + * @param Request $request Request service + */ + public function __construct(Request $request) + { + $this->request = $request; + } + + /** + * Get FlashMessage + * And clean session from this key + * + * @param array $params Block parameters + * @param mixed $content Block content + * @param \Smarty_Internal_Template $template Template + * @param bool $repeat Control how many times + * the block is displayed + * + * @return mixed + */ + public function getFlashMessage($params, $content, \Smarty_Internal_Template $template, &$repeat) + { + if ($repeat) { + $key = $params['key']; + $flashBag = $this->request->getSession()->get('flashMessage'); + $template->assign('value', $flashBag[$key]); + + // Reset flash message (can be read once) + unset($flashBag[$key]); + $this->request->getSession()->set('flashMessage', $flashBag); + } else { + return $content; + } + } + + /** + * @return array an array of SmartyPluginDescriptor + */ + public function getPluginDescriptors() + { + return array( + new SmartyPluginDescriptor("block", "flashMessage", $this, "getFlashMessage") + ); + } + +} diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/Security.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/Security.php index 71b9c3f81..1492f45cd 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/Security.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/Security.php @@ -29,6 +29,8 @@ use Thelia\Core\Template\Smarty\AbstractSmartyPlugin; use Thelia\Core\Security\SecurityContext; use Thelia\Core\Security\Exception\AuthenticationException; use Thelia\Exception\OrderException; +use Thelia\Model\AddressQuery; +use Thelia\Model\ModuleQuery; class Security extends AbstractSmartyPlugin { @@ -78,7 +80,22 @@ class Security extends AbstractSmartyPlugin { $cart = $this->request->getSession()->getCart(); if($cart===null || $cart->countCartItems() == 0) { - throw new OrderException('Cart must not be empty', OrderException::CART_EMPTY); + throw new OrderException('Cart must not be empty', OrderException::CART_EMPTY, array('empty' => 1)); + } + + return ""; + } + + public function checkValidDeliveryFunction($params, &$smarty) + { + $order = $this->request->getSession()->getOrder(); + /* Does address and module still exists ? We assume address owner can't change neither module type */ + if($order !== null) { + $checkAddress = AddressQuery::create()->findPk($order->chosenDeliveryAddress); + $checkModule = ModuleQuery::create()->findPk($order->getDeliveryModuleId()); + } + if(null === $order || null == $checkAddress || null === $checkModule) { + throw new OrderException('Delivery must be defined', OrderException::UNDEFINED_DELIVERY, array('missing' => 1)); } return ""; @@ -94,6 +111,7 @@ class Security extends AbstractSmartyPlugin return array( new SmartyPluginDescriptor('function', 'check_auth', $this, 'checkAuthFunction'), new SmartyPluginDescriptor('function', 'check_cart_not_empty', $this, 'checkCartNotEmptyFunction'), + new SmartyPluginDescriptor('function', 'check_valid_delivery', $this, 'checkValidDeliveryFunction'), ); } } diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/TheliaLoop.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/TheliaLoop.php index 37801f4c8..bd2c10513 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/TheliaLoop.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/TheliaLoop.php @@ -132,6 +132,8 @@ class TheliaLoop extends AbstractSmartyPlugin $loopResults = $loop->exec(self::$pagination[$name]); + $loopResults->rewind(); + $this->loopstack[$name] = $loopResults; // Pas de résultat ? la boucle est terminée, ne pas évaluer le contenu. diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/UrlGenerator.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/UrlGenerator.php index 56c853d00..c74d1d2b3 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/UrlGenerator.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/UrlGenerator.php @@ -27,6 +27,7 @@ use Thelia\Core\Template\Smarty\SmartyPluginDescriptor; use Thelia\Core\Template\Smarty\AbstractSmartyPlugin; use Thelia\Tools\URL; use Thelia\Core\HttpFoundation\Request; +use Thelia\Core\Translation\Translator; class UrlGenerator extends AbstractSmartyPlugin { @@ -47,11 +48,30 @@ class UrlGenerator extends AbstractSmartyPlugin public function generateUrlFunction($params, &$smarty) { // the path to process - $path = $this->getParam($params, 'path'); + $path = $this->getParam($params, 'path', null); + $file = $this->getParam($params, 'file', null); // Do not invoke index.php in URL (get a static file in web space + $noamp = $this->getParam($params, 'noamp', null); // Do not change & in & + + if ($file !== null) { + $path = $file; + $mode = URL::PATH_TO_FILE; + } + else if ($path !== null) { + $mode = URL::WITH_INDEX_PAGE; + } + else { + throw \InvalidArgumentException(Translator::getInstance()->trans("Please specify either 'path' or 'file' parameter in {url} function.")); + } $target = $this->getParam($params, 'target', null); - $url = URL::getInstance()->absoluteUrl($path, $this->getArgsFromParam($params, array('path', 'target'))); + $url = URL::getInstance()->absoluteUrl( + $path, + $this->getArgsFromParam($params, array('noamp', 'path', 'file', 'target')), + $mode + ); + + if ($noamp == null) $url = str_replace('&', '&', $url); if ($target != null) $url .= '#'.$target; @@ -169,7 +189,8 @@ class UrlGenerator extends AbstractSmartyPlugin protected function getCurrentUrl() { - return URL::getInstance()->retrieveCurrent($this->request)->toString(); + //return URL::getInstance()->retrieveCurrent($this->request)->toString(); + return $this->request->getUri(); } protected function getReturnToUrl() diff --git a/core/lib/Thelia/Core/Template/Smarty/SmartyParser.php b/core/lib/Thelia/Core/Template/Smarty/SmartyParser.php index d76dd8dfa..f0cb6d8d4 100755 --- a/core/lib/Thelia/Core/Template/Smarty/SmartyParser.php +++ b/core/lib/Thelia/Core/Template/Smarty/SmartyParser.php @@ -70,14 +70,8 @@ class SmartyParser extends Smarty implements ParserInterface $this->error_reporting = E_ALL ^ E_NOTICE; // Si on n'est pas en mode debug, activer le cache, avec une lifetime de 15mn, et en vérifiant que les templates sources n'ont pas été modifiés. - if ($debug === false) { - $this->caching = Smarty::CACHING_LIFETIME_CURRENT; - $this->cache_lifetime = 300; - $this->compile_check = true; - } else { - $this->caching = Smarty::CACHING_OFF; - $this->force_compile = true; - } + $this->caching = Smarty::CACHING_OFF; + $this->force_compile = true; // The default HTTP status $this->status = 200; diff --git a/core/lib/Thelia/Coupon/CouponBaseAdapter.php b/core/lib/Thelia/Coupon/CouponBaseAdapter.php index f9fae8651..046b4ac81 100644 --- a/core/lib/Thelia/Coupon/CouponBaseAdapter.php +++ b/core/lib/Thelia/Coupon/CouponBaseAdapter.php @@ -266,4 +266,14 @@ class CouponBaseAdapter implements CouponAdapterInterface { return $this->container->get('thelia.constraint.validator'); } + + /** + * Return the event dispatcher, + * + * @return \Symfony\Component\EventDispatcher\EventDispatcher + */ + public function getDispatcher() + { + return $this->container->get('event_dispatcher'); + } } diff --git a/core/lib/Thelia/Exception/ModuleException.php b/core/lib/Thelia/Exception/ModuleException.php new file mode 100755 index 000000000..263a071b0 --- /dev/null +++ b/core/lib/Thelia/Exception/ModuleException.php @@ -0,0 +1,39 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Exception; + +class ModuleException extends \RuntimeException +{ + const UNKNOWN_EXCEPTION = 0; + + const CODE_NOT_FOUND = 404; + + public function __construct($message, $code = null, $previous = null) + { + if ($code === null) { + $code = self::UNKNOWN_EXCEPTION; + } + parent::__construct($message, $code, $previous); + } +} diff --git a/core/lib/Thelia/Exception/OrderException.php b/core/lib/Thelia/Exception/OrderException.php index d276f8b59..70fd21c01 100755 --- a/core/lib/Thelia/Exception/OrderException.php +++ b/core/lib/Thelia/Exception/OrderException.php @@ -25,12 +25,25 @@ namespace Thelia\Exception; class OrderException extends \RuntimeException { + /** + * @var string The cart template name + */ + public $cartRoute = "cart.view"; + public $orderDeliveryRoute = "order.delivery"; + + public $arguments = array(); + const UNKNOWN_EXCEPTION = 0; const CART_EMPTY = 100; - public function __construct($message, $code = null, $previous = null) + const UNDEFINED_DELIVERY = 200; + + public function __construct($message, $code = null, $arguments = array(), $previous = null) { + if(is_array($arguments)) { + $this->arguments = $arguments; + } if ($code === null) { $code = self::UNKNOWN_EXCEPTION; } diff --git a/core/lib/Thelia/Exception/TaxEngineException.php b/core/lib/Thelia/Exception/TaxEngineException.php index 93f5b8237..86f8952b9 100755 --- a/core/lib/Thelia/Exception/TaxEngineException.php +++ b/core/lib/Thelia/Exception/TaxEngineException.php @@ -39,6 +39,7 @@ class TaxEngineException extends \RuntimeException const UNDEFINED_TAX_RULES_COLLECTION = 503; const UNDEFINED_REQUIREMENTS = 504; const UNDEFINED_REQUIREMENT_VALUE = 505; + const UNDEFINED_TAX_RULE = 506; const BAD_AMOUNT_FORMAT = 601; diff --git a/core/lib/Thelia/Exception/TheliaProcessException.php b/core/lib/Thelia/Exception/TheliaProcessException.php new file mode 100755 index 000000000..f61224dea --- /dev/null +++ b/core/lib/Thelia/Exception/TheliaProcessException.php @@ -0,0 +1,54 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Exception; + +/** + * these exception are non fatal exception, due to thelia process exception + * or customer random navigation + * + * they redirect the customer who trig them to a specific error page // @todo + * + * Class TheliaProcessException + * @package Thelia\Exception + */ +class TheliaProcessException extends \RuntimeException +{ + public $data = null; + + const UNKNOWN_EXCEPTION = 0; + + const CART_ITEM_NOT_ENOUGH_STOCK = 100; + const NO_PLACED_ORDER = 101; + const PLACED_ORDER_ID_BAD_CURRENT_CUSTOMER = 102; + + public function __construct($message, $code = null, $data = null, $previous = null) + { + $this->data = $data; + + if ($code === null) { + $code = self::UNKNOWN_EXCEPTION; + } + parent::__construct($message, $code, $previous); + } +} diff --git a/core/lib/Thelia/Form/CategoryDocumentModification.php b/core/lib/Thelia/Form/CategoryDocumentModification.php new file mode 100644 index 000000000..47c637df0 --- /dev/null +++ b/core/lib/Thelia/Form/CategoryDocumentModification.php @@ -0,0 +1,54 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + + +use Thelia\Core\Translation\Translator; +use Thelia\Form\Image\DocumentModification; +use Thelia\Form\Image\ImageModification; + +/** + * Created by JetBrains PhpStorm. + * Date: 9/18/13 + * Time: 3:56 PM + * + * Form allowing to process an document collection + * + * @package Image + * @author Guillaume MOREL + * + */ +class CategoryDocumentModification extends DocumentModification +{ + + /** + * Get form name + * This name must be unique + * + * @return string + */ + public function getName() + { + return 'thelia_category_document_modification'; + } +} diff --git a/core/lib/Thelia/Form/CategoryImageModification.php b/core/lib/Thelia/Form/CategoryImageModification.php new file mode 100644 index 000000000..06674d9ef --- /dev/null +++ b/core/lib/Thelia/Form/CategoryImageModification.php @@ -0,0 +1,53 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + + +use Thelia\Core\Translation\Translator; +use Thelia\Form\Image\ImageModification; + +/** + * Created by JetBrains PhpStorm. + * Date: 9/18/13 + * Time: 3:56 PM + * + * Form allowing to process an image collection + * + * @package Image + * @author Guillaume MOREL + * + */ +class CategoryImageModification extends ImageModification +{ + + /** + * Get form name + * This name must be unique + * + * @return string + */ + public function getName() + { + return 'thelia_category_image_modification'; + } +} diff --git a/core/lib/Thelia/Form/ContentCreationForm.php b/core/lib/Thelia/Form/ContentCreationForm.php new file mode 100644 index 000000000..df8838f59 --- /dev/null +++ b/core/lib/Thelia/Form/ContentCreationForm.php @@ -0,0 +1,65 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + +use Symfony\Component\Validator\Constraints\NotBlank; +use Thelia\Core\Translation\Translator; + +class ContentCreationForm extends BaseForm +{ + protected function buildForm() + { + $this->formBuilder + ->add("title", "text", array( + "constraints" => array( + new NotBlank() + ), + "label" => "Content title *", + "label_attr" => array( + "for" => "title" + ) + )) + ->add("default_folder", "integer", array( + "label" => Translator::getInstance()->trans("Default folder *"), + "constraints" => array( + new NotBlank() + ), + "label_attr" => array("for" => "default_folder") + )) + ->add("locale", "text", array( + "constraints" => array( + new NotBlank() + ) + )) + ->add("visible", "integer", array( + "label" => Translator::getInstance()->trans("This content is online."), + "label_attr" => array("for" => "visible_create") + )) + ; + } + + public function getName() + { + return "thelia_content_creation"; + } +} diff --git a/core/lib/Thelia/Form/ContentDocumentModification.php b/core/lib/Thelia/Form/ContentDocumentModification.php new file mode 100644 index 000000000..748eec0ec --- /dev/null +++ b/core/lib/Thelia/Form/ContentDocumentModification.php @@ -0,0 +1,54 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + + +use Thelia\Core\Translation\Translator; +use Thelia\Form\Image\DocumentModification; +use Thelia\Form\Image\ImageModification; + +/** + * Created by JetBrains PhpStorm. + * Date: 9/18/13 + * Time: 3:56 PM + * + * Form allowing to process a file + * + * @package File + * @author Guillaume MOREL + * + */ +class ContentDocumentModification extends DocumentModification +{ + + /** + * Get form name + * This name must be unique + * + * @return string + */ + public function getName() + { + return 'thelia_content_document_modification'; + } +} diff --git a/core/lib/Thelia/Form/ContentImageModification.php b/core/lib/Thelia/Form/ContentImageModification.php new file mode 100644 index 000000000..f40fc5497 --- /dev/null +++ b/core/lib/Thelia/Form/ContentImageModification.php @@ -0,0 +1,53 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + + +use Thelia\Core\Translation\Translator; +use Thelia\Form\Image\ImageModification; + +/** + * Created by JetBrains PhpStorm. + * Date: 9/18/13 + * Time: 3:56 PM + * + * Form allowing to process an image collection + * + * @package Image + * @author Guillaume MOREL + * + */ +class ContentImageModification extends ImageModification +{ + + /** + * Get form name + * This name must be unique + * + * @return string + */ + public function getName() + { + return 'thelia_content_image_modification'; + } +} diff --git a/core/lib/Thelia/Form/ContentModificationForm.php b/core/lib/Thelia/Form/ContentModificationForm.php new file mode 100644 index 000000000..38ad4e2cf --- /dev/null +++ b/core/lib/Thelia/Form/ContentModificationForm.php @@ -0,0 +1,61 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Form; + +use Symfony\Component\Validator\Constraints\GreaterThan; +use Symfony\Component\Validator\Constraints\NotBlank; +use Thelia\Core\Translation\Translator; +use Thelia\Form\StandardDescriptionFieldsTrait; + +/** + * Class ContentModificationForm + * @package Thelia\Form + * @author manuel raynaud + */ +class ContentModificationForm extends ContentCreationForm { + use StandardDescriptionFieldsTrait; + + protected function buildForm() + { + parent::buildForm(); + + $this->formBuilder + ->add("id", "hidden", array("constraints" => array(new GreaterThan(array('value' => 0))))) + + ->add("url", "text", array( + "label" => Translator::getInstance()->trans("Rewriten URL *"), + "constraints" => array(new NotBlank()), + "label_attr" => array("for" => "rewritten_url") + )) + ; + + // Add standard description fields, excluding title and locale, which a re defined in parent class + $this->addStandardDescFields(array('title', 'locale')); + } + + public function getName() + { + return "thelia_content_modification"; + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Form/FolderCreationForm.php b/core/lib/Thelia/Form/FolderCreationForm.php new file mode 100644 index 000000000..ac7b10376 --- /dev/null +++ b/core/lib/Thelia/Form/FolderCreationForm.php @@ -0,0 +1,66 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + +use Symfony\Component\Validator\Constraints\NotBlank; +use Thelia\Core\Translation\Translator; + +class FolderCreationForm extends BaseForm +{ + protected function buildForm() + { + $this->formBuilder + ->add("title", "text", array( + "constraints" => array( + new NotBlank() + ), + "label" => Translator::getInstance()->trans("Folder title *"), + "label_attr" => array( + "for" => "title" + ) + )) + ->add("parent", "text", array( + "label" => Translator::getInstance()->trans("Parent folder *"), + "constraints" => array( + new NotBlank() + ), + "label_attr" => array("for" => "parent_create") + )) + ->add("locale", "text", array( + "constraints" => array( + new NotBlank() + ), + "label_attr" => array("for" => "locale_create") + )) + ->add("visible", "integer", array( + "label" => Translator::getInstance()->trans("This folder is online."), + "label_attr" => array("for" => "visible_create") + )) + ; + } + + public function getName() + { + return "thelia_folder_creation"; + } +} diff --git a/core/lib/Thelia/Form/FolderDocumentModification.php b/core/lib/Thelia/Form/FolderDocumentModification.php new file mode 100644 index 000000000..bbf57ab9d --- /dev/null +++ b/core/lib/Thelia/Form/FolderDocumentModification.php @@ -0,0 +1,54 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + + +use Thelia\Core\Translation\Translator; +use Thelia\Form\Image\DocumentModification; +use Thelia\Form\Image\ImageModification; + +/** + * Created by JetBrains PhpStorm. + * Date: 9/18/13 + * Time: 3:56 PM + * + * Form allowing to process a file + * + * @package Image + * @author Guillaume MOREL + * + */ +class FolderDocumentModification extends DocumentModification +{ + + /** + * Get form name + * This name must be unique + * + * @return string + */ + public function getName() + { + return 'thelia_folder_document_modification'; + } +} diff --git a/core/lib/Thelia/Form/FolderImageModification.php b/core/lib/Thelia/Form/FolderImageModification.php new file mode 100644 index 000000000..a9305433b --- /dev/null +++ b/core/lib/Thelia/Form/FolderImageModification.php @@ -0,0 +1,53 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + + +use Thelia\Core\Translation\Translator; +use Thelia\Form\Image\ImageModification; + +/** + * Created by JetBrains PhpStorm. + * Date: 9/18/13 + * Time: 3:56 PM + * + * Form allowing to process an image collection + * + * @package Image + * @author Guillaume MOREL + * + */ +class FolderImageModification extends ImageModification +{ + + /** + * Get form name + * This name must be unique + * + * @return string + */ + public function getName() + { + return 'thelia_folder_image_modification'; + } +} diff --git a/core/lib/Thelia/Form/FolderModificationForm.php b/core/lib/Thelia/Form/FolderModificationForm.php new file mode 100644 index 000000000..0ff90868c --- /dev/null +++ b/core/lib/Thelia/Form/FolderModificationForm.php @@ -0,0 +1,55 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + +use Symfony\Component\Validator\Constraints\GreaterThan; +use Thelia\Core\Translation\Translator; +use Symfony\Component\Validator\Constraints\NotBlank; + +class FolderModificationForm extends FolderCreationForm +{ + use StandardDescriptionFieldsTrait; + + protected function buildForm() + { + parent::buildForm(); + + $this->formBuilder + ->add("id", "hidden", array("constraints" => array(new GreaterThan(array('value' => 0))))) + + ->add("url", "text", array( + "label" => Translator::getInstance()->trans("Rewriten URL *"), + "constraints" => array(new NotBlank()), + "label_attr" => array("for" => "rewriten_url") + )) + ; + + // Add standard description fields, excluding title and locale, which a re defined in parent class + $this->addStandardDescFields(array('title', 'locale')); + } + + public function getName() + { + return "thelia_folder_modification"; + } +} diff --git a/core/lib/Thelia/Form/Image/DocumentModification.php b/core/lib/Thelia/Form/Image/DocumentModification.php new file mode 100644 index 000000000..39ba559be --- /dev/null +++ b/core/lib/Thelia/Form/Image/DocumentModification.php @@ -0,0 +1,138 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form\Image; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Validator\Constraints\Image; +use Symfony\Component\Validator\Constraints\NotBlank; +use Thelia\Core\Translation\Translator; +use Thelia\Form\BaseForm; + +/** + * Created by JetBrains PhpStorm. + * Date: 9/18/13 + * Time: 3:56 PM + * + * Form allowing to process a file + * @todo refactor make all document using propel inheritance and factorise image behaviour into one single clean action + * + * @package File + * @author Guillaume MOREL + * + */ +abstract class DocumentModification extends BaseForm +{ + /** + * + * in this function you add all the fields you need for your Form. + * Form this you have to call add method on $this->form attribute : + * + * $this->form->add('name', 'text') + * ->add('email', 'email', array( + * 'attr' => array( + * 'class' => 'field' + * ), + * 'label' => 'email', + * 'constraints' => array( + * new NotBlank() + * ) + * ) + * ) + * ->add('age', 'integer'); + * + * @return null + */ + protected function buildForm() + { + $this->formBuilder->add( + 'file', + 'file', + array( + 'constraints' => array(), + 'label' => Translator::getInstance()->trans('Replace current document by this file'), + 'label_attr' => array( + 'for' => 'file' + ) + ) + ); + + $this->formBuilder + ->add( + 'title', + 'text', + array( + 'constraints' => array( + new NotBlank() + ), + 'label' => Translator::getInstance()->trans('Title'), + 'label_attr' => array( + 'for' => 'title' + ) + ) + ) + ->add( + 'description', + 'text', + array( + 'constraints' => array(), + 'label' => Translator::getInstance()->trans('Description'), + 'label_attr' => array( + 'for' => 'description' + ) + ) + ) + ->add( + 'chapo', + 'text', + array( + 'constraints' => array(), + 'label' => Translator::getInstance()->trans('Chapo'), + 'label_attr' => array( + 'for' => 'chapo' + ) + ) + ) + ->add( + 'postscriptum', + 'text', + array( + 'constraints' => array(), + 'label' => Translator::getInstance()->trans('Post Scriptum'), + 'label_attr' => array( + 'for' => 'postscriptum' + ) + ) + ) + ->add( + 'postscriptum', + 'text', + array( + 'constraints' => array(), + 'label' => Translator::getInstance()->trans('Post Scriptum'), + 'label_attr' => array( + 'for' => 'postscriptum' + ) + ) + ); + } +} diff --git a/core/lib/Thelia/Form/Image/ImageModification.php b/core/lib/Thelia/Form/Image/ImageModification.php new file mode 100644 index 000000000..c4d26378b --- /dev/null +++ b/core/lib/Thelia/Form/Image/ImageModification.php @@ -0,0 +1,146 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form\Image; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Validator\Constraints\Image; +use Symfony\Component\Validator\Constraints\NotBlank; +use Thelia\Core\Translation\Translator; +use Thelia\Form\BaseForm; + +/** + * Created by JetBrains PhpStorm. + * Date: 9/18/13 + * Time: 3:56 PM + * + * Form allowing to process an image + * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action + * + * @package Image + * @author Guillaume MOREL + * + */ +abstract class ImageModification extends BaseForm +{ + + /** + * + * in this function you add all the fields you need for your Form. + * Form this you have to call add method on $this->form attribute : + * + * $this->form->add('name', 'text') + * ->add('email', 'email', array( + * 'attr' => array( + * 'class' => 'field' + * ), + * 'label' => 'email', + * 'constraints' => array( + * new NotBlank() + * ) + * ) + * ) + * ->add('age', 'integer'); + * + * @return null + */ + protected function buildForm() + { + $this->formBuilder->add( + 'file', + 'file', + array( + 'constraints' => array( + new Image( + array( +// 'minWidth' => 200, +// 'minHeight' => 200 + ) + ) + ), + 'label' => Translator::getInstance()->trans('Replace current image by this file'), + 'label_attr' => array( + 'for' => 'file' + ) + ) + ); + + $this->formBuilder + ->add( + 'title', + 'text', + array( + 'constraints' => array( + new NotBlank() + ), + 'label' => Translator::getInstance()->trans('Title'), + 'label_attr' => array( + 'for' => 'title' + ) + ) + ) + ->add( + 'description', + 'text', + array( + 'constraints' => array(), + 'label' => Translator::getInstance()->trans('Description'), + 'label_attr' => array( + 'for' => 'description' + ) + ) + ) + ->add( + 'chapo', + 'text', + array( + 'constraints' => array(), + 'label' => Translator::getInstance()->trans('Chapo'), + 'label_attr' => array( + 'for' => 'chapo' + ) + ) + ) + ->add( + 'postscriptum', + 'text', + array( + 'constraints' => array(), + 'label' => Translator::getInstance()->trans('Post Scriptum'), + 'label_attr' => array( + 'for' => 'postscriptum' + ) + ) + ) + ->add( + 'postscriptum', + 'text', + array( + 'constraints' => array(), + 'label' => Translator::getInstance()->trans('Post Scriptum'), + 'label_attr' => array( + 'for' => 'postscriptum' + ) + ) + ); + } +} diff --git a/core/lib/Thelia/Form/OrderDelivery.php b/core/lib/Thelia/Form/OrderDelivery.php index 3ef1444f6..8cddb5bd9 100755 --- a/core/lib/Thelia/Form/OrderDelivery.php +++ b/core/lib/Thelia/Form/OrderDelivery.php @@ -80,11 +80,18 @@ class OrderDelivery extends BaseForm ->filterByType(BaseModule::DELIVERY_MODULE_TYPE) ->filterByActivate(1) ->filterById($value) - ->find(); + ->findOne(); if(null === $module) { $context->addViolation("Delivery module ID not found"); } + + $moduleReflection = new \ReflectionClass($module->getFullNamespace()); + if ($moduleReflection->isSubclassOf("Thelia\Module\DeliveryModuleInterface") === false) { + $context->addViolation( + sprintf("delivery module %s is not a Thelia\Module\DeliveryModuleInterface", $module->getCode()) + ); + } } public function getName() diff --git a/core/lib/Thelia/Form/OrderPayment.php b/core/lib/Thelia/Form/OrderPayment.php new file mode 100755 index 000000000..6a6305971 --- /dev/null +++ b/core/lib/Thelia/Form/OrderPayment.php @@ -0,0 +1,101 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + +use Symfony\Component\Validator\Constraints; +use Symfony\Component\Validator\ExecutionContextInterface; +use Thelia\Model\AddressQuery; +use Thelia\Model\ConfigQuery; +use Thelia\Core\Translation\Translator; +use Thelia\Model\ModuleQuery; +use Thelia\Module\BaseModule; + +/** + * Class OrderPayment + * @package Thelia\Form + * @author Etienne Roudeix + */ +class OrderPayment extends BaseForm +{ + protected function buildForm() + { + $this->formBuilder + ->add("invoice-address", "integer", array( + "required" => true, + "constraints" => array( + new Constraints\NotBlank(), + new Constraints\Callback(array( + "methods" => array( + array($this, "verifyInvoiceAddress") + ) + )) + ) + )) + ->add("payment-module", "integer", array( + "required" => true, + "constraints" => array( + new Constraints\NotBlank(), + new Constraints\Callback(array( + "methods" => array( + array($this, "verifyPaymentModule") + ) + )) + ) + )); + } + + public function verifyInvoiceAddress($value, ExecutionContextInterface $context) + { + $address = AddressQuery::create() + ->findPk($value); + + if(null === $address) { + $context->addViolation("Address ID not found"); + } + } + + public function verifyPaymentModule($value, ExecutionContextInterface $context) + { + $module = ModuleQuery::create() + ->filterByType(BaseModule::PAYMENT_MODULE_TYPE) + ->filterByActivate(1) + ->filterById($value) + ->findOne(); + + if(null === $module) { + $context->addViolation("Payment module ID not found"); + } + + $moduleReflection = new \ReflectionClass($module->getFullNamespace()); + if ($moduleReflection->isSubclassOf("Thelia\Module\PaymentModuleInterface") === false) { + $context->addViolation( + sprintf("delivery module %s is not a Thelia\Module\PaymentModuleInterface", $module->getCode()) + ); + } + } + + public function getName() + { + return "thelia_order_payment"; + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Form/ProductCreationForm.php b/core/lib/Thelia/Form/ProductCreationForm.php index 49ab76fb7..c1b8bd6b4 100644 --- a/core/lib/Thelia/Form/ProductCreationForm.php +++ b/core/lib/Thelia/Form/ProductCreationForm.php @@ -23,45 +23,85 @@ namespace Thelia\Form; use Symfony\Component\Validator\Constraints\NotBlank; +use Thelia\Core\Translation\Translator; +use Thelia\Model\ProductQuery; +use Symfony\Component\Validator\Constraints\Callback; +use Symfony\Component\Validator\ExecutionContextInterface; class ProductCreationForm extends BaseForm { - protected function buildForm() + protected function buildForm($change_mode = false) { + $ref_constraints = array(new NotBlank()); + + if (! $change_mode) { + $ref_constraints[] = new Callback(array( + "methods" => array(array($this, "checkDuplicateRef")) + )); + } + $this->formBuilder ->add("ref", "text", array( - "constraints" => array( - new NotBlank() - ), - "label" => "Product reference *", - "label_attr" => array( - "for" => "ref" - ) + "constraints" => $ref_constraints, + "label" => "Product reference *", + "label_attr" => array("for" => "ref") )) ->add("title", "text", array( - "constraints" => array( - new NotBlank() - ), + "constraints" => array(new NotBlank()), "label" => "Product title *", - "label_attr" => array( - "for" => "title" - ) + "label_attr" => array("for" => "title") )) ->add("default_category", "integer", array( - "constraints" => array( - new NotBlank() - ) + "constraints" => array(new NotBlank()), + "label" => Translator::getInstance()->trans("Default product category *"), + "label_attr" => array("for" => "default_category_field") )) ->add("locale", "text", array( - "constraints" => array( - new NotBlank() - ) + "constraints" => array(new NotBlank()) )) ->add("visible", "integer", array( - "label" => Translator::getInstance()->trans("This product is online."), - "label_attr" => array("for" => "visible_create") + "label" => Translator::getInstance()->trans("This product is online"), + "label_attr" => array("for" => "visible_field") )) ; + + if (! $change_mode) { + $this->formBuilder + ->add("price", "number", array( + "constraints" => array(new NotBlank()), + "label" => Translator::getInstance()->trans("Product base price excluding taxes *"), + "label_attr" => array("for" => "price_field") + )) + ->add("currency", "integer", array( + "constraints" => array(new NotBlank()), + "label" => Translator::getInstance()->trans("Price currency *"), + "label_attr" => array("for" => "currency_field") + )) + ->add("tax_rule", "integer", array( + "constraints" => array(new NotBlank()), + "label" => Translator::getInstance()->trans("Tax rule for this product *"), + "label_attr" => array("for" => "tax_rule_field") + )) + ->add("weight", "number", array( + "constraints" => array(new NotBlank()), + "label" => Translator::getInstance()->trans("Weight *"), + "label_attr" => array("for" => "weight_field") + )) + ; + } + } + + public function checkDuplicateRef($value, ExecutionContextInterface $context) + { + $count = ProductQuery::create()->filterByRef($value)->count(); + + if ($count > 0) { + $context->addViolation( + Translator::getInstance()->trans( + "A product with reference %ref already exists. Please choose another reference.", + array('%ref' => $value) + )); + } } public function getName() diff --git a/core/lib/Thelia/Form/ProductDetailsModificationForm.php b/core/lib/Thelia/Form/ProductDetailsModificationForm.php new file mode 100644 index 000000000..7ded6ff69 --- /dev/null +++ b/core/lib/Thelia/Form/ProductDetailsModificationForm.php @@ -0,0 +1,90 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + +use Symfony\Component\Validator\Constraints\GreaterThan; +use Thelia\Core\Translation\Translator; +use Symfony\Component\Validator\Constraints\NotBlank; + +class ProductDetailsModificationForm extends BaseForm +{ + use StandardDescriptionFieldsTrait; + + protected function buildForm() + { + $this->formBuilder + ->add("id", "integer", array( + "label" => Translator::getInstance()->trans("Prodcut ID *"), + "label_attr" => array("for" => "product_id_field"), + "constraints" => array(new GreaterThan(array('value' => 0))) + )) + ->add("price", "number", array( + "constraints" => array(new NotBlank()), + "label" => Translator::getInstance()->trans("Product base price excluding taxes *"), + "label_attr" => array("for" => "price_field") + )) + ->add("price_with_tax", "number", array( + "label" => Translator::getInstance()->trans("Product base price including taxes *"), + "label_attr" => array("for" => "price_with_tax_field") + )) + ->add("currency", "integer", array( + "constraints" => array(new NotBlank()), + "label" => Translator::getInstance()->trans("Price currency *"), + "label_attr" => array("for" => "currency_field") + )) + ->add("tax_rule", "integer", array( + "constraints" => array(new NotBlank()), + "label" => Translator::getInstance()->trans("Tax rule for this product *"), + "label_attr" => array("for" => "tax_rule_field") + )) + ->add("weight", "number", array( + "constraints" => array(new NotBlank()), + "label" => Translator::getInstance()->trans("Weight *"), + "label_attr" => array("for" => "weight_field") + )) + ->add("quantity", "number", array( + "constraints" => array(new NotBlank()), + "label" => Translator::getInstance()->trans("Current quantity *"), + "label_attr" => array("for" => "quantity_field") + )) + ->add("sale_price", "number", array( + "label" => Translator::getInstance()->trans("Sale price *"), + "label_attr" => array("for" => "price_with_tax_field") + )) + ->add("onsale", "integer", array( + "label" => Translator::getInstance()->trans("This product is on sale"), + "label_attr" => array("for" => "onsale_field") + )) + ->add("isnew", "integer", array( + "label" => Translator::getInstance()->trans("Advertise this product as new"), + "label_attr" => array("for" => "isnew_field") + )) + + ; + } + + public function getName() + { + return "thelia_product_details_modification"; + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Form/ProductDocumentModification.php b/core/lib/Thelia/Form/ProductDocumentModification.php new file mode 100644 index 000000000..1a9bc5467 --- /dev/null +++ b/core/lib/Thelia/Form/ProductDocumentModification.php @@ -0,0 +1,54 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + + +use Thelia\Core\Translation\Translator; +use Thelia\Form\Image\DocumentModification; +use Thelia\Form\Image\ImageModification; + +/** + * Created by JetBrains PhpStorm. + * Date: 9/18/13 + * Time: 3:56 PM + * + * Form allowing to process a file + * + * @package File + * @author Guillaume MOREL + * + */ +class ProductDocumentModification extends DocumentModification +{ + + /** + * Get form name + * This name must be unique + * + * @return string + */ + public function getName() + { + return 'thelia_product_document_modification'; + } +} diff --git a/core/lib/Thelia/Form/ProductImageModification.php b/core/lib/Thelia/Form/ProductImageModification.php new file mode 100644 index 000000000..2d35e176f --- /dev/null +++ b/core/lib/Thelia/Form/ProductImageModification.php @@ -0,0 +1,53 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + + +use Thelia\Core\Translation\Translator; +use Thelia\Form\Image\ImageModification; + +/** + * Created by JetBrains PhpStorm. + * Date: 9/18/13 + * Time: 3:56 PM + * + * Form allowing to process an image collection + * + * @package Image + * @author Guillaume MOREL + * + */ +class ProductImageModification extends ImageModification +{ + + /** + * Get form name + * This name must be unique + * + * @return string + */ + public function getName() + { + return 'thelia_product_image_modification'; + } +} diff --git a/core/lib/Thelia/Form/ProfileModificationForm.php b/core/lib/Thelia/Form/ProfileModificationForm.php new file mode 100644 index 000000000..e3119cfee --- /dev/null +++ b/core/lib/Thelia/Form/ProfileModificationForm.php @@ -0,0 +1,119 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Form; + +use Symfony\Component\Validator\Constraints; +use Thelia\Core\Translation\Translator; +use Thelia\Model\ConfigQuery; + +/** + * Class ProfileModification + * @package Thelia\Form + * @author Manuel Raynaud + */ +class ProfileModificationForm extends BaseForm +{ + + + protected function buildForm() + { + + $this->formBuilder + ->add("firstname", "text", array( + "constraints" => array( + new Constraints\NotBlank() + ), + "label" => Translator::getInstance()->trans("First Name"), + "label_attr" => array( + "for" => "firstname" + ) + )) + ->add("lastname", "text", array( + "constraints" => array( + new Constraints\NotBlank() + ), + "label" => Translator::getInstance()->trans("Last Name"), + "label_attr" => array( + "for" => "lastname" + ) + )) + ->add("default_language", "text", array( + "constraints" => array( + new Constraints\NotBlank() + ), + "label" => Translator::getInstance()->trans("Default language"), + "label_attr" => array( + "for" => "default_language" + ) + )) + ->add("editing_language_default", "text", array( + "constraints" => array( + new Constraints\NotBlank() + ), + "label" => Translator::getInstance()->trans("Editing language default"), + "label_attr" => array( + "for" => "editing_language_default" + ) + )) + ->add("old_password", "password", array( + "constraints" => array( + new Constraints\NotBlank(), + new Constraints\Length(array("min" => ConfigQuery::read("password.length", 4))) + ), + "label" => Translator::getInstance()->trans("Old password"), + "label_attr" => array( + "for" => "old_password" + ) + )) + ->add("password", "password", array( + "constraints" => array( + new Constraints\NotBlank(), + new Constraints\Length(array("min" => ConfigQuery::read("password.length", 4))) + ), + "label" => Translator::getInstance()->trans("Password"), + "label_attr" => array( + "for" => "password" + ) + )) + ->add("password_confirm", "password", array( + "constraints" => array( + new Constraints\NotBlank(), + new Constraints\Length(array("min" => ConfigQuery::read("password.length", 4))), + new Constraints\Callback(array("methods" => array( + array($this, "verifyPasswordField") + ))) + ), + "label" => "Password confirmation", + "label_attr" => array( + "for" => "password_confirmation" + ) + )) + ; + } + + public function getName() + { + return "thelia_profile_modification"; + } +} diff --git a/core/lib/Thelia/Install/CheckPermission.php b/core/lib/Thelia/Install/CheckPermission.php index d07b8ed83..15317211b 100644 --- a/core/lib/Thelia/Install/CheckPermission.php +++ b/core/lib/Thelia/Install/CheckPermission.php @@ -44,12 +44,14 @@ class CheckPermission extends BaseInstall const DIR_CONF = 'local/config'; const DIR_LOG = 'log'; const DIR_CACHE = 'cache'; + const DIR_WEB = 'web'; /** @var array Directory needed to be writable */ protected $directoriesToBeWritable = array( self::DIR_CONF, self::DIR_LOG, self::DIR_CACHE, + self::DIR_WEB, ); /** @var array Minimum server configuration necessary */ diff --git a/core/lib/Thelia/Model/Accessory.php b/core/lib/Thelia/Model/Accessory.php index 2e927ff7c..f24aab680 100755 --- a/core/lib/Thelia/Model/Accessory.php +++ b/core/lib/Thelia/Model/Accessory.php @@ -3,7 +3,77 @@ namespace Thelia\Model; use Thelia\Model\Base\Accessory as BaseAccessory; +use Thelia\Core\Event\TheliaEvents; +use Propel\Runtime\Connection\ConnectionInterface; +use Thelia\Core\Event\AccessoryEvent; class Accessory extends BaseAccessory { + use \Thelia\Model\Tools\ModelEventDispatcherTrait; + + use \Thelia\Model\Tools\PositionManagementTrait; + + /** + * Calculate next position relative to our product + */ + protected function addCriteriaToPositionQuery($query) { + $query->filterByProductId($this->getProductId()); + } + + /** + * {@inheritDoc} + */ + public function preInsert(ConnectionInterface $con = null) + { + $this->setPosition($this->getNextPosition()); + + $this->dispatchEvent(TheliaEvents::BEFORE_CREATEACCESSORY, new AccessoryEvent($this)); + + return true; + } + + /** + * {@inheritDoc} + */ + public function postInsert(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_CREATEACCESSORY, new AccessoryEvent($this)); + } + + /** + * {@inheritDoc} + */ + public function preUpdate(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::BEFORE_UPDATEACCESSORY, new AccessoryEvent($this)); + + return true; + } + + /** + * {@inheritDoc} + */ + public function postUpdate(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_UPDATEACCESSORY, new AccessoryEvent($this)); + } + + /** + * {@inheritDoc} + */ + public function preDelete(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::BEFORE_DELETEACCESSORY, new AccessoryEvent($this)); + + return true; + } + + /** + * {@inheritDoc} + */ + public function postDelete(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_DELETEACCESSORY, new AccessoryEvent($this)); + } + } diff --git a/core/lib/Thelia/Model/AttributeCategory.php b/core/lib/Thelia/Model/AttributeCategory.php deleted file mode 100755 index ef1341e08..000000000 --- a/core/lib/Thelia/Model/AttributeCategory.php +++ /dev/null @@ -1,9 +0,0 @@ -filterByTemplateId($this->getTemplateId()); + } + + /** + * {@inheritDoc} + */ + public function preInsert(ConnectionInterface $con = null) + { + $this->setPosition($this->getNextPosition()); + + return true; + } } diff --git a/core/lib/Thelia/Model/Base/AttributeTemplate.php b/core/lib/Thelia/Model/Base/AttributeTemplate.php index cedc85431..0014e1a8d 100644 --- a/core/lib/Thelia/Model/Base/AttributeTemplate.php +++ b/core/lib/Thelia/Model/Base/AttributeTemplate.php @@ -76,6 +76,18 @@ abstract class AttributeTemplate implements ActiveRecordInterface */ protected $template_id; + /** + * The value for the position field. + * @var int + */ + protected $position; + + /** + * The value for the attribute_templatecol field. + * @var string + */ + protected $attribute_templatecol; + /** * The value for the created_at field. * @var string @@ -393,6 +405,28 @@ abstract class AttributeTemplate implements ActiveRecordInterface return $this->template_id; } + /** + * Get the [position] column value. + * + * @return int + */ + public function getPosition() + { + + return $this->position; + } + + /** + * Get the [attribute_templatecol] column value. + * + * @return string + */ + public function getAttributeTemplatecol() + { + + return $this->attribute_templatecol; + } + /** * Get the [optionally formatted] temporal [created_at] column value. * @@ -504,6 +538,48 @@ abstract class AttributeTemplate implements ActiveRecordInterface return $this; } // setTemplateId() + /** + * Set the value of [position] column. + * + * @param int $v new value + * @return \Thelia\Model\AttributeTemplate The current object (for fluent API support) + */ + public function setPosition($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->position !== $v) { + $this->position = $v; + $this->modifiedColumns[] = AttributeTemplateTableMap::POSITION; + } + + + return $this; + } // setPosition() + + /** + * Set the value of [attribute_templatecol] column. + * + * @param string $v new value + * @return \Thelia\Model\AttributeTemplate The current object (for fluent API support) + */ + public function setAttributeTemplatecol($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->attribute_templatecol !== $v) { + $this->attribute_templatecol = $v; + $this->modifiedColumns[] = AttributeTemplateTableMap::ATTRIBUTE_TEMPLATECOL; + } + + + return $this; + } // setAttributeTemplatecol() + /** * Sets the value of [created_at] column to a normalized version of the date/time value specified. * @@ -592,13 +668,19 @@ abstract class AttributeTemplate implements ActiveRecordInterface $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : AttributeTemplateTableMap::translateFieldName('TemplateId', TableMap::TYPE_PHPNAME, $indexType)]; $this->template_id = (null !== $col) ? (int) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : AttributeTemplateTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : AttributeTemplateTableMap::translateFieldName('Position', TableMap::TYPE_PHPNAME, $indexType)]; + $this->position = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : AttributeTemplateTableMap::translateFieldName('AttributeTemplatecol', TableMap::TYPE_PHPNAME, $indexType)]; + $this->attribute_templatecol = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : AttributeTemplateTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } $this->created_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : AttributeTemplateTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : AttributeTemplateTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } @@ -611,7 +693,7 @@ abstract class AttributeTemplate implements ActiveRecordInterface $this->ensureConsistency(); } - return $startcol + 5; // 5 = AttributeTemplateTableMap::NUM_HYDRATE_COLUMNS. + return $startcol + 7; // 7 = AttributeTemplateTableMap::NUM_HYDRATE_COLUMNS. } catch (Exception $e) { throw new PropelException("Error populating \Thelia\Model\AttributeTemplate object", 0, $e); @@ -867,6 +949,12 @@ abstract class AttributeTemplate implements ActiveRecordInterface if ($this->isColumnModified(AttributeTemplateTableMap::TEMPLATE_ID)) { $modifiedColumns[':p' . $index++] = 'TEMPLATE_ID'; } + if ($this->isColumnModified(AttributeTemplateTableMap::POSITION)) { + $modifiedColumns[':p' . $index++] = 'POSITION'; + } + if ($this->isColumnModified(AttributeTemplateTableMap::ATTRIBUTE_TEMPLATECOL)) { + $modifiedColumns[':p' . $index++] = 'ATTRIBUTE_TEMPLATECOL'; + } if ($this->isColumnModified(AttributeTemplateTableMap::CREATED_AT)) { $modifiedColumns[':p' . $index++] = 'CREATED_AT'; } @@ -893,6 +981,12 @@ abstract class AttributeTemplate implements ActiveRecordInterface case 'TEMPLATE_ID': $stmt->bindValue($identifier, $this->template_id, PDO::PARAM_INT); break; + case 'POSITION': + $stmt->bindValue($identifier, $this->position, PDO::PARAM_INT); + break; + case 'ATTRIBUTE_TEMPLATECOL': + $stmt->bindValue($identifier, $this->attribute_templatecol, PDO::PARAM_STR); + break; case 'CREATED_AT': $stmt->bindValue($identifier, $this->created_at ? $this->created_at->format("Y-m-d H:i:s") : null, PDO::PARAM_STR); break; @@ -971,9 +1065,15 @@ abstract class AttributeTemplate implements ActiveRecordInterface return $this->getTemplateId(); break; case 3: - return $this->getCreatedAt(); + return $this->getPosition(); break; case 4: + return $this->getAttributeTemplatecol(); + break; + case 5: + return $this->getCreatedAt(); + break; + case 6: return $this->getUpdatedAt(); break; default: @@ -1008,8 +1108,10 @@ abstract class AttributeTemplate implements ActiveRecordInterface $keys[0] => $this->getId(), $keys[1] => $this->getAttributeId(), $keys[2] => $this->getTemplateId(), - $keys[3] => $this->getCreatedAt(), - $keys[4] => $this->getUpdatedAt(), + $keys[3] => $this->getPosition(), + $keys[4] => $this->getAttributeTemplatecol(), + $keys[5] => $this->getCreatedAt(), + $keys[6] => $this->getUpdatedAt(), ); $virtualColumns = $this->virtualColumns; foreach($virtualColumns as $key => $virtualColumn) @@ -1068,9 +1170,15 @@ abstract class AttributeTemplate implements ActiveRecordInterface $this->setTemplateId($value); break; case 3: - $this->setCreatedAt($value); + $this->setPosition($value); break; case 4: + $this->setAttributeTemplatecol($value); + break; + case 5: + $this->setCreatedAt($value); + break; + case 6: $this->setUpdatedAt($value); break; } // switch() @@ -1100,8 +1208,10 @@ abstract class AttributeTemplate implements ActiveRecordInterface if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]); if (array_key_exists($keys[1], $arr)) $this->setAttributeId($arr[$keys[1]]); if (array_key_exists($keys[2], $arr)) $this->setTemplateId($arr[$keys[2]]); - if (array_key_exists($keys[3], $arr)) $this->setCreatedAt($arr[$keys[3]]); - if (array_key_exists($keys[4], $arr)) $this->setUpdatedAt($arr[$keys[4]]); + if (array_key_exists($keys[3], $arr)) $this->setPosition($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setAttributeTemplatecol($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setCreatedAt($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setUpdatedAt($arr[$keys[6]]); } /** @@ -1116,6 +1226,8 @@ abstract class AttributeTemplate implements ActiveRecordInterface if ($this->isColumnModified(AttributeTemplateTableMap::ID)) $criteria->add(AttributeTemplateTableMap::ID, $this->id); if ($this->isColumnModified(AttributeTemplateTableMap::ATTRIBUTE_ID)) $criteria->add(AttributeTemplateTableMap::ATTRIBUTE_ID, $this->attribute_id); if ($this->isColumnModified(AttributeTemplateTableMap::TEMPLATE_ID)) $criteria->add(AttributeTemplateTableMap::TEMPLATE_ID, $this->template_id); + if ($this->isColumnModified(AttributeTemplateTableMap::POSITION)) $criteria->add(AttributeTemplateTableMap::POSITION, $this->position); + if ($this->isColumnModified(AttributeTemplateTableMap::ATTRIBUTE_TEMPLATECOL)) $criteria->add(AttributeTemplateTableMap::ATTRIBUTE_TEMPLATECOL, $this->attribute_templatecol); if ($this->isColumnModified(AttributeTemplateTableMap::CREATED_AT)) $criteria->add(AttributeTemplateTableMap::CREATED_AT, $this->created_at); if ($this->isColumnModified(AttributeTemplateTableMap::UPDATED_AT)) $criteria->add(AttributeTemplateTableMap::UPDATED_AT, $this->updated_at); @@ -1183,6 +1295,8 @@ abstract class AttributeTemplate implements ActiveRecordInterface { $copyObj->setAttributeId($this->getAttributeId()); $copyObj->setTemplateId($this->getTemplateId()); + $copyObj->setPosition($this->getPosition()); + $copyObj->setAttributeTemplatecol($this->getAttributeTemplatecol()); $copyObj->setCreatedAt($this->getCreatedAt()); $copyObj->setUpdatedAt($this->getUpdatedAt()); if ($makeNew) { @@ -1323,6 +1437,8 @@ abstract class AttributeTemplate implements ActiveRecordInterface $this->id = null; $this->attribute_id = null; $this->template_id = null; + $this->position = null; + $this->attribute_templatecol = null; $this->created_at = null; $this->updated_at = null; $this->alreadyInSave = false; diff --git a/core/lib/Thelia/Model/Base/AttributeTemplateQuery.php b/core/lib/Thelia/Model/Base/AttributeTemplateQuery.php index bd895360b..5e53ba738 100644 --- a/core/lib/Thelia/Model/Base/AttributeTemplateQuery.php +++ b/core/lib/Thelia/Model/Base/AttributeTemplateQuery.php @@ -24,12 +24,16 @@ use Thelia\Model\Map\AttributeTemplateTableMap; * @method ChildAttributeTemplateQuery orderById($order = Criteria::ASC) Order by the id column * @method ChildAttributeTemplateQuery orderByAttributeId($order = Criteria::ASC) Order by the attribute_id column * @method ChildAttributeTemplateQuery orderByTemplateId($order = Criteria::ASC) Order by the template_id column + * @method ChildAttributeTemplateQuery orderByPosition($order = Criteria::ASC) Order by the position column + * @method ChildAttributeTemplateQuery orderByAttributeTemplatecol($order = Criteria::ASC) Order by the attribute_templatecol column * @method ChildAttributeTemplateQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column * @method ChildAttributeTemplateQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column * * @method ChildAttributeTemplateQuery groupById() Group by the id column * @method ChildAttributeTemplateQuery groupByAttributeId() Group by the attribute_id column * @method ChildAttributeTemplateQuery groupByTemplateId() Group by the template_id column + * @method ChildAttributeTemplateQuery groupByPosition() Group by the position column + * @method ChildAttributeTemplateQuery groupByAttributeTemplatecol() Group by the attribute_templatecol column * @method ChildAttributeTemplateQuery groupByCreatedAt() Group by the created_at column * @method ChildAttributeTemplateQuery groupByUpdatedAt() Group by the updated_at column * @@ -51,12 +55,16 @@ use Thelia\Model\Map\AttributeTemplateTableMap; * @method ChildAttributeTemplate findOneById(int $id) Return the first ChildAttributeTemplate filtered by the id column * @method ChildAttributeTemplate findOneByAttributeId(int $attribute_id) Return the first ChildAttributeTemplate filtered by the attribute_id column * @method ChildAttributeTemplate findOneByTemplateId(int $template_id) Return the first ChildAttributeTemplate filtered by the template_id column + * @method ChildAttributeTemplate findOneByPosition(int $position) Return the first ChildAttributeTemplate filtered by the position column + * @method ChildAttributeTemplate findOneByAttributeTemplatecol(string $attribute_templatecol) Return the first ChildAttributeTemplate filtered by the attribute_templatecol column * @method ChildAttributeTemplate findOneByCreatedAt(string $created_at) Return the first ChildAttributeTemplate filtered by the created_at column * @method ChildAttributeTemplate findOneByUpdatedAt(string $updated_at) Return the first ChildAttributeTemplate filtered by the updated_at column * * @method array findById(int $id) Return ChildAttributeTemplate objects filtered by the id column * @method array findByAttributeId(int $attribute_id) Return ChildAttributeTemplate objects filtered by the attribute_id column * @method array findByTemplateId(int $template_id) Return ChildAttributeTemplate objects filtered by the template_id column + * @method array findByPosition(int $position) Return ChildAttributeTemplate objects filtered by the position column + * @method array findByAttributeTemplatecol(string $attribute_templatecol) Return ChildAttributeTemplate objects filtered by the attribute_templatecol column * @method array findByCreatedAt(string $created_at) Return ChildAttributeTemplate objects filtered by the created_at column * @method array findByUpdatedAt(string $updated_at) Return ChildAttributeTemplate objects filtered by the updated_at column * @@ -147,7 +155,7 @@ abstract class AttributeTemplateQuery extends ModelCriteria */ protected function findPkSimple($key, $con) { - $sql = 'SELECT ID, ATTRIBUTE_ID, TEMPLATE_ID, CREATED_AT, UPDATED_AT FROM attribute_template WHERE ID = :p0'; + $sql = 'SELECT ID, ATTRIBUTE_ID, TEMPLATE_ID, POSITION, ATTRIBUTE_TEMPLATECOL, CREATED_AT, UPDATED_AT FROM attribute_template WHERE ID = :p0'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key, PDO::PARAM_INT); @@ -363,6 +371,76 @@ abstract class AttributeTemplateQuery extends ModelCriteria return $this->addUsingAlias(AttributeTemplateTableMap::TEMPLATE_ID, $templateId, $comparison); } + /** + * Filter the query on the position column + * + * Example usage: + * + * $query->filterByPosition(1234); // WHERE position = 1234 + * $query->filterByPosition(array(12, 34)); // WHERE position IN (12, 34) + * $query->filterByPosition(array('min' => 12)); // WHERE position > 12 + * + * + * @param mixed $position The value to use as filter. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildAttributeTemplateQuery The current query, for fluid interface + */ + public function filterByPosition($position = null, $comparison = null) + { + if (is_array($position)) { + $useMinMax = false; + if (isset($position['min'])) { + $this->addUsingAlias(AttributeTemplateTableMap::POSITION, $position['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($position['max'])) { + $this->addUsingAlias(AttributeTemplateTableMap::POSITION, $position['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(AttributeTemplateTableMap::POSITION, $position, $comparison); + } + + /** + * Filter the query on the attribute_templatecol column + * + * Example usage: + * + * $query->filterByAttributeTemplatecol('fooValue'); // WHERE attribute_templatecol = 'fooValue' + * $query->filterByAttributeTemplatecol('%fooValue%'); // WHERE attribute_templatecol LIKE '%fooValue%' + * + * + * @param string $attributeTemplatecol The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildAttributeTemplateQuery The current query, for fluid interface + */ + public function filterByAttributeTemplatecol($attributeTemplatecol = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($attributeTemplatecol)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $attributeTemplatecol)) { + $attributeTemplatecol = str_replace('*', '%', $attributeTemplatecol); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(AttributeTemplateTableMap::ATTRIBUTE_TEMPLATECOL, $attributeTemplatecol, $comparison); + } + /** * Filter the query on the created_at column * diff --git a/core/lib/Thelia/Model/Base/FeatureProduct.php b/core/lib/Thelia/Model/Base/FeatureProduct.php index 4af200d51..039967cee 100644 --- a/core/lib/Thelia/Model/Base/FeatureProduct.php +++ b/core/lib/Thelia/Model/Base/FeatureProduct.php @@ -85,10 +85,10 @@ abstract class FeatureProduct implements ActiveRecordInterface protected $feature_av_id; /** - * The value for the by_default field. + * The value for the free_text_value field. * @var string */ - protected $by_default; + protected $free_text_value; /** * The value for the position field. @@ -430,14 +430,14 @@ abstract class FeatureProduct implements ActiveRecordInterface } /** - * Get the [by_default] column value. + * Get the [free_text_value] column value. * * @return string */ - public function getByDefault() + public function getFreeTextValue() { - return $this->by_default; + return $this->free_text_value; } /** @@ -588,25 +588,25 @@ abstract class FeatureProduct implements ActiveRecordInterface } // setFeatureAvId() /** - * Set the value of [by_default] column. + * Set the value of [free_text_value] column. * * @param string $v new value * @return \Thelia\Model\FeatureProduct The current object (for fluent API support) */ - public function setByDefault($v) + public function setFreeTextValue($v) { if ($v !== null) { $v = (string) $v; } - if ($this->by_default !== $v) { - $this->by_default = $v; - $this->modifiedColumns[] = FeatureProductTableMap::BY_DEFAULT; + if ($this->free_text_value !== $v) { + $this->free_text_value = $v; + $this->modifiedColumns[] = FeatureProductTableMap::FREE_TEXT_VALUE; } return $this; - } // setByDefault() + } // setFreeTextValue() /** * Set the value of [position] column. @@ -720,8 +720,8 @@ abstract class FeatureProduct implements ActiveRecordInterface $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : FeatureProductTableMap::translateFieldName('FeatureAvId', TableMap::TYPE_PHPNAME, $indexType)]; $this->feature_av_id = (null !== $col) ? (int) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : FeatureProductTableMap::translateFieldName('ByDefault', TableMap::TYPE_PHPNAME, $indexType)]; - $this->by_default = (null !== $col) ? (string) $col : null; + $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : FeatureProductTableMap::translateFieldName('FreeTextValue', TableMap::TYPE_PHPNAME, $indexType)]; + $this->free_text_value = (null !== $col) ? (string) $col : null; $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : FeatureProductTableMap::translateFieldName('Position', TableMap::TYPE_PHPNAME, $indexType)]; $this->position = (null !== $col) ? (int) $col : null; @@ -1015,8 +1015,8 @@ abstract class FeatureProduct implements ActiveRecordInterface if ($this->isColumnModified(FeatureProductTableMap::FEATURE_AV_ID)) { $modifiedColumns[':p' . $index++] = 'FEATURE_AV_ID'; } - if ($this->isColumnModified(FeatureProductTableMap::BY_DEFAULT)) { - $modifiedColumns[':p' . $index++] = 'BY_DEFAULT'; + if ($this->isColumnModified(FeatureProductTableMap::FREE_TEXT_VALUE)) { + $modifiedColumns[':p' . $index++] = 'FREE_TEXT_VALUE'; } if ($this->isColumnModified(FeatureProductTableMap::POSITION)) { $modifiedColumns[':p' . $index++] = 'POSITION'; @@ -1050,8 +1050,8 @@ abstract class FeatureProduct implements ActiveRecordInterface case 'FEATURE_AV_ID': $stmt->bindValue($identifier, $this->feature_av_id, PDO::PARAM_INT); break; - case 'BY_DEFAULT': - $stmt->bindValue($identifier, $this->by_default, PDO::PARAM_STR); + case 'FREE_TEXT_VALUE': + $stmt->bindValue($identifier, $this->free_text_value, PDO::PARAM_STR); break; case 'POSITION': $stmt->bindValue($identifier, $this->position, PDO::PARAM_INT); @@ -1137,7 +1137,7 @@ abstract class FeatureProduct implements ActiveRecordInterface return $this->getFeatureAvId(); break; case 4: - return $this->getByDefault(); + return $this->getFreeTextValue(); break; case 5: return $this->getPosition(); @@ -1181,7 +1181,7 @@ abstract class FeatureProduct implements ActiveRecordInterface $keys[1] => $this->getProductId(), $keys[2] => $this->getFeatureId(), $keys[3] => $this->getFeatureAvId(), - $keys[4] => $this->getByDefault(), + $keys[4] => $this->getFreeTextValue(), $keys[5] => $this->getPosition(), $keys[6] => $this->getCreatedAt(), $keys[7] => $this->getUpdatedAt(), @@ -1249,7 +1249,7 @@ abstract class FeatureProduct implements ActiveRecordInterface $this->setFeatureAvId($value); break; case 4: - $this->setByDefault($value); + $this->setFreeTextValue($value); break; case 5: $this->setPosition($value); @@ -1288,7 +1288,7 @@ abstract class FeatureProduct implements ActiveRecordInterface if (array_key_exists($keys[1], $arr)) $this->setProductId($arr[$keys[1]]); if (array_key_exists($keys[2], $arr)) $this->setFeatureId($arr[$keys[2]]); if (array_key_exists($keys[3], $arr)) $this->setFeatureAvId($arr[$keys[3]]); - if (array_key_exists($keys[4], $arr)) $this->setByDefault($arr[$keys[4]]); + if (array_key_exists($keys[4], $arr)) $this->setFreeTextValue($arr[$keys[4]]); if (array_key_exists($keys[5], $arr)) $this->setPosition($arr[$keys[5]]); if (array_key_exists($keys[6], $arr)) $this->setCreatedAt($arr[$keys[6]]); if (array_key_exists($keys[7], $arr)) $this->setUpdatedAt($arr[$keys[7]]); @@ -1307,7 +1307,7 @@ abstract class FeatureProduct implements ActiveRecordInterface if ($this->isColumnModified(FeatureProductTableMap::PRODUCT_ID)) $criteria->add(FeatureProductTableMap::PRODUCT_ID, $this->product_id); if ($this->isColumnModified(FeatureProductTableMap::FEATURE_ID)) $criteria->add(FeatureProductTableMap::FEATURE_ID, $this->feature_id); if ($this->isColumnModified(FeatureProductTableMap::FEATURE_AV_ID)) $criteria->add(FeatureProductTableMap::FEATURE_AV_ID, $this->feature_av_id); - if ($this->isColumnModified(FeatureProductTableMap::BY_DEFAULT)) $criteria->add(FeatureProductTableMap::BY_DEFAULT, $this->by_default); + if ($this->isColumnModified(FeatureProductTableMap::FREE_TEXT_VALUE)) $criteria->add(FeatureProductTableMap::FREE_TEXT_VALUE, $this->free_text_value); if ($this->isColumnModified(FeatureProductTableMap::POSITION)) $criteria->add(FeatureProductTableMap::POSITION, $this->position); if ($this->isColumnModified(FeatureProductTableMap::CREATED_AT)) $criteria->add(FeatureProductTableMap::CREATED_AT, $this->created_at); if ($this->isColumnModified(FeatureProductTableMap::UPDATED_AT)) $criteria->add(FeatureProductTableMap::UPDATED_AT, $this->updated_at); @@ -1377,7 +1377,7 @@ abstract class FeatureProduct implements ActiveRecordInterface $copyObj->setProductId($this->getProductId()); $copyObj->setFeatureId($this->getFeatureId()); $copyObj->setFeatureAvId($this->getFeatureAvId()); - $copyObj->setByDefault($this->getByDefault()); + $copyObj->setFreeTextValue($this->getFreeTextValue()); $copyObj->setPosition($this->getPosition()); $copyObj->setCreatedAt($this->getCreatedAt()); $copyObj->setUpdatedAt($this->getUpdatedAt()); @@ -1571,7 +1571,7 @@ abstract class FeatureProduct implements ActiveRecordInterface $this->product_id = null; $this->feature_id = null; $this->feature_av_id = null; - $this->by_default = null; + $this->free_text_value = null; $this->position = null; $this->created_at = null; $this->updated_at = null; diff --git a/core/lib/Thelia/Model/Base/FeatureProductQuery.php b/core/lib/Thelia/Model/Base/FeatureProductQuery.php index c6a8f2a73..eb2ee7ec1 100644 --- a/core/lib/Thelia/Model/Base/FeatureProductQuery.php +++ b/core/lib/Thelia/Model/Base/FeatureProductQuery.php @@ -25,7 +25,7 @@ use Thelia\Model\Map\FeatureProductTableMap; * @method ChildFeatureProductQuery orderByProductId($order = Criteria::ASC) Order by the product_id column * @method ChildFeatureProductQuery orderByFeatureId($order = Criteria::ASC) Order by the feature_id column * @method ChildFeatureProductQuery orderByFeatureAvId($order = Criteria::ASC) Order by the feature_av_id column - * @method ChildFeatureProductQuery orderByByDefault($order = Criteria::ASC) Order by the by_default column + * @method ChildFeatureProductQuery orderByFreeTextValue($order = Criteria::ASC) Order by the free_text_value column * @method ChildFeatureProductQuery orderByPosition($order = Criteria::ASC) Order by the position column * @method ChildFeatureProductQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column * @method ChildFeatureProductQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column @@ -34,7 +34,7 @@ use Thelia\Model\Map\FeatureProductTableMap; * @method ChildFeatureProductQuery groupByProductId() Group by the product_id column * @method ChildFeatureProductQuery groupByFeatureId() Group by the feature_id column * @method ChildFeatureProductQuery groupByFeatureAvId() Group by the feature_av_id column - * @method ChildFeatureProductQuery groupByByDefault() Group by the by_default column + * @method ChildFeatureProductQuery groupByFreeTextValue() Group by the free_text_value column * @method ChildFeatureProductQuery groupByPosition() Group by the position column * @method ChildFeatureProductQuery groupByCreatedAt() Group by the created_at column * @method ChildFeatureProductQuery groupByUpdatedAt() Group by the updated_at column @@ -62,7 +62,7 @@ use Thelia\Model\Map\FeatureProductTableMap; * @method ChildFeatureProduct findOneByProductId(int $product_id) Return the first ChildFeatureProduct filtered by the product_id column * @method ChildFeatureProduct findOneByFeatureId(int $feature_id) Return the first ChildFeatureProduct filtered by the feature_id column * @method ChildFeatureProduct findOneByFeatureAvId(int $feature_av_id) Return the first ChildFeatureProduct filtered by the feature_av_id column - * @method ChildFeatureProduct findOneByByDefault(string $by_default) Return the first ChildFeatureProduct filtered by the by_default column + * @method ChildFeatureProduct findOneByFreeTextValue(string $free_text_value) Return the first ChildFeatureProduct filtered by the free_text_value column * @method ChildFeatureProduct findOneByPosition(int $position) Return the first ChildFeatureProduct filtered by the position column * @method ChildFeatureProduct findOneByCreatedAt(string $created_at) Return the first ChildFeatureProduct filtered by the created_at column * @method ChildFeatureProduct findOneByUpdatedAt(string $updated_at) Return the first ChildFeatureProduct filtered by the updated_at column @@ -71,7 +71,7 @@ use Thelia\Model\Map\FeatureProductTableMap; * @method array findByProductId(int $product_id) Return ChildFeatureProduct objects filtered by the product_id column * @method array findByFeatureId(int $feature_id) Return ChildFeatureProduct objects filtered by the feature_id column * @method array findByFeatureAvId(int $feature_av_id) Return ChildFeatureProduct objects filtered by the feature_av_id column - * @method array findByByDefault(string $by_default) Return ChildFeatureProduct objects filtered by the by_default column + * @method array findByFreeTextValue(string $free_text_value) Return ChildFeatureProduct objects filtered by the free_text_value column * @method array findByPosition(int $position) Return ChildFeatureProduct objects filtered by the position column * @method array findByCreatedAt(string $created_at) Return ChildFeatureProduct objects filtered by the created_at column * @method array findByUpdatedAt(string $updated_at) Return ChildFeatureProduct objects filtered by the updated_at column @@ -163,7 +163,7 @@ abstract class FeatureProductQuery extends ModelCriteria */ protected function findPkSimple($key, $con) { - $sql = 'SELECT ID, PRODUCT_ID, FEATURE_ID, FEATURE_AV_ID, BY_DEFAULT, POSITION, CREATED_AT, UPDATED_AT FROM feature_product WHERE ID = :p0'; + $sql = 'SELECT ID, PRODUCT_ID, FEATURE_ID, FEATURE_AV_ID, FREE_TEXT_VALUE, POSITION, CREATED_AT, UPDATED_AT FROM feature_product WHERE ID = :p0'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key, PDO::PARAM_INT); @@ -423,32 +423,32 @@ abstract class FeatureProductQuery extends ModelCriteria } /** - * Filter the query on the by_default column + * Filter the query on the free_text_value column * * Example usage: * - * $query->filterByByDefault('fooValue'); // WHERE by_default = 'fooValue' - * $query->filterByByDefault('%fooValue%'); // WHERE by_default LIKE '%fooValue%' + * $query->filterByFreeTextValue('fooValue'); // WHERE free_text_value = 'fooValue' + * $query->filterByFreeTextValue('%fooValue%'); // WHERE free_text_value LIKE '%fooValue%' * * - * @param string $byDefault The value to use as filter. + * @param string $freeTextValue The value to use as filter. * Accepts wildcards (* and % trigger a LIKE) * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL * * @return ChildFeatureProductQuery The current query, for fluid interface */ - public function filterByByDefault($byDefault = null, $comparison = null) + public function filterByFreeTextValue($freeTextValue = null, $comparison = null) { if (null === $comparison) { - if (is_array($byDefault)) { + if (is_array($freeTextValue)) { $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $byDefault)) { - $byDefault = str_replace('*', '%', $byDefault); + } elseif (preg_match('/[\%\*]/', $freeTextValue)) { + $freeTextValue = str_replace('*', '%', $freeTextValue); $comparison = Criteria::LIKE; } } - return $this->addUsingAlias(FeatureProductTableMap::BY_DEFAULT, $byDefault, $comparison); + return $this->addUsingAlias(FeatureProductTableMap::FREE_TEXT_VALUE, $freeTextValue, $comparison); } /** diff --git a/core/lib/Thelia/Model/Base/FeatureTemplate.php b/core/lib/Thelia/Model/Base/FeatureTemplate.php index bbccd9251..b8ba55629 100644 --- a/core/lib/Thelia/Model/Base/FeatureTemplate.php +++ b/core/lib/Thelia/Model/Base/FeatureTemplate.php @@ -76,6 +76,12 @@ abstract class FeatureTemplate implements ActiveRecordInterface */ protected $template_id; + /** + * The value for the position field. + * @var int + */ + protected $position; + /** * The value for the created_at field. * @var string @@ -393,6 +399,17 @@ abstract class FeatureTemplate implements ActiveRecordInterface return $this->template_id; } + /** + * Get the [position] column value. + * + * @return int + */ + public function getPosition() + { + + return $this->position; + } + /** * Get the [optionally formatted] temporal [created_at] column value. * @@ -504,6 +521,27 @@ abstract class FeatureTemplate implements ActiveRecordInterface return $this; } // setTemplateId() + /** + * Set the value of [position] column. + * + * @param int $v new value + * @return \Thelia\Model\FeatureTemplate The current object (for fluent API support) + */ + public function setPosition($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->position !== $v) { + $this->position = $v; + $this->modifiedColumns[] = FeatureTemplateTableMap::POSITION; + } + + + return $this; + } // setPosition() + /** * Sets the value of [created_at] column to a normalized version of the date/time value specified. * @@ -592,13 +630,16 @@ abstract class FeatureTemplate implements ActiveRecordInterface $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : FeatureTemplateTableMap::translateFieldName('TemplateId', TableMap::TYPE_PHPNAME, $indexType)]; $this->template_id = (null !== $col) ? (int) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : FeatureTemplateTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : FeatureTemplateTableMap::translateFieldName('Position', TableMap::TYPE_PHPNAME, $indexType)]; + $this->position = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : FeatureTemplateTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } $this->created_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : FeatureTemplateTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : FeatureTemplateTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } @@ -611,7 +652,7 @@ abstract class FeatureTemplate implements ActiveRecordInterface $this->ensureConsistency(); } - return $startcol + 5; // 5 = FeatureTemplateTableMap::NUM_HYDRATE_COLUMNS. + return $startcol + 6; // 6 = FeatureTemplateTableMap::NUM_HYDRATE_COLUMNS. } catch (Exception $e) { throw new PropelException("Error populating \Thelia\Model\FeatureTemplate object", 0, $e); @@ -867,6 +908,9 @@ abstract class FeatureTemplate implements ActiveRecordInterface if ($this->isColumnModified(FeatureTemplateTableMap::TEMPLATE_ID)) { $modifiedColumns[':p' . $index++] = 'TEMPLATE_ID'; } + if ($this->isColumnModified(FeatureTemplateTableMap::POSITION)) { + $modifiedColumns[':p' . $index++] = 'POSITION'; + } if ($this->isColumnModified(FeatureTemplateTableMap::CREATED_AT)) { $modifiedColumns[':p' . $index++] = 'CREATED_AT'; } @@ -893,6 +937,9 @@ abstract class FeatureTemplate implements ActiveRecordInterface case 'TEMPLATE_ID': $stmt->bindValue($identifier, $this->template_id, PDO::PARAM_INT); break; + case 'POSITION': + $stmt->bindValue($identifier, $this->position, PDO::PARAM_INT); + break; case 'CREATED_AT': $stmt->bindValue($identifier, $this->created_at ? $this->created_at->format("Y-m-d H:i:s") : null, PDO::PARAM_STR); break; @@ -971,9 +1018,12 @@ abstract class FeatureTemplate implements ActiveRecordInterface return $this->getTemplateId(); break; case 3: - return $this->getCreatedAt(); + return $this->getPosition(); break; case 4: + return $this->getCreatedAt(); + break; + case 5: return $this->getUpdatedAt(); break; default: @@ -1008,8 +1058,9 @@ abstract class FeatureTemplate implements ActiveRecordInterface $keys[0] => $this->getId(), $keys[1] => $this->getFeatureId(), $keys[2] => $this->getTemplateId(), - $keys[3] => $this->getCreatedAt(), - $keys[4] => $this->getUpdatedAt(), + $keys[3] => $this->getPosition(), + $keys[4] => $this->getCreatedAt(), + $keys[5] => $this->getUpdatedAt(), ); $virtualColumns = $this->virtualColumns; foreach($virtualColumns as $key => $virtualColumn) @@ -1068,9 +1119,12 @@ abstract class FeatureTemplate implements ActiveRecordInterface $this->setTemplateId($value); break; case 3: - $this->setCreatedAt($value); + $this->setPosition($value); break; case 4: + $this->setCreatedAt($value); + break; + case 5: $this->setUpdatedAt($value); break; } // switch() @@ -1100,8 +1154,9 @@ abstract class FeatureTemplate implements ActiveRecordInterface if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]); if (array_key_exists($keys[1], $arr)) $this->setFeatureId($arr[$keys[1]]); if (array_key_exists($keys[2], $arr)) $this->setTemplateId($arr[$keys[2]]); - if (array_key_exists($keys[3], $arr)) $this->setCreatedAt($arr[$keys[3]]); - if (array_key_exists($keys[4], $arr)) $this->setUpdatedAt($arr[$keys[4]]); + if (array_key_exists($keys[3], $arr)) $this->setPosition($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setCreatedAt($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setUpdatedAt($arr[$keys[5]]); } /** @@ -1116,6 +1171,7 @@ abstract class FeatureTemplate implements ActiveRecordInterface if ($this->isColumnModified(FeatureTemplateTableMap::ID)) $criteria->add(FeatureTemplateTableMap::ID, $this->id); if ($this->isColumnModified(FeatureTemplateTableMap::FEATURE_ID)) $criteria->add(FeatureTemplateTableMap::FEATURE_ID, $this->feature_id); if ($this->isColumnModified(FeatureTemplateTableMap::TEMPLATE_ID)) $criteria->add(FeatureTemplateTableMap::TEMPLATE_ID, $this->template_id); + if ($this->isColumnModified(FeatureTemplateTableMap::POSITION)) $criteria->add(FeatureTemplateTableMap::POSITION, $this->position); if ($this->isColumnModified(FeatureTemplateTableMap::CREATED_AT)) $criteria->add(FeatureTemplateTableMap::CREATED_AT, $this->created_at); if ($this->isColumnModified(FeatureTemplateTableMap::UPDATED_AT)) $criteria->add(FeatureTemplateTableMap::UPDATED_AT, $this->updated_at); @@ -1183,6 +1239,7 @@ abstract class FeatureTemplate implements ActiveRecordInterface { $copyObj->setFeatureId($this->getFeatureId()); $copyObj->setTemplateId($this->getTemplateId()); + $copyObj->setPosition($this->getPosition()); $copyObj->setCreatedAt($this->getCreatedAt()); $copyObj->setUpdatedAt($this->getUpdatedAt()); if ($makeNew) { @@ -1323,6 +1380,7 @@ abstract class FeatureTemplate implements ActiveRecordInterface $this->id = null; $this->feature_id = null; $this->template_id = null; + $this->position = null; $this->created_at = null; $this->updated_at = null; $this->alreadyInSave = false; diff --git a/core/lib/Thelia/Model/Base/FeatureTemplateQuery.php b/core/lib/Thelia/Model/Base/FeatureTemplateQuery.php index c99c1305f..cccad15ae 100644 --- a/core/lib/Thelia/Model/Base/FeatureTemplateQuery.php +++ b/core/lib/Thelia/Model/Base/FeatureTemplateQuery.php @@ -24,12 +24,14 @@ use Thelia\Model\Map\FeatureTemplateTableMap; * @method ChildFeatureTemplateQuery orderById($order = Criteria::ASC) Order by the id column * @method ChildFeatureTemplateQuery orderByFeatureId($order = Criteria::ASC) Order by the feature_id column * @method ChildFeatureTemplateQuery orderByTemplateId($order = Criteria::ASC) Order by the template_id column + * @method ChildFeatureTemplateQuery orderByPosition($order = Criteria::ASC) Order by the position column * @method ChildFeatureTemplateQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column * @method ChildFeatureTemplateQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column * * @method ChildFeatureTemplateQuery groupById() Group by the id column * @method ChildFeatureTemplateQuery groupByFeatureId() Group by the feature_id column * @method ChildFeatureTemplateQuery groupByTemplateId() Group by the template_id column + * @method ChildFeatureTemplateQuery groupByPosition() Group by the position column * @method ChildFeatureTemplateQuery groupByCreatedAt() Group by the created_at column * @method ChildFeatureTemplateQuery groupByUpdatedAt() Group by the updated_at column * @@ -51,12 +53,14 @@ use Thelia\Model\Map\FeatureTemplateTableMap; * @method ChildFeatureTemplate findOneById(int $id) Return the first ChildFeatureTemplate filtered by the id column * @method ChildFeatureTemplate findOneByFeatureId(int $feature_id) Return the first ChildFeatureTemplate filtered by the feature_id column * @method ChildFeatureTemplate findOneByTemplateId(int $template_id) Return the first ChildFeatureTemplate filtered by the template_id column + * @method ChildFeatureTemplate findOneByPosition(int $position) Return the first ChildFeatureTemplate filtered by the position column * @method ChildFeatureTemplate findOneByCreatedAt(string $created_at) Return the first ChildFeatureTemplate filtered by the created_at column * @method ChildFeatureTemplate findOneByUpdatedAt(string $updated_at) Return the first ChildFeatureTemplate filtered by the updated_at column * * @method array findById(int $id) Return ChildFeatureTemplate objects filtered by the id column * @method array findByFeatureId(int $feature_id) Return ChildFeatureTemplate objects filtered by the feature_id column * @method array findByTemplateId(int $template_id) Return ChildFeatureTemplate objects filtered by the template_id column + * @method array findByPosition(int $position) Return ChildFeatureTemplate objects filtered by the position column * @method array findByCreatedAt(string $created_at) Return ChildFeatureTemplate objects filtered by the created_at column * @method array findByUpdatedAt(string $updated_at) Return ChildFeatureTemplate objects filtered by the updated_at column * @@ -147,7 +151,7 @@ abstract class FeatureTemplateQuery extends ModelCriteria */ protected function findPkSimple($key, $con) { - $sql = 'SELECT ID, FEATURE_ID, TEMPLATE_ID, CREATED_AT, UPDATED_AT FROM feature_template WHERE ID = :p0'; + $sql = 'SELECT ID, FEATURE_ID, TEMPLATE_ID, POSITION, CREATED_AT, UPDATED_AT FROM feature_template WHERE ID = :p0'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key, PDO::PARAM_INT); @@ -363,6 +367,47 @@ abstract class FeatureTemplateQuery extends ModelCriteria return $this->addUsingAlias(FeatureTemplateTableMap::TEMPLATE_ID, $templateId, $comparison); } + /** + * Filter the query on the position column + * + * Example usage: + * + * $query->filterByPosition(1234); // WHERE position = 1234 + * $query->filterByPosition(array(12, 34)); // WHERE position IN (12, 34) + * $query->filterByPosition(array('min' => 12)); // WHERE position > 12 + * + * + * @param mixed $position The value to use as filter. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildFeatureTemplateQuery The current query, for fluid interface + */ + public function filterByPosition($position = null, $comparison = null) + { + if (is_array($position)) { + $useMinMax = false; + if (isset($position['min'])) { + $this->addUsingAlias(FeatureTemplateTableMap::POSITION, $position['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($position['max'])) { + $this->addUsingAlias(FeatureTemplateTableMap::POSITION, $position['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(FeatureTemplateTableMap::POSITION, $position, $comparison); + } + /** * Filter the query on the created_at column * diff --git a/core/lib/Thelia/Model/Base/Module.php b/core/lib/Thelia/Model/Base/Module.php index 7f4df77ce..88080dbe2 100644 --- a/core/lib/Thelia/Model/Base/Module.php +++ b/core/lib/Thelia/Model/Base/Module.php @@ -24,6 +24,8 @@ use Thelia\Model\GroupModuleQuery as ChildGroupModuleQuery; use Thelia\Model\Module as ChildModule; use Thelia\Model\ModuleI18n as ChildModuleI18n; use Thelia\Model\ModuleI18nQuery as ChildModuleI18nQuery; +use Thelia\Model\ModuleImage as ChildModuleImage; +use Thelia\Model\ModuleImageQuery as ChildModuleImageQuery; use Thelia\Model\ModuleQuery as ChildModuleQuery; use Thelia\Model\Order as ChildOrder; use Thelia\Model\OrderQuery as ChildOrderQuery; @@ -135,6 +137,12 @@ abstract class Module implements ActiveRecordInterface protected $collGroupModules; protected $collGroupModulesPartial; + /** + * @var ObjectCollection|ChildModuleImage[] Collection to store aggregation of ChildModuleImage objects. + */ + protected $collModuleImages; + protected $collModuleImagesPartial; + /** * @var ObjectCollection|ChildModuleI18n[] Collection to store aggregation of ChildModuleI18n objects. */ @@ -187,6 +195,12 @@ abstract class Module implements ActiveRecordInterface */ protected $groupModulesScheduledForDeletion = null; + /** + * An array of objects scheduled for deletion. + * @var ObjectCollection + */ + protected $moduleImagesScheduledForDeletion = null; + /** * An array of objects scheduled for deletion. * @var ObjectCollection @@ -864,6 +878,8 @@ abstract class Module implements ActiveRecordInterface $this->collGroupModules = null; + $this->collModuleImages = null; + $this->collModuleI18ns = null; } // if (deep) @@ -1067,6 +1083,23 @@ abstract class Module implements ActiveRecordInterface } } + if ($this->moduleImagesScheduledForDeletion !== null) { + if (!$this->moduleImagesScheduledForDeletion->isEmpty()) { + \Thelia\Model\ModuleImageQuery::create() + ->filterByPrimaryKeys($this->moduleImagesScheduledForDeletion->getPrimaryKeys(false)) + ->delete($con); + $this->moduleImagesScheduledForDeletion = null; + } + } + + if ($this->collModuleImages !== null) { + foreach ($this->collModuleImages as $referrerFK) { + if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) { + $affectedRows += $referrerFK->save($con); + } + } + } + if ($this->moduleI18nsScheduledForDeletion !== null) { if (!$this->moduleI18nsScheduledForDeletion->isEmpty()) { \Thelia\Model\ModuleI18nQuery::create() @@ -1312,6 +1345,9 @@ abstract class Module implements ActiveRecordInterface if (null !== $this->collGroupModules) { $result['GroupModules'] = $this->collGroupModules->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); } + if (null !== $this->collModuleImages) { + $result['ModuleImages'] = $this->collModuleImages->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); + } if (null !== $this->collModuleI18ns) { $result['ModuleI18ns'] = $this->collModuleI18ns->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); } @@ -1524,6 +1560,12 @@ abstract class Module implements ActiveRecordInterface } } + foreach ($this->getModuleImages() as $relObj) { + if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves + $copyObj->addModuleImage($relObj->copy($deepCopy)); + } + } + foreach ($this->getModuleI18ns() as $relObj) { if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves $copyObj->addModuleI18n($relObj->copy($deepCopy)); @@ -1583,6 +1625,9 @@ abstract class Module implements ActiveRecordInterface if ('GroupModule' == $relationName) { return $this->initGroupModules(); } + if ('ModuleImage' == $relationName) { + return $this->initModuleImages(); + } if ('ModuleI18n' == $relationName) { return $this->initModuleI18ns(); } @@ -2810,6 +2855,224 @@ abstract class Module implements ActiveRecordInterface return $this->getGroupModules($query, $con); } + /** + * Clears out the collModuleImages collection + * + * This does not modify the database; however, it will remove any associated objects, causing + * them to be refetched by subsequent calls to accessor method. + * + * @return void + * @see addModuleImages() + */ + public function clearModuleImages() + { + $this->collModuleImages = null; // important to set this to NULL since that means it is uninitialized + } + + /** + * Reset is the collModuleImages collection loaded partially. + */ + public function resetPartialModuleImages($v = true) + { + $this->collModuleImagesPartial = $v; + } + + /** + * Initializes the collModuleImages collection. + * + * By default this just sets the collModuleImages collection to an empty array (like clearcollModuleImages()); + * however, you may wish to override this method in your stub class to provide setting appropriate + * to your application -- for example, setting the initial array to the values stored in database. + * + * @param boolean $overrideExisting If set to true, the method call initializes + * the collection even if it is not empty + * + * @return void + */ + public function initModuleImages($overrideExisting = true) + { + if (null !== $this->collModuleImages && !$overrideExisting) { + return; + } + $this->collModuleImages = new ObjectCollection(); + $this->collModuleImages->setModel('\Thelia\Model\ModuleImage'); + } + + /** + * Gets an array of ChildModuleImage objects which contain a foreign key that references this object. + * + * If the $criteria is not null, it is used to always fetch the results from the database. + * Otherwise the results are fetched from the database the first time, then cached. + * Next time the same method is called without $criteria, the cached collection is returned. + * If this ChildModule is new, it will return + * an empty collection or the current collection; the criteria is ignored on a new object. + * + * @param Criteria $criteria optional Criteria object to narrow the query + * @param ConnectionInterface $con optional connection object + * @return Collection|ChildModuleImage[] List of ChildModuleImage objects + * @throws PropelException + */ + public function getModuleImages($criteria = null, ConnectionInterface $con = null) + { + $partial = $this->collModuleImagesPartial && !$this->isNew(); + if (null === $this->collModuleImages || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collModuleImages) { + // return empty collection + $this->initModuleImages(); + } else { + $collModuleImages = ChildModuleImageQuery::create(null, $criteria) + ->filterByModule($this) + ->find($con); + + if (null !== $criteria) { + if (false !== $this->collModuleImagesPartial && count($collModuleImages)) { + $this->initModuleImages(false); + + foreach ($collModuleImages as $obj) { + if (false == $this->collModuleImages->contains($obj)) { + $this->collModuleImages->append($obj); + } + } + + $this->collModuleImagesPartial = true; + } + + $collModuleImages->getInternalIterator()->rewind(); + + return $collModuleImages; + } + + if ($partial && $this->collModuleImages) { + foreach ($this->collModuleImages as $obj) { + if ($obj->isNew()) { + $collModuleImages[] = $obj; + } + } + } + + $this->collModuleImages = $collModuleImages; + $this->collModuleImagesPartial = false; + } + } + + return $this->collModuleImages; + } + + /** + * Sets a collection of ModuleImage objects related by a one-to-many relationship + * to the current object. + * It will also schedule objects for deletion based on a diff between old objects (aka persisted) + * and new objects from the given Propel collection. + * + * @param Collection $moduleImages A Propel collection. + * @param ConnectionInterface $con Optional connection object + * @return ChildModule The current object (for fluent API support) + */ + public function setModuleImages(Collection $moduleImages, ConnectionInterface $con = null) + { + $moduleImagesToDelete = $this->getModuleImages(new Criteria(), $con)->diff($moduleImages); + + + $this->moduleImagesScheduledForDeletion = $moduleImagesToDelete; + + foreach ($moduleImagesToDelete as $moduleImageRemoved) { + $moduleImageRemoved->setModule(null); + } + + $this->collModuleImages = null; + foreach ($moduleImages as $moduleImage) { + $this->addModuleImage($moduleImage); + } + + $this->collModuleImages = $moduleImages; + $this->collModuleImagesPartial = false; + + return $this; + } + + /** + * Returns the number of related ModuleImage objects. + * + * @param Criteria $criteria + * @param boolean $distinct + * @param ConnectionInterface $con + * @return int Count of related ModuleImage objects. + * @throws PropelException + */ + public function countModuleImages(Criteria $criteria = null, $distinct = false, ConnectionInterface $con = null) + { + $partial = $this->collModuleImagesPartial && !$this->isNew(); + if (null === $this->collModuleImages || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collModuleImages) { + return 0; + } + + if ($partial && !$criteria) { + return count($this->getModuleImages()); + } + + $query = ChildModuleImageQuery::create(null, $criteria); + if ($distinct) { + $query->distinct(); + } + + return $query + ->filterByModule($this) + ->count($con); + } + + return count($this->collModuleImages); + } + + /** + * Method called to associate a ChildModuleImage object to this object + * through the ChildModuleImage foreign key attribute. + * + * @param ChildModuleImage $l ChildModuleImage + * @return \Thelia\Model\Module The current object (for fluent API support) + */ + public function addModuleImage(ChildModuleImage $l) + { + if ($this->collModuleImages === null) { + $this->initModuleImages(); + $this->collModuleImagesPartial = true; + } + + if (!in_array($l, $this->collModuleImages->getArrayCopy(), true)) { // only add it if the **same** object is not already associated + $this->doAddModuleImage($l); + } + + return $this; + } + + /** + * @param ModuleImage $moduleImage The moduleImage object to add. + */ + protected function doAddModuleImage($moduleImage) + { + $this->collModuleImages[]= $moduleImage; + $moduleImage->setModule($this); + } + + /** + * @param ModuleImage $moduleImage The moduleImage object to remove. + * @return ChildModule The current object (for fluent API support) + */ + public function removeModuleImage($moduleImage) + { + if ($this->getModuleImages()->contains($moduleImage)) { + $this->collModuleImages->remove($this->collModuleImages->search($moduleImage)); + if (null === $this->moduleImagesScheduledForDeletion) { + $this->moduleImagesScheduledForDeletion = clone $this->collModuleImages; + $this->moduleImagesScheduledForDeletion->clear(); + } + $this->moduleImagesScheduledForDeletion[]= clone $moduleImage; + $moduleImage->setModule(null); + } + + return $this; + } + /** * Clears out the collModuleI18ns collection * @@ -3087,6 +3350,11 @@ abstract class Module implements ActiveRecordInterface $o->clearAllReferences($deep); } } + if ($this->collModuleImages) { + foreach ($this->collModuleImages as $o) { + $o->clearAllReferences($deep); + } + } if ($this->collModuleI18ns) { foreach ($this->collModuleI18ns as $o) { $o->clearAllReferences($deep); @@ -3114,6 +3382,10 @@ abstract class Module implements ActiveRecordInterface $this->collGroupModules->clearIterator(); } $this->collGroupModules = null; + if ($this->collModuleImages instanceof Collection) { + $this->collModuleImages->clearIterator(); + } + $this->collModuleImages = null; if ($this->collModuleI18ns instanceof Collection) { $this->collModuleI18ns->clearIterator(); } diff --git a/core/lib/Thelia/Model/Base/ModuleImage.php b/core/lib/Thelia/Model/Base/ModuleImage.php new file mode 100644 index 000000000..f488e289c --- /dev/null +++ b/core/lib/Thelia/Model/Base/ModuleImage.php @@ -0,0 +1,1990 @@ +modifiedColumns); + } + + /** + * Has specified column been modified? + * + * @param string $col column fully qualified name (TableMap::TYPE_COLNAME), e.g. Book::AUTHOR_ID + * @return boolean True if $col has been modified. + */ + public function isColumnModified($col) + { + return in_array($col, $this->modifiedColumns); + } + + /** + * Get the columns that have been modified in this object. + * @return array A unique list of the modified column names for this object. + */ + public function getModifiedColumns() + { + return array_unique($this->modifiedColumns); + } + + /** + * Returns whether the object has ever been saved. This will + * be false, if the object was retrieved from storage or was created + * and then saved. + * + * @return true, if the object has never been persisted. + */ + public function isNew() + { + return $this->new; + } + + /** + * Setter for the isNew attribute. This method will be called + * by Propel-generated children and objects. + * + * @param boolean $b the state of the object. + */ + public function setNew($b) + { + $this->new = (Boolean) $b; + } + + /** + * Whether this object has been deleted. + * @return boolean The deleted state of this object. + */ + public function isDeleted() + { + return $this->deleted; + } + + /** + * Specify whether this object has been deleted. + * @param boolean $b The deleted state of this object. + * @return void + */ + public function setDeleted($b) + { + $this->deleted = (Boolean) $b; + } + + /** + * Sets the modified state for the object to be false. + * @param string $col If supplied, only the specified column is reset. + * @return void + */ + public function resetModified($col = null) + { + if (null !== $col) { + while (false !== ($offset = array_search($col, $this->modifiedColumns))) { + array_splice($this->modifiedColumns, $offset, 1); + } + } else { + $this->modifiedColumns = array(); + } + } + + /** + * Compares this with another ModuleImage instance. If + * obj is an instance of ModuleImage, delegates to + * equals(ModuleImage). Otherwise, returns false. + * + * @param obj The object to compare to. + * @return Whether equal to the object specified. + */ + public function equals($obj) + { + $thisclazz = get_class($this); + if (!is_object($obj) || !($obj instanceof $thisclazz)) { + return false; + } + + if ($this === $obj) { + return true; + } + + if (null === $this->getPrimaryKey() + || null === $obj->getPrimaryKey()) { + return false; + } + + return $this->getPrimaryKey() === $obj->getPrimaryKey(); + } + + /** + * If the primary key is not null, return the hashcode of the + * primary key. Otherwise, return the hash code of the object. + * + * @return int Hashcode + */ + public function hashCode() + { + if (null !== $this->getPrimaryKey()) { + return crc32(serialize($this->getPrimaryKey())); + } + + return crc32(serialize(clone $this)); + } + + /** + * Get the associative array of the virtual columns in this object + * + * @param string $name The virtual column name + * + * @return array + */ + public function getVirtualColumns() + { + return $this->virtualColumns; + } + + /** + * Checks the existence of a virtual column in this object + * + * @return boolean + */ + public function hasVirtualColumn($name) + { + return array_key_exists($name, $this->virtualColumns); + } + + /** + * Get the value of a virtual column in this object + * + * @return mixed + */ + public function getVirtualColumn($name) + { + if (!$this->hasVirtualColumn($name)) { + throw new PropelException(sprintf('Cannot get value of inexistent virtual column %s.', $name)); + } + + return $this->virtualColumns[$name]; + } + + /** + * Set the value of a virtual column in this object + * + * @param string $name The virtual column name + * @param mixed $value The value to give to the virtual column + * + * @return ModuleImage The current object, for fluid interface + */ + public function setVirtualColumn($name, $value) + { + $this->virtualColumns[$name] = $value; + + return $this; + } + + /** + * Logs a message using Propel::log(). + * + * @param string $msg + * @param int $priority One of the Propel::LOG_* logging levels + * @return boolean + */ + protected function log($msg, $priority = Propel::LOG_INFO) + { + return Propel::log(get_class($this) . ': ' . $msg, $priority); + } + + /** + * Populate the current object from a string, using a given parser format + * + * $book = new Book(); + * $book->importFrom('JSON', '{"Id":9012,"Title":"Don Juan","ISBN":"0140422161","Price":12.99,"PublisherId":1234,"AuthorId":5678}'); + * + * + * @param mixed $parser A AbstractParser instance, + * or a format name ('XML', 'YAML', 'JSON', 'CSV') + * @param string $data The source data to import from + * + * @return ModuleImage The current object, for fluid interface + */ + public function importFrom($parser, $data) + { + if (!$parser instanceof AbstractParser) { + $parser = AbstractParser::getParser($parser); + } + + return $this->fromArray($parser->toArray($data), TableMap::TYPE_PHPNAME); + } + + /** + * Export the current object properties to a string, using a given parser format + * + * $book = BookQuery::create()->findPk(9012); + * echo $book->exportTo('JSON'); + * => {"Id":9012,"Title":"Don Juan","ISBN":"0140422161","Price":12.99,"PublisherId":1234,"AuthorId":5678}'); + * + * + * @param mixed $parser A AbstractParser instance, or a format name ('XML', 'YAML', 'JSON', 'CSV') + * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy load(ed) columns. Defaults to TRUE. + * @return string The exported data + */ + public function exportTo($parser, $includeLazyLoadColumns = true) + { + if (!$parser instanceof AbstractParser) { + $parser = AbstractParser::getParser($parser); + } + + return $parser->fromArray($this->toArray(TableMap::TYPE_PHPNAME, $includeLazyLoadColumns, array(), true)); + } + + /** + * Clean up internal collections prior to serializing + * Avoids recursive loops that turn into segmentation faults when serializing + */ + public function __sleep() + { + $this->clearAllReferences(); + + return array_keys(get_object_vars($this)); + } + + /** + * Get the [id] column value. + * + * @return int + */ + public function getId() + { + + return $this->id; + } + + /** + * Get the [module_id] column value. + * + * @return int + */ + public function getModuleId() + { + + return $this->module_id; + } + + /** + * Get the [file] column value. + * + * @return string + */ + public function getFile() + { + + return $this->file; + } + + /** + * Get the [position] column value. + * + * @return int + */ + public function getPosition() + { + + return $this->position; + } + + /** + * Get the [optionally formatted] temporal [created_at] column value. + * + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the raw \DateTime object will be returned. + * + * @return mixed Formatted date/time value as string or \DateTime object (if format is NULL), NULL if column is NULL, and 0 if column value is 0000-00-00 00:00:00 + * + * @throws PropelException - if unable to parse/validate the date/time value. + */ + public function getCreatedAt($format = NULL) + { + if ($format === null) { + return $this->created_at; + } else { + return $this->created_at !== null ? $this->created_at->format($format) : null; + } + } + + /** + * Get the [optionally formatted] temporal [updated_at] column value. + * + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the raw \DateTime object will be returned. + * + * @return mixed Formatted date/time value as string or \DateTime object (if format is NULL), NULL if column is NULL, and 0 if column value is 0000-00-00 00:00:00 + * + * @throws PropelException - if unable to parse/validate the date/time value. + */ + public function getUpdatedAt($format = NULL) + { + if ($format === null) { + return $this->updated_at; + } else { + return $this->updated_at !== null ? $this->updated_at->format($format) : null; + } + } + + /** + * Set the value of [id] column. + * + * @param int $v new value + * @return \Thelia\Model\ModuleImage The current object (for fluent API support) + */ + public function setId($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->id !== $v) { + $this->id = $v; + $this->modifiedColumns[] = ModuleImageTableMap::ID; + } + + + return $this; + } // setId() + + /** + * Set the value of [module_id] column. + * + * @param int $v new value + * @return \Thelia\Model\ModuleImage The current object (for fluent API support) + */ + public function setModuleId($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->module_id !== $v) { + $this->module_id = $v; + $this->modifiedColumns[] = ModuleImageTableMap::MODULE_ID; + } + + if ($this->aModule !== null && $this->aModule->getId() !== $v) { + $this->aModule = null; + } + + + return $this; + } // setModuleId() + + /** + * Set the value of [file] column. + * + * @param string $v new value + * @return \Thelia\Model\ModuleImage The current object (for fluent API support) + */ + public function setFile($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->file !== $v) { + $this->file = $v; + $this->modifiedColumns[] = ModuleImageTableMap::FILE; + } + + + return $this; + } // setFile() + + /** + * Set the value of [position] column. + * + * @param int $v new value + * @return \Thelia\Model\ModuleImage The current object (for fluent API support) + */ + public function setPosition($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->position !== $v) { + $this->position = $v; + $this->modifiedColumns[] = ModuleImageTableMap::POSITION; + } + + + return $this; + } // setPosition() + + /** + * Sets the value of [created_at] column to a normalized version of the date/time value specified. + * + * @param mixed $v string, integer (timestamp), or \DateTime value. + * Empty strings are treated as NULL. + * @return \Thelia\Model\ModuleImage The current object (for fluent API support) + */ + public function setCreatedAt($v) + { + $dt = PropelDateTime::newInstance($v, null, '\DateTime'); + if ($this->created_at !== null || $dt !== null) { + if ($dt !== $this->created_at) { + $this->created_at = $dt; + $this->modifiedColumns[] = ModuleImageTableMap::CREATED_AT; + } + } // if either are not null + + + return $this; + } // setCreatedAt() + + /** + * Sets the value of [updated_at] column to a normalized version of the date/time value specified. + * + * @param mixed $v string, integer (timestamp), or \DateTime value. + * Empty strings are treated as NULL. + * @return \Thelia\Model\ModuleImage The current object (for fluent API support) + */ + public function setUpdatedAt($v) + { + $dt = PropelDateTime::newInstance($v, null, '\DateTime'); + if ($this->updated_at !== null || $dt !== null) { + if ($dt !== $this->updated_at) { + $this->updated_at = $dt; + $this->modifiedColumns[] = ModuleImageTableMap::UPDATED_AT; + } + } // if either are not null + + + return $this; + } // setUpdatedAt() + + /** + * Indicates whether the columns in this object are only set to default values. + * + * This method can be used in conjunction with isModified() to indicate whether an object is both + * modified _and_ has some values set which are non-default. + * + * @return boolean Whether the columns in this object are only been set with default values. + */ + public function hasOnlyDefaultValues() + { + // otherwise, everything was equal, so return TRUE + return true; + } // hasOnlyDefaultValues() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (0-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param array $row The row returned by DataFetcher->fetch(). + * @param int $startcol 0-based offset column which indicates which restultset column to start with. + * @param boolean $rehydrate Whether this object is being re-hydrated from the database. + * @param string $indexType The index type of $row. Mostly DataFetcher->getIndexType(). + One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate($row, $startcol = 0, $rehydrate = false, $indexType = TableMap::TYPE_NUM) + { + try { + + + $col = $row[TableMap::TYPE_NUM == $indexType ? 0 + $startcol : ModuleImageTableMap::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)]; + $this->id = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 1 + $startcol : ModuleImageTableMap::translateFieldName('ModuleId', TableMap::TYPE_PHPNAME, $indexType)]; + $this->module_id = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : ModuleImageTableMap::translateFieldName('File', TableMap::TYPE_PHPNAME, $indexType)]; + $this->file = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : ModuleImageTableMap::translateFieldName('Position', TableMap::TYPE_PHPNAME, $indexType)]; + $this->position = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : ModuleImageTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + if ($col === '0000-00-00 00:00:00') { + $col = null; + } + $this->created_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : ModuleImageTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + if ($col === '0000-00-00 00:00:00') { + $col = null; + } + $this->updated_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; + $this->resetModified(); + + $this->setNew(false); + + if ($rehydrate) { + $this->ensureConsistency(); + } + + return $startcol + 6; // 6 = ModuleImageTableMap::NUM_HYDRATE_COLUMNS. + + } catch (Exception $e) { + throw new PropelException("Error populating \Thelia\Model\ModuleImage object", 0, $e); + } + } + + /** + * Checks and repairs the internal consistency of the object. + * + * This method is executed after an already-instantiated object is re-hydrated + * from the database. It exists to check any foreign keys to make sure that + * the objects related to the current object are correct based on foreign key. + * + * You can override this method in the stub class, but you should always invoke + * the base method from the overridden method (i.e. parent::ensureConsistency()), + * in case your model changes. + * + * @throws PropelException + */ + public function ensureConsistency() + { + if ($this->aModule !== null && $this->module_id !== $this->aModule->getId()) { + $this->aModule = null; + } + } // ensureConsistency + + /** + * Reloads this object from datastore based on primary key and (optionally) resets all associated objects. + * + * This will only work if the object has been saved and has a valid primary key set. + * + * @param boolean $deep (optional) Whether to also de-associated any related objects. + * @param ConnectionInterface $con (optional) The ConnectionInterface connection to use. + * @return void + * @throws PropelException - if this object is deleted, unsaved or doesn't have pk match in db + */ + public function reload($deep = false, ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("Cannot reload a deleted object."); + } + + if ($this->isNew()) { + throw new PropelException("Cannot reload an unsaved object."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getReadConnection(ModuleImageTableMap::DATABASE_NAME); + } + + // We don't need to alter the object instance pool; we're just modifying this instance + // already in the pool. + + $dataFetcher = ChildModuleImageQuery::create(null, $this->buildPkeyCriteria())->setFormatter(ModelCriteria::FORMAT_STATEMENT)->find($con); + $row = $dataFetcher->fetch(); + $dataFetcher->close(); + if (!$row) { + throw new PropelException('Cannot find matching row in the database to reload object values.'); + } + $this->hydrate($row, 0, true, $dataFetcher->getIndexType()); // rehydrate + + if ($deep) { // also de-associate any related objects? + + $this->aModule = null; + $this->collModuleImageI18ns = null; + + } // if (deep) + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param ConnectionInterface $con + * @return void + * @throws PropelException + * @see ModuleImage::setDeleted() + * @see ModuleImage::isDeleted() + */ + public function delete(ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getWriteConnection(ModuleImageTableMap::DATABASE_NAME); + } + + $con->beginTransaction(); + try { + $deleteQuery = ChildModuleImageQuery::create() + ->filterByPrimaryKey($this->getPrimaryKey()); + $ret = $this->preDelete($con); + if ($ret) { + $deleteQuery->delete($con); + $this->postDelete($con); + $con->commit(); + $this->setDeleted(true); + } else { + $con->commit(); + } + } catch (Exception $e) { + $con->rollBack(); + throw $e; + } + } + + /** + * Persists this object to the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All modified related objects will also be persisted in the doSave() + * method. This method wraps all precipitate database operations in a + * single transaction. + * + * @param ConnectionInterface $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save(ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getWriteConnection(ModuleImageTableMap::DATABASE_NAME); + } + + $con->beginTransaction(); + $isInsert = $this->isNew(); + try { + $ret = $this->preSave($con); + if ($isInsert) { + $ret = $ret && $this->preInsert($con); + // timestampable behavior + if (!$this->isColumnModified(ModuleImageTableMap::CREATED_AT)) { + $this->setCreatedAt(time()); + } + if (!$this->isColumnModified(ModuleImageTableMap::UPDATED_AT)) { + $this->setUpdatedAt(time()); + } + } else { + $ret = $ret && $this->preUpdate($con); + // timestampable behavior + if ($this->isModified() && !$this->isColumnModified(ModuleImageTableMap::UPDATED_AT)) { + $this->setUpdatedAt(time()); + } + } + if ($ret) { + $affectedRows = $this->doSave($con); + if ($isInsert) { + $this->postInsert($con); + } else { + $this->postUpdate($con); + } + $this->postSave($con); + ModuleImageTableMap::addInstanceToPool($this); + } else { + $affectedRows = 0; + } + $con->commit(); + + return $affectedRows; + } catch (Exception $e) { + $con->rollBack(); + throw $e; + } + } + + /** + * Performs the work of inserting or updating the row in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param ConnectionInterface $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave(ConnectionInterface $con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + // We call the save method on the following object(s) if they + // were passed to this object by their corresponding set + // method. This object relates to these object(s) by a + // foreign key reference. + + if ($this->aModule !== null) { + if ($this->aModule->isModified() || $this->aModule->isNew()) { + $affectedRows += $this->aModule->save($con); + } + $this->setModule($this->aModule); + } + + if ($this->isNew() || $this->isModified()) { + // persist changes + if ($this->isNew()) { + $this->doInsert($con); + } else { + $this->doUpdate($con); + } + $affectedRows += 1; + $this->resetModified(); + } + + if ($this->moduleImageI18nsScheduledForDeletion !== null) { + if (!$this->moduleImageI18nsScheduledForDeletion->isEmpty()) { + \Thelia\Model\ModuleImageI18nQuery::create() + ->filterByPrimaryKeys($this->moduleImageI18nsScheduledForDeletion->getPrimaryKeys(false)) + ->delete($con); + $this->moduleImageI18nsScheduledForDeletion = null; + } + } + + if ($this->collModuleImageI18ns !== null) { + foreach ($this->collModuleImageI18ns as $referrerFK) { + if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) { + $affectedRows += $referrerFK->save($con); + } + } + } + + $this->alreadyInSave = false; + + } + + return $affectedRows; + } // doSave() + + /** + * Insert the row in the database. + * + * @param ConnectionInterface $con + * + * @throws PropelException + * @see doSave() + */ + protected function doInsert(ConnectionInterface $con) + { + $modifiedColumns = array(); + $index = 0; + + $this->modifiedColumns[] = ModuleImageTableMap::ID; + if (null !== $this->id) { + throw new PropelException('Cannot insert a value for auto-increment primary key (' . ModuleImageTableMap::ID . ')'); + } + + // check the columns in natural order for more readable SQL queries + if ($this->isColumnModified(ModuleImageTableMap::ID)) { + $modifiedColumns[':p' . $index++] = 'ID'; + } + if ($this->isColumnModified(ModuleImageTableMap::MODULE_ID)) { + $modifiedColumns[':p' . $index++] = 'MODULE_ID'; + } + if ($this->isColumnModified(ModuleImageTableMap::FILE)) { + $modifiedColumns[':p' . $index++] = 'FILE'; + } + if ($this->isColumnModified(ModuleImageTableMap::POSITION)) { + $modifiedColumns[':p' . $index++] = 'POSITION'; + } + if ($this->isColumnModified(ModuleImageTableMap::CREATED_AT)) { + $modifiedColumns[':p' . $index++] = 'CREATED_AT'; + } + if ($this->isColumnModified(ModuleImageTableMap::UPDATED_AT)) { + $modifiedColumns[':p' . $index++] = 'UPDATED_AT'; + } + + $sql = sprintf( + 'INSERT INTO module_image (%s) VALUES (%s)', + implode(', ', $modifiedColumns), + implode(', ', array_keys($modifiedColumns)) + ); + + try { + $stmt = $con->prepare($sql); + foreach ($modifiedColumns as $identifier => $columnName) { + switch ($columnName) { + case 'ID': + $stmt->bindValue($identifier, $this->id, PDO::PARAM_INT); + break; + case 'MODULE_ID': + $stmt->bindValue($identifier, $this->module_id, PDO::PARAM_INT); + break; + case 'FILE': + $stmt->bindValue($identifier, $this->file, PDO::PARAM_STR); + break; + case 'POSITION': + $stmt->bindValue($identifier, $this->position, PDO::PARAM_INT); + break; + case 'CREATED_AT': + $stmt->bindValue($identifier, $this->created_at ? $this->created_at->format("Y-m-d H:i:s") : null, PDO::PARAM_STR); + break; + case 'UPDATED_AT': + $stmt->bindValue($identifier, $this->updated_at ? $this->updated_at->format("Y-m-d H:i:s") : null, PDO::PARAM_STR); + break; + } + } + $stmt->execute(); + } catch (Exception $e) { + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException(sprintf('Unable to execute INSERT statement [%s]', $sql), 0, $e); + } + + try { + $pk = $con->lastInsertId(); + } catch (Exception $e) { + throw new PropelException('Unable to get autoincrement id.', 0, $e); + } + $this->setId($pk); + + $this->setNew(false); + } + + /** + * Update the row in the database. + * + * @param ConnectionInterface $con + * + * @return Integer Number of updated rows + * @see doSave() + */ + protected function doUpdate(ConnectionInterface $con) + { + $selectCriteria = $this->buildPkeyCriteria(); + $valuesCriteria = $this->buildCriteria(); + + return $selectCriteria->doUpdate($valuesCriteria, $con); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @return mixed Value of field. + */ + public function getByName($name, $type = TableMap::TYPE_PHPNAME) + { + $pos = ModuleImageTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); + $field = $this->getByPosition($pos); + + return $field; + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch ($pos) { + case 0: + return $this->getId(); + break; + case 1: + return $this->getModuleId(); + break; + case 2: + return $this->getFile(); + break; + case 3: + return $this->getPosition(); + break; + case 4: + return $this->getCreatedAt(); + break; + case 5: + return $this->getUpdatedAt(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType (optional) One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME, + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE. + * @param array $alreadyDumpedObjects List of objects to skip to avoid recursion + * @param boolean $includeForeignObjects (optional) Whether to include hydrated related objects. Default to FALSE. + * + * @return array an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = TableMap::TYPE_PHPNAME, $includeLazyLoadColumns = true, $alreadyDumpedObjects = array(), $includeForeignObjects = false) + { + if (isset($alreadyDumpedObjects['ModuleImage'][$this->getPrimaryKey()])) { + return '*RECURSION*'; + } + $alreadyDumpedObjects['ModuleImage'][$this->getPrimaryKey()] = true; + $keys = ModuleImageTableMap::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getId(), + $keys[1] => $this->getModuleId(), + $keys[2] => $this->getFile(), + $keys[3] => $this->getPosition(), + $keys[4] => $this->getCreatedAt(), + $keys[5] => $this->getUpdatedAt(), + ); + $virtualColumns = $this->virtualColumns; + foreach($virtualColumns as $key => $virtualColumn) + { + $result[$key] = $virtualColumn; + } + + if ($includeForeignObjects) { + if (null !== $this->aModule) { + $result['Module'] = $this->aModule->toArray($keyType, $includeLazyLoadColumns, $alreadyDumpedObjects, true); + } + if (null !== $this->collModuleImageI18ns) { + $result['ModuleImageI18ns'] = $this->collModuleImageI18ns->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); + } + } + + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @return void + */ + public function setByName($name, $value, $type = TableMap::TYPE_PHPNAME) + { + $pos = ModuleImageTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); + + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch ($pos) { + case 0: + $this->setId($value); + break; + case 1: + $this->setModuleId($value); + break; + case 2: + $this->setFile($value); + break; + case 3: + $this->setPosition($value); + break; + case 4: + $this->setCreatedAt($value); + break; + case 5: + $this->setUpdatedAt($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME, + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * The default key type is the column's TableMap::TYPE_PHPNAME. + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = TableMap::TYPE_PHPNAME) + { + $keys = ModuleImageTableMap::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setModuleId($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setFile($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setPosition($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setCreatedAt($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setUpdatedAt($arr[$keys[5]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(ModuleImageTableMap::DATABASE_NAME); + + if ($this->isColumnModified(ModuleImageTableMap::ID)) $criteria->add(ModuleImageTableMap::ID, $this->id); + if ($this->isColumnModified(ModuleImageTableMap::MODULE_ID)) $criteria->add(ModuleImageTableMap::MODULE_ID, $this->module_id); + if ($this->isColumnModified(ModuleImageTableMap::FILE)) $criteria->add(ModuleImageTableMap::FILE, $this->file); + if ($this->isColumnModified(ModuleImageTableMap::POSITION)) $criteria->add(ModuleImageTableMap::POSITION, $this->position); + if ($this->isColumnModified(ModuleImageTableMap::CREATED_AT)) $criteria->add(ModuleImageTableMap::CREATED_AT, $this->created_at); + if ($this->isColumnModified(ModuleImageTableMap::UPDATED_AT)) $criteria->add(ModuleImageTableMap::UPDATED_AT, $this->updated_at); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(ModuleImageTableMap::DATABASE_NAME); + $criteria->add(ModuleImageTableMap::ID, $this->id); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return int + */ + public function getPrimaryKey() + { + return $this->getId(); + } + + /** + * Generic method to set the primary key (id column). + * + * @param int $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setId($key); + } + + /** + * Returns true if the primary key for this object is null. + * @return boolean + */ + public function isPrimaryKeyNull() + { + + return null === $this->getId(); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of \Thelia\Model\ModuleImage (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @param boolean $makeNew Whether to reset autoincrement PKs and make the object new. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false, $makeNew = true) + { + $copyObj->setModuleId($this->getModuleId()); + $copyObj->setFile($this->getFile()); + $copyObj->setPosition($this->getPosition()); + $copyObj->setCreatedAt($this->getCreatedAt()); + $copyObj->setUpdatedAt($this->getUpdatedAt()); + + if ($deepCopy) { + // important: temporarily setNew(false) because this affects the behavior of + // the getter/setter methods for fkey referrer objects. + $copyObj->setNew(false); + + foreach ($this->getModuleImageI18ns() as $relObj) { + if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves + $copyObj->addModuleImageI18n($relObj->copy($deepCopy)); + } + } + + } // if ($deepCopy) + + if ($makeNew) { + $copyObj->setNew(true); + $copyObj->setId(NULL); // this is a auto-increment column, so set to default value + } + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return \Thelia\Model\ModuleImage Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + + return $copyObj; + } + + /** + * Declares an association between this object and a ChildModule object. + * + * @param ChildModule $v + * @return \Thelia\Model\ModuleImage The current object (for fluent API support) + * @throws PropelException + */ + public function setModule(ChildModule $v = null) + { + if ($v === null) { + $this->setModuleId(NULL); + } else { + $this->setModuleId($v->getId()); + } + + $this->aModule = $v; + + // Add binding for other direction of this n:n relationship. + // If this object has already been added to the ChildModule object, it will not be re-added. + if ($v !== null) { + $v->addModuleImage($this); + } + + + return $this; + } + + + /** + * Get the associated ChildModule object + * + * @param ConnectionInterface $con Optional Connection object. + * @return ChildModule The associated ChildModule object. + * @throws PropelException + */ + public function getModule(ConnectionInterface $con = null) + { + if ($this->aModule === null && ($this->module_id !== null)) { + $this->aModule = ChildModuleQuery::create()->findPk($this->module_id, $con); + /* The following can be used additionally to + guarantee the related object contains a reference + to this object. This level of coupling may, however, be + undesirable since it could result in an only partially populated collection + in the referenced object. + $this->aModule->addModuleImages($this); + */ + } + + return $this->aModule; + } + + + /** + * Initializes a collection based on the name of a relation. + * Avoids crafting an 'init[$relationName]s' method name + * that wouldn't work when StandardEnglishPluralizer is used. + * + * @param string $relationName The name of the relation to initialize + * @return void + */ + public function initRelation($relationName) + { + if ('ModuleImageI18n' == $relationName) { + return $this->initModuleImageI18ns(); + } + } + + /** + * Clears out the collModuleImageI18ns collection + * + * This does not modify the database; however, it will remove any associated objects, causing + * them to be refetched by subsequent calls to accessor method. + * + * @return void + * @see addModuleImageI18ns() + */ + public function clearModuleImageI18ns() + { + $this->collModuleImageI18ns = null; // important to set this to NULL since that means it is uninitialized + } + + /** + * Reset is the collModuleImageI18ns collection loaded partially. + */ + public function resetPartialModuleImageI18ns($v = true) + { + $this->collModuleImageI18nsPartial = $v; + } + + /** + * Initializes the collModuleImageI18ns collection. + * + * By default this just sets the collModuleImageI18ns collection to an empty array (like clearcollModuleImageI18ns()); + * however, you may wish to override this method in your stub class to provide setting appropriate + * to your application -- for example, setting the initial array to the values stored in database. + * + * @param boolean $overrideExisting If set to true, the method call initializes + * the collection even if it is not empty + * + * @return void + */ + public function initModuleImageI18ns($overrideExisting = true) + { + if (null !== $this->collModuleImageI18ns && !$overrideExisting) { + return; + } + $this->collModuleImageI18ns = new ObjectCollection(); + $this->collModuleImageI18ns->setModel('\Thelia\Model\ModuleImageI18n'); + } + + /** + * Gets an array of ChildModuleImageI18n objects which contain a foreign key that references this object. + * + * If the $criteria is not null, it is used to always fetch the results from the database. + * Otherwise the results are fetched from the database the first time, then cached. + * Next time the same method is called without $criteria, the cached collection is returned. + * If this ChildModuleImage is new, it will return + * an empty collection or the current collection; the criteria is ignored on a new object. + * + * @param Criteria $criteria optional Criteria object to narrow the query + * @param ConnectionInterface $con optional connection object + * @return Collection|ChildModuleImageI18n[] List of ChildModuleImageI18n objects + * @throws PropelException + */ + public function getModuleImageI18ns($criteria = null, ConnectionInterface $con = null) + { + $partial = $this->collModuleImageI18nsPartial && !$this->isNew(); + if (null === $this->collModuleImageI18ns || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collModuleImageI18ns) { + // return empty collection + $this->initModuleImageI18ns(); + } else { + $collModuleImageI18ns = ChildModuleImageI18nQuery::create(null, $criteria) + ->filterByModuleImage($this) + ->find($con); + + if (null !== $criteria) { + if (false !== $this->collModuleImageI18nsPartial && count($collModuleImageI18ns)) { + $this->initModuleImageI18ns(false); + + foreach ($collModuleImageI18ns as $obj) { + if (false == $this->collModuleImageI18ns->contains($obj)) { + $this->collModuleImageI18ns->append($obj); + } + } + + $this->collModuleImageI18nsPartial = true; + } + + $collModuleImageI18ns->getInternalIterator()->rewind(); + + return $collModuleImageI18ns; + } + + if ($partial && $this->collModuleImageI18ns) { + foreach ($this->collModuleImageI18ns as $obj) { + if ($obj->isNew()) { + $collModuleImageI18ns[] = $obj; + } + } + } + + $this->collModuleImageI18ns = $collModuleImageI18ns; + $this->collModuleImageI18nsPartial = false; + } + } + + return $this->collModuleImageI18ns; + } + + /** + * Sets a collection of ModuleImageI18n objects related by a one-to-many relationship + * to the current object. + * It will also schedule objects for deletion based on a diff between old objects (aka persisted) + * and new objects from the given Propel collection. + * + * @param Collection $moduleImageI18ns A Propel collection. + * @param ConnectionInterface $con Optional connection object + * @return ChildModuleImage The current object (for fluent API support) + */ + public function setModuleImageI18ns(Collection $moduleImageI18ns, ConnectionInterface $con = null) + { + $moduleImageI18nsToDelete = $this->getModuleImageI18ns(new Criteria(), $con)->diff($moduleImageI18ns); + + + //since at least one column in the foreign key is at the same time a PK + //we can not just set a PK to NULL in the lines below. We have to store + //a backup of all values, so we are able to manipulate these items based on the onDelete value later. + $this->moduleImageI18nsScheduledForDeletion = clone $moduleImageI18nsToDelete; + + foreach ($moduleImageI18nsToDelete as $moduleImageI18nRemoved) { + $moduleImageI18nRemoved->setModuleImage(null); + } + + $this->collModuleImageI18ns = null; + foreach ($moduleImageI18ns as $moduleImageI18n) { + $this->addModuleImageI18n($moduleImageI18n); + } + + $this->collModuleImageI18ns = $moduleImageI18ns; + $this->collModuleImageI18nsPartial = false; + + return $this; + } + + /** + * Returns the number of related ModuleImageI18n objects. + * + * @param Criteria $criteria + * @param boolean $distinct + * @param ConnectionInterface $con + * @return int Count of related ModuleImageI18n objects. + * @throws PropelException + */ + public function countModuleImageI18ns(Criteria $criteria = null, $distinct = false, ConnectionInterface $con = null) + { + $partial = $this->collModuleImageI18nsPartial && !$this->isNew(); + if (null === $this->collModuleImageI18ns || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collModuleImageI18ns) { + return 0; + } + + if ($partial && !$criteria) { + return count($this->getModuleImageI18ns()); + } + + $query = ChildModuleImageI18nQuery::create(null, $criteria); + if ($distinct) { + $query->distinct(); + } + + return $query + ->filterByModuleImage($this) + ->count($con); + } + + return count($this->collModuleImageI18ns); + } + + /** + * Method called to associate a ChildModuleImageI18n object to this object + * through the ChildModuleImageI18n foreign key attribute. + * + * @param ChildModuleImageI18n $l ChildModuleImageI18n + * @return \Thelia\Model\ModuleImage The current object (for fluent API support) + */ + public function addModuleImageI18n(ChildModuleImageI18n $l) + { + if ($l && $locale = $l->getLocale()) { + $this->setLocale($locale); + $this->currentTranslations[$locale] = $l; + } + if ($this->collModuleImageI18ns === null) { + $this->initModuleImageI18ns(); + $this->collModuleImageI18nsPartial = true; + } + + if (!in_array($l, $this->collModuleImageI18ns->getArrayCopy(), true)) { // only add it if the **same** object is not already associated + $this->doAddModuleImageI18n($l); + } + + return $this; + } + + /** + * @param ModuleImageI18n $moduleImageI18n The moduleImageI18n object to add. + */ + protected function doAddModuleImageI18n($moduleImageI18n) + { + $this->collModuleImageI18ns[]= $moduleImageI18n; + $moduleImageI18n->setModuleImage($this); + } + + /** + * @param ModuleImageI18n $moduleImageI18n The moduleImageI18n object to remove. + * @return ChildModuleImage The current object (for fluent API support) + */ + public function removeModuleImageI18n($moduleImageI18n) + { + if ($this->getModuleImageI18ns()->contains($moduleImageI18n)) { + $this->collModuleImageI18ns->remove($this->collModuleImageI18ns->search($moduleImageI18n)); + if (null === $this->moduleImageI18nsScheduledForDeletion) { + $this->moduleImageI18nsScheduledForDeletion = clone $this->collModuleImageI18ns; + $this->moduleImageI18nsScheduledForDeletion->clear(); + } + $this->moduleImageI18nsScheduledForDeletion[]= clone $moduleImageI18n; + $moduleImageI18n->setModuleImage(null); + } + + return $this; + } + + /** + * Clears the current object and sets all attributes to their default values + */ + public function clear() + { + $this->id = null; + $this->module_id = null; + $this->file = null; + $this->position = null; + $this->created_at = null; + $this->updated_at = null; + $this->alreadyInSave = false; + $this->clearAllReferences(); + $this->resetModified(); + $this->setNew(true); + $this->setDeleted(false); + } + + /** + * Resets all references to other model objects or collections of model objects. + * + * This method is a user-space workaround for PHP's inability to garbage collect + * objects with circular references (even in PHP 5.3). This is currently necessary + * when using Propel in certain daemon or large-volume/high-memory operations. + * + * @param boolean $deep Whether to also clear the references on all referrer objects. + */ + public function clearAllReferences($deep = false) + { + if ($deep) { + if ($this->collModuleImageI18ns) { + foreach ($this->collModuleImageI18ns as $o) { + $o->clearAllReferences($deep); + } + } + } // if ($deep) + + // i18n behavior + $this->currentLocale = 'en_US'; + $this->currentTranslations = null; + + if ($this->collModuleImageI18ns instanceof Collection) { + $this->collModuleImageI18ns->clearIterator(); + } + $this->collModuleImageI18ns = null; + $this->aModule = null; + } + + /** + * Return the string representation of this object + * + * @return string + */ + public function __toString() + { + return (string) $this->exportTo(ModuleImageTableMap::DEFAULT_STRING_FORMAT); + } + + // timestampable behavior + + /** + * Mark the current object so that the update date doesn't get updated during next save + * + * @return ChildModuleImage The current object (for fluent API support) + */ + public function keepUpdateDateUnchanged() + { + $this->modifiedColumns[] = ModuleImageTableMap::UPDATED_AT; + + return $this; + } + + // i18n behavior + + /** + * Sets the locale for translations + * + * @param string $locale Locale to use for the translation, e.g. 'fr_FR' + * + * @return ChildModuleImage The current object (for fluent API support) + */ + public function setLocale($locale = 'en_US') + { + $this->currentLocale = $locale; + + return $this; + } + + /** + * Gets the locale for translations + * + * @return string $locale Locale to use for the translation, e.g. 'fr_FR' + */ + public function getLocale() + { + return $this->currentLocale; + } + + /** + * Returns the current translation for a given locale + * + * @param string $locale Locale to use for the translation, e.g. 'fr_FR' + * @param ConnectionInterface $con an optional connection object + * + * @return ChildModuleImageI18n */ + public function getTranslation($locale = 'en_US', ConnectionInterface $con = null) + { + if (!isset($this->currentTranslations[$locale])) { + if (null !== $this->collModuleImageI18ns) { + foreach ($this->collModuleImageI18ns as $translation) { + if ($translation->getLocale() == $locale) { + $this->currentTranslations[$locale] = $translation; + + return $translation; + } + } + } + if ($this->isNew()) { + $translation = new ChildModuleImageI18n(); + $translation->setLocale($locale); + } else { + $translation = ChildModuleImageI18nQuery::create() + ->filterByPrimaryKey(array($this->getPrimaryKey(), $locale)) + ->findOneOrCreate($con); + $this->currentTranslations[$locale] = $translation; + } + $this->addModuleImageI18n($translation); + } + + return $this->currentTranslations[$locale]; + } + + /** + * Remove the translation for a given locale + * + * @param string $locale Locale to use for the translation, e.g. 'fr_FR' + * @param ConnectionInterface $con an optional connection object + * + * @return ChildModuleImage The current object (for fluent API support) + */ + public function removeTranslation($locale = 'en_US', ConnectionInterface $con = null) + { + if (!$this->isNew()) { + ChildModuleImageI18nQuery::create() + ->filterByPrimaryKey(array($this->getPrimaryKey(), $locale)) + ->delete($con); + } + if (isset($this->currentTranslations[$locale])) { + unset($this->currentTranslations[$locale]); + } + foreach ($this->collModuleImageI18ns as $key => $translation) { + if ($translation->getLocale() == $locale) { + unset($this->collModuleImageI18ns[$key]); + break; + } + } + + return $this; + } + + /** + * Returns the current translation + * + * @param ConnectionInterface $con an optional connection object + * + * @return ChildModuleImageI18n */ + public function getCurrentTranslation(ConnectionInterface $con = null) + { + return $this->getTranslation($this->getLocale(), $con); + } + + + /** + * Get the [title] column value. + * + * @return string + */ + public function getTitle() + { + return $this->getCurrentTranslation()->getTitle(); + } + + + /** + * Set the value of [title] column. + * + * @param string $v new value + * @return \Thelia\Model\ModuleImageI18n The current object (for fluent API support) + */ + public function setTitle($v) + { $this->getCurrentTranslation()->setTitle($v); + + return $this; + } + + + /** + * Get the [description] column value. + * + * @return string + */ + public function getDescription() + { + return $this->getCurrentTranslation()->getDescription(); + } + + + /** + * Set the value of [description] column. + * + * @param string $v new value + * @return \Thelia\Model\ModuleImageI18n The current object (for fluent API support) + */ + public function setDescription($v) + { $this->getCurrentTranslation()->setDescription($v); + + return $this; + } + + + /** + * Get the [chapo] column value. + * + * @return string + */ + public function getChapo() + { + return $this->getCurrentTranslation()->getChapo(); + } + + + /** + * Set the value of [chapo] column. + * + * @param string $v new value + * @return \Thelia\Model\ModuleImageI18n The current object (for fluent API support) + */ + public function setChapo($v) + { $this->getCurrentTranslation()->setChapo($v); + + return $this; + } + + + /** + * Get the [postscriptum] column value. + * + * @return string + */ + public function getPostscriptum() + { + return $this->getCurrentTranslation()->getPostscriptum(); + } + + + /** + * Set the value of [postscriptum] column. + * + * @param string $v new value + * @return \Thelia\Model\ModuleImageI18n The current object (for fluent API support) + */ + public function setPostscriptum($v) + { $this->getCurrentTranslation()->setPostscriptum($v); + + return $this; + } + + /** + * Code to be run before persisting the object + * @param ConnectionInterface $con + * @return boolean + */ + public function preSave(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after persisting the object + * @param ConnectionInterface $con + */ + public function postSave(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before inserting to database + * @param ConnectionInterface $con + * @return boolean + */ + public function preInsert(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after inserting to database + * @param ConnectionInterface $con + */ + public function postInsert(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before updating the object in database + * @param ConnectionInterface $con + * @return boolean + */ + public function preUpdate(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after updating the object in database + * @param ConnectionInterface $con + */ + public function postUpdate(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before deleting the object in database + * @param ConnectionInterface $con + * @return boolean + */ + public function preDelete(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after deleting the object in database + * @param ConnectionInterface $con + */ + public function postDelete(ConnectionInterface $con = null) + { + + } + + + /** + * Derived method to catches calls to undefined methods. + * + * Provides magic import/export method support (fromXML()/toXML(), fromYAML()/toYAML(), etc.). + * Allows to define default __call() behavior if you overwrite __call() + * + * @param string $name + * @param mixed $params + * + * @return array|string + */ + public function __call($name, $params) + { + if (0 === strpos($name, 'get')) { + $virtualColumn = substr($name, 3); + if ($this->hasVirtualColumn($virtualColumn)) { + return $this->getVirtualColumn($virtualColumn); + } + + $virtualColumn = lcfirst($virtualColumn); + if ($this->hasVirtualColumn($virtualColumn)) { + return $this->getVirtualColumn($virtualColumn); + } + } + + if (0 === strpos($name, 'from')) { + $format = substr($name, 4); + + return $this->importFrom($format, reset($params)); + } + + if (0 === strpos($name, 'to')) { + $format = substr($name, 2); + $includeLazyLoadColumns = isset($params[0]) ? $params[0] : true; + + return $this->exportTo($format, $includeLazyLoadColumns); + } + + throw new BadMethodCallException(sprintf('Call to undefined method: %s.', $name)); + } + +} diff --git a/core/lib/Thelia/Model/Base/AttributeCategory.php b/core/lib/Thelia/Model/Base/ModuleImageI18n.php similarity index 64% rename from core/lib/Thelia/Model/Base/AttributeCategory.php rename to core/lib/Thelia/Model/Base/ModuleImageI18n.php index da702559a..2425b4e65 100644 --- a/core/lib/Thelia/Model/Base/AttributeCategory.php +++ b/core/lib/Thelia/Model/Base/ModuleImageI18n.php @@ -2,7 +2,6 @@ namespace Thelia\Model\Base; -use \DateTime; use \Exception; use \PDO; use Propel\Runtime\Propel; @@ -15,21 +14,17 @@ use Propel\Runtime\Exception\BadMethodCallException; use Propel\Runtime\Exception\PropelException; use Propel\Runtime\Map\TableMap; use Propel\Runtime\Parser\AbstractParser; -use Propel\Runtime\Util\PropelDateTime; -use Thelia\Model\Attribute as ChildAttribute; -use Thelia\Model\AttributeCategory as ChildAttributeCategory; -use Thelia\Model\AttributeCategoryQuery as ChildAttributeCategoryQuery; -use Thelia\Model\AttributeQuery as ChildAttributeQuery; -use Thelia\Model\Category as ChildCategory; -use Thelia\Model\CategoryQuery as ChildCategoryQuery; -use Thelia\Model\Map\AttributeCategoryTableMap; +use Thelia\Model\ModuleImage as ChildModuleImage; +use Thelia\Model\ModuleImageI18nQuery as ChildModuleImageI18nQuery; +use Thelia\Model\ModuleImageQuery as ChildModuleImageQuery; +use Thelia\Model\Map\ModuleImageI18nTableMap; -abstract class AttributeCategory implements ActiveRecordInterface +abstract class ModuleImageI18n implements ActiveRecordInterface { /** * TableMap class name */ - const TABLE_MAP = '\\Thelia\\Model\\Map\\AttributeCategoryTableMap'; + const TABLE_MAP = '\\Thelia\\Model\\Map\\ModuleImageI18nTableMap'; /** @@ -65,38 +60,40 @@ abstract class AttributeCategory implements ActiveRecordInterface protected $id; /** - * The value for the category_id field. - * @var int - */ - protected $category_id; - - /** - * The value for the attribute_id field. - * @var int - */ - protected $attribute_id; - - /** - * The value for the created_at field. + * The value for the locale field. + * Note: this column has a database default value of: 'en_US' * @var string */ - protected $created_at; + protected $locale; /** - * The value for the updated_at field. + * The value for the title field. * @var string */ - protected $updated_at; + protected $title; /** - * @var Category + * The value for the description field. + * @var string */ - protected $aCategory; + protected $description; /** - * @var Attribute + * The value for the chapo field. + * @var string */ - protected $aAttribute; + protected $chapo; + + /** + * The value for the postscriptum field. + * @var string + */ + protected $postscriptum; + + /** + * @var ModuleImage + */ + protected $aModuleImage; /** * Flag to prevent endless save loop, if this object is referenced @@ -107,10 +104,23 @@ abstract class AttributeCategory implements ActiveRecordInterface protected $alreadyInSave = false; /** - * Initializes internal state of Thelia\Model\Base\AttributeCategory object. + * Applies default values to this object. + * This method should be called from the object's constructor (or + * equivalent initialization method). + * @see __construct() + */ + public function applyDefaultValues() + { + $this->locale = 'en_US'; + } + + /** + * Initializes internal state of Thelia\Model\Base\ModuleImageI18n object. + * @see applyDefaults() */ public function __construct() { + $this->applyDefaultValues(); } /** @@ -202,9 +212,9 @@ abstract class AttributeCategory implements ActiveRecordInterface } /** - * Compares this with another AttributeCategory instance. If - * obj is an instance of AttributeCategory, delegates to - * equals(AttributeCategory). Otherwise, returns false. + * Compares this with another ModuleImageI18n instance. If + * obj is an instance of ModuleImageI18n, delegates to + * equals(ModuleImageI18n). Otherwise, returns false. * * @param obj The object to compare to. * @return Whether equal to the object specified. @@ -285,7 +295,7 @@ abstract class AttributeCategory implements ActiveRecordInterface * @param string $name The virtual column name * @param mixed $value The value to give to the virtual column * - * @return AttributeCategory The current object, for fluid interface + * @return ModuleImageI18n The current object, for fluid interface */ public function setVirtualColumn($name, $value) { @@ -317,7 +327,7 @@ abstract class AttributeCategory implements ActiveRecordInterface * or a format name ('XML', 'YAML', 'JSON', 'CSV') * @param string $data The source data to import from * - * @return AttributeCategory The current object, for fluid interface + * @return ModuleImageI18n The current object, for fluid interface */ public function importFrom($parser, $data) { @@ -372,72 +382,65 @@ abstract class AttributeCategory implements ActiveRecordInterface } /** - * Get the [category_id] column value. + * Get the [locale] column value. * - * @return int + * @return string */ - public function getCategoryId() + public function getLocale() { - return $this->category_id; + return $this->locale; } /** - * Get the [attribute_id] column value. + * Get the [title] column value. * - * @return int + * @return string */ - public function getAttributeId() + public function getTitle() { - return $this->attribute_id; + return $this->title; } /** - * Get the [optionally formatted] temporal [created_at] column value. + * Get the [description] column value. * - * - * @param string $format The date/time format string (either date()-style or strftime()-style). - * If format is NULL, then the raw \DateTime object will be returned. - * - * @return mixed Formatted date/time value as string or \DateTime object (if format is NULL), NULL if column is NULL, and 0 if column value is 0000-00-00 00:00:00 - * - * @throws PropelException - if unable to parse/validate the date/time value. + * @return string */ - public function getCreatedAt($format = NULL) + public function getDescription() { - if ($format === null) { - return $this->created_at; - } else { - return $this->created_at !== null ? $this->created_at->format($format) : null; - } + + return $this->description; } /** - * Get the [optionally formatted] temporal [updated_at] column value. + * Get the [chapo] column value. * - * - * @param string $format The date/time format string (either date()-style or strftime()-style). - * If format is NULL, then the raw \DateTime object will be returned. - * - * @return mixed Formatted date/time value as string or \DateTime object (if format is NULL), NULL if column is NULL, and 0 if column value is 0000-00-00 00:00:00 - * - * @throws PropelException - if unable to parse/validate the date/time value. + * @return string */ - public function getUpdatedAt($format = NULL) + public function getChapo() { - if ($format === null) { - return $this->updated_at; - } else { - return $this->updated_at !== null ? $this->updated_at->format($format) : null; - } + + return $this->chapo; + } + + /** + * Get the [postscriptum] column value. + * + * @return string + */ + public function getPostscriptum() + { + + return $this->postscriptum; } /** * Set the value of [id] column. * * @param int $v new value - * @return \Thelia\Model\AttributeCategory The current object (for fluent API support) + * @return \Thelia\Model\ModuleImageI18n The current object (for fluent API support) */ public function setId($v) { @@ -447,7 +450,11 @@ abstract class AttributeCategory implements ActiveRecordInterface if ($this->id !== $v) { $this->id = $v; - $this->modifiedColumns[] = AttributeCategoryTableMap::ID; + $this->modifiedColumns[] = ModuleImageI18nTableMap::ID; + } + + if ($this->aModuleImage !== null && $this->aModuleImage->getId() !== $v) { + $this->aModuleImage = null; } @@ -455,96 +462,109 @@ abstract class AttributeCategory implements ActiveRecordInterface } // setId() /** - * Set the value of [category_id] column. + * Set the value of [locale] column. * - * @param int $v new value - * @return \Thelia\Model\AttributeCategory The current object (for fluent API support) + * @param string $v new value + * @return \Thelia\Model\ModuleImageI18n The current object (for fluent API support) */ - public function setCategoryId($v) + public function setLocale($v) { if ($v !== null) { - $v = (int) $v; + $v = (string) $v; } - if ($this->category_id !== $v) { - $this->category_id = $v; - $this->modifiedColumns[] = AttributeCategoryTableMap::CATEGORY_ID; - } - - if ($this->aCategory !== null && $this->aCategory->getId() !== $v) { - $this->aCategory = null; + if ($this->locale !== $v) { + $this->locale = $v; + $this->modifiedColumns[] = ModuleImageI18nTableMap::LOCALE; } return $this; - } // setCategoryId() + } // setLocale() /** - * Set the value of [attribute_id] column. + * Set the value of [title] column. * - * @param int $v new value - * @return \Thelia\Model\AttributeCategory The current object (for fluent API support) + * @param string $v new value + * @return \Thelia\Model\ModuleImageI18n The current object (for fluent API support) */ - public function setAttributeId($v) + public function setTitle($v) { if ($v !== null) { - $v = (int) $v; + $v = (string) $v; } - if ($this->attribute_id !== $v) { - $this->attribute_id = $v; - $this->modifiedColumns[] = AttributeCategoryTableMap::ATTRIBUTE_ID; - } - - if ($this->aAttribute !== null && $this->aAttribute->getId() !== $v) { - $this->aAttribute = null; + if ($this->title !== $v) { + $this->title = $v; + $this->modifiedColumns[] = ModuleImageI18nTableMap::TITLE; } return $this; - } // setAttributeId() + } // setTitle() /** - * Sets the value of [created_at] column to a normalized version of the date/time value specified. + * Set the value of [description] column. * - * @param mixed $v string, integer (timestamp), or \DateTime value. - * Empty strings are treated as NULL. - * @return \Thelia\Model\AttributeCategory The current object (for fluent API support) + * @param string $v new value + * @return \Thelia\Model\ModuleImageI18n The current object (for fluent API support) */ - public function setCreatedAt($v) + public function setDescription($v) { - $dt = PropelDateTime::newInstance($v, null, '\DateTime'); - if ($this->created_at !== null || $dt !== null) { - if ($dt !== $this->created_at) { - $this->created_at = $dt; - $this->modifiedColumns[] = AttributeCategoryTableMap::CREATED_AT; - } - } // if either are not null + if ($v !== null) { + $v = (string) $v; + } + + if ($this->description !== $v) { + $this->description = $v; + $this->modifiedColumns[] = ModuleImageI18nTableMap::DESCRIPTION; + } return $this; - } // setCreatedAt() + } // setDescription() /** - * Sets the value of [updated_at] column to a normalized version of the date/time value specified. + * Set the value of [chapo] column. * - * @param mixed $v string, integer (timestamp), or \DateTime value. - * Empty strings are treated as NULL. - * @return \Thelia\Model\AttributeCategory The current object (for fluent API support) + * @param string $v new value + * @return \Thelia\Model\ModuleImageI18n The current object (for fluent API support) */ - public function setUpdatedAt($v) + public function setChapo($v) { - $dt = PropelDateTime::newInstance($v, null, '\DateTime'); - if ($this->updated_at !== null || $dt !== null) { - if ($dt !== $this->updated_at) { - $this->updated_at = $dt; - $this->modifiedColumns[] = AttributeCategoryTableMap::UPDATED_AT; - } - } // if either are not null + if ($v !== null) { + $v = (string) $v; + } + + if ($this->chapo !== $v) { + $this->chapo = $v; + $this->modifiedColumns[] = ModuleImageI18nTableMap::CHAPO; + } return $this; - } // setUpdatedAt() + } // setChapo() + + /** + * Set the value of [postscriptum] column. + * + * @param string $v new value + * @return \Thelia\Model\ModuleImageI18n The current object (for fluent API support) + */ + public function setPostscriptum($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->postscriptum !== $v) { + $this->postscriptum = $v; + $this->modifiedColumns[] = ModuleImageI18nTableMap::POSTSCRIPTUM; + } + + + return $this; + } // setPostscriptum() /** * Indicates whether the columns in this object are only set to default values. @@ -556,6 +576,10 @@ abstract class AttributeCategory implements ActiveRecordInterface */ public function hasOnlyDefaultValues() { + if ($this->locale !== 'en_US') { + return false; + } + // otherwise, everything was equal, so return TRUE return true; } // hasOnlyDefaultValues() @@ -583,26 +607,23 @@ abstract class AttributeCategory implements ActiveRecordInterface try { - $col = $row[TableMap::TYPE_NUM == $indexType ? 0 + $startcol : AttributeCategoryTableMap::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 0 + $startcol : ModuleImageI18nTableMap::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)]; $this->id = (null !== $col) ? (int) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 1 + $startcol : AttributeCategoryTableMap::translateFieldName('CategoryId', TableMap::TYPE_PHPNAME, $indexType)]; - $this->category_id = (null !== $col) ? (int) $col : null; + $col = $row[TableMap::TYPE_NUM == $indexType ? 1 + $startcol : ModuleImageI18nTableMap::translateFieldName('Locale', TableMap::TYPE_PHPNAME, $indexType)]; + $this->locale = (null !== $col) ? (string) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : AttributeCategoryTableMap::translateFieldName('AttributeId', TableMap::TYPE_PHPNAME, $indexType)]; - $this->attribute_id = (null !== $col) ? (int) $col : null; + $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : ModuleImageI18nTableMap::translateFieldName('Title', TableMap::TYPE_PHPNAME, $indexType)]; + $this->title = (null !== $col) ? (string) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : AttributeCategoryTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; - if ($col === '0000-00-00 00:00:00') { - $col = null; - } - $this->created_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; + $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : ModuleImageI18nTableMap::translateFieldName('Description', TableMap::TYPE_PHPNAME, $indexType)]; + $this->description = (null !== $col) ? (string) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : AttributeCategoryTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; - if ($col === '0000-00-00 00:00:00') { - $col = null; - } - $this->updated_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; + $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : ModuleImageI18nTableMap::translateFieldName('Chapo', TableMap::TYPE_PHPNAME, $indexType)]; + $this->chapo = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : ModuleImageI18nTableMap::translateFieldName('Postscriptum', TableMap::TYPE_PHPNAME, $indexType)]; + $this->postscriptum = (null !== $col) ? (string) $col : null; $this->resetModified(); $this->setNew(false); @@ -611,10 +632,10 @@ abstract class AttributeCategory implements ActiveRecordInterface $this->ensureConsistency(); } - return $startcol + 5; // 5 = AttributeCategoryTableMap::NUM_HYDRATE_COLUMNS. + return $startcol + 6; // 6 = ModuleImageI18nTableMap::NUM_HYDRATE_COLUMNS. } catch (Exception $e) { - throw new PropelException("Error populating \Thelia\Model\AttributeCategory object", 0, $e); + throw new PropelException("Error populating \Thelia\Model\ModuleImageI18n object", 0, $e); } } @@ -633,11 +654,8 @@ abstract class AttributeCategory implements ActiveRecordInterface */ public function ensureConsistency() { - if ($this->aCategory !== null && $this->category_id !== $this->aCategory->getId()) { - $this->aCategory = null; - } - if ($this->aAttribute !== null && $this->attribute_id !== $this->aAttribute->getId()) { - $this->aAttribute = null; + if ($this->aModuleImage !== null && $this->id !== $this->aModuleImage->getId()) { + $this->aModuleImage = null; } } // ensureConsistency @@ -662,13 +680,13 @@ abstract class AttributeCategory implements ActiveRecordInterface } if ($con === null) { - $con = Propel::getServiceContainer()->getReadConnection(AttributeCategoryTableMap::DATABASE_NAME); + $con = Propel::getServiceContainer()->getReadConnection(ModuleImageI18nTableMap::DATABASE_NAME); } // We don't need to alter the object instance pool; we're just modifying this instance // already in the pool. - $dataFetcher = ChildAttributeCategoryQuery::create(null, $this->buildPkeyCriteria())->setFormatter(ModelCriteria::FORMAT_STATEMENT)->find($con); + $dataFetcher = ChildModuleImageI18nQuery::create(null, $this->buildPkeyCriteria())->setFormatter(ModelCriteria::FORMAT_STATEMENT)->find($con); $row = $dataFetcher->fetch(); $dataFetcher->close(); if (!$row) { @@ -678,8 +696,7 @@ abstract class AttributeCategory implements ActiveRecordInterface if ($deep) { // also de-associate any related objects? - $this->aCategory = null; - $this->aAttribute = null; + $this->aModuleImage = null; } // if (deep) } @@ -689,8 +706,8 @@ abstract class AttributeCategory implements ActiveRecordInterface * @param ConnectionInterface $con * @return void * @throws PropelException - * @see AttributeCategory::setDeleted() - * @see AttributeCategory::isDeleted() + * @see ModuleImageI18n::setDeleted() + * @see ModuleImageI18n::isDeleted() */ public function delete(ConnectionInterface $con = null) { @@ -699,12 +716,12 @@ abstract class AttributeCategory implements ActiveRecordInterface } if ($con === null) { - $con = Propel::getServiceContainer()->getWriteConnection(AttributeCategoryTableMap::DATABASE_NAME); + $con = Propel::getServiceContainer()->getWriteConnection(ModuleImageI18nTableMap::DATABASE_NAME); } $con->beginTransaction(); try { - $deleteQuery = ChildAttributeCategoryQuery::create() + $deleteQuery = ChildModuleImageI18nQuery::create() ->filterByPrimaryKey($this->getPrimaryKey()); $ret = $this->preDelete($con); if ($ret) { @@ -741,7 +758,7 @@ abstract class AttributeCategory implements ActiveRecordInterface } if ($con === null) { - $con = Propel::getServiceContainer()->getWriteConnection(AttributeCategoryTableMap::DATABASE_NAME); + $con = Propel::getServiceContainer()->getWriteConnection(ModuleImageI18nTableMap::DATABASE_NAME); } $con->beginTransaction(); @@ -750,19 +767,8 @@ abstract class AttributeCategory implements ActiveRecordInterface $ret = $this->preSave($con); if ($isInsert) { $ret = $ret && $this->preInsert($con); - // timestampable behavior - if (!$this->isColumnModified(AttributeCategoryTableMap::CREATED_AT)) { - $this->setCreatedAt(time()); - } - if (!$this->isColumnModified(AttributeCategoryTableMap::UPDATED_AT)) { - $this->setUpdatedAt(time()); - } } else { $ret = $ret && $this->preUpdate($con); - // timestampable behavior - if ($this->isModified() && !$this->isColumnModified(AttributeCategoryTableMap::UPDATED_AT)) { - $this->setUpdatedAt(time()); - } } if ($ret) { $affectedRows = $this->doSave($con); @@ -772,7 +778,7 @@ abstract class AttributeCategory implements ActiveRecordInterface $this->postUpdate($con); } $this->postSave($con); - AttributeCategoryTableMap::addInstanceToPool($this); + ModuleImageI18nTableMap::addInstanceToPool($this); } else { $affectedRows = 0; } @@ -807,18 +813,11 @@ abstract class AttributeCategory implements ActiveRecordInterface // method. This object relates to these object(s) by a // foreign key reference. - if ($this->aCategory !== null) { - if ($this->aCategory->isModified() || $this->aCategory->isNew()) { - $affectedRows += $this->aCategory->save($con); + if ($this->aModuleImage !== null) { + if ($this->aModuleImage->isModified() || $this->aModuleImage->isNew()) { + $affectedRows += $this->aModuleImage->save($con); } - $this->setCategory($this->aCategory); - } - - if ($this->aAttribute !== null) { - if ($this->aAttribute->isModified() || $this->aAttribute->isNew()) { - $affectedRows += $this->aAttribute->save($con); - } - $this->setAttribute($this->aAttribute); + $this->setModuleImage($this->aModuleImage); } if ($this->isNew() || $this->isModified()) { @@ -852,30 +851,29 @@ abstract class AttributeCategory implements ActiveRecordInterface $modifiedColumns = array(); $index = 0; - $this->modifiedColumns[] = AttributeCategoryTableMap::ID; - if (null !== $this->id) { - throw new PropelException('Cannot insert a value for auto-increment primary key (' . AttributeCategoryTableMap::ID . ')'); - } // check the columns in natural order for more readable SQL queries - if ($this->isColumnModified(AttributeCategoryTableMap::ID)) { + if ($this->isColumnModified(ModuleImageI18nTableMap::ID)) { $modifiedColumns[':p' . $index++] = 'ID'; } - if ($this->isColumnModified(AttributeCategoryTableMap::CATEGORY_ID)) { - $modifiedColumns[':p' . $index++] = 'CATEGORY_ID'; + if ($this->isColumnModified(ModuleImageI18nTableMap::LOCALE)) { + $modifiedColumns[':p' . $index++] = 'LOCALE'; } - if ($this->isColumnModified(AttributeCategoryTableMap::ATTRIBUTE_ID)) { - $modifiedColumns[':p' . $index++] = 'ATTRIBUTE_ID'; + if ($this->isColumnModified(ModuleImageI18nTableMap::TITLE)) { + $modifiedColumns[':p' . $index++] = 'TITLE'; } - if ($this->isColumnModified(AttributeCategoryTableMap::CREATED_AT)) { - $modifiedColumns[':p' . $index++] = 'CREATED_AT'; + if ($this->isColumnModified(ModuleImageI18nTableMap::DESCRIPTION)) { + $modifiedColumns[':p' . $index++] = 'DESCRIPTION'; } - if ($this->isColumnModified(AttributeCategoryTableMap::UPDATED_AT)) { - $modifiedColumns[':p' . $index++] = 'UPDATED_AT'; + if ($this->isColumnModified(ModuleImageI18nTableMap::CHAPO)) { + $modifiedColumns[':p' . $index++] = 'CHAPO'; + } + if ($this->isColumnModified(ModuleImageI18nTableMap::POSTSCRIPTUM)) { + $modifiedColumns[':p' . $index++] = 'POSTSCRIPTUM'; } $sql = sprintf( - 'INSERT INTO attribute_category (%s) VALUES (%s)', + 'INSERT INTO module_image_i18n (%s) VALUES (%s)', implode(', ', $modifiedColumns), implode(', ', array_keys($modifiedColumns)) ); @@ -887,17 +885,20 @@ abstract class AttributeCategory implements ActiveRecordInterface case 'ID': $stmt->bindValue($identifier, $this->id, PDO::PARAM_INT); break; - case 'CATEGORY_ID': - $stmt->bindValue($identifier, $this->category_id, PDO::PARAM_INT); + case 'LOCALE': + $stmt->bindValue($identifier, $this->locale, PDO::PARAM_STR); break; - case 'ATTRIBUTE_ID': - $stmt->bindValue($identifier, $this->attribute_id, PDO::PARAM_INT); + case 'TITLE': + $stmt->bindValue($identifier, $this->title, PDO::PARAM_STR); break; - case 'CREATED_AT': - $stmt->bindValue($identifier, $this->created_at ? $this->created_at->format("Y-m-d H:i:s") : null, PDO::PARAM_STR); + case 'DESCRIPTION': + $stmt->bindValue($identifier, $this->description, PDO::PARAM_STR); break; - case 'UPDATED_AT': - $stmt->bindValue($identifier, $this->updated_at ? $this->updated_at->format("Y-m-d H:i:s") : null, PDO::PARAM_STR); + case 'CHAPO': + $stmt->bindValue($identifier, $this->chapo, PDO::PARAM_STR); + break; + case 'POSTSCRIPTUM': + $stmt->bindValue($identifier, $this->postscriptum, PDO::PARAM_STR); break; } } @@ -907,13 +908,6 @@ abstract class AttributeCategory implements ActiveRecordInterface throw new PropelException(sprintf('Unable to execute INSERT statement [%s]', $sql), 0, $e); } - try { - $pk = $con->lastInsertId(); - } catch (Exception $e) { - throw new PropelException('Unable to get autoincrement id.', 0, $e); - } - $this->setId($pk); - $this->setNew(false); } @@ -945,7 +939,7 @@ abstract class AttributeCategory implements ActiveRecordInterface */ public function getByName($name, $type = TableMap::TYPE_PHPNAME) { - $pos = AttributeCategoryTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); + $pos = ModuleImageI18nTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); $field = $this->getByPosition($pos); return $field; @@ -965,16 +959,19 @@ abstract class AttributeCategory implements ActiveRecordInterface return $this->getId(); break; case 1: - return $this->getCategoryId(); + return $this->getLocale(); break; case 2: - return $this->getAttributeId(); + return $this->getTitle(); break; case 3: - return $this->getCreatedAt(); + return $this->getDescription(); break; case 4: - return $this->getUpdatedAt(); + return $this->getChapo(); + break; + case 5: + return $this->getPostscriptum(); break; default: return null; @@ -999,17 +996,18 @@ abstract class AttributeCategory implements ActiveRecordInterface */ public function toArray($keyType = TableMap::TYPE_PHPNAME, $includeLazyLoadColumns = true, $alreadyDumpedObjects = array(), $includeForeignObjects = false) { - if (isset($alreadyDumpedObjects['AttributeCategory'][$this->getPrimaryKey()])) { + if (isset($alreadyDumpedObjects['ModuleImageI18n'][serialize($this->getPrimaryKey())])) { return '*RECURSION*'; } - $alreadyDumpedObjects['AttributeCategory'][$this->getPrimaryKey()] = true; - $keys = AttributeCategoryTableMap::getFieldNames($keyType); + $alreadyDumpedObjects['ModuleImageI18n'][serialize($this->getPrimaryKey())] = true; + $keys = ModuleImageI18nTableMap::getFieldNames($keyType); $result = array( $keys[0] => $this->getId(), - $keys[1] => $this->getCategoryId(), - $keys[2] => $this->getAttributeId(), - $keys[3] => $this->getCreatedAt(), - $keys[4] => $this->getUpdatedAt(), + $keys[1] => $this->getLocale(), + $keys[2] => $this->getTitle(), + $keys[3] => $this->getDescription(), + $keys[4] => $this->getChapo(), + $keys[5] => $this->getPostscriptum(), ); $virtualColumns = $this->virtualColumns; foreach($virtualColumns as $key => $virtualColumn) @@ -1018,11 +1016,8 @@ abstract class AttributeCategory implements ActiveRecordInterface } if ($includeForeignObjects) { - if (null !== $this->aCategory) { - $result['Category'] = $this->aCategory->toArray($keyType, $includeLazyLoadColumns, $alreadyDumpedObjects, true); - } - if (null !== $this->aAttribute) { - $result['Attribute'] = $this->aAttribute->toArray($keyType, $includeLazyLoadColumns, $alreadyDumpedObjects, true); + if (null !== $this->aModuleImage) { + $result['ModuleImage'] = $this->aModuleImage->toArray($keyType, $includeLazyLoadColumns, $alreadyDumpedObjects, true); } } @@ -1042,7 +1037,7 @@ abstract class AttributeCategory implements ActiveRecordInterface */ public function setByName($name, $value, $type = TableMap::TYPE_PHPNAME) { - $pos = AttributeCategoryTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); + $pos = ModuleImageI18nTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); return $this->setByPosition($pos, $value); } @@ -1062,16 +1057,19 @@ abstract class AttributeCategory implements ActiveRecordInterface $this->setId($value); break; case 1: - $this->setCategoryId($value); + $this->setLocale($value); break; case 2: - $this->setAttributeId($value); + $this->setTitle($value); break; case 3: - $this->setCreatedAt($value); + $this->setDescription($value); break; case 4: - $this->setUpdatedAt($value); + $this->setChapo($value); + break; + case 5: + $this->setPostscriptum($value); break; } // switch() } @@ -1095,13 +1093,14 @@ abstract class AttributeCategory implements ActiveRecordInterface */ public function fromArray($arr, $keyType = TableMap::TYPE_PHPNAME) { - $keys = AttributeCategoryTableMap::getFieldNames($keyType); + $keys = ModuleImageI18nTableMap::getFieldNames($keyType); if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]); - if (array_key_exists($keys[1], $arr)) $this->setCategoryId($arr[$keys[1]]); - if (array_key_exists($keys[2], $arr)) $this->setAttributeId($arr[$keys[2]]); - if (array_key_exists($keys[3], $arr)) $this->setCreatedAt($arr[$keys[3]]); - if (array_key_exists($keys[4], $arr)) $this->setUpdatedAt($arr[$keys[4]]); + if (array_key_exists($keys[1], $arr)) $this->setLocale($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setTitle($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setDescription($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setChapo($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setPostscriptum($arr[$keys[5]]); } /** @@ -1111,13 +1110,14 @@ abstract class AttributeCategory implements ActiveRecordInterface */ public function buildCriteria() { - $criteria = new Criteria(AttributeCategoryTableMap::DATABASE_NAME); + $criteria = new Criteria(ModuleImageI18nTableMap::DATABASE_NAME); - if ($this->isColumnModified(AttributeCategoryTableMap::ID)) $criteria->add(AttributeCategoryTableMap::ID, $this->id); - if ($this->isColumnModified(AttributeCategoryTableMap::CATEGORY_ID)) $criteria->add(AttributeCategoryTableMap::CATEGORY_ID, $this->category_id); - if ($this->isColumnModified(AttributeCategoryTableMap::ATTRIBUTE_ID)) $criteria->add(AttributeCategoryTableMap::ATTRIBUTE_ID, $this->attribute_id); - if ($this->isColumnModified(AttributeCategoryTableMap::CREATED_AT)) $criteria->add(AttributeCategoryTableMap::CREATED_AT, $this->created_at); - if ($this->isColumnModified(AttributeCategoryTableMap::UPDATED_AT)) $criteria->add(AttributeCategoryTableMap::UPDATED_AT, $this->updated_at); + if ($this->isColumnModified(ModuleImageI18nTableMap::ID)) $criteria->add(ModuleImageI18nTableMap::ID, $this->id); + if ($this->isColumnModified(ModuleImageI18nTableMap::LOCALE)) $criteria->add(ModuleImageI18nTableMap::LOCALE, $this->locale); + if ($this->isColumnModified(ModuleImageI18nTableMap::TITLE)) $criteria->add(ModuleImageI18nTableMap::TITLE, $this->title); + if ($this->isColumnModified(ModuleImageI18nTableMap::DESCRIPTION)) $criteria->add(ModuleImageI18nTableMap::DESCRIPTION, $this->description); + if ($this->isColumnModified(ModuleImageI18nTableMap::CHAPO)) $criteria->add(ModuleImageI18nTableMap::CHAPO, $this->chapo); + if ($this->isColumnModified(ModuleImageI18nTableMap::POSTSCRIPTUM)) $criteria->add(ModuleImageI18nTableMap::POSTSCRIPTUM, $this->postscriptum); return $criteria; } @@ -1132,30 +1132,37 @@ abstract class AttributeCategory implements ActiveRecordInterface */ public function buildPkeyCriteria() { - $criteria = new Criteria(AttributeCategoryTableMap::DATABASE_NAME); - $criteria->add(AttributeCategoryTableMap::ID, $this->id); + $criteria = new Criteria(ModuleImageI18nTableMap::DATABASE_NAME); + $criteria->add(ModuleImageI18nTableMap::ID, $this->id); + $criteria->add(ModuleImageI18nTableMap::LOCALE, $this->locale); return $criteria; } /** - * Returns the primary key for this object (row). - * @return int + * Returns the composite primary key for this object. + * The array elements will be in same order as specified in XML. + * @return array */ public function getPrimaryKey() { - return $this->getId(); + $pks = array(); + $pks[0] = $this->getId(); + $pks[1] = $this->getLocale(); + + return $pks; } /** - * Generic method to set the primary key (id column). + * Set the [composite] primary key. * - * @param int $key Primary key. + * @param array $keys The elements of the composite key (order must match the order in XML file). * @return void */ - public function setPrimaryKey($key) + public function setPrimaryKey($keys) { - $this->setId($key); + $this->setId($keys[0]); + $this->setLocale($keys[1]); } /** @@ -1165,7 +1172,7 @@ abstract class AttributeCategory implements ActiveRecordInterface public function isPrimaryKeyNull() { - return null === $this->getId(); + return (null === $this->getId()) && (null === $this->getLocale()); } /** @@ -1174,20 +1181,21 @@ abstract class AttributeCategory implements ActiveRecordInterface * If desired, this method can also make copies of all associated (fkey referrers) * objects. * - * @param object $copyObj An object of \Thelia\Model\AttributeCategory (or compatible) type. + * @param object $copyObj An object of \Thelia\Model\ModuleImageI18n (or compatible) type. * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. * @param boolean $makeNew Whether to reset autoincrement PKs and make the object new. * @throws PropelException */ public function copyInto($copyObj, $deepCopy = false, $makeNew = true) { - $copyObj->setCategoryId($this->getCategoryId()); - $copyObj->setAttributeId($this->getAttributeId()); - $copyObj->setCreatedAt($this->getCreatedAt()); - $copyObj->setUpdatedAt($this->getUpdatedAt()); + $copyObj->setId($this->getId()); + $copyObj->setLocale($this->getLocale()); + $copyObj->setTitle($this->getTitle()); + $copyObj->setDescription($this->getDescription()); + $copyObj->setChapo($this->getChapo()); + $copyObj->setPostscriptum($this->getPostscriptum()); if ($makeNew) { $copyObj->setNew(true); - $copyObj->setId(NULL); // this is a auto-increment column, so set to default value } } @@ -1200,7 +1208,7 @@ abstract class AttributeCategory implements ActiveRecordInterface * objects. * * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. - * @return \Thelia\Model\AttributeCategory Clone of current object. + * @return \Thelia\Model\ModuleImageI18n Clone of current object. * @throws PropelException */ public function copy($deepCopy = false) @@ -1214,26 +1222,26 @@ abstract class AttributeCategory implements ActiveRecordInterface } /** - * Declares an association between this object and a ChildCategory object. + * Declares an association between this object and a ChildModuleImage object. * - * @param ChildCategory $v - * @return \Thelia\Model\AttributeCategory The current object (for fluent API support) + * @param ChildModuleImage $v + * @return \Thelia\Model\ModuleImageI18n The current object (for fluent API support) * @throws PropelException */ - public function setCategory(ChildCategory $v = null) + public function setModuleImage(ChildModuleImage $v = null) { if ($v === null) { - $this->setCategoryId(NULL); + $this->setId(NULL); } else { - $this->setCategoryId($v->getId()); + $this->setId($v->getId()); } - $this->aCategory = $v; + $this->aModuleImage = $v; // Add binding for other direction of this n:n relationship. - // If this object has already been added to the ChildCategory object, it will not be re-added. + // If this object has already been added to the ChildModuleImage object, it will not be re-added. if ($v !== null) { - $v->addAttributeCategory($this); + $v->addModuleImageI18n($this); } @@ -1242,77 +1250,26 @@ abstract class AttributeCategory implements ActiveRecordInterface /** - * Get the associated ChildCategory object + * Get the associated ChildModuleImage object * * @param ConnectionInterface $con Optional Connection object. - * @return ChildCategory The associated ChildCategory object. + * @return ChildModuleImage The associated ChildModuleImage object. * @throws PropelException */ - public function getCategory(ConnectionInterface $con = null) + public function getModuleImage(ConnectionInterface $con = null) { - if ($this->aCategory === null && ($this->category_id !== null)) { - $this->aCategory = ChildCategoryQuery::create()->findPk($this->category_id, $con); + if ($this->aModuleImage === null && ($this->id !== null)) { + $this->aModuleImage = ChildModuleImageQuery::create()->findPk($this->id, $con); /* The following can be used additionally to guarantee the related object contains a reference to this object. This level of coupling may, however, be undesirable since it could result in an only partially populated collection in the referenced object. - $this->aCategory->addAttributeCategories($this); + $this->aModuleImage->addModuleImageI18ns($this); */ } - return $this->aCategory; - } - - /** - * Declares an association between this object and a ChildAttribute object. - * - * @param ChildAttribute $v - * @return \Thelia\Model\AttributeCategory The current object (for fluent API support) - * @throws PropelException - */ - public function setAttribute(ChildAttribute $v = null) - { - if ($v === null) { - $this->setAttributeId(NULL); - } else { - $this->setAttributeId($v->getId()); - } - - $this->aAttribute = $v; - - // Add binding for other direction of this n:n relationship. - // If this object has already been added to the ChildAttribute object, it will not be re-added. - if ($v !== null) { - $v->addAttributeCategory($this); - } - - - return $this; - } - - - /** - * Get the associated ChildAttribute object - * - * @param ConnectionInterface $con Optional Connection object. - * @return ChildAttribute The associated ChildAttribute object. - * @throws PropelException - */ - public function getAttribute(ConnectionInterface $con = null) - { - if ($this->aAttribute === null && ($this->attribute_id !== null)) { - $this->aAttribute = ChildAttributeQuery::create()->findPk($this->attribute_id, $con); - /* The following can be used additionally to - guarantee the related object contains a reference - to this object. This level of coupling may, however, be - undesirable since it could result in an only partially populated collection - in the referenced object. - $this->aAttribute->addAttributeCategories($this); - */ - } - - return $this->aAttribute; + return $this->aModuleImage; } /** @@ -1321,12 +1278,14 @@ abstract class AttributeCategory implements ActiveRecordInterface public function clear() { $this->id = null; - $this->category_id = null; - $this->attribute_id = null; - $this->created_at = null; - $this->updated_at = null; + $this->locale = null; + $this->title = null; + $this->description = null; + $this->chapo = null; + $this->postscriptum = null; $this->alreadyInSave = false; $this->clearAllReferences(); + $this->applyDefaultValues(); $this->resetModified(); $this->setNew(true); $this->setDeleted(false); @@ -1346,8 +1305,7 @@ abstract class AttributeCategory implements ActiveRecordInterface if ($deep) { } // if ($deep) - $this->aCategory = null; - $this->aAttribute = null; + $this->aModuleImage = null; } /** @@ -1357,21 +1315,7 @@ abstract class AttributeCategory implements ActiveRecordInterface */ public function __toString() { - return (string) $this->exportTo(AttributeCategoryTableMap::DEFAULT_STRING_FORMAT); - } - - // timestampable behavior - - /** - * Mark the current object so that the update date doesn't get updated during next save - * - * @return ChildAttributeCategory The current object (for fluent API support) - */ - public function keepUpdateDateUnchanged() - { - $this->modifiedColumns[] = AttributeCategoryTableMap::UPDATED_AT; - - return $this; + return (string) $this->exportTo(ModuleImageI18nTableMap::DEFAULT_STRING_FORMAT); } /** diff --git a/core/lib/Thelia/Model/Base/ModuleImageI18nQuery.php b/core/lib/Thelia/Model/Base/ModuleImageI18nQuery.php new file mode 100644 index 000000000..e5b6813d6 --- /dev/null +++ b/core/lib/Thelia/Model/Base/ModuleImageI18nQuery.php @@ -0,0 +1,607 @@ +setModelAlias($modelAlias); + } + if ($criteria instanceof Criteria) { + $query->mergeWith($criteria); + } + + return $query; + } + + /** + * Find object by primary key. + * Propel uses the instance pool to skip the database if the object exists. + * Go fast if the query is untouched. + * + * + * $obj = $c->findPk(array(12, 34), $con); + * + * + * @param array[$id, $locale] $key Primary key to use for the query + * @param ConnectionInterface $con an optional connection object + * + * @return ChildModuleImageI18n|array|mixed the result, formatted by the current formatter + */ + public function findPk($key, $con = null) + { + if ($key === null) { + return null; + } + if ((null !== ($obj = ModuleImageI18nTableMap::getInstanceFromPool(serialize(array((string) $key[0], (string) $key[1]))))) && !$this->formatter) { + // the object is already in the instance pool + return $obj; + } + if ($con === null) { + $con = Propel::getServiceContainer()->getReadConnection(ModuleImageI18nTableMap::DATABASE_NAME); + } + $this->basePreSelect($con); + if ($this->formatter || $this->modelAlias || $this->with || $this->select + || $this->selectColumns || $this->asColumns || $this->selectModifiers + || $this->map || $this->having || $this->joins) { + return $this->findPkComplex($key, $con); + } else { + return $this->findPkSimple($key, $con); + } + } + + /** + * Find object by primary key using raw SQL to go fast. + * Bypass doSelect() and the object formatter by using generated code. + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con A connection object + * + * @return ChildModuleImageI18n A model object, or null if the key is not found + */ + protected function findPkSimple($key, $con) + { + $sql = 'SELECT ID, LOCALE, TITLE, DESCRIPTION, CHAPO, POSTSCRIPTUM FROM module_image_i18n WHERE ID = :p0 AND LOCALE = :p1'; + try { + $stmt = $con->prepare($sql); + $stmt->bindValue(':p0', $key[0], PDO::PARAM_INT); + $stmt->bindValue(':p1', $key[1], PDO::PARAM_STR); + $stmt->execute(); + } catch (Exception $e) { + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException(sprintf('Unable to execute SELECT statement [%s]', $sql), 0, $e); + } + $obj = null; + if ($row = $stmt->fetch(\PDO::FETCH_NUM)) { + $obj = new ChildModuleImageI18n(); + $obj->hydrate($row); + ModuleImageI18nTableMap::addInstanceToPool($obj, serialize(array((string) $key[0], (string) $key[1]))); + } + $stmt->closeCursor(); + + return $obj; + } + + /** + * Find object by primary key. + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con A connection object + * + * @return ChildModuleImageI18n|array|mixed the result, formatted by the current formatter + */ + protected function findPkComplex($key, $con) + { + // As the query uses a PK condition, no limit(1) is necessary. + $criteria = $this->isKeepQuery() ? clone $this : $this; + $dataFetcher = $criteria + ->filterByPrimaryKey($key) + ->doSelect($con); + + return $criteria->getFormatter()->init($criteria)->formatOne($dataFetcher); + } + + /** + * Find objects by primary key + * + * $objs = $c->findPks(array(array(12, 56), array(832, 123), array(123, 456)), $con); + * + * @param array $keys Primary keys to use for the query + * @param ConnectionInterface $con an optional connection object + * + * @return ObjectCollection|array|mixed the list of results, formatted by the current formatter + */ + public function findPks($keys, $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getReadConnection($this->getDbName()); + } + $this->basePreSelect($con); + $criteria = $this->isKeepQuery() ? clone $this : $this; + $dataFetcher = $criteria + ->filterByPrimaryKeys($keys) + ->doSelect($con); + + return $criteria->getFormatter()->init($criteria)->format($dataFetcher); + } + + /** + * Filter the query by primary key + * + * @param mixed $key Primary key to use for the query + * + * @return ChildModuleImageI18nQuery The current query, for fluid interface + */ + public function filterByPrimaryKey($key) + { + $this->addUsingAlias(ModuleImageI18nTableMap::ID, $key[0], Criteria::EQUAL); + $this->addUsingAlias(ModuleImageI18nTableMap::LOCALE, $key[1], Criteria::EQUAL); + + return $this; + } + + /** + * Filter the query by a list of primary keys + * + * @param array $keys The list of primary key to use for the query + * + * @return ChildModuleImageI18nQuery The current query, for fluid interface + */ + public function filterByPrimaryKeys($keys) + { + if (empty($keys)) { + return $this->add(null, '1<>1', Criteria::CUSTOM); + } + foreach ($keys as $key) { + $cton0 = $this->getNewCriterion(ModuleImageI18nTableMap::ID, $key[0], Criteria::EQUAL); + $cton1 = $this->getNewCriterion(ModuleImageI18nTableMap::LOCALE, $key[1], Criteria::EQUAL); + $cton0->addAnd($cton1); + $this->addOr($cton0); + } + + return $this; + } + + /** + * Filter the query on the id column + * + * Example usage: + * + * $query->filterById(1234); // WHERE id = 1234 + * $query->filterById(array(12, 34)); // WHERE id IN (12, 34) + * $query->filterById(array('min' => 12)); // WHERE id > 12 + * + * + * @see filterByModuleImage() + * + * @param mixed $id The value to use as filter. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildModuleImageI18nQuery The current query, for fluid interface + */ + public function filterById($id = null, $comparison = null) + { + if (is_array($id)) { + $useMinMax = false; + if (isset($id['min'])) { + $this->addUsingAlias(ModuleImageI18nTableMap::ID, $id['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($id['max'])) { + $this->addUsingAlias(ModuleImageI18nTableMap::ID, $id['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(ModuleImageI18nTableMap::ID, $id, $comparison); + } + + /** + * Filter the query on the locale column + * + * Example usage: + * + * $query->filterByLocale('fooValue'); // WHERE locale = 'fooValue' + * $query->filterByLocale('%fooValue%'); // WHERE locale LIKE '%fooValue%' + * + * + * @param string $locale The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildModuleImageI18nQuery The current query, for fluid interface + */ + public function filterByLocale($locale = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($locale)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $locale)) { + $locale = str_replace('*', '%', $locale); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(ModuleImageI18nTableMap::LOCALE, $locale, $comparison); + } + + /** + * Filter the query on the title column + * + * Example usage: + * + * $query->filterByTitle('fooValue'); // WHERE title = 'fooValue' + * $query->filterByTitle('%fooValue%'); // WHERE title LIKE '%fooValue%' + * + * + * @param string $title The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildModuleImageI18nQuery The current query, for fluid interface + */ + public function filterByTitle($title = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($title)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $title)) { + $title = str_replace('*', '%', $title); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(ModuleImageI18nTableMap::TITLE, $title, $comparison); + } + + /** + * Filter the query on the description column + * + * Example usage: + * + * $query->filterByDescription('fooValue'); // WHERE description = 'fooValue' + * $query->filterByDescription('%fooValue%'); // WHERE description LIKE '%fooValue%' + * + * + * @param string $description The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildModuleImageI18nQuery The current query, for fluid interface + */ + public function filterByDescription($description = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($description)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $description)) { + $description = str_replace('*', '%', $description); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(ModuleImageI18nTableMap::DESCRIPTION, $description, $comparison); + } + + /** + * Filter the query on the chapo column + * + * Example usage: + * + * $query->filterByChapo('fooValue'); // WHERE chapo = 'fooValue' + * $query->filterByChapo('%fooValue%'); // WHERE chapo LIKE '%fooValue%' + * + * + * @param string $chapo The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildModuleImageI18nQuery The current query, for fluid interface + */ + public function filterByChapo($chapo = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($chapo)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $chapo)) { + $chapo = str_replace('*', '%', $chapo); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(ModuleImageI18nTableMap::CHAPO, $chapo, $comparison); + } + + /** + * Filter the query on the postscriptum column + * + * Example usage: + * + * $query->filterByPostscriptum('fooValue'); // WHERE postscriptum = 'fooValue' + * $query->filterByPostscriptum('%fooValue%'); // WHERE postscriptum LIKE '%fooValue%' + * + * + * @param string $postscriptum The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildModuleImageI18nQuery The current query, for fluid interface + */ + public function filterByPostscriptum($postscriptum = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($postscriptum)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $postscriptum)) { + $postscriptum = str_replace('*', '%', $postscriptum); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(ModuleImageI18nTableMap::POSTSCRIPTUM, $postscriptum, $comparison); + } + + /** + * Filter the query by a related \Thelia\Model\ModuleImage object + * + * @param \Thelia\Model\ModuleImage|ObjectCollection $moduleImage The related object(s) to use as filter + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildModuleImageI18nQuery The current query, for fluid interface + */ + public function filterByModuleImage($moduleImage, $comparison = null) + { + if ($moduleImage instanceof \Thelia\Model\ModuleImage) { + return $this + ->addUsingAlias(ModuleImageI18nTableMap::ID, $moduleImage->getId(), $comparison); + } elseif ($moduleImage instanceof ObjectCollection) { + if (null === $comparison) { + $comparison = Criteria::IN; + } + + return $this + ->addUsingAlias(ModuleImageI18nTableMap::ID, $moduleImage->toKeyValue('PrimaryKey', 'Id'), $comparison); + } else { + throw new PropelException('filterByModuleImage() only accepts arguments of type \Thelia\Model\ModuleImage or Collection'); + } + } + + /** + * Adds a JOIN clause to the query using the ModuleImage relation + * + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return ChildModuleImageI18nQuery The current query, for fluid interface + */ + public function joinModuleImage($relationAlias = null, $joinType = 'LEFT JOIN') + { + $tableMap = $this->getTableMap(); + $relationMap = $tableMap->getRelation('ModuleImage'); + + // create a ModelJoin object for this join + $join = new ModelJoin(); + $join->setJoinType($joinType); + $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); + if ($previousJoin = $this->getPreviousJoin()) { + $join->setPreviousJoin($previousJoin); + } + + // add the ModelJoin to the current object + if ($relationAlias) { + $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); + $this->addJoinObject($join, $relationAlias); + } else { + $this->addJoinObject($join, 'ModuleImage'); + } + + return $this; + } + + /** + * Use the ModuleImage relation ModuleImage object + * + * @see useQuery() + * + * @param string $relationAlias optional alias for the relation, + * to be used as main alias in the secondary query + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return \Thelia\Model\ModuleImageQuery A secondary query class using the current class as primary query + */ + public function useModuleImageQuery($relationAlias = null, $joinType = 'LEFT JOIN') + { + return $this + ->joinModuleImage($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'ModuleImage', '\Thelia\Model\ModuleImageQuery'); + } + + /** + * Exclude object from result + * + * @param ChildModuleImageI18n $moduleImageI18n Object to remove from the list of results + * + * @return ChildModuleImageI18nQuery The current query, for fluid interface + */ + public function prune($moduleImageI18n = null) + { + if ($moduleImageI18n) { + $this->addCond('pruneCond0', $this->getAliasedColName(ModuleImageI18nTableMap::ID), $moduleImageI18n->getId(), Criteria::NOT_EQUAL); + $this->addCond('pruneCond1', $this->getAliasedColName(ModuleImageI18nTableMap::LOCALE), $moduleImageI18n->getLocale(), Criteria::NOT_EQUAL); + $this->combine(array('pruneCond0', 'pruneCond1'), Criteria::LOGICAL_OR); + } + + return $this; + } + + /** + * Deletes all rows from the module_image_i18n table. + * + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). + */ + public function doDeleteAll(ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(ModuleImageI18nTableMap::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->beginTransaction(); + $affectedRows += parent::doDeleteAll($con); + // Because this db requires some delete cascade/set null emulation, we have to + // clear the cached instance *after* the emulation has happened (since + // instances get re-added by the select statement contained therein). + ModuleImageI18nTableMap::clearInstancePool(); + ModuleImageI18nTableMap::clearRelatedInstancePool(); + + $con->commit(); + } catch (PropelException $e) { + $con->rollBack(); + throw $e; + } + + return $affectedRows; + } + + /** + * Performs a DELETE on the database, given a ChildModuleImageI18n or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or ChildModuleImageI18n object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public function delete(ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(ModuleImageI18nTableMap::DATABASE_NAME); + } + + $criteria = $this; + + // Set the correct dbName + $criteria->setDbName(ModuleImageI18nTableMap::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->beginTransaction(); + + + ModuleImageI18nTableMap::removeInstanceFromPool($criteria); + + $affectedRows += ModelCriteria::delete($con); + ModuleImageI18nTableMap::clearRelatedInstancePool(); + $con->commit(); + + return $affectedRows; + } catch (PropelException $e) { + $con->rollBack(); + throw $e; + } + } + +} // ModuleImageI18nQuery diff --git a/core/lib/Thelia/Model/Base/AttributeCategoryQuery.php b/core/lib/Thelia/Model/Base/ModuleImageQuery.php similarity index 50% rename from core/lib/Thelia/Model/Base/AttributeCategoryQuery.php rename to core/lib/Thelia/Model/Base/ModuleImageQuery.php index d325d2037..966e686ad 100644 --- a/core/lib/Thelia/Model/Base/AttributeCategoryQuery.php +++ b/core/lib/Thelia/Model/Base/ModuleImageQuery.php @@ -12,84 +12,89 @@ use Propel\Runtime\Collection\Collection; use Propel\Runtime\Collection\ObjectCollection; use Propel\Runtime\Connection\ConnectionInterface; use Propel\Runtime\Exception\PropelException; -use Thelia\Model\AttributeCategory as ChildAttributeCategory; -use Thelia\Model\AttributeCategoryQuery as ChildAttributeCategoryQuery; -use Thelia\Model\Map\AttributeCategoryTableMap; +use Thelia\Model\ModuleImage as ChildModuleImage; +use Thelia\Model\ModuleImageI18nQuery as ChildModuleImageI18nQuery; +use Thelia\Model\ModuleImageQuery as ChildModuleImageQuery; +use Thelia\Model\Map\ModuleImageTableMap; /** - * Base class that represents a query for the 'attribute_category' table. + * Base class that represents a query for the 'module_image' table. * * * - * @method ChildAttributeCategoryQuery orderById($order = Criteria::ASC) Order by the id column - * @method ChildAttributeCategoryQuery orderByCategoryId($order = Criteria::ASC) Order by the category_id column - * @method ChildAttributeCategoryQuery orderByAttributeId($order = Criteria::ASC) Order by the attribute_id column - * @method ChildAttributeCategoryQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column - * @method ChildAttributeCategoryQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column + * @method ChildModuleImageQuery orderById($order = Criteria::ASC) Order by the id column + * @method ChildModuleImageQuery orderByModuleId($order = Criteria::ASC) Order by the module_id column + * @method ChildModuleImageQuery orderByFile($order = Criteria::ASC) Order by the file column + * @method ChildModuleImageQuery orderByPosition($order = Criteria::ASC) Order by the position column + * @method ChildModuleImageQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column + * @method ChildModuleImageQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column * - * @method ChildAttributeCategoryQuery groupById() Group by the id column - * @method ChildAttributeCategoryQuery groupByCategoryId() Group by the category_id column - * @method ChildAttributeCategoryQuery groupByAttributeId() Group by the attribute_id column - * @method ChildAttributeCategoryQuery groupByCreatedAt() Group by the created_at column - * @method ChildAttributeCategoryQuery groupByUpdatedAt() Group by the updated_at column + * @method ChildModuleImageQuery groupById() Group by the id column + * @method ChildModuleImageQuery groupByModuleId() Group by the module_id column + * @method ChildModuleImageQuery groupByFile() Group by the file column + * @method ChildModuleImageQuery groupByPosition() Group by the position column + * @method ChildModuleImageQuery groupByCreatedAt() Group by the created_at column + * @method ChildModuleImageQuery groupByUpdatedAt() Group by the updated_at column * - * @method ChildAttributeCategoryQuery leftJoin($relation) Adds a LEFT JOIN clause to the query - * @method ChildAttributeCategoryQuery rightJoin($relation) Adds a RIGHT JOIN clause to the query - * @method ChildAttributeCategoryQuery innerJoin($relation) Adds a INNER JOIN clause to the query + * @method ChildModuleImageQuery leftJoin($relation) Adds a LEFT JOIN clause to the query + * @method ChildModuleImageQuery rightJoin($relation) Adds a RIGHT JOIN clause to the query + * @method ChildModuleImageQuery innerJoin($relation) Adds a INNER JOIN clause to the query * - * @method ChildAttributeCategoryQuery leftJoinCategory($relationAlias = null) Adds a LEFT JOIN clause to the query using the Category relation - * @method ChildAttributeCategoryQuery rightJoinCategory($relationAlias = null) Adds a RIGHT JOIN clause to the query using the Category relation - * @method ChildAttributeCategoryQuery innerJoinCategory($relationAlias = null) Adds a INNER JOIN clause to the query using the Category relation + * @method ChildModuleImageQuery leftJoinModule($relationAlias = null) Adds a LEFT JOIN clause to the query using the Module relation + * @method ChildModuleImageQuery rightJoinModule($relationAlias = null) Adds a RIGHT JOIN clause to the query using the Module relation + * @method ChildModuleImageQuery innerJoinModule($relationAlias = null) Adds a INNER JOIN clause to the query using the Module relation * - * @method ChildAttributeCategoryQuery leftJoinAttribute($relationAlias = null) Adds a LEFT JOIN clause to the query using the Attribute relation - * @method ChildAttributeCategoryQuery rightJoinAttribute($relationAlias = null) Adds a RIGHT JOIN clause to the query using the Attribute relation - * @method ChildAttributeCategoryQuery innerJoinAttribute($relationAlias = null) Adds a INNER JOIN clause to the query using the Attribute relation + * @method ChildModuleImageQuery leftJoinModuleImageI18n($relationAlias = null) Adds a LEFT JOIN clause to the query using the ModuleImageI18n relation + * @method ChildModuleImageQuery rightJoinModuleImageI18n($relationAlias = null) Adds a RIGHT JOIN clause to the query using the ModuleImageI18n relation + * @method ChildModuleImageQuery innerJoinModuleImageI18n($relationAlias = null) Adds a INNER JOIN clause to the query using the ModuleImageI18n relation * - * @method ChildAttributeCategory findOne(ConnectionInterface $con = null) Return the first ChildAttributeCategory matching the query - * @method ChildAttributeCategory findOneOrCreate(ConnectionInterface $con = null) Return the first ChildAttributeCategory matching the query, or a new ChildAttributeCategory object populated from the query conditions when no match is found + * @method ChildModuleImage findOne(ConnectionInterface $con = null) Return the first ChildModuleImage matching the query + * @method ChildModuleImage findOneOrCreate(ConnectionInterface $con = null) Return the first ChildModuleImage matching the query, or a new ChildModuleImage object populated from the query conditions when no match is found * - * @method ChildAttributeCategory findOneById(int $id) Return the first ChildAttributeCategory filtered by the id column - * @method ChildAttributeCategory findOneByCategoryId(int $category_id) Return the first ChildAttributeCategory filtered by the category_id column - * @method ChildAttributeCategory findOneByAttributeId(int $attribute_id) Return the first ChildAttributeCategory filtered by the attribute_id column - * @method ChildAttributeCategory findOneByCreatedAt(string $created_at) Return the first ChildAttributeCategory filtered by the created_at column - * @method ChildAttributeCategory findOneByUpdatedAt(string $updated_at) Return the first ChildAttributeCategory filtered by the updated_at column + * @method ChildModuleImage findOneById(int $id) Return the first ChildModuleImage filtered by the id column + * @method ChildModuleImage findOneByModuleId(int $module_id) Return the first ChildModuleImage filtered by the module_id column + * @method ChildModuleImage findOneByFile(string $file) Return the first ChildModuleImage filtered by the file column + * @method ChildModuleImage findOneByPosition(int $position) Return the first ChildModuleImage filtered by the position column + * @method ChildModuleImage findOneByCreatedAt(string $created_at) Return the first ChildModuleImage filtered by the created_at column + * @method ChildModuleImage findOneByUpdatedAt(string $updated_at) Return the first ChildModuleImage filtered by the updated_at column * - * @method array findById(int $id) Return ChildAttributeCategory objects filtered by the id column - * @method array findByCategoryId(int $category_id) Return ChildAttributeCategory objects filtered by the category_id column - * @method array findByAttributeId(int $attribute_id) Return ChildAttributeCategory objects filtered by the attribute_id column - * @method array findByCreatedAt(string $created_at) Return ChildAttributeCategory objects filtered by the created_at column - * @method array findByUpdatedAt(string $updated_at) Return ChildAttributeCategory objects filtered by the updated_at column + * @method array findById(int $id) Return ChildModuleImage objects filtered by the id column + * @method array findByModuleId(int $module_id) Return ChildModuleImage objects filtered by the module_id column + * @method array findByFile(string $file) Return ChildModuleImage objects filtered by the file column + * @method array findByPosition(int $position) Return ChildModuleImage objects filtered by the position column + * @method array findByCreatedAt(string $created_at) Return ChildModuleImage objects filtered by the created_at column + * @method array findByUpdatedAt(string $updated_at) Return ChildModuleImage objects filtered by the updated_at column * */ -abstract class AttributeCategoryQuery extends ModelCriteria +abstract class ModuleImageQuery extends ModelCriteria { /** - * Initializes internal state of \Thelia\Model\Base\AttributeCategoryQuery object. + * Initializes internal state of \Thelia\Model\Base\ModuleImageQuery object. * * @param string $dbName The database name * @param string $modelName The phpName of a model, e.g. 'Book' * @param string $modelAlias The alias for the model in this query, e.g. 'b' */ - public function __construct($dbName = 'thelia', $modelName = '\\Thelia\\Model\\AttributeCategory', $modelAlias = null) + public function __construct($dbName = 'thelia', $modelName = '\\Thelia\\Model\\ModuleImage', $modelAlias = null) { parent::__construct($dbName, $modelName, $modelAlias); } /** - * Returns a new ChildAttributeCategoryQuery object. + * Returns a new ChildModuleImageQuery object. * * @param string $modelAlias The alias of a model in the query * @param Criteria $criteria Optional Criteria to build the query from * - * @return ChildAttributeCategoryQuery + * @return ChildModuleImageQuery */ public static function create($modelAlias = null, $criteria = null) { - if ($criteria instanceof \Thelia\Model\AttributeCategoryQuery) { + if ($criteria instanceof \Thelia\Model\ModuleImageQuery) { return $criteria; } - $query = new \Thelia\Model\AttributeCategoryQuery(); + $query = new \Thelia\Model\ModuleImageQuery(); if (null !== $modelAlias) { $query->setModelAlias($modelAlias); } @@ -112,19 +117,19 @@ abstract class AttributeCategoryQuery extends ModelCriteria * @param mixed $key Primary key to use for the query * @param ConnectionInterface $con an optional connection object * - * @return ChildAttributeCategory|array|mixed the result, formatted by the current formatter + * @return ChildModuleImage|array|mixed the result, formatted by the current formatter */ public function findPk($key, $con = null) { if ($key === null) { return null; } - if ((null !== ($obj = AttributeCategoryTableMap::getInstanceFromPool((string) $key))) && !$this->formatter) { + if ((null !== ($obj = ModuleImageTableMap::getInstanceFromPool((string) $key))) && !$this->formatter) { // the object is already in the instance pool return $obj; } if ($con === null) { - $con = Propel::getServiceContainer()->getReadConnection(AttributeCategoryTableMap::DATABASE_NAME); + $con = Propel::getServiceContainer()->getReadConnection(ModuleImageTableMap::DATABASE_NAME); } $this->basePreSelect($con); if ($this->formatter || $this->modelAlias || $this->with || $this->select @@ -143,11 +148,11 @@ abstract class AttributeCategoryQuery extends ModelCriteria * @param mixed $key Primary key to use for the query * @param ConnectionInterface $con A connection object * - * @return ChildAttributeCategory A model object, or null if the key is not found + * @return ChildModuleImage A model object, or null if the key is not found */ protected function findPkSimple($key, $con) { - $sql = 'SELECT ID, CATEGORY_ID, ATTRIBUTE_ID, CREATED_AT, UPDATED_AT FROM attribute_category WHERE ID = :p0'; + $sql = 'SELECT ID, MODULE_ID, FILE, POSITION, CREATED_AT, UPDATED_AT FROM module_image WHERE ID = :p0'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key, PDO::PARAM_INT); @@ -158,9 +163,9 @@ abstract class AttributeCategoryQuery extends ModelCriteria } $obj = null; if ($row = $stmt->fetch(\PDO::FETCH_NUM)) { - $obj = new ChildAttributeCategory(); + $obj = new ChildModuleImage(); $obj->hydrate($row); - AttributeCategoryTableMap::addInstanceToPool($obj, (string) $key); + ModuleImageTableMap::addInstanceToPool($obj, (string) $key); } $stmt->closeCursor(); @@ -173,7 +178,7 @@ abstract class AttributeCategoryQuery extends ModelCriteria * @param mixed $key Primary key to use for the query * @param ConnectionInterface $con A connection object * - * @return ChildAttributeCategory|array|mixed the result, formatted by the current formatter + * @return ChildModuleImage|array|mixed the result, formatted by the current formatter */ protected function findPkComplex($key, $con) { @@ -215,12 +220,12 @@ abstract class AttributeCategoryQuery extends ModelCriteria * * @param mixed $key Primary key to use for the query * - * @return ChildAttributeCategoryQuery The current query, for fluid interface + * @return ChildModuleImageQuery The current query, for fluid interface */ public function filterByPrimaryKey($key) { - return $this->addUsingAlias(AttributeCategoryTableMap::ID, $key, Criteria::EQUAL); + return $this->addUsingAlias(ModuleImageTableMap::ID, $key, Criteria::EQUAL); } /** @@ -228,12 +233,12 @@ abstract class AttributeCategoryQuery extends ModelCriteria * * @param array $keys The list of primary key to use for the query * - * @return ChildAttributeCategoryQuery The current query, for fluid interface + * @return ChildModuleImageQuery The current query, for fluid interface */ public function filterByPrimaryKeys($keys) { - return $this->addUsingAlias(AttributeCategoryTableMap::ID, $keys, Criteria::IN); + return $this->addUsingAlias(ModuleImageTableMap::ID, $keys, Criteria::IN); } /** @@ -252,18 +257,18 @@ abstract class AttributeCategoryQuery extends ModelCriteria * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL * - * @return ChildAttributeCategoryQuery The current query, for fluid interface + * @return ChildModuleImageQuery The current query, for fluid interface */ public function filterById($id = null, $comparison = null) { if (is_array($id)) { $useMinMax = false; if (isset($id['min'])) { - $this->addUsingAlias(AttributeCategoryTableMap::ID, $id['min'], Criteria::GREATER_EQUAL); + $this->addUsingAlias(ModuleImageTableMap::ID, $id['min'], Criteria::GREATER_EQUAL); $useMinMax = true; } if (isset($id['max'])) { - $this->addUsingAlias(AttributeCategoryTableMap::ID, $id['max'], Criteria::LESS_EQUAL); + $this->addUsingAlias(ModuleImageTableMap::ID, $id['max'], Criteria::LESS_EQUAL); $useMinMax = true; } if ($useMinMax) { @@ -274,39 +279,39 @@ abstract class AttributeCategoryQuery extends ModelCriteria } } - return $this->addUsingAlias(AttributeCategoryTableMap::ID, $id, $comparison); + return $this->addUsingAlias(ModuleImageTableMap::ID, $id, $comparison); } /** - * Filter the query on the category_id column + * Filter the query on the module_id column * * Example usage: * - * $query->filterByCategoryId(1234); // WHERE category_id = 1234 - * $query->filterByCategoryId(array(12, 34)); // WHERE category_id IN (12, 34) - * $query->filterByCategoryId(array('min' => 12)); // WHERE category_id > 12 + * $query->filterByModuleId(1234); // WHERE module_id = 1234 + * $query->filterByModuleId(array(12, 34)); // WHERE module_id IN (12, 34) + * $query->filterByModuleId(array('min' => 12)); // WHERE module_id > 12 * * - * @see filterByCategory() + * @see filterByModule() * - * @param mixed $categoryId The value to use as filter. + * @param mixed $moduleId The value to use as filter. * Use scalar values for equality. * Use array values for in_array() equivalent. * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL * - * @return ChildAttributeCategoryQuery The current query, for fluid interface + * @return ChildModuleImageQuery The current query, for fluid interface */ - public function filterByCategoryId($categoryId = null, $comparison = null) + public function filterByModuleId($moduleId = null, $comparison = null) { - if (is_array($categoryId)) { + if (is_array($moduleId)) { $useMinMax = false; - if (isset($categoryId['min'])) { - $this->addUsingAlias(AttributeCategoryTableMap::CATEGORY_ID, $categoryId['min'], Criteria::GREATER_EQUAL); + if (isset($moduleId['min'])) { + $this->addUsingAlias(ModuleImageTableMap::MODULE_ID, $moduleId['min'], Criteria::GREATER_EQUAL); $useMinMax = true; } - if (isset($categoryId['max'])) { - $this->addUsingAlias(AttributeCategoryTableMap::CATEGORY_ID, $categoryId['max'], Criteria::LESS_EQUAL); + if (isset($moduleId['max'])) { + $this->addUsingAlias(ModuleImageTableMap::MODULE_ID, $moduleId['max'], Criteria::LESS_EQUAL); $useMinMax = true; } if ($useMinMax) { @@ -317,39 +322,66 @@ abstract class AttributeCategoryQuery extends ModelCriteria } } - return $this->addUsingAlias(AttributeCategoryTableMap::CATEGORY_ID, $categoryId, $comparison); + return $this->addUsingAlias(ModuleImageTableMap::MODULE_ID, $moduleId, $comparison); } /** - * Filter the query on the attribute_id column + * Filter the query on the file column * * Example usage: * - * $query->filterByAttributeId(1234); // WHERE attribute_id = 1234 - * $query->filterByAttributeId(array(12, 34)); // WHERE attribute_id IN (12, 34) - * $query->filterByAttributeId(array('min' => 12)); // WHERE attribute_id > 12 + * $query->filterByFile('fooValue'); // WHERE file = 'fooValue' + * $query->filterByFile('%fooValue%'); // WHERE file LIKE '%fooValue%' * * - * @see filterByAttribute() + * @param string $file The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL * - * @param mixed $attributeId The value to use as filter. + * @return ChildModuleImageQuery The current query, for fluid interface + */ + public function filterByFile($file = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($file)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $file)) { + $file = str_replace('*', '%', $file); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(ModuleImageTableMap::FILE, $file, $comparison); + } + + /** + * Filter the query on the position column + * + * Example usage: + * + * $query->filterByPosition(1234); // WHERE position = 1234 + * $query->filterByPosition(array(12, 34)); // WHERE position IN (12, 34) + * $query->filterByPosition(array('min' => 12)); // WHERE position > 12 + * + * + * @param mixed $position The value to use as filter. * Use scalar values for equality. * Use array values for in_array() equivalent. * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL * - * @return ChildAttributeCategoryQuery The current query, for fluid interface + * @return ChildModuleImageQuery The current query, for fluid interface */ - public function filterByAttributeId($attributeId = null, $comparison = null) + public function filterByPosition($position = null, $comparison = null) { - if (is_array($attributeId)) { + if (is_array($position)) { $useMinMax = false; - if (isset($attributeId['min'])) { - $this->addUsingAlias(AttributeCategoryTableMap::ATTRIBUTE_ID, $attributeId['min'], Criteria::GREATER_EQUAL); + if (isset($position['min'])) { + $this->addUsingAlias(ModuleImageTableMap::POSITION, $position['min'], Criteria::GREATER_EQUAL); $useMinMax = true; } - if (isset($attributeId['max'])) { - $this->addUsingAlias(AttributeCategoryTableMap::ATTRIBUTE_ID, $attributeId['max'], Criteria::LESS_EQUAL); + if (isset($position['max'])) { + $this->addUsingAlias(ModuleImageTableMap::POSITION, $position['max'], Criteria::LESS_EQUAL); $useMinMax = true; } if ($useMinMax) { @@ -360,7 +392,7 @@ abstract class AttributeCategoryQuery extends ModelCriteria } } - return $this->addUsingAlias(AttributeCategoryTableMap::ATTRIBUTE_ID, $attributeId, $comparison); + return $this->addUsingAlias(ModuleImageTableMap::POSITION, $position, $comparison); } /** @@ -381,18 +413,18 @@ abstract class AttributeCategoryQuery extends ModelCriteria * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL * - * @return ChildAttributeCategoryQuery The current query, for fluid interface + * @return ChildModuleImageQuery The current query, for fluid interface */ public function filterByCreatedAt($createdAt = null, $comparison = null) { if (is_array($createdAt)) { $useMinMax = false; if (isset($createdAt['min'])) { - $this->addUsingAlias(AttributeCategoryTableMap::CREATED_AT, $createdAt['min'], Criteria::GREATER_EQUAL); + $this->addUsingAlias(ModuleImageTableMap::CREATED_AT, $createdAt['min'], Criteria::GREATER_EQUAL); $useMinMax = true; } if (isset($createdAt['max'])) { - $this->addUsingAlias(AttributeCategoryTableMap::CREATED_AT, $createdAt['max'], Criteria::LESS_EQUAL); + $this->addUsingAlias(ModuleImageTableMap::CREATED_AT, $createdAt['max'], Criteria::LESS_EQUAL); $useMinMax = true; } if ($useMinMax) { @@ -403,7 +435,7 @@ abstract class AttributeCategoryQuery extends ModelCriteria } } - return $this->addUsingAlias(AttributeCategoryTableMap::CREATED_AT, $createdAt, $comparison); + return $this->addUsingAlias(ModuleImageTableMap::CREATED_AT, $createdAt, $comparison); } /** @@ -424,18 +456,18 @@ abstract class AttributeCategoryQuery extends ModelCriteria * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL * - * @return ChildAttributeCategoryQuery The current query, for fluid interface + * @return ChildModuleImageQuery The current query, for fluid interface */ public function filterByUpdatedAt($updatedAt = null, $comparison = null) { if (is_array($updatedAt)) { $useMinMax = false; if (isset($updatedAt['min'])) { - $this->addUsingAlias(AttributeCategoryTableMap::UPDATED_AT, $updatedAt['min'], Criteria::GREATER_EQUAL); + $this->addUsingAlias(ModuleImageTableMap::UPDATED_AT, $updatedAt['min'], Criteria::GREATER_EQUAL); $useMinMax = true; } if (isset($updatedAt['max'])) { - $this->addUsingAlias(AttributeCategoryTableMap::UPDATED_AT, $updatedAt['max'], Criteria::LESS_EQUAL); + $this->addUsingAlias(ModuleImageTableMap::UPDATED_AT, $updatedAt['max'], Criteria::LESS_EQUAL); $useMinMax = true; } if ($useMinMax) { @@ -446,46 +478,46 @@ abstract class AttributeCategoryQuery extends ModelCriteria } } - return $this->addUsingAlias(AttributeCategoryTableMap::UPDATED_AT, $updatedAt, $comparison); + return $this->addUsingAlias(ModuleImageTableMap::UPDATED_AT, $updatedAt, $comparison); } /** - * Filter the query by a related \Thelia\Model\Category object + * Filter the query by a related \Thelia\Model\Module object * - * @param \Thelia\Model\Category|ObjectCollection $category The related object(s) to use as filter + * @param \Thelia\Model\Module|ObjectCollection $module The related object(s) to use as filter * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL * - * @return ChildAttributeCategoryQuery The current query, for fluid interface + * @return ChildModuleImageQuery The current query, for fluid interface */ - public function filterByCategory($category, $comparison = null) + public function filterByModule($module, $comparison = null) { - if ($category instanceof \Thelia\Model\Category) { + if ($module instanceof \Thelia\Model\Module) { return $this - ->addUsingAlias(AttributeCategoryTableMap::CATEGORY_ID, $category->getId(), $comparison); - } elseif ($category instanceof ObjectCollection) { + ->addUsingAlias(ModuleImageTableMap::MODULE_ID, $module->getId(), $comparison); + } elseif ($module instanceof ObjectCollection) { if (null === $comparison) { $comparison = Criteria::IN; } return $this - ->addUsingAlias(AttributeCategoryTableMap::CATEGORY_ID, $category->toKeyValue('PrimaryKey', 'Id'), $comparison); + ->addUsingAlias(ModuleImageTableMap::MODULE_ID, $module->toKeyValue('PrimaryKey', 'Id'), $comparison); } else { - throw new PropelException('filterByCategory() only accepts arguments of type \Thelia\Model\Category or Collection'); + throw new PropelException('filterByModule() only accepts arguments of type \Thelia\Model\Module or Collection'); } } /** - * Adds a JOIN clause to the query using the Category relation + * Adds a JOIN clause to the query using the Module relation * * @param string $relationAlias optional alias for the relation * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' * - * @return ChildAttributeCategoryQuery The current query, for fluid interface + * @return ChildModuleImageQuery The current query, for fluid interface */ - public function joinCategory($relationAlias = null, $joinType = Criteria::INNER_JOIN) + public function joinModule($relationAlias = null, $joinType = Criteria::INNER_JOIN) { $tableMap = $this->getTableMap(); - $relationMap = $tableMap->getRelation('Category'); + $relationMap = $tableMap->getRelation('Module'); // create a ModelJoin object for this join $join = new ModelJoin(); @@ -500,14 +532,14 @@ abstract class AttributeCategoryQuery extends ModelCriteria $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); $this->addJoinObject($join, $relationAlias); } else { - $this->addJoinObject($join, 'Category'); + $this->addJoinObject($join, 'Module'); } return $this; } /** - * Use the Category relation Category object + * Use the Module relation Module object * * @see useQuery() * @@ -515,52 +547,50 @@ abstract class AttributeCategoryQuery extends ModelCriteria * to be used as main alias in the secondary query * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' * - * @return \Thelia\Model\CategoryQuery A secondary query class using the current class as primary query + * @return \Thelia\Model\ModuleQuery A secondary query class using the current class as primary query */ - public function useCategoryQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) + public function useModuleQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) { return $this - ->joinCategory($relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'Category', '\Thelia\Model\CategoryQuery'); + ->joinModule($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'Module', '\Thelia\Model\ModuleQuery'); } /** - * Filter the query by a related \Thelia\Model\Attribute object + * Filter the query by a related \Thelia\Model\ModuleImageI18n object * - * @param \Thelia\Model\Attribute|ObjectCollection $attribute The related object(s) to use as filter + * @param \Thelia\Model\ModuleImageI18n|ObjectCollection $moduleImageI18n the related object to use as filter * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL * - * @return ChildAttributeCategoryQuery The current query, for fluid interface + * @return ChildModuleImageQuery The current query, for fluid interface */ - public function filterByAttribute($attribute, $comparison = null) + public function filterByModuleImageI18n($moduleImageI18n, $comparison = null) { - if ($attribute instanceof \Thelia\Model\Attribute) { + if ($moduleImageI18n instanceof \Thelia\Model\ModuleImageI18n) { return $this - ->addUsingAlias(AttributeCategoryTableMap::ATTRIBUTE_ID, $attribute->getId(), $comparison); - } elseif ($attribute instanceof ObjectCollection) { - if (null === $comparison) { - $comparison = Criteria::IN; - } - + ->addUsingAlias(ModuleImageTableMap::ID, $moduleImageI18n->getId(), $comparison); + } elseif ($moduleImageI18n instanceof ObjectCollection) { return $this - ->addUsingAlias(AttributeCategoryTableMap::ATTRIBUTE_ID, $attribute->toKeyValue('PrimaryKey', 'Id'), $comparison); + ->useModuleImageI18nQuery() + ->filterByPrimaryKeys($moduleImageI18n->getPrimaryKeys()) + ->endUse(); } else { - throw new PropelException('filterByAttribute() only accepts arguments of type \Thelia\Model\Attribute or Collection'); + throw new PropelException('filterByModuleImageI18n() only accepts arguments of type \Thelia\Model\ModuleImageI18n or Collection'); } } /** - * Adds a JOIN clause to the query using the Attribute relation + * Adds a JOIN clause to the query using the ModuleImageI18n relation * * @param string $relationAlias optional alias for the relation * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' * - * @return ChildAttributeCategoryQuery The current query, for fluid interface + * @return ChildModuleImageQuery The current query, for fluid interface */ - public function joinAttribute($relationAlias = null, $joinType = Criteria::INNER_JOIN) + public function joinModuleImageI18n($relationAlias = null, $joinType = 'LEFT JOIN') { $tableMap = $this->getTableMap(); - $relationMap = $tableMap->getRelation('Attribute'); + $relationMap = $tableMap->getRelation('ModuleImageI18n'); // create a ModelJoin object for this join $join = new ModelJoin(); @@ -575,14 +605,14 @@ abstract class AttributeCategoryQuery extends ModelCriteria $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); $this->addJoinObject($join, $relationAlias); } else { - $this->addJoinObject($join, 'Attribute'); + $this->addJoinObject($join, 'ModuleImageI18n'); } return $this; } /** - * Use the Attribute relation Attribute object + * Use the ModuleImageI18n relation ModuleImageI18n object * * @see useQuery() * @@ -590,33 +620,33 @@ abstract class AttributeCategoryQuery extends ModelCriteria * to be used as main alias in the secondary query * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' * - * @return \Thelia\Model\AttributeQuery A secondary query class using the current class as primary query + * @return \Thelia\Model\ModuleImageI18nQuery A secondary query class using the current class as primary query */ - public function useAttributeQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) + public function useModuleImageI18nQuery($relationAlias = null, $joinType = 'LEFT JOIN') { return $this - ->joinAttribute($relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'Attribute', '\Thelia\Model\AttributeQuery'); + ->joinModuleImageI18n($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'ModuleImageI18n', '\Thelia\Model\ModuleImageI18nQuery'); } /** * Exclude object from result * - * @param ChildAttributeCategory $attributeCategory Object to remove from the list of results + * @param ChildModuleImage $moduleImage Object to remove from the list of results * - * @return ChildAttributeCategoryQuery The current query, for fluid interface + * @return ChildModuleImageQuery The current query, for fluid interface */ - public function prune($attributeCategory = null) + public function prune($moduleImage = null) { - if ($attributeCategory) { - $this->addUsingAlias(AttributeCategoryTableMap::ID, $attributeCategory->getId(), Criteria::NOT_EQUAL); + if ($moduleImage) { + $this->addUsingAlias(ModuleImageTableMap::ID, $moduleImage->getId(), Criteria::NOT_EQUAL); } return $this; } /** - * Deletes all rows from the attribute_category table. + * Deletes all rows from the module_image table. * * @param ConnectionInterface $con the connection to use * @return int The number of affected rows (if supported by underlying database driver). @@ -624,7 +654,7 @@ abstract class AttributeCategoryQuery extends ModelCriteria public function doDeleteAll(ConnectionInterface $con = null) { if (null === $con) { - $con = Propel::getServiceContainer()->getWriteConnection(AttributeCategoryTableMap::DATABASE_NAME); + $con = Propel::getServiceContainer()->getWriteConnection(ModuleImageTableMap::DATABASE_NAME); } $affectedRows = 0; // initialize var to track total num of affected rows try { @@ -635,8 +665,8 @@ abstract class AttributeCategoryQuery extends ModelCriteria // Because this db requires some delete cascade/set null emulation, we have to // clear the cached instance *after* the emulation has happened (since // instances get re-added by the select statement contained therein). - AttributeCategoryTableMap::clearInstancePool(); - AttributeCategoryTableMap::clearRelatedInstancePool(); + ModuleImageTableMap::clearInstancePool(); + ModuleImageTableMap::clearRelatedInstancePool(); $con->commit(); } catch (PropelException $e) { @@ -648,9 +678,9 @@ abstract class AttributeCategoryQuery extends ModelCriteria } /** - * Performs a DELETE on the database, given a ChildAttributeCategory or Criteria object OR a primary key value. + * Performs a DELETE on the database, given a ChildModuleImage or Criteria object OR a primary key value. * - * @param mixed $values Criteria or ChildAttributeCategory object or primary key or array of primary keys + * @param mixed $values Criteria or ChildModuleImage object or primary key or array of primary keys * which is used to create the DELETE statement * @param ConnectionInterface $con the connection to use * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows @@ -661,13 +691,13 @@ abstract class AttributeCategoryQuery extends ModelCriteria public function delete(ConnectionInterface $con = null) { if (null === $con) { - $con = Propel::getServiceContainer()->getWriteConnection(AttributeCategoryTableMap::DATABASE_NAME); + $con = Propel::getServiceContainer()->getWriteConnection(ModuleImageTableMap::DATABASE_NAME); } $criteria = $this; // Set the correct dbName - $criteria->setDbName(AttributeCategoryTableMap::DATABASE_NAME); + $criteria->setDbName(ModuleImageTableMap::DATABASE_NAME); $affectedRows = 0; // initialize var to track total num of affected rows @@ -677,10 +707,10 @@ abstract class AttributeCategoryQuery extends ModelCriteria $con->beginTransaction(); - AttributeCategoryTableMap::removeInstanceFromPool($criteria); + ModuleImageTableMap::removeInstanceFromPool($criteria); $affectedRows += ModelCriteria::delete($con); - AttributeCategoryTableMap::clearRelatedInstancePool(); + ModuleImageTableMap::clearRelatedInstancePool(); $con->commit(); return $affectedRows; @@ -697,11 +727,11 @@ abstract class AttributeCategoryQuery extends ModelCriteria * * @param int $nbDays Maximum age of the latest update in days * - * @return ChildAttributeCategoryQuery The current query, for fluid interface + * @return ChildModuleImageQuery The current query, for fluid interface */ public function recentlyUpdated($nbDays = 7) { - return $this->addUsingAlias(AttributeCategoryTableMap::UPDATED_AT, time() - $nbDays * 24 * 60 * 60, Criteria::GREATER_EQUAL); + return $this->addUsingAlias(ModuleImageTableMap::UPDATED_AT, time() - $nbDays * 24 * 60 * 60, Criteria::GREATER_EQUAL); } /** @@ -709,51 +739,108 @@ abstract class AttributeCategoryQuery extends ModelCriteria * * @param int $nbDays Maximum age of in days * - * @return ChildAttributeCategoryQuery The current query, for fluid interface + * @return ChildModuleImageQuery The current query, for fluid interface */ public function recentlyCreated($nbDays = 7) { - return $this->addUsingAlias(AttributeCategoryTableMap::CREATED_AT, time() - $nbDays * 24 * 60 * 60, Criteria::GREATER_EQUAL); + return $this->addUsingAlias(ModuleImageTableMap::CREATED_AT, time() - $nbDays * 24 * 60 * 60, Criteria::GREATER_EQUAL); } /** * Order by update date desc * - * @return ChildAttributeCategoryQuery The current query, for fluid interface + * @return ChildModuleImageQuery The current query, for fluid interface */ public function lastUpdatedFirst() { - return $this->addDescendingOrderByColumn(AttributeCategoryTableMap::UPDATED_AT); + return $this->addDescendingOrderByColumn(ModuleImageTableMap::UPDATED_AT); } /** * Order by update date asc * - * @return ChildAttributeCategoryQuery The current query, for fluid interface + * @return ChildModuleImageQuery The current query, for fluid interface */ public function firstUpdatedFirst() { - return $this->addAscendingOrderByColumn(AttributeCategoryTableMap::UPDATED_AT); + return $this->addAscendingOrderByColumn(ModuleImageTableMap::UPDATED_AT); } /** * Order by create date desc * - * @return ChildAttributeCategoryQuery The current query, for fluid interface + * @return ChildModuleImageQuery The current query, for fluid interface */ public function lastCreatedFirst() { - return $this->addDescendingOrderByColumn(AttributeCategoryTableMap::CREATED_AT); + return $this->addDescendingOrderByColumn(ModuleImageTableMap::CREATED_AT); } /** * Order by create date asc * - * @return ChildAttributeCategoryQuery The current query, for fluid interface + * @return ChildModuleImageQuery The current query, for fluid interface */ public function firstCreatedFirst() { - return $this->addAscendingOrderByColumn(AttributeCategoryTableMap::CREATED_AT); + return $this->addAscendingOrderByColumn(ModuleImageTableMap::CREATED_AT); } -} // AttributeCategoryQuery + // i18n behavior + + /** + * Adds a JOIN clause to the query using the i18n relation + * + * @param string $locale Locale to use for the join condition, e.g. 'fr_FR' + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join'. Defaults to left join. + * + * @return ChildModuleImageQuery The current query, for fluid interface + */ + public function joinI18n($locale = 'en_US', $relationAlias = null, $joinType = Criteria::LEFT_JOIN) + { + $relationName = $relationAlias ? $relationAlias : 'ModuleImageI18n'; + + return $this + ->joinModuleImageI18n($relationAlias, $joinType) + ->addJoinCondition($relationName, $relationName . '.Locale = ?', $locale); + } + + /** + * Adds a JOIN clause to the query and hydrates the related I18n object. + * Shortcut for $c->joinI18n($locale)->with() + * + * @param string $locale Locale to use for the join condition, e.g. 'fr_FR' + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join'. Defaults to left join. + * + * @return ChildModuleImageQuery The current query, for fluid interface + */ + public function joinWithI18n($locale = 'en_US', $joinType = Criteria::LEFT_JOIN) + { + $this + ->joinI18n($locale, null, $joinType) + ->with('ModuleImageI18n'); + $this->with['ModuleImageI18n']->setIsWithOneToMany(false); + + return $this; + } + + /** + * Use the I18n relation query object + * + * @see useQuery() + * + * @param string $locale Locale to use for the join condition, e.g. 'fr_FR' + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join'. Defaults to left join. + * + * @return ChildModuleImageI18nQuery A secondary query class using the current class as primary query + */ + public function useI18nQuery($locale = 'en_US', $relationAlias = null, $joinType = Criteria::LEFT_JOIN) + { + return $this + ->joinI18n($locale, $relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'ModuleImageI18n', '\Thelia\Model\ModuleImageI18nQuery'); + } + +} // ModuleImageQuery diff --git a/core/lib/Thelia/Model/Base/ModuleQuery.php b/core/lib/Thelia/Model/Base/ModuleQuery.php index 0ed6c5293..4031a4f63 100644 --- a/core/lib/Thelia/Model/Base/ModuleQuery.php +++ b/core/lib/Thelia/Model/Base/ModuleQuery.php @@ -60,6 +60,10 @@ use Thelia\Model\Map\ModuleTableMap; * @method ChildModuleQuery rightJoinGroupModule($relationAlias = null) Adds a RIGHT JOIN clause to the query using the GroupModule relation * @method ChildModuleQuery innerJoinGroupModule($relationAlias = null) Adds a INNER JOIN clause to the query using the GroupModule relation * + * @method ChildModuleQuery leftJoinModuleImage($relationAlias = null) Adds a LEFT JOIN clause to the query using the ModuleImage relation + * @method ChildModuleQuery rightJoinModuleImage($relationAlias = null) Adds a RIGHT JOIN clause to the query using the ModuleImage relation + * @method ChildModuleQuery innerJoinModuleImage($relationAlias = null) Adds a INNER JOIN clause to the query using the ModuleImage relation + * * @method ChildModuleQuery leftJoinModuleI18n($relationAlias = null) Adds a LEFT JOIN clause to the query using the ModuleI18n relation * @method ChildModuleQuery rightJoinModuleI18n($relationAlias = null) Adds a RIGHT JOIN clause to the query using the ModuleI18n relation * @method ChildModuleQuery innerJoinModuleI18n($relationAlias = null) Adds a INNER JOIN clause to the query using the ModuleI18n relation @@ -861,6 +865,79 @@ abstract class ModuleQuery extends ModelCriteria ->useQuery($relationAlias ? $relationAlias : 'GroupModule', '\Thelia\Model\GroupModuleQuery'); } + /** + * Filter the query by a related \Thelia\Model\ModuleImage object + * + * @param \Thelia\Model\ModuleImage|ObjectCollection $moduleImage the related object to use as filter + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildModuleQuery The current query, for fluid interface + */ + public function filterByModuleImage($moduleImage, $comparison = null) + { + if ($moduleImage instanceof \Thelia\Model\ModuleImage) { + return $this + ->addUsingAlias(ModuleTableMap::ID, $moduleImage->getModuleId(), $comparison); + } elseif ($moduleImage instanceof ObjectCollection) { + return $this + ->useModuleImageQuery() + ->filterByPrimaryKeys($moduleImage->getPrimaryKeys()) + ->endUse(); + } else { + throw new PropelException('filterByModuleImage() only accepts arguments of type \Thelia\Model\ModuleImage or Collection'); + } + } + + /** + * Adds a JOIN clause to the query using the ModuleImage relation + * + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return ChildModuleQuery The current query, for fluid interface + */ + public function joinModuleImage($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + $tableMap = $this->getTableMap(); + $relationMap = $tableMap->getRelation('ModuleImage'); + + // create a ModelJoin object for this join + $join = new ModelJoin(); + $join->setJoinType($joinType); + $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); + if ($previousJoin = $this->getPreviousJoin()) { + $join->setPreviousJoin($previousJoin); + } + + // add the ModelJoin to the current object + if ($relationAlias) { + $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); + $this->addJoinObject($join, $relationAlias); + } else { + $this->addJoinObject($join, 'ModuleImage'); + } + + return $this; + } + + /** + * Use the ModuleImage relation ModuleImage object + * + * @see useQuery() + * + * @param string $relationAlias optional alias for the relation, + * to be used as main alias in the secondary query + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return \Thelia\Model\ModuleImageQuery A secondary query class using the current class as primary query + */ + public function useModuleImageQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + return $this + ->joinModuleImage($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'ModuleImage', '\Thelia\Model\ModuleImageQuery'); + } + /** * Filter the query by a related \Thelia\Model\ModuleI18n object * diff --git a/core/lib/Thelia/Model/Base/OrderProduct.php b/core/lib/Thelia/Model/Base/OrderProduct.php index 2bf9c7ace..6ff03d427 100644 --- a/core/lib/Thelia/Model/Base/OrderProduct.php +++ b/core/lib/Thelia/Model/Base/OrderProduct.php @@ -18,10 +18,12 @@ use Propel\Runtime\Map\TableMap; use Propel\Runtime\Parser\AbstractParser; use Propel\Runtime\Util\PropelDateTime; use Thelia\Model\Order as ChildOrder; -use Thelia\Model\OrderFeature as ChildOrderFeature; -use Thelia\Model\OrderFeatureQuery as ChildOrderFeatureQuery; use Thelia\Model\OrderProduct as ChildOrderProduct; +use Thelia\Model\OrderProductAttributeCombination as ChildOrderProductAttributeCombination; +use Thelia\Model\OrderProductAttributeCombinationQuery as ChildOrderProductAttributeCombinationQuery; use Thelia\Model\OrderProductQuery as ChildOrderProductQuery; +use Thelia\Model\OrderProductTax as ChildOrderProductTax; +use Thelia\Model\OrderProductTaxQuery as ChildOrderProductTaxQuery; use Thelia\Model\OrderQuery as ChildOrderQuery; use Thelia\Model\Map\OrderProductTableMap; @@ -77,12 +79,24 @@ abstract class OrderProduct implements ActiveRecordInterface */ protected $product_ref; + /** + * The value for the product_sale_elements_ref field. + * @var string + */ + protected $product_sale_elements_ref; + /** * The value for the title field. * @var string */ protected $title; + /** + * The value for the chapo field. + * @var string + */ + protected $chapo; + /** * The value for the description field. * @var string @@ -90,10 +104,10 @@ abstract class OrderProduct implements ActiveRecordInterface protected $description; /** - * The value for the chapo field. + * The value for the postscriptum field. * @var string */ - protected $chapo; + protected $postscriptum; /** * The value for the quantity field. @@ -108,10 +122,40 @@ abstract class OrderProduct implements ActiveRecordInterface protected $price; /** - * The value for the tax field. - * @var double + * The value for the promo_price field. + * @var string */ - protected $tax; + protected $promo_price; + + /** + * The value for the was_new field. + * @var int + */ + protected $was_new; + + /** + * The value for the was_in_promo field. + * @var int + */ + protected $was_in_promo; + + /** + * The value for the weight field. + * @var string + */ + protected $weight; + + /** + * The value for the tax_rule_title field. + * @var string + */ + protected $tax_rule_title; + + /** + * The value for the tax_rule_description field. + * @var string + */ + protected $tax_rule_description; /** * The value for the parent field. @@ -137,10 +181,16 @@ abstract class OrderProduct implements ActiveRecordInterface protected $aOrder; /** - * @var ObjectCollection|ChildOrderFeature[] Collection to store aggregation of ChildOrderFeature objects. + * @var ObjectCollection|ChildOrderProductAttributeCombination[] Collection to store aggregation of ChildOrderProductAttributeCombination objects. */ - protected $collOrderFeatures; - protected $collOrderFeaturesPartial; + protected $collOrderProductAttributeCombinations; + protected $collOrderProductAttributeCombinationsPartial; + + /** + * @var ObjectCollection|ChildOrderProductTax[] Collection to store aggregation of ChildOrderProductTax objects. + */ + protected $collOrderProductTaxes; + protected $collOrderProductTaxesPartial; /** * Flag to prevent endless save loop, if this object is referenced @@ -154,7 +204,13 @@ abstract class OrderProduct implements ActiveRecordInterface * An array of objects scheduled for deletion. * @var ObjectCollection */ - protected $orderFeaturesScheduledForDeletion = null; + protected $orderProductAttributeCombinationsScheduledForDeletion = null; + + /** + * An array of objects scheduled for deletion. + * @var ObjectCollection + */ + protected $orderProductTaxesScheduledForDeletion = null; /** * Initializes internal state of Thelia\Model\Base\OrderProduct object. @@ -443,6 +499,17 @@ abstract class OrderProduct implements ActiveRecordInterface return $this->product_ref; } + /** + * Get the [product_sale_elements_ref] column value. + * + * @return string + */ + public function getProductSaleElementsRef() + { + + return $this->product_sale_elements_ref; + } + /** * Get the [title] column value. * @@ -454,6 +521,17 @@ abstract class OrderProduct implements ActiveRecordInterface return $this->title; } + /** + * Get the [chapo] column value. + * + * @return string + */ + public function getChapo() + { + + return $this->chapo; + } + /** * Get the [description] column value. * @@ -466,14 +544,14 @@ abstract class OrderProduct implements ActiveRecordInterface } /** - * Get the [chapo] column value. + * Get the [postscriptum] column value. * * @return string */ - public function getChapo() + public function getPostscriptum() { - return $this->chapo; + return $this->postscriptum; } /** @@ -499,19 +577,74 @@ abstract class OrderProduct implements ActiveRecordInterface } /** - * Get the [tax] column value. + * Get the [promo_price] column value. * - * @return double + * @return string */ - public function getTax() + public function getPromoPrice() { - return $this->tax; + return $this->promo_price; + } + + /** + * Get the [was_new] column value. + * + * @return int + */ + public function getWasNew() + { + + return $this->was_new; + } + + /** + * Get the [was_in_promo] column value. + * + * @return int + */ + public function getWasInPromo() + { + + return $this->was_in_promo; + } + + /** + * Get the [weight] column value. + * + * @return string + */ + public function getWeight() + { + + return $this->weight; + } + + /** + * Get the [tax_rule_title] column value. + * + * @return string + */ + public function getTaxRuleTitle() + { + + return $this->tax_rule_title; + } + + /** + * Get the [tax_rule_description] column value. + * + * @return string + */ + public function getTaxRuleDescription() + { + + return $this->tax_rule_description; } /** * Get the [parent] column value. - * + * not managed yet * @return int */ public function getParent() @@ -627,6 +760,27 @@ abstract class OrderProduct implements ActiveRecordInterface return $this; } // setProductRef() + /** + * Set the value of [product_sale_elements_ref] column. + * + * @param string $v new value + * @return \Thelia\Model\OrderProduct The current object (for fluent API support) + */ + public function setProductSaleElementsRef($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->product_sale_elements_ref !== $v) { + $this->product_sale_elements_ref = $v; + $this->modifiedColumns[] = OrderProductTableMap::PRODUCT_SALE_ELEMENTS_REF; + } + + + return $this; + } // setProductSaleElementsRef() + /** * Set the value of [title] column. * @@ -648,6 +802,27 @@ abstract class OrderProduct implements ActiveRecordInterface return $this; } // setTitle() + /** + * Set the value of [chapo] column. + * + * @param string $v new value + * @return \Thelia\Model\OrderProduct The current object (for fluent API support) + */ + public function setChapo($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->chapo !== $v) { + $this->chapo = $v; + $this->modifiedColumns[] = OrderProductTableMap::CHAPO; + } + + + return $this; + } // setChapo() + /** * Set the value of [description] column. * @@ -670,25 +845,25 @@ abstract class OrderProduct implements ActiveRecordInterface } // setDescription() /** - * Set the value of [chapo] column. + * Set the value of [postscriptum] column. * * @param string $v new value * @return \Thelia\Model\OrderProduct The current object (for fluent API support) */ - public function setChapo($v) + public function setPostscriptum($v) { if ($v !== null) { $v = (string) $v; } - if ($this->chapo !== $v) { - $this->chapo = $v; - $this->modifiedColumns[] = OrderProductTableMap::CHAPO; + if ($this->postscriptum !== $v) { + $this->postscriptum = $v; + $this->modifiedColumns[] = OrderProductTableMap::POSTSCRIPTUM; } return $this; - } // setChapo() + } // setPostscriptum() /** * Set the value of [quantity] column. @@ -733,29 +908,134 @@ abstract class OrderProduct implements ActiveRecordInterface } // setPrice() /** - * Set the value of [tax] column. + * Set the value of [promo_price] column. * - * @param double $v new value + * @param string $v new value * @return \Thelia\Model\OrderProduct The current object (for fluent API support) */ - public function setTax($v) + public function setPromoPrice($v) { if ($v !== null) { - $v = (double) $v; + $v = (string) $v; } - if ($this->tax !== $v) { - $this->tax = $v; - $this->modifiedColumns[] = OrderProductTableMap::TAX; + if ($this->promo_price !== $v) { + $this->promo_price = $v; + $this->modifiedColumns[] = OrderProductTableMap::PROMO_PRICE; } return $this; - } // setTax() + } // setPromoPrice() + + /** + * Set the value of [was_new] column. + * + * @param int $v new value + * @return \Thelia\Model\OrderProduct The current object (for fluent API support) + */ + public function setWasNew($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->was_new !== $v) { + $this->was_new = $v; + $this->modifiedColumns[] = OrderProductTableMap::WAS_NEW; + } + + + return $this; + } // setWasNew() + + /** + * Set the value of [was_in_promo] column. + * + * @param int $v new value + * @return \Thelia\Model\OrderProduct The current object (for fluent API support) + */ + public function setWasInPromo($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->was_in_promo !== $v) { + $this->was_in_promo = $v; + $this->modifiedColumns[] = OrderProductTableMap::WAS_IN_PROMO; + } + + + return $this; + } // setWasInPromo() + + /** + * Set the value of [weight] column. + * + * @param string $v new value + * @return \Thelia\Model\OrderProduct The current object (for fluent API support) + */ + public function setWeight($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->weight !== $v) { + $this->weight = $v; + $this->modifiedColumns[] = OrderProductTableMap::WEIGHT; + } + + + return $this; + } // setWeight() + + /** + * Set the value of [tax_rule_title] column. + * + * @param string $v new value + * @return \Thelia\Model\OrderProduct The current object (for fluent API support) + */ + public function setTaxRuleTitle($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->tax_rule_title !== $v) { + $this->tax_rule_title = $v; + $this->modifiedColumns[] = OrderProductTableMap::TAX_RULE_TITLE; + } + + + return $this; + } // setTaxRuleTitle() + + /** + * Set the value of [tax_rule_description] column. + * + * @param string $v new value + * @return \Thelia\Model\OrderProduct The current object (for fluent API support) + */ + public function setTaxRuleDescription($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->tax_rule_description !== $v) { + $this->tax_rule_description = $v; + $this->modifiedColumns[] = OrderProductTableMap::TAX_RULE_DESCRIPTION; + } + + + return $this; + } // setTaxRuleDescription() /** * Set the value of [parent] column. - * + * not managed yet * @param int $v new value * @return \Thelia\Model\OrderProduct The current object (for fluent API support) */ @@ -862,34 +1142,55 @@ abstract class OrderProduct implements ActiveRecordInterface $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : OrderProductTableMap::translateFieldName('ProductRef', TableMap::TYPE_PHPNAME, $indexType)]; $this->product_ref = (null !== $col) ? (string) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : OrderProductTableMap::translateFieldName('Title', TableMap::TYPE_PHPNAME, $indexType)]; - $this->title = (null !== $col) ? (string) $col : null; + $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : OrderProductTableMap::translateFieldName('ProductSaleElementsRef', TableMap::TYPE_PHPNAME, $indexType)]; + $this->product_sale_elements_ref = (null !== $col) ? (string) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : OrderProductTableMap::translateFieldName('Description', TableMap::TYPE_PHPNAME, $indexType)]; - $this->description = (null !== $col) ? (string) $col : null; + $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : OrderProductTableMap::translateFieldName('Title', TableMap::TYPE_PHPNAME, $indexType)]; + $this->title = (null !== $col) ? (string) $col : null; $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : OrderProductTableMap::translateFieldName('Chapo', TableMap::TYPE_PHPNAME, $indexType)]; $this->chapo = (null !== $col) ? (string) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : OrderProductTableMap::translateFieldName('Quantity', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : OrderProductTableMap::translateFieldName('Description', TableMap::TYPE_PHPNAME, $indexType)]; + $this->description = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : OrderProductTableMap::translateFieldName('Postscriptum', TableMap::TYPE_PHPNAME, $indexType)]; + $this->postscriptum = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 8 + $startcol : OrderProductTableMap::translateFieldName('Quantity', TableMap::TYPE_PHPNAME, $indexType)]; $this->quantity = (null !== $col) ? (double) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : OrderProductTableMap::translateFieldName('Price', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 9 + $startcol : OrderProductTableMap::translateFieldName('Price', TableMap::TYPE_PHPNAME, $indexType)]; $this->price = (null !== $col) ? (double) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 8 + $startcol : OrderProductTableMap::translateFieldName('Tax', TableMap::TYPE_PHPNAME, $indexType)]; - $this->tax = (null !== $col) ? (double) $col : null; + $col = $row[TableMap::TYPE_NUM == $indexType ? 10 + $startcol : OrderProductTableMap::translateFieldName('PromoPrice', TableMap::TYPE_PHPNAME, $indexType)]; + $this->promo_price = (null !== $col) ? (string) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 9 + $startcol : OrderProductTableMap::translateFieldName('Parent', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 11 + $startcol : OrderProductTableMap::translateFieldName('WasNew', TableMap::TYPE_PHPNAME, $indexType)]; + $this->was_new = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 12 + $startcol : OrderProductTableMap::translateFieldName('WasInPromo', TableMap::TYPE_PHPNAME, $indexType)]; + $this->was_in_promo = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 13 + $startcol : OrderProductTableMap::translateFieldName('Weight', TableMap::TYPE_PHPNAME, $indexType)]; + $this->weight = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 14 + $startcol : OrderProductTableMap::translateFieldName('TaxRuleTitle', TableMap::TYPE_PHPNAME, $indexType)]; + $this->tax_rule_title = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 15 + $startcol : OrderProductTableMap::translateFieldName('TaxRuleDescription', TableMap::TYPE_PHPNAME, $indexType)]; + $this->tax_rule_description = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 16 + $startcol : OrderProductTableMap::translateFieldName('Parent', TableMap::TYPE_PHPNAME, $indexType)]; $this->parent = (null !== $col) ? (int) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 10 + $startcol : OrderProductTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 17 + $startcol : OrderProductTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } $this->created_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 11 + $startcol : OrderProductTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 18 + $startcol : OrderProductTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } @@ -902,7 +1203,7 @@ abstract class OrderProduct implements ActiveRecordInterface $this->ensureConsistency(); } - return $startcol + 12; // 12 = OrderProductTableMap::NUM_HYDRATE_COLUMNS. + return $startcol + 19; // 19 = OrderProductTableMap::NUM_HYDRATE_COLUMNS. } catch (Exception $e) { throw new PropelException("Error populating \Thelia\Model\OrderProduct object", 0, $e); @@ -967,7 +1268,9 @@ abstract class OrderProduct implements ActiveRecordInterface if ($deep) { // also de-associate any related objects? $this->aOrder = null; - $this->collOrderFeatures = null; + $this->collOrderProductAttributeCombinations = null; + + $this->collOrderProductTaxes = null; } // if (deep) } @@ -1114,17 +1417,34 @@ abstract class OrderProduct implements ActiveRecordInterface $this->resetModified(); } - if ($this->orderFeaturesScheduledForDeletion !== null) { - if (!$this->orderFeaturesScheduledForDeletion->isEmpty()) { - \Thelia\Model\OrderFeatureQuery::create() - ->filterByPrimaryKeys($this->orderFeaturesScheduledForDeletion->getPrimaryKeys(false)) + if ($this->orderProductAttributeCombinationsScheduledForDeletion !== null) { + if (!$this->orderProductAttributeCombinationsScheduledForDeletion->isEmpty()) { + \Thelia\Model\OrderProductAttributeCombinationQuery::create() + ->filterByPrimaryKeys($this->orderProductAttributeCombinationsScheduledForDeletion->getPrimaryKeys(false)) ->delete($con); - $this->orderFeaturesScheduledForDeletion = null; + $this->orderProductAttributeCombinationsScheduledForDeletion = null; } } - if ($this->collOrderFeatures !== null) { - foreach ($this->collOrderFeatures as $referrerFK) { + if ($this->collOrderProductAttributeCombinations !== null) { + foreach ($this->collOrderProductAttributeCombinations as $referrerFK) { + if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) { + $affectedRows += $referrerFK->save($con); + } + } + } + + if ($this->orderProductTaxesScheduledForDeletion !== null) { + if (!$this->orderProductTaxesScheduledForDeletion->isEmpty()) { + \Thelia\Model\OrderProductTaxQuery::create() + ->filterByPrimaryKeys($this->orderProductTaxesScheduledForDeletion->getPrimaryKeys(false)) + ->delete($con); + $this->orderProductTaxesScheduledForDeletion = null; + } + } + + if ($this->collOrderProductTaxes !== null) { + foreach ($this->collOrderProductTaxes as $referrerFK) { if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) { $affectedRows += $referrerFK->save($con); } @@ -1166,14 +1486,20 @@ abstract class OrderProduct implements ActiveRecordInterface if ($this->isColumnModified(OrderProductTableMap::PRODUCT_REF)) { $modifiedColumns[':p' . $index++] = 'PRODUCT_REF'; } + if ($this->isColumnModified(OrderProductTableMap::PRODUCT_SALE_ELEMENTS_REF)) { + $modifiedColumns[':p' . $index++] = 'PRODUCT_SALE_ELEMENTS_REF'; + } if ($this->isColumnModified(OrderProductTableMap::TITLE)) { $modifiedColumns[':p' . $index++] = 'TITLE'; } + if ($this->isColumnModified(OrderProductTableMap::CHAPO)) { + $modifiedColumns[':p' . $index++] = 'CHAPO'; + } if ($this->isColumnModified(OrderProductTableMap::DESCRIPTION)) { $modifiedColumns[':p' . $index++] = 'DESCRIPTION'; } - if ($this->isColumnModified(OrderProductTableMap::CHAPO)) { - $modifiedColumns[':p' . $index++] = 'CHAPO'; + if ($this->isColumnModified(OrderProductTableMap::POSTSCRIPTUM)) { + $modifiedColumns[':p' . $index++] = 'POSTSCRIPTUM'; } if ($this->isColumnModified(OrderProductTableMap::QUANTITY)) { $modifiedColumns[':p' . $index++] = 'QUANTITY'; @@ -1181,8 +1507,23 @@ abstract class OrderProduct implements ActiveRecordInterface if ($this->isColumnModified(OrderProductTableMap::PRICE)) { $modifiedColumns[':p' . $index++] = 'PRICE'; } - if ($this->isColumnModified(OrderProductTableMap::TAX)) { - $modifiedColumns[':p' . $index++] = 'TAX'; + if ($this->isColumnModified(OrderProductTableMap::PROMO_PRICE)) { + $modifiedColumns[':p' . $index++] = 'PROMO_PRICE'; + } + if ($this->isColumnModified(OrderProductTableMap::WAS_NEW)) { + $modifiedColumns[':p' . $index++] = 'WAS_NEW'; + } + if ($this->isColumnModified(OrderProductTableMap::WAS_IN_PROMO)) { + $modifiedColumns[':p' . $index++] = 'WAS_IN_PROMO'; + } + if ($this->isColumnModified(OrderProductTableMap::WEIGHT)) { + $modifiedColumns[':p' . $index++] = 'WEIGHT'; + } + if ($this->isColumnModified(OrderProductTableMap::TAX_RULE_TITLE)) { + $modifiedColumns[':p' . $index++] = 'TAX_RULE_TITLE'; + } + if ($this->isColumnModified(OrderProductTableMap::TAX_RULE_DESCRIPTION)) { + $modifiedColumns[':p' . $index++] = 'TAX_RULE_DESCRIPTION'; } if ($this->isColumnModified(OrderProductTableMap::PARENT)) { $modifiedColumns[':p' . $index++] = 'PARENT'; @@ -1213,14 +1554,20 @@ abstract class OrderProduct implements ActiveRecordInterface case 'PRODUCT_REF': $stmt->bindValue($identifier, $this->product_ref, PDO::PARAM_STR); break; + case 'PRODUCT_SALE_ELEMENTS_REF': + $stmt->bindValue($identifier, $this->product_sale_elements_ref, PDO::PARAM_STR); + break; case 'TITLE': $stmt->bindValue($identifier, $this->title, PDO::PARAM_STR); break; + case 'CHAPO': + $stmt->bindValue($identifier, $this->chapo, PDO::PARAM_STR); + break; case 'DESCRIPTION': $stmt->bindValue($identifier, $this->description, PDO::PARAM_STR); break; - case 'CHAPO': - $stmt->bindValue($identifier, $this->chapo, PDO::PARAM_STR); + case 'POSTSCRIPTUM': + $stmt->bindValue($identifier, $this->postscriptum, PDO::PARAM_STR); break; case 'QUANTITY': $stmt->bindValue($identifier, $this->quantity, PDO::PARAM_STR); @@ -1228,8 +1575,23 @@ abstract class OrderProduct implements ActiveRecordInterface case 'PRICE': $stmt->bindValue($identifier, $this->price, PDO::PARAM_STR); break; - case 'TAX': - $stmt->bindValue($identifier, $this->tax, PDO::PARAM_STR); + case 'PROMO_PRICE': + $stmt->bindValue($identifier, $this->promo_price, PDO::PARAM_STR); + break; + case 'WAS_NEW': + $stmt->bindValue($identifier, $this->was_new, PDO::PARAM_INT); + break; + case 'WAS_IN_PROMO': + $stmt->bindValue($identifier, $this->was_in_promo, PDO::PARAM_INT); + break; + case 'WEIGHT': + $stmt->bindValue($identifier, $this->weight, PDO::PARAM_STR); + break; + case 'TAX_RULE_TITLE': + $stmt->bindValue($identifier, $this->tax_rule_title, PDO::PARAM_STR); + break; + case 'TAX_RULE_DESCRIPTION': + $stmt->bindValue($identifier, $this->tax_rule_description, PDO::PARAM_STR); break; case 'PARENT': $stmt->bindValue($identifier, $this->parent, PDO::PARAM_INT); @@ -1312,30 +1674,51 @@ abstract class OrderProduct implements ActiveRecordInterface return $this->getProductRef(); break; case 3: - return $this->getTitle(); + return $this->getProductSaleElementsRef(); break; case 4: - return $this->getDescription(); + return $this->getTitle(); break; case 5: return $this->getChapo(); break; case 6: - return $this->getQuantity(); + return $this->getDescription(); break; case 7: - return $this->getPrice(); + return $this->getPostscriptum(); break; case 8: - return $this->getTax(); + return $this->getQuantity(); break; case 9: - return $this->getParent(); + return $this->getPrice(); break; case 10: - return $this->getCreatedAt(); + return $this->getPromoPrice(); break; case 11: + return $this->getWasNew(); + break; + case 12: + return $this->getWasInPromo(); + break; + case 13: + return $this->getWeight(); + break; + case 14: + return $this->getTaxRuleTitle(); + break; + case 15: + return $this->getTaxRuleDescription(); + break; + case 16: + return $this->getParent(); + break; + case 17: + return $this->getCreatedAt(); + break; + case 18: return $this->getUpdatedAt(); break; default: @@ -1370,15 +1753,22 @@ abstract class OrderProduct implements ActiveRecordInterface $keys[0] => $this->getId(), $keys[1] => $this->getOrderId(), $keys[2] => $this->getProductRef(), - $keys[3] => $this->getTitle(), - $keys[4] => $this->getDescription(), + $keys[3] => $this->getProductSaleElementsRef(), + $keys[4] => $this->getTitle(), $keys[5] => $this->getChapo(), - $keys[6] => $this->getQuantity(), - $keys[7] => $this->getPrice(), - $keys[8] => $this->getTax(), - $keys[9] => $this->getParent(), - $keys[10] => $this->getCreatedAt(), - $keys[11] => $this->getUpdatedAt(), + $keys[6] => $this->getDescription(), + $keys[7] => $this->getPostscriptum(), + $keys[8] => $this->getQuantity(), + $keys[9] => $this->getPrice(), + $keys[10] => $this->getPromoPrice(), + $keys[11] => $this->getWasNew(), + $keys[12] => $this->getWasInPromo(), + $keys[13] => $this->getWeight(), + $keys[14] => $this->getTaxRuleTitle(), + $keys[15] => $this->getTaxRuleDescription(), + $keys[16] => $this->getParent(), + $keys[17] => $this->getCreatedAt(), + $keys[18] => $this->getUpdatedAt(), ); $virtualColumns = $this->virtualColumns; foreach($virtualColumns as $key => $virtualColumn) @@ -1390,8 +1780,11 @@ abstract class OrderProduct implements ActiveRecordInterface if (null !== $this->aOrder) { $result['Order'] = $this->aOrder->toArray($keyType, $includeLazyLoadColumns, $alreadyDumpedObjects, true); } - if (null !== $this->collOrderFeatures) { - $result['OrderFeatures'] = $this->collOrderFeatures->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); + if (null !== $this->collOrderProductAttributeCombinations) { + $result['OrderProductAttributeCombinations'] = $this->collOrderProductAttributeCombinations->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); + } + if (null !== $this->collOrderProductTaxes) { + $result['OrderProductTaxes'] = $this->collOrderProductTaxes->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); } } @@ -1437,30 +1830,51 @@ abstract class OrderProduct implements ActiveRecordInterface $this->setProductRef($value); break; case 3: - $this->setTitle($value); + $this->setProductSaleElementsRef($value); break; case 4: - $this->setDescription($value); + $this->setTitle($value); break; case 5: $this->setChapo($value); break; case 6: - $this->setQuantity($value); + $this->setDescription($value); break; case 7: - $this->setPrice($value); + $this->setPostscriptum($value); break; case 8: - $this->setTax($value); + $this->setQuantity($value); break; case 9: - $this->setParent($value); + $this->setPrice($value); break; case 10: - $this->setCreatedAt($value); + $this->setPromoPrice($value); break; case 11: + $this->setWasNew($value); + break; + case 12: + $this->setWasInPromo($value); + break; + case 13: + $this->setWeight($value); + break; + case 14: + $this->setTaxRuleTitle($value); + break; + case 15: + $this->setTaxRuleDescription($value); + break; + case 16: + $this->setParent($value); + break; + case 17: + $this->setCreatedAt($value); + break; + case 18: $this->setUpdatedAt($value); break; } // switch() @@ -1490,15 +1904,22 @@ abstract class OrderProduct implements ActiveRecordInterface if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]); if (array_key_exists($keys[1], $arr)) $this->setOrderId($arr[$keys[1]]); if (array_key_exists($keys[2], $arr)) $this->setProductRef($arr[$keys[2]]); - if (array_key_exists($keys[3], $arr)) $this->setTitle($arr[$keys[3]]); - if (array_key_exists($keys[4], $arr)) $this->setDescription($arr[$keys[4]]); + if (array_key_exists($keys[3], $arr)) $this->setProductSaleElementsRef($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setTitle($arr[$keys[4]]); if (array_key_exists($keys[5], $arr)) $this->setChapo($arr[$keys[5]]); - if (array_key_exists($keys[6], $arr)) $this->setQuantity($arr[$keys[6]]); - if (array_key_exists($keys[7], $arr)) $this->setPrice($arr[$keys[7]]); - if (array_key_exists($keys[8], $arr)) $this->setTax($arr[$keys[8]]); - if (array_key_exists($keys[9], $arr)) $this->setParent($arr[$keys[9]]); - if (array_key_exists($keys[10], $arr)) $this->setCreatedAt($arr[$keys[10]]); - if (array_key_exists($keys[11], $arr)) $this->setUpdatedAt($arr[$keys[11]]); + if (array_key_exists($keys[6], $arr)) $this->setDescription($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setPostscriptum($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setQuantity($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setPrice($arr[$keys[9]]); + if (array_key_exists($keys[10], $arr)) $this->setPromoPrice($arr[$keys[10]]); + if (array_key_exists($keys[11], $arr)) $this->setWasNew($arr[$keys[11]]); + if (array_key_exists($keys[12], $arr)) $this->setWasInPromo($arr[$keys[12]]); + if (array_key_exists($keys[13], $arr)) $this->setWeight($arr[$keys[13]]); + if (array_key_exists($keys[14], $arr)) $this->setTaxRuleTitle($arr[$keys[14]]); + if (array_key_exists($keys[15], $arr)) $this->setTaxRuleDescription($arr[$keys[15]]); + if (array_key_exists($keys[16], $arr)) $this->setParent($arr[$keys[16]]); + if (array_key_exists($keys[17], $arr)) $this->setCreatedAt($arr[$keys[17]]); + if (array_key_exists($keys[18], $arr)) $this->setUpdatedAt($arr[$keys[18]]); } /** @@ -1513,12 +1934,19 @@ abstract class OrderProduct implements ActiveRecordInterface if ($this->isColumnModified(OrderProductTableMap::ID)) $criteria->add(OrderProductTableMap::ID, $this->id); if ($this->isColumnModified(OrderProductTableMap::ORDER_ID)) $criteria->add(OrderProductTableMap::ORDER_ID, $this->order_id); if ($this->isColumnModified(OrderProductTableMap::PRODUCT_REF)) $criteria->add(OrderProductTableMap::PRODUCT_REF, $this->product_ref); + if ($this->isColumnModified(OrderProductTableMap::PRODUCT_SALE_ELEMENTS_REF)) $criteria->add(OrderProductTableMap::PRODUCT_SALE_ELEMENTS_REF, $this->product_sale_elements_ref); if ($this->isColumnModified(OrderProductTableMap::TITLE)) $criteria->add(OrderProductTableMap::TITLE, $this->title); - if ($this->isColumnModified(OrderProductTableMap::DESCRIPTION)) $criteria->add(OrderProductTableMap::DESCRIPTION, $this->description); if ($this->isColumnModified(OrderProductTableMap::CHAPO)) $criteria->add(OrderProductTableMap::CHAPO, $this->chapo); + if ($this->isColumnModified(OrderProductTableMap::DESCRIPTION)) $criteria->add(OrderProductTableMap::DESCRIPTION, $this->description); + if ($this->isColumnModified(OrderProductTableMap::POSTSCRIPTUM)) $criteria->add(OrderProductTableMap::POSTSCRIPTUM, $this->postscriptum); if ($this->isColumnModified(OrderProductTableMap::QUANTITY)) $criteria->add(OrderProductTableMap::QUANTITY, $this->quantity); if ($this->isColumnModified(OrderProductTableMap::PRICE)) $criteria->add(OrderProductTableMap::PRICE, $this->price); - if ($this->isColumnModified(OrderProductTableMap::TAX)) $criteria->add(OrderProductTableMap::TAX, $this->tax); + if ($this->isColumnModified(OrderProductTableMap::PROMO_PRICE)) $criteria->add(OrderProductTableMap::PROMO_PRICE, $this->promo_price); + if ($this->isColumnModified(OrderProductTableMap::WAS_NEW)) $criteria->add(OrderProductTableMap::WAS_NEW, $this->was_new); + if ($this->isColumnModified(OrderProductTableMap::WAS_IN_PROMO)) $criteria->add(OrderProductTableMap::WAS_IN_PROMO, $this->was_in_promo); + if ($this->isColumnModified(OrderProductTableMap::WEIGHT)) $criteria->add(OrderProductTableMap::WEIGHT, $this->weight); + if ($this->isColumnModified(OrderProductTableMap::TAX_RULE_TITLE)) $criteria->add(OrderProductTableMap::TAX_RULE_TITLE, $this->tax_rule_title); + if ($this->isColumnModified(OrderProductTableMap::TAX_RULE_DESCRIPTION)) $criteria->add(OrderProductTableMap::TAX_RULE_DESCRIPTION, $this->tax_rule_description); if ($this->isColumnModified(OrderProductTableMap::PARENT)) $criteria->add(OrderProductTableMap::PARENT, $this->parent); if ($this->isColumnModified(OrderProductTableMap::CREATED_AT)) $criteria->add(OrderProductTableMap::CREATED_AT, $this->created_at); if ($this->isColumnModified(OrderProductTableMap::UPDATED_AT)) $criteria->add(OrderProductTableMap::UPDATED_AT, $this->updated_at); @@ -1587,12 +2015,19 @@ abstract class OrderProduct implements ActiveRecordInterface { $copyObj->setOrderId($this->getOrderId()); $copyObj->setProductRef($this->getProductRef()); + $copyObj->setProductSaleElementsRef($this->getProductSaleElementsRef()); $copyObj->setTitle($this->getTitle()); - $copyObj->setDescription($this->getDescription()); $copyObj->setChapo($this->getChapo()); + $copyObj->setDescription($this->getDescription()); + $copyObj->setPostscriptum($this->getPostscriptum()); $copyObj->setQuantity($this->getQuantity()); $copyObj->setPrice($this->getPrice()); - $copyObj->setTax($this->getTax()); + $copyObj->setPromoPrice($this->getPromoPrice()); + $copyObj->setWasNew($this->getWasNew()); + $copyObj->setWasInPromo($this->getWasInPromo()); + $copyObj->setWeight($this->getWeight()); + $copyObj->setTaxRuleTitle($this->getTaxRuleTitle()); + $copyObj->setTaxRuleDescription($this->getTaxRuleDescription()); $copyObj->setParent($this->getParent()); $copyObj->setCreatedAt($this->getCreatedAt()); $copyObj->setUpdatedAt($this->getUpdatedAt()); @@ -1602,9 +2037,15 @@ abstract class OrderProduct implements ActiveRecordInterface // the getter/setter methods for fkey referrer objects. $copyObj->setNew(false); - foreach ($this->getOrderFeatures() as $relObj) { + foreach ($this->getOrderProductAttributeCombinations() as $relObj) { if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves - $copyObj->addOrderFeature($relObj->copy($deepCopy)); + $copyObj->addOrderProductAttributeCombination($relObj->copy($deepCopy)); + } + } + + foreach ($this->getOrderProductTaxes() as $relObj) { + if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves + $copyObj->addOrderProductTax($relObj->copy($deepCopy)); } } @@ -1700,37 +2141,40 @@ abstract class OrderProduct implements ActiveRecordInterface */ public function initRelation($relationName) { - if ('OrderFeature' == $relationName) { - return $this->initOrderFeatures(); + if ('OrderProductAttributeCombination' == $relationName) { + return $this->initOrderProductAttributeCombinations(); + } + if ('OrderProductTax' == $relationName) { + return $this->initOrderProductTaxes(); } } /** - * Clears out the collOrderFeatures collection + * Clears out the collOrderProductAttributeCombinations collection * * This does not modify the database; however, it will remove any associated objects, causing * them to be refetched by subsequent calls to accessor method. * * @return void - * @see addOrderFeatures() + * @see addOrderProductAttributeCombinations() */ - public function clearOrderFeatures() + public function clearOrderProductAttributeCombinations() { - $this->collOrderFeatures = null; // important to set this to NULL since that means it is uninitialized + $this->collOrderProductAttributeCombinations = null; // important to set this to NULL since that means it is uninitialized } /** - * Reset is the collOrderFeatures collection loaded partially. + * Reset is the collOrderProductAttributeCombinations collection loaded partially. */ - public function resetPartialOrderFeatures($v = true) + public function resetPartialOrderProductAttributeCombinations($v = true) { - $this->collOrderFeaturesPartial = $v; + $this->collOrderProductAttributeCombinationsPartial = $v; } /** - * Initializes the collOrderFeatures collection. + * Initializes the collOrderProductAttributeCombinations collection. * - * By default this just sets the collOrderFeatures collection to an empty array (like clearcollOrderFeatures()); + * By default this just sets the collOrderProductAttributeCombinations collection to an empty array (like clearcollOrderProductAttributeCombinations()); * however, you may wish to override this method in your stub class to provide setting appropriate * to your application -- for example, setting the initial array to the values stored in database. * @@ -1739,17 +2183,17 @@ abstract class OrderProduct implements ActiveRecordInterface * * @return void */ - public function initOrderFeatures($overrideExisting = true) + public function initOrderProductAttributeCombinations($overrideExisting = true) { - if (null !== $this->collOrderFeatures && !$overrideExisting) { + if (null !== $this->collOrderProductAttributeCombinations && !$overrideExisting) { return; } - $this->collOrderFeatures = new ObjectCollection(); - $this->collOrderFeatures->setModel('\Thelia\Model\OrderFeature'); + $this->collOrderProductAttributeCombinations = new ObjectCollection(); + $this->collOrderProductAttributeCombinations->setModel('\Thelia\Model\OrderProductAttributeCombination'); } /** - * Gets an array of ChildOrderFeature objects which contain a foreign key that references this object. + * Gets an array of ChildOrderProductAttributeCombination objects which contain a foreign key that references this object. * * If the $criteria is not null, it is used to always fetch the results from the database. * Otherwise the results are fetched from the database the first time, then cached. @@ -1759,109 +2203,109 @@ abstract class OrderProduct implements ActiveRecordInterface * * @param Criteria $criteria optional Criteria object to narrow the query * @param ConnectionInterface $con optional connection object - * @return Collection|ChildOrderFeature[] List of ChildOrderFeature objects + * @return Collection|ChildOrderProductAttributeCombination[] List of ChildOrderProductAttributeCombination objects * @throws PropelException */ - public function getOrderFeatures($criteria = null, ConnectionInterface $con = null) + public function getOrderProductAttributeCombinations($criteria = null, ConnectionInterface $con = null) { - $partial = $this->collOrderFeaturesPartial && !$this->isNew(); - if (null === $this->collOrderFeatures || null !== $criteria || $partial) { - if ($this->isNew() && null === $this->collOrderFeatures) { + $partial = $this->collOrderProductAttributeCombinationsPartial && !$this->isNew(); + if (null === $this->collOrderProductAttributeCombinations || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collOrderProductAttributeCombinations) { // return empty collection - $this->initOrderFeatures(); + $this->initOrderProductAttributeCombinations(); } else { - $collOrderFeatures = ChildOrderFeatureQuery::create(null, $criteria) + $collOrderProductAttributeCombinations = ChildOrderProductAttributeCombinationQuery::create(null, $criteria) ->filterByOrderProduct($this) ->find($con); if (null !== $criteria) { - if (false !== $this->collOrderFeaturesPartial && count($collOrderFeatures)) { - $this->initOrderFeatures(false); + if (false !== $this->collOrderProductAttributeCombinationsPartial && count($collOrderProductAttributeCombinations)) { + $this->initOrderProductAttributeCombinations(false); - foreach ($collOrderFeatures as $obj) { - if (false == $this->collOrderFeatures->contains($obj)) { - $this->collOrderFeatures->append($obj); + foreach ($collOrderProductAttributeCombinations as $obj) { + if (false == $this->collOrderProductAttributeCombinations->contains($obj)) { + $this->collOrderProductAttributeCombinations->append($obj); } } - $this->collOrderFeaturesPartial = true; + $this->collOrderProductAttributeCombinationsPartial = true; } - $collOrderFeatures->getInternalIterator()->rewind(); + $collOrderProductAttributeCombinations->getInternalIterator()->rewind(); - return $collOrderFeatures; + return $collOrderProductAttributeCombinations; } - if ($partial && $this->collOrderFeatures) { - foreach ($this->collOrderFeatures as $obj) { + if ($partial && $this->collOrderProductAttributeCombinations) { + foreach ($this->collOrderProductAttributeCombinations as $obj) { if ($obj->isNew()) { - $collOrderFeatures[] = $obj; + $collOrderProductAttributeCombinations[] = $obj; } } } - $this->collOrderFeatures = $collOrderFeatures; - $this->collOrderFeaturesPartial = false; + $this->collOrderProductAttributeCombinations = $collOrderProductAttributeCombinations; + $this->collOrderProductAttributeCombinationsPartial = false; } } - return $this->collOrderFeatures; + return $this->collOrderProductAttributeCombinations; } /** - * Sets a collection of OrderFeature objects related by a one-to-many relationship + * Sets a collection of OrderProductAttributeCombination objects related by a one-to-many relationship * to the current object. * It will also schedule objects for deletion based on a diff between old objects (aka persisted) * and new objects from the given Propel collection. * - * @param Collection $orderFeatures A Propel collection. + * @param Collection $orderProductAttributeCombinations A Propel collection. * @param ConnectionInterface $con Optional connection object * @return ChildOrderProduct The current object (for fluent API support) */ - public function setOrderFeatures(Collection $orderFeatures, ConnectionInterface $con = null) + public function setOrderProductAttributeCombinations(Collection $orderProductAttributeCombinations, ConnectionInterface $con = null) { - $orderFeaturesToDelete = $this->getOrderFeatures(new Criteria(), $con)->diff($orderFeatures); + $orderProductAttributeCombinationsToDelete = $this->getOrderProductAttributeCombinations(new Criteria(), $con)->diff($orderProductAttributeCombinations); - $this->orderFeaturesScheduledForDeletion = $orderFeaturesToDelete; + $this->orderProductAttributeCombinationsScheduledForDeletion = $orderProductAttributeCombinationsToDelete; - foreach ($orderFeaturesToDelete as $orderFeatureRemoved) { - $orderFeatureRemoved->setOrderProduct(null); + foreach ($orderProductAttributeCombinationsToDelete as $orderProductAttributeCombinationRemoved) { + $orderProductAttributeCombinationRemoved->setOrderProduct(null); } - $this->collOrderFeatures = null; - foreach ($orderFeatures as $orderFeature) { - $this->addOrderFeature($orderFeature); + $this->collOrderProductAttributeCombinations = null; + foreach ($orderProductAttributeCombinations as $orderProductAttributeCombination) { + $this->addOrderProductAttributeCombination($orderProductAttributeCombination); } - $this->collOrderFeatures = $orderFeatures; - $this->collOrderFeaturesPartial = false; + $this->collOrderProductAttributeCombinations = $orderProductAttributeCombinations; + $this->collOrderProductAttributeCombinationsPartial = false; return $this; } /** - * Returns the number of related OrderFeature objects. + * Returns the number of related OrderProductAttributeCombination objects. * * @param Criteria $criteria * @param boolean $distinct * @param ConnectionInterface $con - * @return int Count of related OrderFeature objects. + * @return int Count of related OrderProductAttributeCombination objects. * @throws PropelException */ - public function countOrderFeatures(Criteria $criteria = null, $distinct = false, ConnectionInterface $con = null) + public function countOrderProductAttributeCombinations(Criteria $criteria = null, $distinct = false, ConnectionInterface $con = null) { - $partial = $this->collOrderFeaturesPartial && !$this->isNew(); - if (null === $this->collOrderFeatures || null !== $criteria || $partial) { - if ($this->isNew() && null === $this->collOrderFeatures) { + $partial = $this->collOrderProductAttributeCombinationsPartial && !$this->isNew(); + if (null === $this->collOrderProductAttributeCombinations || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collOrderProductAttributeCombinations) { return 0; } if ($partial && !$criteria) { - return count($this->getOrderFeatures()); + return count($this->getOrderProductAttributeCombinations()); } - $query = ChildOrderFeatureQuery::create(null, $criteria); + $query = ChildOrderProductAttributeCombinationQuery::create(null, $criteria); if ($distinct) { $query->distinct(); } @@ -1871,53 +2315,271 @@ abstract class OrderProduct implements ActiveRecordInterface ->count($con); } - return count($this->collOrderFeatures); + return count($this->collOrderProductAttributeCombinations); } /** - * Method called to associate a ChildOrderFeature object to this object - * through the ChildOrderFeature foreign key attribute. + * Method called to associate a ChildOrderProductAttributeCombination object to this object + * through the ChildOrderProductAttributeCombination foreign key attribute. * - * @param ChildOrderFeature $l ChildOrderFeature + * @param ChildOrderProductAttributeCombination $l ChildOrderProductAttributeCombination * @return \Thelia\Model\OrderProduct The current object (for fluent API support) */ - public function addOrderFeature(ChildOrderFeature $l) + public function addOrderProductAttributeCombination(ChildOrderProductAttributeCombination $l) { - if ($this->collOrderFeatures === null) { - $this->initOrderFeatures(); - $this->collOrderFeaturesPartial = true; + if ($this->collOrderProductAttributeCombinations === null) { + $this->initOrderProductAttributeCombinations(); + $this->collOrderProductAttributeCombinationsPartial = true; } - if (!in_array($l, $this->collOrderFeatures->getArrayCopy(), true)) { // only add it if the **same** object is not already associated - $this->doAddOrderFeature($l); + if (!in_array($l, $this->collOrderProductAttributeCombinations->getArrayCopy(), true)) { // only add it if the **same** object is not already associated + $this->doAddOrderProductAttributeCombination($l); } return $this; } /** - * @param OrderFeature $orderFeature The orderFeature object to add. + * @param OrderProductAttributeCombination $orderProductAttributeCombination The orderProductAttributeCombination object to add. */ - protected function doAddOrderFeature($orderFeature) + protected function doAddOrderProductAttributeCombination($orderProductAttributeCombination) { - $this->collOrderFeatures[]= $orderFeature; - $orderFeature->setOrderProduct($this); + $this->collOrderProductAttributeCombinations[]= $orderProductAttributeCombination; + $orderProductAttributeCombination->setOrderProduct($this); } /** - * @param OrderFeature $orderFeature The orderFeature object to remove. + * @param OrderProductAttributeCombination $orderProductAttributeCombination The orderProductAttributeCombination object to remove. * @return ChildOrderProduct The current object (for fluent API support) */ - public function removeOrderFeature($orderFeature) + public function removeOrderProductAttributeCombination($orderProductAttributeCombination) { - if ($this->getOrderFeatures()->contains($orderFeature)) { - $this->collOrderFeatures->remove($this->collOrderFeatures->search($orderFeature)); - if (null === $this->orderFeaturesScheduledForDeletion) { - $this->orderFeaturesScheduledForDeletion = clone $this->collOrderFeatures; - $this->orderFeaturesScheduledForDeletion->clear(); + if ($this->getOrderProductAttributeCombinations()->contains($orderProductAttributeCombination)) { + $this->collOrderProductAttributeCombinations->remove($this->collOrderProductAttributeCombinations->search($orderProductAttributeCombination)); + if (null === $this->orderProductAttributeCombinationsScheduledForDeletion) { + $this->orderProductAttributeCombinationsScheduledForDeletion = clone $this->collOrderProductAttributeCombinations; + $this->orderProductAttributeCombinationsScheduledForDeletion->clear(); } - $this->orderFeaturesScheduledForDeletion[]= clone $orderFeature; - $orderFeature->setOrderProduct(null); + $this->orderProductAttributeCombinationsScheduledForDeletion[]= clone $orderProductAttributeCombination; + $orderProductAttributeCombination->setOrderProduct(null); + } + + return $this; + } + + /** + * Clears out the collOrderProductTaxes collection + * + * This does not modify the database; however, it will remove any associated objects, causing + * them to be refetched by subsequent calls to accessor method. + * + * @return void + * @see addOrderProductTaxes() + */ + public function clearOrderProductTaxes() + { + $this->collOrderProductTaxes = null; // important to set this to NULL since that means it is uninitialized + } + + /** + * Reset is the collOrderProductTaxes collection loaded partially. + */ + public function resetPartialOrderProductTaxes($v = true) + { + $this->collOrderProductTaxesPartial = $v; + } + + /** + * Initializes the collOrderProductTaxes collection. + * + * By default this just sets the collOrderProductTaxes collection to an empty array (like clearcollOrderProductTaxes()); + * however, you may wish to override this method in your stub class to provide setting appropriate + * to your application -- for example, setting the initial array to the values stored in database. + * + * @param boolean $overrideExisting If set to true, the method call initializes + * the collection even if it is not empty + * + * @return void + */ + public function initOrderProductTaxes($overrideExisting = true) + { + if (null !== $this->collOrderProductTaxes && !$overrideExisting) { + return; + } + $this->collOrderProductTaxes = new ObjectCollection(); + $this->collOrderProductTaxes->setModel('\Thelia\Model\OrderProductTax'); + } + + /** + * Gets an array of ChildOrderProductTax objects which contain a foreign key that references this object. + * + * If the $criteria is not null, it is used to always fetch the results from the database. + * Otherwise the results are fetched from the database the first time, then cached. + * Next time the same method is called without $criteria, the cached collection is returned. + * If this ChildOrderProduct is new, it will return + * an empty collection or the current collection; the criteria is ignored on a new object. + * + * @param Criteria $criteria optional Criteria object to narrow the query + * @param ConnectionInterface $con optional connection object + * @return Collection|ChildOrderProductTax[] List of ChildOrderProductTax objects + * @throws PropelException + */ + public function getOrderProductTaxes($criteria = null, ConnectionInterface $con = null) + { + $partial = $this->collOrderProductTaxesPartial && !$this->isNew(); + if (null === $this->collOrderProductTaxes || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collOrderProductTaxes) { + // return empty collection + $this->initOrderProductTaxes(); + } else { + $collOrderProductTaxes = ChildOrderProductTaxQuery::create(null, $criteria) + ->filterByOrderProduct($this) + ->find($con); + + if (null !== $criteria) { + if (false !== $this->collOrderProductTaxesPartial && count($collOrderProductTaxes)) { + $this->initOrderProductTaxes(false); + + foreach ($collOrderProductTaxes as $obj) { + if (false == $this->collOrderProductTaxes->contains($obj)) { + $this->collOrderProductTaxes->append($obj); + } + } + + $this->collOrderProductTaxesPartial = true; + } + + $collOrderProductTaxes->getInternalIterator()->rewind(); + + return $collOrderProductTaxes; + } + + if ($partial && $this->collOrderProductTaxes) { + foreach ($this->collOrderProductTaxes as $obj) { + if ($obj->isNew()) { + $collOrderProductTaxes[] = $obj; + } + } + } + + $this->collOrderProductTaxes = $collOrderProductTaxes; + $this->collOrderProductTaxesPartial = false; + } + } + + return $this->collOrderProductTaxes; + } + + /** + * Sets a collection of OrderProductTax objects related by a one-to-many relationship + * to the current object. + * It will also schedule objects for deletion based on a diff between old objects (aka persisted) + * and new objects from the given Propel collection. + * + * @param Collection $orderProductTaxes A Propel collection. + * @param ConnectionInterface $con Optional connection object + * @return ChildOrderProduct The current object (for fluent API support) + */ + public function setOrderProductTaxes(Collection $orderProductTaxes, ConnectionInterface $con = null) + { + $orderProductTaxesToDelete = $this->getOrderProductTaxes(new Criteria(), $con)->diff($orderProductTaxes); + + + $this->orderProductTaxesScheduledForDeletion = $orderProductTaxesToDelete; + + foreach ($orderProductTaxesToDelete as $orderProductTaxRemoved) { + $orderProductTaxRemoved->setOrderProduct(null); + } + + $this->collOrderProductTaxes = null; + foreach ($orderProductTaxes as $orderProductTax) { + $this->addOrderProductTax($orderProductTax); + } + + $this->collOrderProductTaxes = $orderProductTaxes; + $this->collOrderProductTaxesPartial = false; + + return $this; + } + + /** + * Returns the number of related OrderProductTax objects. + * + * @param Criteria $criteria + * @param boolean $distinct + * @param ConnectionInterface $con + * @return int Count of related OrderProductTax objects. + * @throws PropelException + */ + public function countOrderProductTaxes(Criteria $criteria = null, $distinct = false, ConnectionInterface $con = null) + { + $partial = $this->collOrderProductTaxesPartial && !$this->isNew(); + if (null === $this->collOrderProductTaxes || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collOrderProductTaxes) { + return 0; + } + + if ($partial && !$criteria) { + return count($this->getOrderProductTaxes()); + } + + $query = ChildOrderProductTaxQuery::create(null, $criteria); + if ($distinct) { + $query->distinct(); + } + + return $query + ->filterByOrderProduct($this) + ->count($con); + } + + return count($this->collOrderProductTaxes); + } + + /** + * Method called to associate a ChildOrderProductTax object to this object + * through the ChildOrderProductTax foreign key attribute. + * + * @param ChildOrderProductTax $l ChildOrderProductTax + * @return \Thelia\Model\OrderProduct The current object (for fluent API support) + */ + public function addOrderProductTax(ChildOrderProductTax $l) + { + if ($this->collOrderProductTaxes === null) { + $this->initOrderProductTaxes(); + $this->collOrderProductTaxesPartial = true; + } + + if (!in_array($l, $this->collOrderProductTaxes->getArrayCopy(), true)) { // only add it if the **same** object is not already associated + $this->doAddOrderProductTax($l); + } + + return $this; + } + + /** + * @param OrderProductTax $orderProductTax The orderProductTax object to add. + */ + protected function doAddOrderProductTax($orderProductTax) + { + $this->collOrderProductTaxes[]= $orderProductTax; + $orderProductTax->setOrderProduct($this); + } + + /** + * @param OrderProductTax $orderProductTax The orderProductTax object to remove. + * @return ChildOrderProduct The current object (for fluent API support) + */ + public function removeOrderProductTax($orderProductTax) + { + if ($this->getOrderProductTaxes()->contains($orderProductTax)) { + $this->collOrderProductTaxes->remove($this->collOrderProductTaxes->search($orderProductTax)); + if (null === $this->orderProductTaxesScheduledForDeletion) { + $this->orderProductTaxesScheduledForDeletion = clone $this->collOrderProductTaxes; + $this->orderProductTaxesScheduledForDeletion->clear(); + } + $this->orderProductTaxesScheduledForDeletion[]= clone $orderProductTax; + $orderProductTax->setOrderProduct(null); } return $this; @@ -1931,12 +2593,19 @@ abstract class OrderProduct implements ActiveRecordInterface $this->id = null; $this->order_id = null; $this->product_ref = null; + $this->product_sale_elements_ref = null; $this->title = null; - $this->description = null; $this->chapo = null; + $this->description = null; + $this->postscriptum = null; $this->quantity = null; $this->price = null; - $this->tax = null; + $this->promo_price = null; + $this->was_new = null; + $this->was_in_promo = null; + $this->weight = null; + $this->tax_rule_title = null; + $this->tax_rule_description = null; $this->parent = null; $this->created_at = null; $this->updated_at = null; @@ -1959,17 +2628,26 @@ abstract class OrderProduct implements ActiveRecordInterface public function clearAllReferences($deep = false) { if ($deep) { - if ($this->collOrderFeatures) { - foreach ($this->collOrderFeatures as $o) { + if ($this->collOrderProductAttributeCombinations) { + foreach ($this->collOrderProductAttributeCombinations as $o) { + $o->clearAllReferences($deep); + } + } + if ($this->collOrderProductTaxes) { + foreach ($this->collOrderProductTaxes as $o) { $o->clearAllReferences($deep); } } } // if ($deep) - if ($this->collOrderFeatures instanceof Collection) { - $this->collOrderFeatures->clearIterator(); + if ($this->collOrderProductAttributeCombinations instanceof Collection) { + $this->collOrderProductAttributeCombinations->clearIterator(); } - $this->collOrderFeatures = null; + $this->collOrderProductAttributeCombinations = null; + if ($this->collOrderProductTaxes instanceof Collection) { + $this->collOrderProductTaxes->clearIterator(); + } + $this->collOrderProductTaxes = null; $this->aOrder = null; } diff --git a/core/lib/Thelia/Model/Base/OrderProductAttributeCombination.php b/core/lib/Thelia/Model/Base/OrderProductAttributeCombination.php new file mode 100644 index 000000000..e02bc9cc5 --- /dev/null +++ b/core/lib/Thelia/Model/Base/OrderProductAttributeCombination.php @@ -0,0 +1,1824 @@ +modifiedColumns); + } + + /** + * Has specified column been modified? + * + * @param string $col column fully qualified name (TableMap::TYPE_COLNAME), e.g. Book::AUTHOR_ID + * @return boolean True if $col has been modified. + */ + public function isColumnModified($col) + { + return in_array($col, $this->modifiedColumns); + } + + /** + * Get the columns that have been modified in this object. + * @return array A unique list of the modified column names for this object. + */ + public function getModifiedColumns() + { + return array_unique($this->modifiedColumns); + } + + /** + * Returns whether the object has ever been saved. This will + * be false, if the object was retrieved from storage or was created + * and then saved. + * + * @return true, if the object has never been persisted. + */ + public function isNew() + { + return $this->new; + } + + /** + * Setter for the isNew attribute. This method will be called + * by Propel-generated children and objects. + * + * @param boolean $b the state of the object. + */ + public function setNew($b) + { + $this->new = (Boolean) $b; + } + + /** + * Whether this object has been deleted. + * @return boolean The deleted state of this object. + */ + public function isDeleted() + { + return $this->deleted; + } + + /** + * Specify whether this object has been deleted. + * @param boolean $b The deleted state of this object. + * @return void + */ + public function setDeleted($b) + { + $this->deleted = (Boolean) $b; + } + + /** + * Sets the modified state for the object to be false. + * @param string $col If supplied, only the specified column is reset. + * @return void + */ + public function resetModified($col = null) + { + if (null !== $col) { + while (false !== ($offset = array_search($col, $this->modifiedColumns))) { + array_splice($this->modifiedColumns, $offset, 1); + } + } else { + $this->modifiedColumns = array(); + } + } + + /** + * Compares this with another OrderProductAttributeCombination instance. If + * obj is an instance of OrderProductAttributeCombination, delegates to + * equals(OrderProductAttributeCombination). Otherwise, returns false. + * + * @param obj The object to compare to. + * @return Whether equal to the object specified. + */ + public function equals($obj) + { + $thisclazz = get_class($this); + if (!is_object($obj) || !($obj instanceof $thisclazz)) { + return false; + } + + if ($this === $obj) { + return true; + } + + if (null === $this->getPrimaryKey() + || null === $obj->getPrimaryKey()) { + return false; + } + + return $this->getPrimaryKey() === $obj->getPrimaryKey(); + } + + /** + * If the primary key is not null, return the hashcode of the + * primary key. Otherwise, return the hash code of the object. + * + * @return int Hashcode + */ + public function hashCode() + { + if (null !== $this->getPrimaryKey()) { + return crc32(serialize($this->getPrimaryKey())); + } + + return crc32(serialize(clone $this)); + } + + /** + * Get the associative array of the virtual columns in this object + * + * @param string $name The virtual column name + * + * @return array + */ + public function getVirtualColumns() + { + return $this->virtualColumns; + } + + /** + * Checks the existence of a virtual column in this object + * + * @return boolean + */ + public function hasVirtualColumn($name) + { + return array_key_exists($name, $this->virtualColumns); + } + + /** + * Get the value of a virtual column in this object + * + * @return mixed + */ + public function getVirtualColumn($name) + { + if (!$this->hasVirtualColumn($name)) { + throw new PropelException(sprintf('Cannot get value of inexistent virtual column %s.', $name)); + } + + return $this->virtualColumns[$name]; + } + + /** + * Set the value of a virtual column in this object + * + * @param string $name The virtual column name + * @param mixed $value The value to give to the virtual column + * + * @return OrderProductAttributeCombination The current object, for fluid interface + */ + public function setVirtualColumn($name, $value) + { + $this->virtualColumns[$name] = $value; + + return $this; + } + + /** + * Logs a message using Propel::log(). + * + * @param string $msg + * @param int $priority One of the Propel::LOG_* logging levels + * @return boolean + */ + protected function log($msg, $priority = Propel::LOG_INFO) + { + return Propel::log(get_class($this) . ': ' . $msg, $priority); + } + + /** + * Populate the current object from a string, using a given parser format + * + * $book = new Book(); + * $book->importFrom('JSON', '{"Id":9012,"Title":"Don Juan","ISBN":"0140422161","Price":12.99,"PublisherId":1234,"AuthorId":5678}'); + * + * + * @param mixed $parser A AbstractParser instance, + * or a format name ('XML', 'YAML', 'JSON', 'CSV') + * @param string $data The source data to import from + * + * @return OrderProductAttributeCombination The current object, for fluid interface + */ + public function importFrom($parser, $data) + { + if (!$parser instanceof AbstractParser) { + $parser = AbstractParser::getParser($parser); + } + + return $this->fromArray($parser->toArray($data), TableMap::TYPE_PHPNAME); + } + + /** + * Export the current object properties to a string, using a given parser format + * + * $book = BookQuery::create()->findPk(9012); + * echo $book->exportTo('JSON'); + * => {"Id":9012,"Title":"Don Juan","ISBN":"0140422161","Price":12.99,"PublisherId":1234,"AuthorId":5678}'); + * + * + * @param mixed $parser A AbstractParser instance, or a format name ('XML', 'YAML', 'JSON', 'CSV') + * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy load(ed) columns. Defaults to TRUE. + * @return string The exported data + */ + public function exportTo($parser, $includeLazyLoadColumns = true) + { + if (!$parser instanceof AbstractParser) { + $parser = AbstractParser::getParser($parser); + } + + return $parser->fromArray($this->toArray(TableMap::TYPE_PHPNAME, $includeLazyLoadColumns, array(), true)); + } + + /** + * Clean up internal collections prior to serializing + * Avoids recursive loops that turn into segmentation faults when serializing + */ + public function __sleep() + { + $this->clearAllReferences(); + + return array_keys(get_object_vars($this)); + } + + /** + * Get the [id] column value. + * + * @return int + */ + public function getId() + { + + return $this->id; + } + + /** + * Get the [order_product_id] column value. + * + * @return int + */ + public function getOrderProductId() + { + + return $this->order_product_id; + } + + /** + * Get the [attribute_title] column value. + * + * @return string + */ + public function getAttributeTitle() + { + + return $this->attribute_title; + } + + /** + * Get the [attribute_chapo] column value. + * + * @return string + */ + public function getAttributeChapo() + { + + return $this->attribute_chapo; + } + + /** + * Get the [attribute_description] column value. + * + * @return string + */ + public function getAttributeDescription() + { + + return $this->attribute_description; + } + + /** + * Get the [attribute_postscriptumn] column value. + * + * @return string + */ + public function getAttributePostscriptumn() + { + + return $this->attribute_postscriptumn; + } + + /** + * Get the [attribute_av_title] column value. + * + * @return string + */ + public function getAttributeAvTitle() + { + + return $this->attribute_av_title; + } + + /** + * Get the [attribute_av_chapo] column value. + * + * @return string + */ + public function getAttributeAvChapo() + { + + return $this->attribute_av_chapo; + } + + /** + * Get the [attribute_av_description] column value. + * + * @return string + */ + public function getAttributeAvDescription() + { + + return $this->attribute_av_description; + } + + /** + * Get the [attribute_av_postscriptum] column value. + * + * @return string + */ + public function getAttributeAvPostscriptum() + { + + return $this->attribute_av_postscriptum; + } + + /** + * Get the [optionally formatted] temporal [created_at] column value. + * + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the raw \DateTime object will be returned. + * + * @return mixed Formatted date/time value as string or \DateTime object (if format is NULL), NULL if column is NULL, and 0 if column value is 0000-00-00 00:00:00 + * + * @throws PropelException - if unable to parse/validate the date/time value. + */ + public function getCreatedAt($format = NULL) + { + if ($format === null) { + return $this->created_at; + } else { + return $this->created_at !== null ? $this->created_at->format($format) : null; + } + } + + /** + * Get the [optionally formatted] temporal [updated_at] column value. + * + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the raw \DateTime object will be returned. + * + * @return mixed Formatted date/time value as string or \DateTime object (if format is NULL), NULL if column is NULL, and 0 if column value is 0000-00-00 00:00:00 + * + * @throws PropelException - if unable to parse/validate the date/time value. + */ + public function getUpdatedAt($format = NULL) + { + if ($format === null) { + return $this->updated_at; + } else { + return $this->updated_at !== null ? $this->updated_at->format($format) : null; + } + } + + /** + * Set the value of [id] column. + * + * @param int $v new value + * @return \Thelia\Model\OrderProductAttributeCombination The current object (for fluent API support) + */ + public function setId($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->id !== $v) { + $this->id = $v; + $this->modifiedColumns[] = OrderProductAttributeCombinationTableMap::ID; + } + + + return $this; + } // setId() + + /** + * Set the value of [order_product_id] column. + * + * @param int $v new value + * @return \Thelia\Model\OrderProductAttributeCombination The current object (for fluent API support) + */ + public function setOrderProductId($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->order_product_id !== $v) { + $this->order_product_id = $v; + $this->modifiedColumns[] = OrderProductAttributeCombinationTableMap::ORDER_PRODUCT_ID; + } + + if ($this->aOrderProduct !== null && $this->aOrderProduct->getId() !== $v) { + $this->aOrderProduct = null; + } + + + return $this; + } // setOrderProductId() + + /** + * Set the value of [attribute_title] column. + * + * @param string $v new value + * @return \Thelia\Model\OrderProductAttributeCombination The current object (for fluent API support) + */ + public function setAttributeTitle($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->attribute_title !== $v) { + $this->attribute_title = $v; + $this->modifiedColumns[] = OrderProductAttributeCombinationTableMap::ATTRIBUTE_TITLE; + } + + + return $this; + } // setAttributeTitle() + + /** + * Set the value of [attribute_chapo] column. + * + * @param string $v new value + * @return \Thelia\Model\OrderProductAttributeCombination The current object (for fluent API support) + */ + public function setAttributeChapo($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->attribute_chapo !== $v) { + $this->attribute_chapo = $v; + $this->modifiedColumns[] = OrderProductAttributeCombinationTableMap::ATTRIBUTE_CHAPO; + } + + + return $this; + } // setAttributeChapo() + + /** + * Set the value of [attribute_description] column. + * + * @param string $v new value + * @return \Thelia\Model\OrderProductAttributeCombination The current object (for fluent API support) + */ + public function setAttributeDescription($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->attribute_description !== $v) { + $this->attribute_description = $v; + $this->modifiedColumns[] = OrderProductAttributeCombinationTableMap::ATTRIBUTE_DESCRIPTION; + } + + + return $this; + } // setAttributeDescription() + + /** + * Set the value of [attribute_postscriptumn] column. + * + * @param string $v new value + * @return \Thelia\Model\OrderProductAttributeCombination The current object (for fluent API support) + */ + public function setAttributePostscriptumn($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->attribute_postscriptumn !== $v) { + $this->attribute_postscriptumn = $v; + $this->modifiedColumns[] = OrderProductAttributeCombinationTableMap::ATTRIBUTE_POSTSCRIPTUMN; + } + + + return $this; + } // setAttributePostscriptumn() + + /** + * Set the value of [attribute_av_title] column. + * + * @param string $v new value + * @return \Thelia\Model\OrderProductAttributeCombination The current object (for fluent API support) + */ + public function setAttributeAvTitle($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->attribute_av_title !== $v) { + $this->attribute_av_title = $v; + $this->modifiedColumns[] = OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_TITLE; + } + + + return $this; + } // setAttributeAvTitle() + + /** + * Set the value of [attribute_av_chapo] column. + * + * @param string $v new value + * @return \Thelia\Model\OrderProductAttributeCombination The current object (for fluent API support) + */ + public function setAttributeAvChapo($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->attribute_av_chapo !== $v) { + $this->attribute_av_chapo = $v; + $this->modifiedColumns[] = OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_CHAPO; + } + + + return $this; + } // setAttributeAvChapo() + + /** + * Set the value of [attribute_av_description] column. + * + * @param string $v new value + * @return \Thelia\Model\OrderProductAttributeCombination The current object (for fluent API support) + */ + public function setAttributeAvDescription($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->attribute_av_description !== $v) { + $this->attribute_av_description = $v; + $this->modifiedColumns[] = OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_DESCRIPTION; + } + + + return $this; + } // setAttributeAvDescription() + + /** + * Set the value of [attribute_av_postscriptum] column. + * + * @param string $v new value + * @return \Thelia\Model\OrderProductAttributeCombination The current object (for fluent API support) + */ + public function setAttributeAvPostscriptum($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->attribute_av_postscriptum !== $v) { + $this->attribute_av_postscriptum = $v; + $this->modifiedColumns[] = OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_POSTSCRIPTUM; + } + + + return $this; + } // setAttributeAvPostscriptum() + + /** + * Sets the value of [created_at] column to a normalized version of the date/time value specified. + * + * @param mixed $v string, integer (timestamp), or \DateTime value. + * Empty strings are treated as NULL. + * @return \Thelia\Model\OrderProductAttributeCombination The current object (for fluent API support) + */ + public function setCreatedAt($v) + { + $dt = PropelDateTime::newInstance($v, null, '\DateTime'); + if ($this->created_at !== null || $dt !== null) { + if ($dt !== $this->created_at) { + $this->created_at = $dt; + $this->modifiedColumns[] = OrderProductAttributeCombinationTableMap::CREATED_AT; + } + } // if either are not null + + + return $this; + } // setCreatedAt() + + /** + * Sets the value of [updated_at] column to a normalized version of the date/time value specified. + * + * @param mixed $v string, integer (timestamp), or \DateTime value. + * Empty strings are treated as NULL. + * @return \Thelia\Model\OrderProductAttributeCombination The current object (for fluent API support) + */ + public function setUpdatedAt($v) + { + $dt = PropelDateTime::newInstance($v, null, '\DateTime'); + if ($this->updated_at !== null || $dt !== null) { + if ($dt !== $this->updated_at) { + $this->updated_at = $dt; + $this->modifiedColumns[] = OrderProductAttributeCombinationTableMap::UPDATED_AT; + } + } // if either are not null + + + return $this; + } // setUpdatedAt() + + /** + * Indicates whether the columns in this object are only set to default values. + * + * This method can be used in conjunction with isModified() to indicate whether an object is both + * modified _and_ has some values set which are non-default. + * + * @return boolean Whether the columns in this object are only been set with default values. + */ + public function hasOnlyDefaultValues() + { + // otherwise, everything was equal, so return TRUE + return true; + } // hasOnlyDefaultValues() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (0-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param array $row The row returned by DataFetcher->fetch(). + * @param int $startcol 0-based offset column which indicates which restultset column to start with. + * @param boolean $rehydrate Whether this object is being re-hydrated from the database. + * @param string $indexType The index type of $row. Mostly DataFetcher->getIndexType(). + One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate($row, $startcol = 0, $rehydrate = false, $indexType = TableMap::TYPE_NUM) + { + try { + + + $col = $row[TableMap::TYPE_NUM == $indexType ? 0 + $startcol : OrderProductAttributeCombinationTableMap::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)]; + $this->id = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 1 + $startcol : OrderProductAttributeCombinationTableMap::translateFieldName('OrderProductId', TableMap::TYPE_PHPNAME, $indexType)]; + $this->order_product_id = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : OrderProductAttributeCombinationTableMap::translateFieldName('AttributeTitle', TableMap::TYPE_PHPNAME, $indexType)]; + $this->attribute_title = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : OrderProductAttributeCombinationTableMap::translateFieldName('AttributeChapo', TableMap::TYPE_PHPNAME, $indexType)]; + $this->attribute_chapo = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : OrderProductAttributeCombinationTableMap::translateFieldName('AttributeDescription', TableMap::TYPE_PHPNAME, $indexType)]; + $this->attribute_description = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : OrderProductAttributeCombinationTableMap::translateFieldName('AttributePostscriptumn', TableMap::TYPE_PHPNAME, $indexType)]; + $this->attribute_postscriptumn = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : OrderProductAttributeCombinationTableMap::translateFieldName('AttributeAvTitle', TableMap::TYPE_PHPNAME, $indexType)]; + $this->attribute_av_title = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : OrderProductAttributeCombinationTableMap::translateFieldName('AttributeAvChapo', TableMap::TYPE_PHPNAME, $indexType)]; + $this->attribute_av_chapo = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 8 + $startcol : OrderProductAttributeCombinationTableMap::translateFieldName('AttributeAvDescription', TableMap::TYPE_PHPNAME, $indexType)]; + $this->attribute_av_description = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 9 + $startcol : OrderProductAttributeCombinationTableMap::translateFieldName('AttributeAvPostscriptum', TableMap::TYPE_PHPNAME, $indexType)]; + $this->attribute_av_postscriptum = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 10 + $startcol : OrderProductAttributeCombinationTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + if ($col === '0000-00-00 00:00:00') { + $col = null; + } + $this->created_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 11 + $startcol : OrderProductAttributeCombinationTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + if ($col === '0000-00-00 00:00:00') { + $col = null; + } + $this->updated_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; + $this->resetModified(); + + $this->setNew(false); + + if ($rehydrate) { + $this->ensureConsistency(); + } + + return $startcol + 12; // 12 = OrderProductAttributeCombinationTableMap::NUM_HYDRATE_COLUMNS. + + } catch (Exception $e) { + throw new PropelException("Error populating \Thelia\Model\OrderProductAttributeCombination object", 0, $e); + } + } + + /** + * Checks and repairs the internal consistency of the object. + * + * This method is executed after an already-instantiated object is re-hydrated + * from the database. It exists to check any foreign keys to make sure that + * the objects related to the current object are correct based on foreign key. + * + * You can override this method in the stub class, but you should always invoke + * the base method from the overridden method (i.e. parent::ensureConsistency()), + * in case your model changes. + * + * @throws PropelException + */ + public function ensureConsistency() + { + if ($this->aOrderProduct !== null && $this->order_product_id !== $this->aOrderProduct->getId()) { + $this->aOrderProduct = null; + } + } // ensureConsistency + + /** + * Reloads this object from datastore based on primary key and (optionally) resets all associated objects. + * + * This will only work if the object has been saved and has a valid primary key set. + * + * @param boolean $deep (optional) Whether to also de-associated any related objects. + * @param ConnectionInterface $con (optional) The ConnectionInterface connection to use. + * @return void + * @throws PropelException - if this object is deleted, unsaved or doesn't have pk match in db + */ + public function reload($deep = false, ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("Cannot reload a deleted object."); + } + + if ($this->isNew()) { + throw new PropelException("Cannot reload an unsaved object."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getReadConnection(OrderProductAttributeCombinationTableMap::DATABASE_NAME); + } + + // We don't need to alter the object instance pool; we're just modifying this instance + // already in the pool. + + $dataFetcher = ChildOrderProductAttributeCombinationQuery::create(null, $this->buildPkeyCriteria())->setFormatter(ModelCriteria::FORMAT_STATEMENT)->find($con); + $row = $dataFetcher->fetch(); + $dataFetcher->close(); + if (!$row) { + throw new PropelException('Cannot find matching row in the database to reload object values.'); + } + $this->hydrate($row, 0, true, $dataFetcher->getIndexType()); // rehydrate + + if ($deep) { // also de-associate any related objects? + + $this->aOrderProduct = null; + } // if (deep) + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param ConnectionInterface $con + * @return void + * @throws PropelException + * @see OrderProductAttributeCombination::setDeleted() + * @see OrderProductAttributeCombination::isDeleted() + */ + public function delete(ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getWriteConnection(OrderProductAttributeCombinationTableMap::DATABASE_NAME); + } + + $con->beginTransaction(); + try { + $deleteQuery = ChildOrderProductAttributeCombinationQuery::create() + ->filterByPrimaryKey($this->getPrimaryKey()); + $ret = $this->preDelete($con); + if ($ret) { + $deleteQuery->delete($con); + $this->postDelete($con); + $con->commit(); + $this->setDeleted(true); + } else { + $con->commit(); + } + } catch (Exception $e) { + $con->rollBack(); + throw $e; + } + } + + /** + * Persists this object to the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All modified related objects will also be persisted in the doSave() + * method. This method wraps all precipitate database operations in a + * single transaction. + * + * @param ConnectionInterface $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save(ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getWriteConnection(OrderProductAttributeCombinationTableMap::DATABASE_NAME); + } + + $con->beginTransaction(); + $isInsert = $this->isNew(); + try { + $ret = $this->preSave($con); + if ($isInsert) { + $ret = $ret && $this->preInsert($con); + // timestampable behavior + if (!$this->isColumnModified(OrderProductAttributeCombinationTableMap::CREATED_AT)) { + $this->setCreatedAt(time()); + } + if (!$this->isColumnModified(OrderProductAttributeCombinationTableMap::UPDATED_AT)) { + $this->setUpdatedAt(time()); + } + } else { + $ret = $ret && $this->preUpdate($con); + // timestampable behavior + if ($this->isModified() && !$this->isColumnModified(OrderProductAttributeCombinationTableMap::UPDATED_AT)) { + $this->setUpdatedAt(time()); + } + } + if ($ret) { + $affectedRows = $this->doSave($con); + if ($isInsert) { + $this->postInsert($con); + } else { + $this->postUpdate($con); + } + $this->postSave($con); + OrderProductAttributeCombinationTableMap::addInstanceToPool($this); + } else { + $affectedRows = 0; + } + $con->commit(); + + return $affectedRows; + } catch (Exception $e) { + $con->rollBack(); + throw $e; + } + } + + /** + * Performs the work of inserting or updating the row in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param ConnectionInterface $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave(ConnectionInterface $con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + // We call the save method on the following object(s) if they + // were passed to this object by their corresponding set + // method. This object relates to these object(s) by a + // foreign key reference. + + if ($this->aOrderProduct !== null) { + if ($this->aOrderProduct->isModified() || $this->aOrderProduct->isNew()) { + $affectedRows += $this->aOrderProduct->save($con); + } + $this->setOrderProduct($this->aOrderProduct); + } + + if ($this->isNew() || $this->isModified()) { + // persist changes + if ($this->isNew()) { + $this->doInsert($con); + } else { + $this->doUpdate($con); + } + $affectedRows += 1; + $this->resetModified(); + } + + $this->alreadyInSave = false; + + } + + return $affectedRows; + } // doSave() + + /** + * Insert the row in the database. + * + * @param ConnectionInterface $con + * + * @throws PropelException + * @see doSave() + */ + protected function doInsert(ConnectionInterface $con) + { + $modifiedColumns = array(); + $index = 0; + + $this->modifiedColumns[] = OrderProductAttributeCombinationTableMap::ID; + if (null !== $this->id) { + throw new PropelException('Cannot insert a value for auto-increment primary key (' . OrderProductAttributeCombinationTableMap::ID . ')'); + } + + // check the columns in natural order for more readable SQL queries + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ID)) { + $modifiedColumns[':p' . $index++] = 'ID'; + } + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ORDER_PRODUCT_ID)) { + $modifiedColumns[':p' . $index++] = 'ORDER_PRODUCT_ID'; + } + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_TITLE)) { + $modifiedColumns[':p' . $index++] = 'ATTRIBUTE_TITLE'; + } + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_CHAPO)) { + $modifiedColumns[':p' . $index++] = 'ATTRIBUTE_CHAPO'; + } + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_DESCRIPTION)) { + $modifiedColumns[':p' . $index++] = 'ATTRIBUTE_DESCRIPTION'; + } + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_POSTSCRIPTUMN)) { + $modifiedColumns[':p' . $index++] = 'ATTRIBUTE_POSTSCRIPTUMN'; + } + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_TITLE)) { + $modifiedColumns[':p' . $index++] = 'ATTRIBUTE_AV_TITLE'; + } + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_CHAPO)) { + $modifiedColumns[':p' . $index++] = 'ATTRIBUTE_AV_CHAPO'; + } + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_DESCRIPTION)) { + $modifiedColumns[':p' . $index++] = 'ATTRIBUTE_AV_DESCRIPTION'; + } + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_POSTSCRIPTUM)) { + $modifiedColumns[':p' . $index++] = 'ATTRIBUTE_AV_POSTSCRIPTUM'; + } + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::CREATED_AT)) { + $modifiedColumns[':p' . $index++] = 'CREATED_AT'; + } + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::UPDATED_AT)) { + $modifiedColumns[':p' . $index++] = 'UPDATED_AT'; + } + + $sql = sprintf( + 'INSERT INTO order_product_attribute_combination (%s) VALUES (%s)', + implode(', ', $modifiedColumns), + implode(', ', array_keys($modifiedColumns)) + ); + + try { + $stmt = $con->prepare($sql); + foreach ($modifiedColumns as $identifier => $columnName) { + switch ($columnName) { + case 'ID': + $stmt->bindValue($identifier, $this->id, PDO::PARAM_INT); + break; + case 'ORDER_PRODUCT_ID': + $stmt->bindValue($identifier, $this->order_product_id, PDO::PARAM_INT); + break; + case 'ATTRIBUTE_TITLE': + $stmt->bindValue($identifier, $this->attribute_title, PDO::PARAM_STR); + break; + case 'ATTRIBUTE_CHAPO': + $stmt->bindValue($identifier, $this->attribute_chapo, PDO::PARAM_STR); + break; + case 'ATTRIBUTE_DESCRIPTION': + $stmt->bindValue($identifier, $this->attribute_description, PDO::PARAM_STR); + break; + case 'ATTRIBUTE_POSTSCRIPTUMN': + $stmt->bindValue($identifier, $this->attribute_postscriptumn, PDO::PARAM_STR); + break; + case 'ATTRIBUTE_AV_TITLE': + $stmt->bindValue($identifier, $this->attribute_av_title, PDO::PARAM_STR); + break; + case 'ATTRIBUTE_AV_CHAPO': + $stmt->bindValue($identifier, $this->attribute_av_chapo, PDO::PARAM_STR); + break; + case 'ATTRIBUTE_AV_DESCRIPTION': + $stmt->bindValue($identifier, $this->attribute_av_description, PDO::PARAM_STR); + break; + case 'ATTRIBUTE_AV_POSTSCRIPTUM': + $stmt->bindValue($identifier, $this->attribute_av_postscriptum, PDO::PARAM_STR); + break; + case 'CREATED_AT': + $stmt->bindValue($identifier, $this->created_at ? $this->created_at->format("Y-m-d H:i:s") : null, PDO::PARAM_STR); + break; + case 'UPDATED_AT': + $stmt->bindValue($identifier, $this->updated_at ? $this->updated_at->format("Y-m-d H:i:s") : null, PDO::PARAM_STR); + break; + } + } + $stmt->execute(); + } catch (Exception $e) { + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException(sprintf('Unable to execute INSERT statement [%s]', $sql), 0, $e); + } + + try { + $pk = $con->lastInsertId(); + } catch (Exception $e) { + throw new PropelException('Unable to get autoincrement id.', 0, $e); + } + $this->setId($pk); + + $this->setNew(false); + } + + /** + * Update the row in the database. + * + * @param ConnectionInterface $con + * + * @return Integer Number of updated rows + * @see doSave() + */ + protected function doUpdate(ConnectionInterface $con) + { + $selectCriteria = $this->buildPkeyCriteria(); + $valuesCriteria = $this->buildCriteria(); + + return $selectCriteria->doUpdate($valuesCriteria, $con); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @return mixed Value of field. + */ + public function getByName($name, $type = TableMap::TYPE_PHPNAME) + { + $pos = OrderProductAttributeCombinationTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); + $field = $this->getByPosition($pos); + + return $field; + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch ($pos) { + case 0: + return $this->getId(); + break; + case 1: + return $this->getOrderProductId(); + break; + case 2: + return $this->getAttributeTitle(); + break; + case 3: + return $this->getAttributeChapo(); + break; + case 4: + return $this->getAttributeDescription(); + break; + case 5: + return $this->getAttributePostscriptumn(); + break; + case 6: + return $this->getAttributeAvTitle(); + break; + case 7: + return $this->getAttributeAvChapo(); + break; + case 8: + return $this->getAttributeAvDescription(); + break; + case 9: + return $this->getAttributeAvPostscriptum(); + break; + case 10: + return $this->getCreatedAt(); + break; + case 11: + return $this->getUpdatedAt(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType (optional) One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME, + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE. + * @param array $alreadyDumpedObjects List of objects to skip to avoid recursion + * @param boolean $includeForeignObjects (optional) Whether to include hydrated related objects. Default to FALSE. + * + * @return array an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = TableMap::TYPE_PHPNAME, $includeLazyLoadColumns = true, $alreadyDumpedObjects = array(), $includeForeignObjects = false) + { + if (isset($alreadyDumpedObjects['OrderProductAttributeCombination'][$this->getPrimaryKey()])) { + return '*RECURSION*'; + } + $alreadyDumpedObjects['OrderProductAttributeCombination'][$this->getPrimaryKey()] = true; + $keys = OrderProductAttributeCombinationTableMap::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getId(), + $keys[1] => $this->getOrderProductId(), + $keys[2] => $this->getAttributeTitle(), + $keys[3] => $this->getAttributeChapo(), + $keys[4] => $this->getAttributeDescription(), + $keys[5] => $this->getAttributePostscriptumn(), + $keys[6] => $this->getAttributeAvTitle(), + $keys[7] => $this->getAttributeAvChapo(), + $keys[8] => $this->getAttributeAvDescription(), + $keys[9] => $this->getAttributeAvPostscriptum(), + $keys[10] => $this->getCreatedAt(), + $keys[11] => $this->getUpdatedAt(), + ); + $virtualColumns = $this->virtualColumns; + foreach($virtualColumns as $key => $virtualColumn) + { + $result[$key] = $virtualColumn; + } + + if ($includeForeignObjects) { + if (null !== $this->aOrderProduct) { + $result['OrderProduct'] = $this->aOrderProduct->toArray($keyType, $includeLazyLoadColumns, $alreadyDumpedObjects, true); + } + } + + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @return void + */ + public function setByName($name, $value, $type = TableMap::TYPE_PHPNAME) + { + $pos = OrderProductAttributeCombinationTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); + + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch ($pos) { + case 0: + $this->setId($value); + break; + case 1: + $this->setOrderProductId($value); + break; + case 2: + $this->setAttributeTitle($value); + break; + case 3: + $this->setAttributeChapo($value); + break; + case 4: + $this->setAttributeDescription($value); + break; + case 5: + $this->setAttributePostscriptumn($value); + break; + case 6: + $this->setAttributeAvTitle($value); + break; + case 7: + $this->setAttributeAvChapo($value); + break; + case 8: + $this->setAttributeAvDescription($value); + break; + case 9: + $this->setAttributeAvPostscriptum($value); + break; + case 10: + $this->setCreatedAt($value); + break; + case 11: + $this->setUpdatedAt($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME, + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * The default key type is the column's TableMap::TYPE_PHPNAME. + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = TableMap::TYPE_PHPNAME) + { + $keys = OrderProductAttributeCombinationTableMap::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setOrderProductId($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setAttributeTitle($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setAttributeChapo($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setAttributeDescription($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setAttributePostscriptumn($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setAttributeAvTitle($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setAttributeAvChapo($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setAttributeAvDescription($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setAttributeAvPostscriptum($arr[$keys[9]]); + if (array_key_exists($keys[10], $arr)) $this->setCreatedAt($arr[$keys[10]]); + if (array_key_exists($keys[11], $arr)) $this->setUpdatedAt($arr[$keys[11]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(OrderProductAttributeCombinationTableMap::DATABASE_NAME); + + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ID)) $criteria->add(OrderProductAttributeCombinationTableMap::ID, $this->id); + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ORDER_PRODUCT_ID)) $criteria->add(OrderProductAttributeCombinationTableMap::ORDER_PRODUCT_ID, $this->order_product_id); + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_TITLE)) $criteria->add(OrderProductAttributeCombinationTableMap::ATTRIBUTE_TITLE, $this->attribute_title); + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_CHAPO)) $criteria->add(OrderProductAttributeCombinationTableMap::ATTRIBUTE_CHAPO, $this->attribute_chapo); + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_DESCRIPTION)) $criteria->add(OrderProductAttributeCombinationTableMap::ATTRIBUTE_DESCRIPTION, $this->attribute_description); + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_POSTSCRIPTUMN)) $criteria->add(OrderProductAttributeCombinationTableMap::ATTRIBUTE_POSTSCRIPTUMN, $this->attribute_postscriptumn); + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_TITLE)) $criteria->add(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_TITLE, $this->attribute_av_title); + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_CHAPO)) $criteria->add(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_CHAPO, $this->attribute_av_chapo); + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_DESCRIPTION)) $criteria->add(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_DESCRIPTION, $this->attribute_av_description); + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_POSTSCRIPTUM)) $criteria->add(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_POSTSCRIPTUM, $this->attribute_av_postscriptum); + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::CREATED_AT)) $criteria->add(OrderProductAttributeCombinationTableMap::CREATED_AT, $this->created_at); + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::UPDATED_AT)) $criteria->add(OrderProductAttributeCombinationTableMap::UPDATED_AT, $this->updated_at); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(OrderProductAttributeCombinationTableMap::DATABASE_NAME); + $criteria->add(OrderProductAttributeCombinationTableMap::ID, $this->id); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return int + */ + public function getPrimaryKey() + { + return $this->getId(); + } + + /** + * Generic method to set the primary key (id column). + * + * @param int $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setId($key); + } + + /** + * Returns true if the primary key for this object is null. + * @return boolean + */ + public function isPrimaryKeyNull() + { + + return null === $this->getId(); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of \Thelia\Model\OrderProductAttributeCombination (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @param boolean $makeNew Whether to reset autoincrement PKs and make the object new. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false, $makeNew = true) + { + $copyObj->setOrderProductId($this->getOrderProductId()); + $copyObj->setAttributeTitle($this->getAttributeTitle()); + $copyObj->setAttributeChapo($this->getAttributeChapo()); + $copyObj->setAttributeDescription($this->getAttributeDescription()); + $copyObj->setAttributePostscriptumn($this->getAttributePostscriptumn()); + $copyObj->setAttributeAvTitle($this->getAttributeAvTitle()); + $copyObj->setAttributeAvChapo($this->getAttributeAvChapo()); + $copyObj->setAttributeAvDescription($this->getAttributeAvDescription()); + $copyObj->setAttributeAvPostscriptum($this->getAttributeAvPostscriptum()); + $copyObj->setCreatedAt($this->getCreatedAt()); + $copyObj->setUpdatedAt($this->getUpdatedAt()); + if ($makeNew) { + $copyObj->setNew(true); + $copyObj->setId(NULL); // this is a auto-increment column, so set to default value + } + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return \Thelia\Model\OrderProductAttributeCombination Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + + return $copyObj; + } + + /** + * Declares an association between this object and a ChildOrderProduct object. + * + * @param ChildOrderProduct $v + * @return \Thelia\Model\OrderProductAttributeCombination The current object (for fluent API support) + * @throws PropelException + */ + public function setOrderProduct(ChildOrderProduct $v = null) + { + if ($v === null) { + $this->setOrderProductId(NULL); + } else { + $this->setOrderProductId($v->getId()); + } + + $this->aOrderProduct = $v; + + // Add binding for other direction of this n:n relationship. + // If this object has already been added to the ChildOrderProduct object, it will not be re-added. + if ($v !== null) { + $v->addOrderProductAttributeCombination($this); + } + + + return $this; + } + + + /** + * Get the associated ChildOrderProduct object + * + * @param ConnectionInterface $con Optional Connection object. + * @return ChildOrderProduct The associated ChildOrderProduct object. + * @throws PropelException + */ + public function getOrderProduct(ConnectionInterface $con = null) + { + if ($this->aOrderProduct === null && ($this->order_product_id !== null)) { + $this->aOrderProduct = ChildOrderProductQuery::create()->findPk($this->order_product_id, $con); + /* The following can be used additionally to + guarantee the related object contains a reference + to this object. This level of coupling may, however, be + undesirable since it could result in an only partially populated collection + in the referenced object. + $this->aOrderProduct->addOrderProductAttributeCombinations($this); + */ + } + + return $this->aOrderProduct; + } + + /** + * Clears the current object and sets all attributes to their default values + */ + public function clear() + { + $this->id = null; + $this->order_product_id = null; + $this->attribute_title = null; + $this->attribute_chapo = null; + $this->attribute_description = null; + $this->attribute_postscriptumn = null; + $this->attribute_av_title = null; + $this->attribute_av_chapo = null; + $this->attribute_av_description = null; + $this->attribute_av_postscriptum = null; + $this->created_at = null; + $this->updated_at = null; + $this->alreadyInSave = false; + $this->clearAllReferences(); + $this->resetModified(); + $this->setNew(true); + $this->setDeleted(false); + } + + /** + * Resets all references to other model objects or collections of model objects. + * + * This method is a user-space workaround for PHP's inability to garbage collect + * objects with circular references (even in PHP 5.3). This is currently necessary + * when using Propel in certain daemon or large-volume/high-memory operations. + * + * @param boolean $deep Whether to also clear the references on all referrer objects. + */ + public function clearAllReferences($deep = false) + { + if ($deep) { + } // if ($deep) + + $this->aOrderProduct = null; + } + + /** + * Return the string representation of this object + * + * @return string + */ + public function __toString() + { + return (string) $this->exportTo(OrderProductAttributeCombinationTableMap::DEFAULT_STRING_FORMAT); + } + + // timestampable behavior + + /** + * Mark the current object so that the update date doesn't get updated during next save + * + * @return ChildOrderProductAttributeCombination The current object (for fluent API support) + */ + public function keepUpdateDateUnchanged() + { + $this->modifiedColumns[] = OrderProductAttributeCombinationTableMap::UPDATED_AT; + + return $this; + } + + /** + * Code to be run before persisting the object + * @param ConnectionInterface $con + * @return boolean + */ + public function preSave(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after persisting the object + * @param ConnectionInterface $con + */ + public function postSave(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before inserting to database + * @param ConnectionInterface $con + * @return boolean + */ + public function preInsert(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after inserting to database + * @param ConnectionInterface $con + */ + public function postInsert(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before updating the object in database + * @param ConnectionInterface $con + * @return boolean + */ + public function preUpdate(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after updating the object in database + * @param ConnectionInterface $con + */ + public function postUpdate(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before deleting the object in database + * @param ConnectionInterface $con + * @return boolean + */ + public function preDelete(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after deleting the object in database + * @param ConnectionInterface $con + */ + public function postDelete(ConnectionInterface $con = null) + { + + } + + + /** + * Derived method to catches calls to undefined methods. + * + * Provides magic import/export method support (fromXML()/toXML(), fromYAML()/toYAML(), etc.). + * Allows to define default __call() behavior if you overwrite __call() + * + * @param string $name + * @param mixed $params + * + * @return array|string + */ + public function __call($name, $params) + { + if (0 === strpos($name, 'get')) { + $virtualColumn = substr($name, 3); + if ($this->hasVirtualColumn($virtualColumn)) { + return $this->getVirtualColumn($virtualColumn); + } + + $virtualColumn = lcfirst($virtualColumn); + if ($this->hasVirtualColumn($virtualColumn)) { + return $this->getVirtualColumn($virtualColumn); + } + } + + if (0 === strpos($name, 'from')) { + $format = substr($name, 4); + + return $this->importFrom($format, reset($params)); + } + + if (0 === strpos($name, 'to')) { + $format = substr($name, 2); + $includeLazyLoadColumns = isset($params[0]) ? $params[0] : true; + + return $this->exportTo($format, $includeLazyLoadColumns); + } + + throw new BadMethodCallException(sprintf('Call to undefined method: %s.', $name)); + } + +} diff --git a/core/lib/Thelia/Model/Base/OrderProductAttributeCombinationQuery.php b/core/lib/Thelia/Model/Base/OrderProductAttributeCombinationQuery.php new file mode 100644 index 000000000..9e8298aa5 --- /dev/null +++ b/core/lib/Thelia/Model/Base/OrderProductAttributeCombinationQuery.php @@ -0,0 +1,897 @@ +setModelAlias($modelAlias); + } + if ($criteria instanceof Criteria) { + $query->mergeWith($criteria); + } + + return $query; + } + + /** + * Find object by primary key. + * Propel uses the instance pool to skip the database if the object exists. + * Go fast if the query is untouched. + * + * + * $obj = $c->findPk(12, $con); + * + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con an optional connection object + * + * @return ChildOrderProductAttributeCombination|array|mixed the result, formatted by the current formatter + */ + public function findPk($key, $con = null) + { + if ($key === null) { + return null; + } + if ((null !== ($obj = OrderProductAttributeCombinationTableMap::getInstanceFromPool((string) $key))) && !$this->formatter) { + // the object is already in the instance pool + return $obj; + } + if ($con === null) { + $con = Propel::getServiceContainer()->getReadConnection(OrderProductAttributeCombinationTableMap::DATABASE_NAME); + } + $this->basePreSelect($con); + if ($this->formatter || $this->modelAlias || $this->with || $this->select + || $this->selectColumns || $this->asColumns || $this->selectModifiers + || $this->map || $this->having || $this->joins) { + return $this->findPkComplex($key, $con); + } else { + return $this->findPkSimple($key, $con); + } + } + + /** + * Find object by primary key using raw SQL to go fast. + * Bypass doSelect() and the object formatter by using generated code. + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con A connection object + * + * @return ChildOrderProductAttributeCombination A model object, or null if the key is not found + */ + protected function findPkSimple($key, $con) + { + $sql = 'SELECT ID, ORDER_PRODUCT_ID, ATTRIBUTE_TITLE, ATTRIBUTE_CHAPO, ATTRIBUTE_DESCRIPTION, ATTRIBUTE_POSTSCRIPTUMN, ATTRIBUTE_AV_TITLE, ATTRIBUTE_AV_CHAPO, ATTRIBUTE_AV_DESCRIPTION, ATTRIBUTE_AV_POSTSCRIPTUM, CREATED_AT, UPDATED_AT FROM order_product_attribute_combination WHERE ID = :p0'; + try { + $stmt = $con->prepare($sql); + $stmt->bindValue(':p0', $key, PDO::PARAM_INT); + $stmt->execute(); + } catch (Exception $e) { + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException(sprintf('Unable to execute SELECT statement [%s]', $sql), 0, $e); + } + $obj = null; + if ($row = $stmt->fetch(\PDO::FETCH_NUM)) { + $obj = new ChildOrderProductAttributeCombination(); + $obj->hydrate($row); + OrderProductAttributeCombinationTableMap::addInstanceToPool($obj, (string) $key); + } + $stmt->closeCursor(); + + return $obj; + } + + /** + * Find object by primary key. + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con A connection object + * + * @return ChildOrderProductAttributeCombination|array|mixed the result, formatted by the current formatter + */ + protected function findPkComplex($key, $con) + { + // As the query uses a PK condition, no limit(1) is necessary. + $criteria = $this->isKeepQuery() ? clone $this : $this; + $dataFetcher = $criteria + ->filterByPrimaryKey($key) + ->doSelect($con); + + return $criteria->getFormatter()->init($criteria)->formatOne($dataFetcher); + } + + /** + * Find objects by primary key + * + * $objs = $c->findPks(array(12, 56, 832), $con); + * + * @param array $keys Primary keys to use for the query + * @param ConnectionInterface $con an optional connection object + * + * @return ObjectCollection|array|mixed the list of results, formatted by the current formatter + */ + public function findPks($keys, $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getReadConnection($this->getDbName()); + } + $this->basePreSelect($con); + $criteria = $this->isKeepQuery() ? clone $this : $this; + $dataFetcher = $criteria + ->filterByPrimaryKeys($keys) + ->doSelect($con); + + return $criteria->getFormatter()->init($criteria)->format($dataFetcher); + } + + /** + * Filter the query by primary key + * + * @param mixed $key Primary key to use for the query + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function filterByPrimaryKey($key) + { + + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ID, $key, Criteria::EQUAL); + } + + /** + * Filter the query by a list of primary keys + * + * @param array $keys The list of primary key to use for the query + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function filterByPrimaryKeys($keys) + { + + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ID, $keys, Criteria::IN); + } + + /** + * Filter the query on the id column + * + * Example usage: + * + * $query->filterById(1234); // WHERE id = 1234 + * $query->filterById(array(12, 34)); // WHERE id IN (12, 34) + * $query->filterById(array('min' => 12)); // WHERE id > 12 + * + * + * @param mixed $id The value to use as filter. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function filterById($id = null, $comparison = null) + { + if (is_array($id)) { + $useMinMax = false; + if (isset($id['min'])) { + $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ID, $id['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($id['max'])) { + $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ID, $id['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ID, $id, $comparison); + } + + /** + * Filter the query on the order_product_id column + * + * Example usage: + * + * $query->filterByOrderProductId(1234); // WHERE order_product_id = 1234 + * $query->filterByOrderProductId(array(12, 34)); // WHERE order_product_id IN (12, 34) + * $query->filterByOrderProductId(array('min' => 12)); // WHERE order_product_id > 12 + * + * + * @see filterByOrderProduct() + * + * @param mixed $orderProductId The value to use as filter. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function filterByOrderProductId($orderProductId = null, $comparison = null) + { + if (is_array($orderProductId)) { + $useMinMax = false; + if (isset($orderProductId['min'])) { + $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ORDER_PRODUCT_ID, $orderProductId['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($orderProductId['max'])) { + $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ORDER_PRODUCT_ID, $orderProductId['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ORDER_PRODUCT_ID, $orderProductId, $comparison); + } + + /** + * Filter the query on the attribute_title column + * + * Example usage: + * + * $query->filterByAttributeTitle('fooValue'); // WHERE attribute_title = 'fooValue' + * $query->filterByAttributeTitle('%fooValue%'); // WHERE attribute_title LIKE '%fooValue%' + * + * + * @param string $attributeTitle The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function filterByAttributeTitle($attributeTitle = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($attributeTitle)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $attributeTitle)) { + $attributeTitle = str_replace('*', '%', $attributeTitle); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ATTRIBUTE_TITLE, $attributeTitle, $comparison); + } + + /** + * Filter the query on the attribute_chapo column + * + * Example usage: + * + * $query->filterByAttributeChapo('fooValue'); // WHERE attribute_chapo = 'fooValue' + * $query->filterByAttributeChapo('%fooValue%'); // WHERE attribute_chapo LIKE '%fooValue%' + * + * + * @param string $attributeChapo The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function filterByAttributeChapo($attributeChapo = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($attributeChapo)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $attributeChapo)) { + $attributeChapo = str_replace('*', '%', $attributeChapo); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ATTRIBUTE_CHAPO, $attributeChapo, $comparison); + } + + /** + * Filter the query on the attribute_description column + * + * Example usage: + * + * $query->filterByAttributeDescription('fooValue'); // WHERE attribute_description = 'fooValue' + * $query->filterByAttributeDescription('%fooValue%'); // WHERE attribute_description LIKE '%fooValue%' + * + * + * @param string $attributeDescription The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function filterByAttributeDescription($attributeDescription = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($attributeDescription)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $attributeDescription)) { + $attributeDescription = str_replace('*', '%', $attributeDescription); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ATTRIBUTE_DESCRIPTION, $attributeDescription, $comparison); + } + + /** + * Filter the query on the attribute_postscriptumn column + * + * Example usage: + * + * $query->filterByAttributePostscriptumn('fooValue'); // WHERE attribute_postscriptumn = 'fooValue' + * $query->filterByAttributePostscriptumn('%fooValue%'); // WHERE attribute_postscriptumn LIKE '%fooValue%' + * + * + * @param string $attributePostscriptumn The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function filterByAttributePostscriptumn($attributePostscriptumn = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($attributePostscriptumn)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $attributePostscriptumn)) { + $attributePostscriptumn = str_replace('*', '%', $attributePostscriptumn); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ATTRIBUTE_POSTSCRIPTUMN, $attributePostscriptumn, $comparison); + } + + /** + * Filter the query on the attribute_av_title column + * + * Example usage: + * + * $query->filterByAttributeAvTitle('fooValue'); // WHERE attribute_av_title = 'fooValue' + * $query->filterByAttributeAvTitle('%fooValue%'); // WHERE attribute_av_title LIKE '%fooValue%' + * + * + * @param string $attributeAvTitle The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function filterByAttributeAvTitle($attributeAvTitle = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($attributeAvTitle)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $attributeAvTitle)) { + $attributeAvTitle = str_replace('*', '%', $attributeAvTitle); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_TITLE, $attributeAvTitle, $comparison); + } + + /** + * Filter the query on the attribute_av_chapo column + * + * Example usage: + * + * $query->filterByAttributeAvChapo('fooValue'); // WHERE attribute_av_chapo = 'fooValue' + * $query->filterByAttributeAvChapo('%fooValue%'); // WHERE attribute_av_chapo LIKE '%fooValue%' + * + * + * @param string $attributeAvChapo The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function filterByAttributeAvChapo($attributeAvChapo = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($attributeAvChapo)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $attributeAvChapo)) { + $attributeAvChapo = str_replace('*', '%', $attributeAvChapo); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_CHAPO, $attributeAvChapo, $comparison); + } + + /** + * Filter the query on the attribute_av_description column + * + * Example usage: + * + * $query->filterByAttributeAvDescription('fooValue'); // WHERE attribute_av_description = 'fooValue' + * $query->filterByAttributeAvDescription('%fooValue%'); // WHERE attribute_av_description LIKE '%fooValue%' + * + * + * @param string $attributeAvDescription The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function filterByAttributeAvDescription($attributeAvDescription = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($attributeAvDescription)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $attributeAvDescription)) { + $attributeAvDescription = str_replace('*', '%', $attributeAvDescription); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_DESCRIPTION, $attributeAvDescription, $comparison); + } + + /** + * Filter the query on the attribute_av_postscriptum column + * + * Example usage: + * + * $query->filterByAttributeAvPostscriptum('fooValue'); // WHERE attribute_av_postscriptum = 'fooValue' + * $query->filterByAttributeAvPostscriptum('%fooValue%'); // WHERE attribute_av_postscriptum LIKE '%fooValue%' + * + * + * @param string $attributeAvPostscriptum The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function filterByAttributeAvPostscriptum($attributeAvPostscriptum = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($attributeAvPostscriptum)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $attributeAvPostscriptum)) { + $attributeAvPostscriptum = str_replace('*', '%', $attributeAvPostscriptum); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_POSTSCRIPTUM, $attributeAvPostscriptum, $comparison); + } + + /** + * Filter the query on the created_at column + * + * Example usage: + * + * $query->filterByCreatedAt('2011-03-14'); // WHERE created_at = '2011-03-14' + * $query->filterByCreatedAt('now'); // WHERE created_at = '2011-03-14' + * $query->filterByCreatedAt(array('max' => 'yesterday')); // WHERE created_at > '2011-03-13' + * + * + * @param mixed $createdAt The value to use as filter. + * Values can be integers (unix timestamps), DateTime objects, or strings. + * Empty strings are treated as NULL. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function filterByCreatedAt($createdAt = null, $comparison = null) + { + if (is_array($createdAt)) { + $useMinMax = false; + if (isset($createdAt['min'])) { + $this->addUsingAlias(OrderProductAttributeCombinationTableMap::CREATED_AT, $createdAt['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($createdAt['max'])) { + $this->addUsingAlias(OrderProductAttributeCombinationTableMap::CREATED_AT, $createdAt['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::CREATED_AT, $createdAt, $comparison); + } + + /** + * Filter the query on the updated_at column + * + * Example usage: + * + * $query->filterByUpdatedAt('2011-03-14'); // WHERE updated_at = '2011-03-14' + * $query->filterByUpdatedAt('now'); // WHERE updated_at = '2011-03-14' + * $query->filterByUpdatedAt(array('max' => 'yesterday')); // WHERE updated_at > '2011-03-13' + * + * + * @param mixed $updatedAt The value to use as filter. + * Values can be integers (unix timestamps), DateTime objects, or strings. + * Empty strings are treated as NULL. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function filterByUpdatedAt($updatedAt = null, $comparison = null) + { + if (is_array($updatedAt)) { + $useMinMax = false; + if (isset($updatedAt['min'])) { + $this->addUsingAlias(OrderProductAttributeCombinationTableMap::UPDATED_AT, $updatedAt['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($updatedAt['max'])) { + $this->addUsingAlias(OrderProductAttributeCombinationTableMap::UPDATED_AT, $updatedAt['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::UPDATED_AT, $updatedAt, $comparison); + } + + /** + * Filter the query by a related \Thelia\Model\OrderProduct object + * + * @param \Thelia\Model\OrderProduct|ObjectCollection $orderProduct The related object(s) to use as filter + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function filterByOrderProduct($orderProduct, $comparison = null) + { + if ($orderProduct instanceof \Thelia\Model\OrderProduct) { + return $this + ->addUsingAlias(OrderProductAttributeCombinationTableMap::ORDER_PRODUCT_ID, $orderProduct->getId(), $comparison); + } elseif ($orderProduct instanceof ObjectCollection) { + if (null === $comparison) { + $comparison = Criteria::IN; + } + + return $this + ->addUsingAlias(OrderProductAttributeCombinationTableMap::ORDER_PRODUCT_ID, $orderProduct->toKeyValue('PrimaryKey', 'Id'), $comparison); + } else { + throw new PropelException('filterByOrderProduct() only accepts arguments of type \Thelia\Model\OrderProduct or Collection'); + } + } + + /** + * Adds a JOIN clause to the query using the OrderProduct relation + * + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function joinOrderProduct($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + $tableMap = $this->getTableMap(); + $relationMap = $tableMap->getRelation('OrderProduct'); + + // create a ModelJoin object for this join + $join = new ModelJoin(); + $join->setJoinType($joinType); + $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); + if ($previousJoin = $this->getPreviousJoin()) { + $join->setPreviousJoin($previousJoin); + } + + // add the ModelJoin to the current object + if ($relationAlias) { + $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); + $this->addJoinObject($join, $relationAlias); + } else { + $this->addJoinObject($join, 'OrderProduct'); + } + + return $this; + } + + /** + * Use the OrderProduct relation OrderProduct object + * + * @see useQuery() + * + * @param string $relationAlias optional alias for the relation, + * to be used as main alias in the secondary query + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return \Thelia\Model\OrderProductQuery A secondary query class using the current class as primary query + */ + public function useOrderProductQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + return $this + ->joinOrderProduct($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'OrderProduct', '\Thelia\Model\OrderProductQuery'); + } + + /** + * Exclude object from result + * + * @param ChildOrderProductAttributeCombination $orderProductAttributeCombination Object to remove from the list of results + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function prune($orderProductAttributeCombination = null) + { + if ($orderProductAttributeCombination) { + $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ID, $orderProductAttributeCombination->getId(), Criteria::NOT_EQUAL); + } + + return $this; + } + + /** + * Deletes all rows from the order_product_attribute_combination table. + * + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). + */ + public function doDeleteAll(ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(OrderProductAttributeCombinationTableMap::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->beginTransaction(); + $affectedRows += parent::doDeleteAll($con); + // Because this db requires some delete cascade/set null emulation, we have to + // clear the cached instance *after* the emulation has happened (since + // instances get re-added by the select statement contained therein). + OrderProductAttributeCombinationTableMap::clearInstancePool(); + OrderProductAttributeCombinationTableMap::clearRelatedInstancePool(); + + $con->commit(); + } catch (PropelException $e) { + $con->rollBack(); + throw $e; + } + + return $affectedRows; + } + + /** + * Performs a DELETE on the database, given a ChildOrderProductAttributeCombination or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or ChildOrderProductAttributeCombination object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public function delete(ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(OrderProductAttributeCombinationTableMap::DATABASE_NAME); + } + + $criteria = $this; + + // Set the correct dbName + $criteria->setDbName(OrderProductAttributeCombinationTableMap::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->beginTransaction(); + + + OrderProductAttributeCombinationTableMap::removeInstanceFromPool($criteria); + + $affectedRows += ModelCriteria::delete($con); + OrderProductAttributeCombinationTableMap::clearRelatedInstancePool(); + $con->commit(); + + return $affectedRows; + } catch (PropelException $e) { + $con->rollBack(); + throw $e; + } + } + + // timestampable behavior + + /** + * Filter by the latest updated + * + * @param int $nbDays Maximum age of the latest update in days + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function recentlyUpdated($nbDays = 7) + { + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::UPDATED_AT, time() - $nbDays * 24 * 60 * 60, Criteria::GREATER_EQUAL); + } + + /** + * Filter by the latest created + * + * @param int $nbDays Maximum age of in days + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function recentlyCreated($nbDays = 7) + { + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::CREATED_AT, time() - $nbDays * 24 * 60 * 60, Criteria::GREATER_EQUAL); + } + + /** + * Order by update date desc + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function lastUpdatedFirst() + { + return $this->addDescendingOrderByColumn(OrderProductAttributeCombinationTableMap::UPDATED_AT); + } + + /** + * Order by update date asc + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function firstUpdatedFirst() + { + return $this->addAscendingOrderByColumn(OrderProductAttributeCombinationTableMap::UPDATED_AT); + } + + /** + * Order by create date desc + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function lastCreatedFirst() + { + return $this->addDescendingOrderByColumn(OrderProductAttributeCombinationTableMap::CREATED_AT); + } + + /** + * Order by create date asc + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function firstCreatedFirst() + { + return $this->addAscendingOrderByColumn(OrderProductAttributeCombinationTableMap::CREATED_AT); + } + +} // OrderProductAttributeCombinationQuery diff --git a/core/lib/Thelia/Model/Base/OrderProductQuery.php b/core/lib/Thelia/Model/Base/OrderProductQuery.php index b007c89e1..f28102dfb 100644 --- a/core/lib/Thelia/Model/Base/OrderProductQuery.php +++ b/core/lib/Thelia/Model/Base/OrderProductQuery.php @@ -24,12 +24,19 @@ use Thelia\Model\Map\OrderProductTableMap; * @method ChildOrderProductQuery orderById($order = Criteria::ASC) Order by the id column * @method ChildOrderProductQuery orderByOrderId($order = Criteria::ASC) Order by the order_id column * @method ChildOrderProductQuery orderByProductRef($order = Criteria::ASC) Order by the product_ref column + * @method ChildOrderProductQuery orderByProductSaleElementsRef($order = Criteria::ASC) Order by the product_sale_elements_ref column * @method ChildOrderProductQuery orderByTitle($order = Criteria::ASC) Order by the title column - * @method ChildOrderProductQuery orderByDescription($order = Criteria::ASC) Order by the description column * @method ChildOrderProductQuery orderByChapo($order = Criteria::ASC) Order by the chapo column + * @method ChildOrderProductQuery orderByDescription($order = Criteria::ASC) Order by the description column + * @method ChildOrderProductQuery orderByPostscriptum($order = Criteria::ASC) Order by the postscriptum column * @method ChildOrderProductQuery orderByQuantity($order = Criteria::ASC) Order by the quantity column * @method ChildOrderProductQuery orderByPrice($order = Criteria::ASC) Order by the price column - * @method ChildOrderProductQuery orderByTax($order = Criteria::ASC) Order by the tax column + * @method ChildOrderProductQuery orderByPromoPrice($order = Criteria::ASC) Order by the promo_price column + * @method ChildOrderProductQuery orderByWasNew($order = Criteria::ASC) Order by the was_new column + * @method ChildOrderProductQuery orderByWasInPromo($order = Criteria::ASC) Order by the was_in_promo column + * @method ChildOrderProductQuery orderByWeight($order = Criteria::ASC) Order by the weight column + * @method ChildOrderProductQuery orderByTaxRuleTitle($order = Criteria::ASC) Order by the tax_rule_title column + * @method ChildOrderProductQuery orderByTaxRuleDescription($order = Criteria::ASC) Order by the tax_rule_description column * @method ChildOrderProductQuery orderByParent($order = Criteria::ASC) Order by the parent column * @method ChildOrderProductQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column * @method ChildOrderProductQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column @@ -37,12 +44,19 @@ use Thelia\Model\Map\OrderProductTableMap; * @method ChildOrderProductQuery groupById() Group by the id column * @method ChildOrderProductQuery groupByOrderId() Group by the order_id column * @method ChildOrderProductQuery groupByProductRef() Group by the product_ref column + * @method ChildOrderProductQuery groupByProductSaleElementsRef() Group by the product_sale_elements_ref column * @method ChildOrderProductQuery groupByTitle() Group by the title column - * @method ChildOrderProductQuery groupByDescription() Group by the description column * @method ChildOrderProductQuery groupByChapo() Group by the chapo column + * @method ChildOrderProductQuery groupByDescription() Group by the description column + * @method ChildOrderProductQuery groupByPostscriptum() Group by the postscriptum column * @method ChildOrderProductQuery groupByQuantity() Group by the quantity column * @method ChildOrderProductQuery groupByPrice() Group by the price column - * @method ChildOrderProductQuery groupByTax() Group by the tax column + * @method ChildOrderProductQuery groupByPromoPrice() Group by the promo_price column + * @method ChildOrderProductQuery groupByWasNew() Group by the was_new column + * @method ChildOrderProductQuery groupByWasInPromo() Group by the was_in_promo column + * @method ChildOrderProductQuery groupByWeight() Group by the weight column + * @method ChildOrderProductQuery groupByTaxRuleTitle() Group by the tax_rule_title column + * @method ChildOrderProductQuery groupByTaxRuleDescription() Group by the tax_rule_description column * @method ChildOrderProductQuery groupByParent() Group by the parent column * @method ChildOrderProductQuery groupByCreatedAt() Group by the created_at column * @method ChildOrderProductQuery groupByUpdatedAt() Group by the updated_at column @@ -55,9 +69,13 @@ use Thelia\Model\Map\OrderProductTableMap; * @method ChildOrderProductQuery rightJoinOrder($relationAlias = null) Adds a RIGHT JOIN clause to the query using the Order relation * @method ChildOrderProductQuery innerJoinOrder($relationAlias = null) Adds a INNER JOIN clause to the query using the Order relation * - * @method ChildOrderProductQuery leftJoinOrderFeature($relationAlias = null) Adds a LEFT JOIN clause to the query using the OrderFeature relation - * @method ChildOrderProductQuery rightJoinOrderFeature($relationAlias = null) Adds a RIGHT JOIN clause to the query using the OrderFeature relation - * @method ChildOrderProductQuery innerJoinOrderFeature($relationAlias = null) Adds a INNER JOIN clause to the query using the OrderFeature relation + * @method ChildOrderProductQuery leftJoinOrderProductAttributeCombination($relationAlias = null) Adds a LEFT JOIN clause to the query using the OrderProductAttributeCombination relation + * @method ChildOrderProductQuery rightJoinOrderProductAttributeCombination($relationAlias = null) Adds a RIGHT JOIN clause to the query using the OrderProductAttributeCombination relation + * @method ChildOrderProductQuery innerJoinOrderProductAttributeCombination($relationAlias = null) Adds a INNER JOIN clause to the query using the OrderProductAttributeCombination relation + * + * @method ChildOrderProductQuery leftJoinOrderProductTax($relationAlias = null) Adds a LEFT JOIN clause to the query using the OrderProductTax relation + * @method ChildOrderProductQuery rightJoinOrderProductTax($relationAlias = null) Adds a RIGHT JOIN clause to the query using the OrderProductTax relation + * @method ChildOrderProductQuery innerJoinOrderProductTax($relationAlias = null) Adds a INNER JOIN clause to the query using the OrderProductTax relation * * @method ChildOrderProduct findOne(ConnectionInterface $con = null) Return the first ChildOrderProduct matching the query * @method ChildOrderProduct findOneOrCreate(ConnectionInterface $con = null) Return the first ChildOrderProduct matching the query, or a new ChildOrderProduct object populated from the query conditions when no match is found @@ -65,12 +83,19 @@ use Thelia\Model\Map\OrderProductTableMap; * @method ChildOrderProduct findOneById(int $id) Return the first ChildOrderProduct filtered by the id column * @method ChildOrderProduct findOneByOrderId(int $order_id) Return the first ChildOrderProduct filtered by the order_id column * @method ChildOrderProduct findOneByProductRef(string $product_ref) Return the first ChildOrderProduct filtered by the product_ref column + * @method ChildOrderProduct findOneByProductSaleElementsRef(string $product_sale_elements_ref) Return the first ChildOrderProduct filtered by the product_sale_elements_ref column * @method ChildOrderProduct findOneByTitle(string $title) Return the first ChildOrderProduct filtered by the title column - * @method ChildOrderProduct findOneByDescription(string $description) Return the first ChildOrderProduct filtered by the description column * @method ChildOrderProduct findOneByChapo(string $chapo) Return the first ChildOrderProduct filtered by the chapo column + * @method ChildOrderProduct findOneByDescription(string $description) Return the first ChildOrderProduct filtered by the description column + * @method ChildOrderProduct findOneByPostscriptum(string $postscriptum) Return the first ChildOrderProduct filtered by the postscriptum column * @method ChildOrderProduct findOneByQuantity(double $quantity) Return the first ChildOrderProduct filtered by the quantity column * @method ChildOrderProduct findOneByPrice(double $price) Return the first ChildOrderProduct filtered by the price column - * @method ChildOrderProduct findOneByTax(double $tax) Return the first ChildOrderProduct filtered by the tax column + * @method ChildOrderProduct findOneByPromoPrice(string $promo_price) Return the first ChildOrderProduct filtered by the promo_price column + * @method ChildOrderProduct findOneByWasNew(int $was_new) Return the first ChildOrderProduct filtered by the was_new column + * @method ChildOrderProduct findOneByWasInPromo(int $was_in_promo) Return the first ChildOrderProduct filtered by the was_in_promo column + * @method ChildOrderProduct findOneByWeight(string $weight) Return the first ChildOrderProduct filtered by the weight column + * @method ChildOrderProduct findOneByTaxRuleTitle(string $tax_rule_title) Return the first ChildOrderProduct filtered by the tax_rule_title column + * @method ChildOrderProduct findOneByTaxRuleDescription(string $tax_rule_description) Return the first ChildOrderProduct filtered by the tax_rule_description column * @method ChildOrderProduct findOneByParent(int $parent) Return the first ChildOrderProduct filtered by the parent column * @method ChildOrderProduct findOneByCreatedAt(string $created_at) Return the first ChildOrderProduct filtered by the created_at column * @method ChildOrderProduct findOneByUpdatedAt(string $updated_at) Return the first ChildOrderProduct filtered by the updated_at column @@ -78,12 +103,19 @@ use Thelia\Model\Map\OrderProductTableMap; * @method array findById(int $id) Return ChildOrderProduct objects filtered by the id column * @method array findByOrderId(int $order_id) Return ChildOrderProduct objects filtered by the order_id column * @method array findByProductRef(string $product_ref) Return ChildOrderProduct objects filtered by the product_ref column + * @method array findByProductSaleElementsRef(string $product_sale_elements_ref) Return ChildOrderProduct objects filtered by the product_sale_elements_ref column * @method array findByTitle(string $title) Return ChildOrderProduct objects filtered by the title column - * @method array findByDescription(string $description) Return ChildOrderProduct objects filtered by the description column * @method array findByChapo(string $chapo) Return ChildOrderProduct objects filtered by the chapo column + * @method array findByDescription(string $description) Return ChildOrderProduct objects filtered by the description column + * @method array findByPostscriptum(string $postscriptum) Return ChildOrderProduct objects filtered by the postscriptum column * @method array findByQuantity(double $quantity) Return ChildOrderProduct objects filtered by the quantity column * @method array findByPrice(double $price) Return ChildOrderProduct objects filtered by the price column - * @method array findByTax(double $tax) Return ChildOrderProduct objects filtered by the tax column + * @method array findByPromoPrice(string $promo_price) Return ChildOrderProduct objects filtered by the promo_price column + * @method array findByWasNew(int $was_new) Return ChildOrderProduct objects filtered by the was_new column + * @method array findByWasInPromo(int $was_in_promo) Return ChildOrderProduct objects filtered by the was_in_promo column + * @method array findByWeight(string $weight) Return ChildOrderProduct objects filtered by the weight column + * @method array findByTaxRuleTitle(string $tax_rule_title) Return ChildOrderProduct objects filtered by the tax_rule_title column + * @method array findByTaxRuleDescription(string $tax_rule_description) Return ChildOrderProduct objects filtered by the tax_rule_description column * @method array findByParent(int $parent) Return ChildOrderProduct objects filtered by the parent column * @method array findByCreatedAt(string $created_at) Return ChildOrderProduct objects filtered by the created_at column * @method array findByUpdatedAt(string $updated_at) Return ChildOrderProduct objects filtered by the updated_at column @@ -175,7 +207,7 @@ abstract class OrderProductQuery extends ModelCriteria */ protected function findPkSimple($key, $con) { - $sql = 'SELECT ID, ORDER_ID, PRODUCT_REF, TITLE, DESCRIPTION, CHAPO, QUANTITY, PRICE, TAX, PARENT, CREATED_AT, UPDATED_AT FROM order_product WHERE ID = :p0'; + $sql = 'SELECT ID, ORDER_ID, PRODUCT_REF, PRODUCT_SALE_ELEMENTS_REF, TITLE, CHAPO, DESCRIPTION, POSTSCRIPTUM, QUANTITY, PRICE, PROMO_PRICE, WAS_NEW, WAS_IN_PROMO, WEIGHT, TAX_RULE_TITLE, TAX_RULE_DESCRIPTION, PARENT, CREATED_AT, UPDATED_AT FROM order_product WHERE ID = :p0'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key, PDO::PARAM_INT); @@ -377,6 +409,35 @@ abstract class OrderProductQuery extends ModelCriteria return $this->addUsingAlias(OrderProductTableMap::PRODUCT_REF, $productRef, $comparison); } + /** + * Filter the query on the product_sale_elements_ref column + * + * Example usage: + * + * $query->filterByProductSaleElementsRef('fooValue'); // WHERE product_sale_elements_ref = 'fooValue' + * $query->filterByProductSaleElementsRef('%fooValue%'); // WHERE product_sale_elements_ref LIKE '%fooValue%' + * + * + * @param string $productSaleElementsRef The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildOrderProductQuery The current query, for fluid interface + */ + public function filterByProductSaleElementsRef($productSaleElementsRef = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($productSaleElementsRef)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $productSaleElementsRef)) { + $productSaleElementsRef = str_replace('*', '%', $productSaleElementsRef); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductTableMap::PRODUCT_SALE_ELEMENTS_REF, $productSaleElementsRef, $comparison); + } + /** * Filter the query on the title column * @@ -406,6 +467,35 @@ abstract class OrderProductQuery extends ModelCriteria return $this->addUsingAlias(OrderProductTableMap::TITLE, $title, $comparison); } + /** + * Filter the query on the chapo column + * + * Example usage: + * + * $query->filterByChapo('fooValue'); // WHERE chapo = 'fooValue' + * $query->filterByChapo('%fooValue%'); // WHERE chapo LIKE '%fooValue%' + * + * + * @param string $chapo The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildOrderProductQuery The current query, for fluid interface + */ + public function filterByChapo($chapo = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($chapo)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $chapo)) { + $chapo = str_replace('*', '%', $chapo); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductTableMap::CHAPO, $chapo, $comparison); + } + /** * Filter the query on the description column * @@ -436,32 +526,32 @@ abstract class OrderProductQuery extends ModelCriteria } /** - * Filter the query on the chapo column + * Filter the query on the postscriptum column * * Example usage: * - * $query->filterByChapo('fooValue'); // WHERE chapo = 'fooValue' - * $query->filterByChapo('%fooValue%'); // WHERE chapo LIKE '%fooValue%' + * $query->filterByPostscriptum('fooValue'); // WHERE postscriptum = 'fooValue' + * $query->filterByPostscriptum('%fooValue%'); // WHERE postscriptum LIKE '%fooValue%' * * - * @param string $chapo The value to use as filter. + * @param string $postscriptum The value to use as filter. * Accepts wildcards (* and % trigger a LIKE) * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL * * @return ChildOrderProductQuery The current query, for fluid interface */ - public function filterByChapo($chapo = null, $comparison = null) + public function filterByPostscriptum($postscriptum = null, $comparison = null) { if (null === $comparison) { - if (is_array($chapo)) { + if (is_array($postscriptum)) { $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $chapo)) { - $chapo = str_replace('*', '%', $chapo); + } elseif (preg_match('/[\%\*]/', $postscriptum)) { + $postscriptum = str_replace('*', '%', $postscriptum); $comparison = Criteria::LIKE; } } - return $this->addUsingAlias(OrderProductTableMap::CHAPO, $chapo, $comparison); + return $this->addUsingAlias(OrderProductTableMap::POSTSCRIPTUM, $postscriptum, $comparison); } /** @@ -547,16 +637,45 @@ abstract class OrderProductQuery extends ModelCriteria } /** - * Filter the query on the tax column + * Filter the query on the promo_price column * * Example usage: * - * $query->filterByTax(1234); // WHERE tax = 1234 - * $query->filterByTax(array(12, 34)); // WHERE tax IN (12, 34) - * $query->filterByTax(array('min' => 12)); // WHERE tax > 12 + * $query->filterByPromoPrice('fooValue'); // WHERE promo_price = 'fooValue' + * $query->filterByPromoPrice('%fooValue%'); // WHERE promo_price LIKE '%fooValue%' * * - * @param mixed $tax The value to use as filter. + * @param string $promoPrice The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildOrderProductQuery The current query, for fluid interface + */ + public function filterByPromoPrice($promoPrice = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($promoPrice)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $promoPrice)) { + $promoPrice = str_replace('*', '%', $promoPrice); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductTableMap::PROMO_PRICE, $promoPrice, $comparison); + } + + /** + * Filter the query on the was_new column + * + * Example usage: + * + * $query->filterByWasNew(1234); // WHERE was_new = 1234 + * $query->filterByWasNew(array(12, 34)); // WHERE was_new IN (12, 34) + * $query->filterByWasNew(array('min' => 12)); // WHERE was_new > 12 + * + * + * @param mixed $wasNew The value to use as filter. * Use scalar values for equality. * Use array values for in_array() equivalent. * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. @@ -564,16 +683,16 @@ abstract class OrderProductQuery extends ModelCriteria * * @return ChildOrderProductQuery The current query, for fluid interface */ - public function filterByTax($tax = null, $comparison = null) + public function filterByWasNew($wasNew = null, $comparison = null) { - if (is_array($tax)) { + if (is_array($wasNew)) { $useMinMax = false; - if (isset($tax['min'])) { - $this->addUsingAlias(OrderProductTableMap::TAX, $tax['min'], Criteria::GREATER_EQUAL); + if (isset($wasNew['min'])) { + $this->addUsingAlias(OrderProductTableMap::WAS_NEW, $wasNew['min'], Criteria::GREATER_EQUAL); $useMinMax = true; } - if (isset($tax['max'])) { - $this->addUsingAlias(OrderProductTableMap::TAX, $tax['max'], Criteria::LESS_EQUAL); + if (isset($wasNew['max'])) { + $this->addUsingAlias(OrderProductTableMap::WAS_NEW, $wasNew['max'], Criteria::LESS_EQUAL); $useMinMax = true; } if ($useMinMax) { @@ -584,7 +703,135 @@ abstract class OrderProductQuery extends ModelCriteria } } - return $this->addUsingAlias(OrderProductTableMap::TAX, $tax, $comparison); + return $this->addUsingAlias(OrderProductTableMap::WAS_NEW, $wasNew, $comparison); + } + + /** + * Filter the query on the was_in_promo column + * + * Example usage: + * + * $query->filterByWasInPromo(1234); // WHERE was_in_promo = 1234 + * $query->filterByWasInPromo(array(12, 34)); // WHERE was_in_promo IN (12, 34) + * $query->filterByWasInPromo(array('min' => 12)); // WHERE was_in_promo > 12 + * + * + * @param mixed $wasInPromo The value to use as filter. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildOrderProductQuery The current query, for fluid interface + */ + public function filterByWasInPromo($wasInPromo = null, $comparison = null) + { + if (is_array($wasInPromo)) { + $useMinMax = false; + if (isset($wasInPromo['min'])) { + $this->addUsingAlias(OrderProductTableMap::WAS_IN_PROMO, $wasInPromo['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($wasInPromo['max'])) { + $this->addUsingAlias(OrderProductTableMap::WAS_IN_PROMO, $wasInPromo['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(OrderProductTableMap::WAS_IN_PROMO, $wasInPromo, $comparison); + } + + /** + * Filter the query on the weight column + * + * Example usage: + * + * $query->filterByWeight('fooValue'); // WHERE weight = 'fooValue' + * $query->filterByWeight('%fooValue%'); // WHERE weight LIKE '%fooValue%' + * + * + * @param string $weight The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildOrderProductQuery The current query, for fluid interface + */ + public function filterByWeight($weight = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($weight)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $weight)) { + $weight = str_replace('*', '%', $weight); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductTableMap::WEIGHT, $weight, $comparison); + } + + /** + * Filter the query on the tax_rule_title column + * + * Example usage: + * + * $query->filterByTaxRuleTitle('fooValue'); // WHERE tax_rule_title = 'fooValue' + * $query->filterByTaxRuleTitle('%fooValue%'); // WHERE tax_rule_title LIKE '%fooValue%' + * + * + * @param string $taxRuleTitle The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildOrderProductQuery The current query, for fluid interface + */ + public function filterByTaxRuleTitle($taxRuleTitle = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($taxRuleTitle)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $taxRuleTitle)) { + $taxRuleTitle = str_replace('*', '%', $taxRuleTitle); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductTableMap::TAX_RULE_TITLE, $taxRuleTitle, $comparison); + } + + /** + * Filter the query on the tax_rule_description column + * + * Example usage: + * + * $query->filterByTaxRuleDescription('fooValue'); // WHERE tax_rule_description = 'fooValue' + * $query->filterByTaxRuleDescription('%fooValue%'); // WHERE tax_rule_description LIKE '%fooValue%' + * + * + * @param string $taxRuleDescription The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildOrderProductQuery The current query, for fluid interface + */ + public function filterByTaxRuleDescription($taxRuleDescription = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($taxRuleDescription)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $taxRuleDescription)) { + $taxRuleDescription = str_replace('*', '%', $taxRuleDescription); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductTableMap::TAX_RULE_DESCRIPTION, $taxRuleDescription, $comparison); } /** @@ -790,40 +1037,40 @@ abstract class OrderProductQuery extends ModelCriteria } /** - * Filter the query by a related \Thelia\Model\OrderFeature object + * Filter the query by a related \Thelia\Model\OrderProductAttributeCombination object * - * @param \Thelia\Model\OrderFeature|ObjectCollection $orderFeature the related object to use as filter + * @param \Thelia\Model\OrderProductAttributeCombination|ObjectCollection $orderProductAttributeCombination the related object to use as filter * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL * * @return ChildOrderProductQuery The current query, for fluid interface */ - public function filterByOrderFeature($orderFeature, $comparison = null) + public function filterByOrderProductAttributeCombination($orderProductAttributeCombination, $comparison = null) { - if ($orderFeature instanceof \Thelia\Model\OrderFeature) { + if ($orderProductAttributeCombination instanceof \Thelia\Model\OrderProductAttributeCombination) { return $this - ->addUsingAlias(OrderProductTableMap::ID, $orderFeature->getOrderProductId(), $comparison); - } elseif ($orderFeature instanceof ObjectCollection) { + ->addUsingAlias(OrderProductTableMap::ID, $orderProductAttributeCombination->getOrderProductId(), $comparison); + } elseif ($orderProductAttributeCombination instanceof ObjectCollection) { return $this - ->useOrderFeatureQuery() - ->filterByPrimaryKeys($orderFeature->getPrimaryKeys()) + ->useOrderProductAttributeCombinationQuery() + ->filterByPrimaryKeys($orderProductAttributeCombination->getPrimaryKeys()) ->endUse(); } else { - throw new PropelException('filterByOrderFeature() only accepts arguments of type \Thelia\Model\OrderFeature or Collection'); + throw new PropelException('filterByOrderProductAttributeCombination() only accepts arguments of type \Thelia\Model\OrderProductAttributeCombination or Collection'); } } /** - * Adds a JOIN clause to the query using the OrderFeature relation + * Adds a JOIN clause to the query using the OrderProductAttributeCombination relation * * @param string $relationAlias optional alias for the relation * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' * * @return ChildOrderProductQuery The current query, for fluid interface */ - public function joinOrderFeature($relationAlias = null, $joinType = Criteria::INNER_JOIN) + public function joinOrderProductAttributeCombination($relationAlias = null, $joinType = Criteria::INNER_JOIN) { $tableMap = $this->getTableMap(); - $relationMap = $tableMap->getRelation('OrderFeature'); + $relationMap = $tableMap->getRelation('OrderProductAttributeCombination'); // create a ModelJoin object for this join $join = new ModelJoin(); @@ -838,14 +1085,14 @@ abstract class OrderProductQuery extends ModelCriteria $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); $this->addJoinObject($join, $relationAlias); } else { - $this->addJoinObject($join, 'OrderFeature'); + $this->addJoinObject($join, 'OrderProductAttributeCombination'); } return $this; } /** - * Use the OrderFeature relation OrderFeature object + * Use the OrderProductAttributeCombination relation OrderProductAttributeCombination object * * @see useQuery() * @@ -853,13 +1100,86 @@ abstract class OrderProductQuery extends ModelCriteria * to be used as main alias in the secondary query * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' * - * @return \Thelia\Model\OrderFeatureQuery A secondary query class using the current class as primary query + * @return \Thelia\Model\OrderProductAttributeCombinationQuery A secondary query class using the current class as primary query */ - public function useOrderFeatureQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) + public function useOrderProductAttributeCombinationQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) { return $this - ->joinOrderFeature($relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'OrderFeature', '\Thelia\Model\OrderFeatureQuery'); + ->joinOrderProductAttributeCombination($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'OrderProductAttributeCombination', '\Thelia\Model\OrderProductAttributeCombinationQuery'); + } + + /** + * Filter the query by a related \Thelia\Model\OrderProductTax object + * + * @param \Thelia\Model\OrderProductTax|ObjectCollection $orderProductTax the related object to use as filter + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildOrderProductQuery The current query, for fluid interface + */ + public function filterByOrderProductTax($orderProductTax, $comparison = null) + { + if ($orderProductTax instanceof \Thelia\Model\OrderProductTax) { + return $this + ->addUsingAlias(OrderProductTableMap::ID, $orderProductTax->getOrderProductId(), $comparison); + } elseif ($orderProductTax instanceof ObjectCollection) { + return $this + ->useOrderProductTaxQuery() + ->filterByPrimaryKeys($orderProductTax->getPrimaryKeys()) + ->endUse(); + } else { + throw new PropelException('filterByOrderProductTax() only accepts arguments of type \Thelia\Model\OrderProductTax or Collection'); + } + } + + /** + * Adds a JOIN clause to the query using the OrderProductTax relation + * + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return ChildOrderProductQuery The current query, for fluid interface + */ + public function joinOrderProductTax($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + $tableMap = $this->getTableMap(); + $relationMap = $tableMap->getRelation('OrderProductTax'); + + // create a ModelJoin object for this join + $join = new ModelJoin(); + $join->setJoinType($joinType); + $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); + if ($previousJoin = $this->getPreviousJoin()) { + $join->setPreviousJoin($previousJoin); + } + + // add the ModelJoin to the current object + if ($relationAlias) { + $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); + $this->addJoinObject($join, $relationAlias); + } else { + $this->addJoinObject($join, 'OrderProductTax'); + } + + return $this; + } + + /** + * Use the OrderProductTax relation OrderProductTax object + * + * @see useQuery() + * + * @param string $relationAlias optional alias for the relation, + * to be used as main alias in the secondary query + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return \Thelia\Model\OrderProductTaxQuery A secondary query class using the current class as primary query + */ + public function useOrderProductTaxQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + return $this + ->joinOrderProductTax($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'OrderProductTax', '\Thelia\Model\OrderProductTaxQuery'); } /** diff --git a/core/lib/Thelia/Model/Base/FeatureCategory.php b/core/lib/Thelia/Model/Base/OrderProductTax.php similarity index 75% rename from core/lib/Thelia/Model/Base/FeatureCategory.php rename to core/lib/Thelia/Model/Base/OrderProductTax.php index 035e077d2..544755ff4 100644 --- a/core/lib/Thelia/Model/Base/FeatureCategory.php +++ b/core/lib/Thelia/Model/Base/OrderProductTax.php @@ -16,20 +16,18 @@ use Propel\Runtime\Exception\PropelException; use Propel\Runtime\Map\TableMap; use Propel\Runtime\Parser\AbstractParser; use Propel\Runtime\Util\PropelDateTime; -use Thelia\Model\Category as ChildCategory; -use Thelia\Model\CategoryQuery as ChildCategoryQuery; -use Thelia\Model\Feature as ChildFeature; -use Thelia\Model\FeatureCategory as ChildFeatureCategory; -use Thelia\Model\FeatureCategoryQuery as ChildFeatureCategoryQuery; -use Thelia\Model\FeatureQuery as ChildFeatureQuery; -use Thelia\Model\Map\FeatureCategoryTableMap; +use Thelia\Model\OrderProduct as ChildOrderProduct; +use Thelia\Model\OrderProductQuery as ChildOrderProductQuery; +use Thelia\Model\OrderProductTax as ChildOrderProductTax; +use Thelia\Model\OrderProductTaxQuery as ChildOrderProductTaxQuery; +use Thelia\Model\Map\OrderProductTaxTableMap; -abstract class FeatureCategory implements ActiveRecordInterface +abstract class OrderProductTax implements ActiveRecordInterface { /** * TableMap class name */ - const TABLE_MAP = '\\Thelia\\Model\\Map\\FeatureCategoryTableMap'; + const TABLE_MAP = '\\Thelia\\Model\\Map\\OrderProductTaxTableMap'; /** @@ -65,16 +63,28 @@ abstract class FeatureCategory implements ActiveRecordInterface protected $id; /** - * The value for the feature_id field. + * The value for the order_product_id field. * @var int */ - protected $feature_id; + protected $order_product_id; /** - * The value for the category_id field. - * @var int + * The value for the title field. + * @var string */ - protected $category_id; + protected $title; + + /** + * The value for the description field. + * @var string + */ + protected $description; + + /** + * The value for the amount field. + * @var double + */ + protected $amount; /** * The value for the created_at field. @@ -89,14 +99,9 @@ abstract class FeatureCategory implements ActiveRecordInterface protected $updated_at; /** - * @var Category + * @var OrderProduct */ - protected $aCategory; - - /** - * @var Feature - */ - protected $aFeature; + protected $aOrderProduct; /** * Flag to prevent endless save loop, if this object is referenced @@ -107,7 +112,7 @@ abstract class FeatureCategory implements ActiveRecordInterface protected $alreadyInSave = false; /** - * Initializes internal state of Thelia\Model\Base\FeatureCategory object. + * Initializes internal state of Thelia\Model\Base\OrderProductTax object. */ public function __construct() { @@ -202,9 +207,9 @@ abstract class FeatureCategory implements ActiveRecordInterface } /** - * Compares this with another FeatureCategory instance. If - * obj is an instance of FeatureCategory, delegates to - * equals(FeatureCategory). Otherwise, returns false. + * Compares this with another OrderProductTax instance. If + * obj is an instance of OrderProductTax, delegates to + * equals(OrderProductTax). Otherwise, returns false. * * @param obj The object to compare to. * @return Whether equal to the object specified. @@ -285,7 +290,7 @@ abstract class FeatureCategory implements ActiveRecordInterface * @param string $name The virtual column name * @param mixed $value The value to give to the virtual column * - * @return FeatureCategory The current object, for fluid interface + * @return OrderProductTax The current object, for fluid interface */ public function setVirtualColumn($name, $value) { @@ -317,7 +322,7 @@ abstract class FeatureCategory implements ActiveRecordInterface * or a format name ('XML', 'YAML', 'JSON', 'CSV') * @param string $data The source data to import from * - * @return FeatureCategory The current object, for fluid interface + * @return OrderProductTax The current object, for fluid interface */ public function importFrom($parser, $data) { @@ -372,25 +377,47 @@ abstract class FeatureCategory implements ActiveRecordInterface } /** - * Get the [feature_id] column value. + * Get the [order_product_id] column value. * * @return int */ - public function getFeatureId() + public function getOrderProductId() { - return $this->feature_id; + return $this->order_product_id; } /** - * Get the [category_id] column value. + * Get the [title] column value. * - * @return int + * @return string */ - public function getCategoryId() + public function getTitle() { - return $this->category_id; + return $this->title; + } + + /** + * Get the [description] column value. + * + * @return string + */ + public function getDescription() + { + + return $this->description; + } + + /** + * Get the [amount] column value. + * + * @return double + */ + public function getAmount() + { + + return $this->amount; } /** @@ -437,7 +464,7 @@ abstract class FeatureCategory implements ActiveRecordInterface * Set the value of [id] column. * * @param int $v new value - * @return \Thelia\Model\FeatureCategory The current object (for fluent API support) + * @return \Thelia\Model\OrderProductTax The current object (for fluent API support) */ public function setId($v) { @@ -447,7 +474,7 @@ abstract class FeatureCategory implements ActiveRecordInterface if ($this->id !== $v) { $this->id = $v; - $this->modifiedColumns[] = FeatureCategoryTableMap::ID; + $this->modifiedColumns[] = OrderProductTaxTableMap::ID; } @@ -455,61 +482,99 @@ abstract class FeatureCategory implements ActiveRecordInterface } // setId() /** - * Set the value of [feature_id] column. + * Set the value of [order_product_id] column. * * @param int $v new value - * @return \Thelia\Model\FeatureCategory The current object (for fluent API support) + * @return \Thelia\Model\OrderProductTax The current object (for fluent API support) */ - public function setFeatureId($v) + public function setOrderProductId($v) { if ($v !== null) { $v = (int) $v; } - if ($this->feature_id !== $v) { - $this->feature_id = $v; - $this->modifiedColumns[] = FeatureCategoryTableMap::FEATURE_ID; + if ($this->order_product_id !== $v) { + $this->order_product_id = $v; + $this->modifiedColumns[] = OrderProductTaxTableMap::ORDER_PRODUCT_ID; } - if ($this->aFeature !== null && $this->aFeature->getId() !== $v) { - $this->aFeature = null; + if ($this->aOrderProduct !== null && $this->aOrderProduct->getId() !== $v) { + $this->aOrderProduct = null; } return $this; - } // setFeatureId() + } // setOrderProductId() /** - * Set the value of [category_id] column. + * Set the value of [title] column. * - * @param int $v new value - * @return \Thelia\Model\FeatureCategory The current object (for fluent API support) + * @param string $v new value + * @return \Thelia\Model\OrderProductTax The current object (for fluent API support) */ - public function setCategoryId($v) + public function setTitle($v) { if ($v !== null) { - $v = (int) $v; + $v = (string) $v; } - if ($this->category_id !== $v) { - $this->category_id = $v; - $this->modifiedColumns[] = FeatureCategoryTableMap::CATEGORY_ID; - } - - if ($this->aCategory !== null && $this->aCategory->getId() !== $v) { - $this->aCategory = null; + if ($this->title !== $v) { + $this->title = $v; + $this->modifiedColumns[] = OrderProductTaxTableMap::TITLE; } return $this; - } // setCategoryId() + } // setTitle() + + /** + * Set the value of [description] column. + * + * @param string $v new value + * @return \Thelia\Model\OrderProductTax The current object (for fluent API support) + */ + public function setDescription($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->description !== $v) { + $this->description = $v; + $this->modifiedColumns[] = OrderProductTaxTableMap::DESCRIPTION; + } + + + return $this; + } // setDescription() + + /** + * Set the value of [amount] column. + * + * @param double $v new value + * @return \Thelia\Model\OrderProductTax The current object (for fluent API support) + */ + public function setAmount($v) + { + if ($v !== null) { + $v = (double) $v; + } + + if ($this->amount !== $v) { + $this->amount = $v; + $this->modifiedColumns[] = OrderProductTaxTableMap::AMOUNT; + } + + + return $this; + } // setAmount() /** * Sets the value of [created_at] column to a normalized version of the date/time value specified. * * @param mixed $v string, integer (timestamp), or \DateTime value. * Empty strings are treated as NULL. - * @return \Thelia\Model\FeatureCategory The current object (for fluent API support) + * @return \Thelia\Model\OrderProductTax The current object (for fluent API support) */ public function setCreatedAt($v) { @@ -517,7 +582,7 @@ abstract class FeatureCategory implements ActiveRecordInterface if ($this->created_at !== null || $dt !== null) { if ($dt !== $this->created_at) { $this->created_at = $dt; - $this->modifiedColumns[] = FeatureCategoryTableMap::CREATED_AT; + $this->modifiedColumns[] = OrderProductTaxTableMap::CREATED_AT; } } // if either are not null @@ -530,7 +595,7 @@ abstract class FeatureCategory implements ActiveRecordInterface * * @param mixed $v string, integer (timestamp), or \DateTime value. * Empty strings are treated as NULL. - * @return \Thelia\Model\FeatureCategory The current object (for fluent API support) + * @return \Thelia\Model\OrderProductTax The current object (for fluent API support) */ public function setUpdatedAt($v) { @@ -538,7 +603,7 @@ abstract class FeatureCategory implements ActiveRecordInterface if ($this->updated_at !== null || $dt !== null) { if ($dt !== $this->updated_at) { $this->updated_at = $dt; - $this->modifiedColumns[] = FeatureCategoryTableMap::UPDATED_AT; + $this->modifiedColumns[] = OrderProductTaxTableMap::UPDATED_AT; } } // if either are not null @@ -583,22 +648,28 @@ abstract class FeatureCategory implements ActiveRecordInterface try { - $col = $row[TableMap::TYPE_NUM == $indexType ? 0 + $startcol : FeatureCategoryTableMap::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 0 + $startcol : OrderProductTaxTableMap::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)]; $this->id = (null !== $col) ? (int) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 1 + $startcol : FeatureCategoryTableMap::translateFieldName('FeatureId', TableMap::TYPE_PHPNAME, $indexType)]; - $this->feature_id = (null !== $col) ? (int) $col : null; + $col = $row[TableMap::TYPE_NUM == $indexType ? 1 + $startcol : OrderProductTaxTableMap::translateFieldName('OrderProductId', TableMap::TYPE_PHPNAME, $indexType)]; + $this->order_product_id = (null !== $col) ? (int) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : FeatureCategoryTableMap::translateFieldName('CategoryId', TableMap::TYPE_PHPNAME, $indexType)]; - $this->category_id = (null !== $col) ? (int) $col : null; + $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : OrderProductTaxTableMap::translateFieldName('Title', TableMap::TYPE_PHPNAME, $indexType)]; + $this->title = (null !== $col) ? (string) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : FeatureCategoryTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : OrderProductTaxTableMap::translateFieldName('Description', TableMap::TYPE_PHPNAME, $indexType)]; + $this->description = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : OrderProductTaxTableMap::translateFieldName('Amount', TableMap::TYPE_PHPNAME, $indexType)]; + $this->amount = (null !== $col) ? (double) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : OrderProductTaxTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } $this->created_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : FeatureCategoryTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : OrderProductTaxTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } @@ -611,10 +682,10 @@ abstract class FeatureCategory implements ActiveRecordInterface $this->ensureConsistency(); } - return $startcol + 5; // 5 = FeatureCategoryTableMap::NUM_HYDRATE_COLUMNS. + return $startcol + 7; // 7 = OrderProductTaxTableMap::NUM_HYDRATE_COLUMNS. } catch (Exception $e) { - throw new PropelException("Error populating \Thelia\Model\FeatureCategory object", 0, $e); + throw new PropelException("Error populating \Thelia\Model\OrderProductTax object", 0, $e); } } @@ -633,11 +704,8 @@ abstract class FeatureCategory implements ActiveRecordInterface */ public function ensureConsistency() { - if ($this->aFeature !== null && $this->feature_id !== $this->aFeature->getId()) { - $this->aFeature = null; - } - if ($this->aCategory !== null && $this->category_id !== $this->aCategory->getId()) { - $this->aCategory = null; + if ($this->aOrderProduct !== null && $this->order_product_id !== $this->aOrderProduct->getId()) { + $this->aOrderProduct = null; } } // ensureConsistency @@ -662,13 +730,13 @@ abstract class FeatureCategory implements ActiveRecordInterface } if ($con === null) { - $con = Propel::getServiceContainer()->getReadConnection(FeatureCategoryTableMap::DATABASE_NAME); + $con = Propel::getServiceContainer()->getReadConnection(OrderProductTaxTableMap::DATABASE_NAME); } // We don't need to alter the object instance pool; we're just modifying this instance // already in the pool. - $dataFetcher = ChildFeatureCategoryQuery::create(null, $this->buildPkeyCriteria())->setFormatter(ModelCriteria::FORMAT_STATEMENT)->find($con); + $dataFetcher = ChildOrderProductTaxQuery::create(null, $this->buildPkeyCriteria())->setFormatter(ModelCriteria::FORMAT_STATEMENT)->find($con); $row = $dataFetcher->fetch(); $dataFetcher->close(); if (!$row) { @@ -678,8 +746,7 @@ abstract class FeatureCategory implements ActiveRecordInterface if ($deep) { // also de-associate any related objects? - $this->aCategory = null; - $this->aFeature = null; + $this->aOrderProduct = null; } // if (deep) } @@ -689,8 +756,8 @@ abstract class FeatureCategory implements ActiveRecordInterface * @param ConnectionInterface $con * @return void * @throws PropelException - * @see FeatureCategory::setDeleted() - * @see FeatureCategory::isDeleted() + * @see OrderProductTax::setDeleted() + * @see OrderProductTax::isDeleted() */ public function delete(ConnectionInterface $con = null) { @@ -699,12 +766,12 @@ abstract class FeatureCategory implements ActiveRecordInterface } if ($con === null) { - $con = Propel::getServiceContainer()->getWriteConnection(FeatureCategoryTableMap::DATABASE_NAME); + $con = Propel::getServiceContainer()->getWriteConnection(OrderProductTaxTableMap::DATABASE_NAME); } $con->beginTransaction(); try { - $deleteQuery = ChildFeatureCategoryQuery::create() + $deleteQuery = ChildOrderProductTaxQuery::create() ->filterByPrimaryKey($this->getPrimaryKey()); $ret = $this->preDelete($con); if ($ret) { @@ -741,7 +808,7 @@ abstract class FeatureCategory implements ActiveRecordInterface } if ($con === null) { - $con = Propel::getServiceContainer()->getWriteConnection(FeatureCategoryTableMap::DATABASE_NAME); + $con = Propel::getServiceContainer()->getWriteConnection(OrderProductTaxTableMap::DATABASE_NAME); } $con->beginTransaction(); @@ -751,16 +818,16 @@ abstract class FeatureCategory implements ActiveRecordInterface if ($isInsert) { $ret = $ret && $this->preInsert($con); // timestampable behavior - if (!$this->isColumnModified(FeatureCategoryTableMap::CREATED_AT)) { + if (!$this->isColumnModified(OrderProductTaxTableMap::CREATED_AT)) { $this->setCreatedAt(time()); } - if (!$this->isColumnModified(FeatureCategoryTableMap::UPDATED_AT)) { + if (!$this->isColumnModified(OrderProductTaxTableMap::UPDATED_AT)) { $this->setUpdatedAt(time()); } } else { $ret = $ret && $this->preUpdate($con); // timestampable behavior - if ($this->isModified() && !$this->isColumnModified(FeatureCategoryTableMap::UPDATED_AT)) { + if ($this->isModified() && !$this->isColumnModified(OrderProductTaxTableMap::UPDATED_AT)) { $this->setUpdatedAt(time()); } } @@ -772,7 +839,7 @@ abstract class FeatureCategory implements ActiveRecordInterface $this->postUpdate($con); } $this->postSave($con); - FeatureCategoryTableMap::addInstanceToPool($this); + OrderProductTaxTableMap::addInstanceToPool($this); } else { $affectedRows = 0; } @@ -807,18 +874,11 @@ abstract class FeatureCategory implements ActiveRecordInterface // method. This object relates to these object(s) by a // foreign key reference. - if ($this->aCategory !== null) { - if ($this->aCategory->isModified() || $this->aCategory->isNew()) { - $affectedRows += $this->aCategory->save($con); + if ($this->aOrderProduct !== null) { + if ($this->aOrderProduct->isModified() || $this->aOrderProduct->isNew()) { + $affectedRows += $this->aOrderProduct->save($con); } - $this->setCategory($this->aCategory); - } - - if ($this->aFeature !== null) { - if ($this->aFeature->isModified() || $this->aFeature->isNew()) { - $affectedRows += $this->aFeature->save($con); - } - $this->setFeature($this->aFeature); + $this->setOrderProduct($this->aOrderProduct); } if ($this->isNew() || $this->isModified()) { @@ -852,30 +912,36 @@ abstract class FeatureCategory implements ActiveRecordInterface $modifiedColumns = array(); $index = 0; - $this->modifiedColumns[] = FeatureCategoryTableMap::ID; + $this->modifiedColumns[] = OrderProductTaxTableMap::ID; if (null !== $this->id) { - throw new PropelException('Cannot insert a value for auto-increment primary key (' . FeatureCategoryTableMap::ID . ')'); + throw new PropelException('Cannot insert a value for auto-increment primary key (' . OrderProductTaxTableMap::ID . ')'); } // check the columns in natural order for more readable SQL queries - if ($this->isColumnModified(FeatureCategoryTableMap::ID)) { + if ($this->isColumnModified(OrderProductTaxTableMap::ID)) { $modifiedColumns[':p' . $index++] = 'ID'; } - if ($this->isColumnModified(FeatureCategoryTableMap::FEATURE_ID)) { - $modifiedColumns[':p' . $index++] = 'FEATURE_ID'; + if ($this->isColumnModified(OrderProductTaxTableMap::ORDER_PRODUCT_ID)) { + $modifiedColumns[':p' . $index++] = 'ORDER_PRODUCT_ID'; } - if ($this->isColumnModified(FeatureCategoryTableMap::CATEGORY_ID)) { - $modifiedColumns[':p' . $index++] = 'CATEGORY_ID'; + if ($this->isColumnModified(OrderProductTaxTableMap::TITLE)) { + $modifiedColumns[':p' . $index++] = 'TITLE'; } - if ($this->isColumnModified(FeatureCategoryTableMap::CREATED_AT)) { + if ($this->isColumnModified(OrderProductTaxTableMap::DESCRIPTION)) { + $modifiedColumns[':p' . $index++] = 'DESCRIPTION'; + } + if ($this->isColumnModified(OrderProductTaxTableMap::AMOUNT)) { + $modifiedColumns[':p' . $index++] = 'AMOUNT'; + } + if ($this->isColumnModified(OrderProductTaxTableMap::CREATED_AT)) { $modifiedColumns[':p' . $index++] = 'CREATED_AT'; } - if ($this->isColumnModified(FeatureCategoryTableMap::UPDATED_AT)) { + if ($this->isColumnModified(OrderProductTaxTableMap::UPDATED_AT)) { $modifiedColumns[':p' . $index++] = 'UPDATED_AT'; } $sql = sprintf( - 'INSERT INTO feature_category (%s) VALUES (%s)', + 'INSERT INTO order_product_tax (%s) VALUES (%s)', implode(', ', $modifiedColumns), implode(', ', array_keys($modifiedColumns)) ); @@ -887,11 +953,17 @@ abstract class FeatureCategory implements ActiveRecordInterface case 'ID': $stmt->bindValue($identifier, $this->id, PDO::PARAM_INT); break; - case 'FEATURE_ID': - $stmt->bindValue($identifier, $this->feature_id, PDO::PARAM_INT); + case 'ORDER_PRODUCT_ID': + $stmt->bindValue($identifier, $this->order_product_id, PDO::PARAM_INT); break; - case 'CATEGORY_ID': - $stmt->bindValue($identifier, $this->category_id, PDO::PARAM_INT); + case 'TITLE': + $stmt->bindValue($identifier, $this->title, PDO::PARAM_STR); + break; + case 'DESCRIPTION': + $stmt->bindValue($identifier, $this->description, PDO::PARAM_STR); + break; + case 'AMOUNT': + $stmt->bindValue($identifier, $this->amount, PDO::PARAM_STR); break; case 'CREATED_AT': $stmt->bindValue($identifier, $this->created_at ? $this->created_at->format("Y-m-d H:i:s") : null, PDO::PARAM_STR); @@ -945,7 +1017,7 @@ abstract class FeatureCategory implements ActiveRecordInterface */ public function getByName($name, $type = TableMap::TYPE_PHPNAME) { - $pos = FeatureCategoryTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); + $pos = OrderProductTaxTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); $field = $this->getByPosition($pos); return $field; @@ -965,15 +1037,21 @@ abstract class FeatureCategory implements ActiveRecordInterface return $this->getId(); break; case 1: - return $this->getFeatureId(); + return $this->getOrderProductId(); break; case 2: - return $this->getCategoryId(); + return $this->getTitle(); break; case 3: - return $this->getCreatedAt(); + return $this->getDescription(); break; case 4: + return $this->getAmount(); + break; + case 5: + return $this->getCreatedAt(); + break; + case 6: return $this->getUpdatedAt(); break; default: @@ -999,17 +1077,19 @@ abstract class FeatureCategory implements ActiveRecordInterface */ public function toArray($keyType = TableMap::TYPE_PHPNAME, $includeLazyLoadColumns = true, $alreadyDumpedObjects = array(), $includeForeignObjects = false) { - if (isset($alreadyDumpedObjects['FeatureCategory'][$this->getPrimaryKey()])) { + if (isset($alreadyDumpedObjects['OrderProductTax'][$this->getPrimaryKey()])) { return '*RECURSION*'; } - $alreadyDumpedObjects['FeatureCategory'][$this->getPrimaryKey()] = true; - $keys = FeatureCategoryTableMap::getFieldNames($keyType); + $alreadyDumpedObjects['OrderProductTax'][$this->getPrimaryKey()] = true; + $keys = OrderProductTaxTableMap::getFieldNames($keyType); $result = array( $keys[0] => $this->getId(), - $keys[1] => $this->getFeatureId(), - $keys[2] => $this->getCategoryId(), - $keys[3] => $this->getCreatedAt(), - $keys[4] => $this->getUpdatedAt(), + $keys[1] => $this->getOrderProductId(), + $keys[2] => $this->getTitle(), + $keys[3] => $this->getDescription(), + $keys[4] => $this->getAmount(), + $keys[5] => $this->getCreatedAt(), + $keys[6] => $this->getUpdatedAt(), ); $virtualColumns = $this->virtualColumns; foreach($virtualColumns as $key => $virtualColumn) @@ -1018,11 +1098,8 @@ abstract class FeatureCategory implements ActiveRecordInterface } if ($includeForeignObjects) { - if (null !== $this->aCategory) { - $result['Category'] = $this->aCategory->toArray($keyType, $includeLazyLoadColumns, $alreadyDumpedObjects, true); - } - if (null !== $this->aFeature) { - $result['Feature'] = $this->aFeature->toArray($keyType, $includeLazyLoadColumns, $alreadyDumpedObjects, true); + if (null !== $this->aOrderProduct) { + $result['OrderProduct'] = $this->aOrderProduct->toArray($keyType, $includeLazyLoadColumns, $alreadyDumpedObjects, true); } } @@ -1042,7 +1119,7 @@ abstract class FeatureCategory implements ActiveRecordInterface */ public function setByName($name, $value, $type = TableMap::TYPE_PHPNAME) { - $pos = FeatureCategoryTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); + $pos = OrderProductTaxTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); return $this->setByPosition($pos, $value); } @@ -1062,15 +1139,21 @@ abstract class FeatureCategory implements ActiveRecordInterface $this->setId($value); break; case 1: - $this->setFeatureId($value); + $this->setOrderProductId($value); break; case 2: - $this->setCategoryId($value); + $this->setTitle($value); break; case 3: - $this->setCreatedAt($value); + $this->setDescription($value); break; case 4: + $this->setAmount($value); + break; + case 5: + $this->setCreatedAt($value); + break; + case 6: $this->setUpdatedAt($value); break; } // switch() @@ -1095,13 +1178,15 @@ abstract class FeatureCategory implements ActiveRecordInterface */ public function fromArray($arr, $keyType = TableMap::TYPE_PHPNAME) { - $keys = FeatureCategoryTableMap::getFieldNames($keyType); + $keys = OrderProductTaxTableMap::getFieldNames($keyType); if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]); - if (array_key_exists($keys[1], $arr)) $this->setFeatureId($arr[$keys[1]]); - if (array_key_exists($keys[2], $arr)) $this->setCategoryId($arr[$keys[2]]); - if (array_key_exists($keys[3], $arr)) $this->setCreatedAt($arr[$keys[3]]); - if (array_key_exists($keys[4], $arr)) $this->setUpdatedAt($arr[$keys[4]]); + if (array_key_exists($keys[1], $arr)) $this->setOrderProductId($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setTitle($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setDescription($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setAmount($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setCreatedAt($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setUpdatedAt($arr[$keys[6]]); } /** @@ -1111,13 +1196,15 @@ abstract class FeatureCategory implements ActiveRecordInterface */ public function buildCriteria() { - $criteria = new Criteria(FeatureCategoryTableMap::DATABASE_NAME); + $criteria = new Criteria(OrderProductTaxTableMap::DATABASE_NAME); - if ($this->isColumnModified(FeatureCategoryTableMap::ID)) $criteria->add(FeatureCategoryTableMap::ID, $this->id); - if ($this->isColumnModified(FeatureCategoryTableMap::FEATURE_ID)) $criteria->add(FeatureCategoryTableMap::FEATURE_ID, $this->feature_id); - if ($this->isColumnModified(FeatureCategoryTableMap::CATEGORY_ID)) $criteria->add(FeatureCategoryTableMap::CATEGORY_ID, $this->category_id); - if ($this->isColumnModified(FeatureCategoryTableMap::CREATED_AT)) $criteria->add(FeatureCategoryTableMap::CREATED_AT, $this->created_at); - if ($this->isColumnModified(FeatureCategoryTableMap::UPDATED_AT)) $criteria->add(FeatureCategoryTableMap::UPDATED_AT, $this->updated_at); + if ($this->isColumnModified(OrderProductTaxTableMap::ID)) $criteria->add(OrderProductTaxTableMap::ID, $this->id); + if ($this->isColumnModified(OrderProductTaxTableMap::ORDER_PRODUCT_ID)) $criteria->add(OrderProductTaxTableMap::ORDER_PRODUCT_ID, $this->order_product_id); + if ($this->isColumnModified(OrderProductTaxTableMap::TITLE)) $criteria->add(OrderProductTaxTableMap::TITLE, $this->title); + if ($this->isColumnModified(OrderProductTaxTableMap::DESCRIPTION)) $criteria->add(OrderProductTaxTableMap::DESCRIPTION, $this->description); + if ($this->isColumnModified(OrderProductTaxTableMap::AMOUNT)) $criteria->add(OrderProductTaxTableMap::AMOUNT, $this->amount); + if ($this->isColumnModified(OrderProductTaxTableMap::CREATED_AT)) $criteria->add(OrderProductTaxTableMap::CREATED_AT, $this->created_at); + if ($this->isColumnModified(OrderProductTaxTableMap::UPDATED_AT)) $criteria->add(OrderProductTaxTableMap::UPDATED_AT, $this->updated_at); return $criteria; } @@ -1132,8 +1219,8 @@ abstract class FeatureCategory implements ActiveRecordInterface */ public function buildPkeyCriteria() { - $criteria = new Criteria(FeatureCategoryTableMap::DATABASE_NAME); - $criteria->add(FeatureCategoryTableMap::ID, $this->id); + $criteria = new Criteria(OrderProductTaxTableMap::DATABASE_NAME); + $criteria->add(OrderProductTaxTableMap::ID, $this->id); return $criteria; } @@ -1174,15 +1261,17 @@ abstract class FeatureCategory implements ActiveRecordInterface * If desired, this method can also make copies of all associated (fkey referrers) * objects. * - * @param object $copyObj An object of \Thelia\Model\FeatureCategory (or compatible) type. + * @param object $copyObj An object of \Thelia\Model\OrderProductTax (or compatible) type. * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. * @param boolean $makeNew Whether to reset autoincrement PKs and make the object new. * @throws PropelException */ public function copyInto($copyObj, $deepCopy = false, $makeNew = true) { - $copyObj->setFeatureId($this->getFeatureId()); - $copyObj->setCategoryId($this->getCategoryId()); + $copyObj->setOrderProductId($this->getOrderProductId()); + $copyObj->setTitle($this->getTitle()); + $copyObj->setDescription($this->getDescription()); + $copyObj->setAmount($this->getAmount()); $copyObj->setCreatedAt($this->getCreatedAt()); $copyObj->setUpdatedAt($this->getUpdatedAt()); if ($makeNew) { @@ -1200,7 +1289,7 @@ abstract class FeatureCategory implements ActiveRecordInterface * objects. * * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. - * @return \Thelia\Model\FeatureCategory Clone of current object. + * @return \Thelia\Model\OrderProductTax Clone of current object. * @throws PropelException */ public function copy($deepCopy = false) @@ -1214,26 +1303,26 @@ abstract class FeatureCategory implements ActiveRecordInterface } /** - * Declares an association between this object and a ChildCategory object. + * Declares an association between this object and a ChildOrderProduct object. * - * @param ChildCategory $v - * @return \Thelia\Model\FeatureCategory The current object (for fluent API support) + * @param ChildOrderProduct $v + * @return \Thelia\Model\OrderProductTax The current object (for fluent API support) * @throws PropelException */ - public function setCategory(ChildCategory $v = null) + public function setOrderProduct(ChildOrderProduct $v = null) { if ($v === null) { - $this->setCategoryId(NULL); + $this->setOrderProductId(NULL); } else { - $this->setCategoryId($v->getId()); + $this->setOrderProductId($v->getId()); } - $this->aCategory = $v; + $this->aOrderProduct = $v; // Add binding for other direction of this n:n relationship. - // If this object has already been added to the ChildCategory object, it will not be re-added. + // If this object has already been added to the ChildOrderProduct object, it will not be re-added. if ($v !== null) { - $v->addFeatureCategory($this); + $v->addOrderProductTax($this); } @@ -1242,77 +1331,26 @@ abstract class FeatureCategory implements ActiveRecordInterface /** - * Get the associated ChildCategory object + * Get the associated ChildOrderProduct object * * @param ConnectionInterface $con Optional Connection object. - * @return ChildCategory The associated ChildCategory object. + * @return ChildOrderProduct The associated ChildOrderProduct object. * @throws PropelException */ - public function getCategory(ConnectionInterface $con = null) + public function getOrderProduct(ConnectionInterface $con = null) { - if ($this->aCategory === null && ($this->category_id !== null)) { - $this->aCategory = ChildCategoryQuery::create()->findPk($this->category_id, $con); + if ($this->aOrderProduct === null && ($this->order_product_id !== null)) { + $this->aOrderProduct = ChildOrderProductQuery::create()->findPk($this->order_product_id, $con); /* The following can be used additionally to guarantee the related object contains a reference to this object. This level of coupling may, however, be undesirable since it could result in an only partially populated collection in the referenced object. - $this->aCategory->addFeatureCategories($this); + $this->aOrderProduct->addOrderProductTaxes($this); */ } - return $this->aCategory; - } - - /** - * Declares an association between this object and a ChildFeature object. - * - * @param ChildFeature $v - * @return \Thelia\Model\FeatureCategory The current object (for fluent API support) - * @throws PropelException - */ - public function setFeature(ChildFeature $v = null) - { - if ($v === null) { - $this->setFeatureId(NULL); - } else { - $this->setFeatureId($v->getId()); - } - - $this->aFeature = $v; - - // Add binding for other direction of this n:n relationship. - // If this object has already been added to the ChildFeature object, it will not be re-added. - if ($v !== null) { - $v->addFeatureCategory($this); - } - - - return $this; - } - - - /** - * Get the associated ChildFeature object - * - * @param ConnectionInterface $con Optional Connection object. - * @return ChildFeature The associated ChildFeature object. - * @throws PropelException - */ - public function getFeature(ConnectionInterface $con = null) - { - if ($this->aFeature === null && ($this->feature_id !== null)) { - $this->aFeature = ChildFeatureQuery::create()->findPk($this->feature_id, $con); - /* The following can be used additionally to - guarantee the related object contains a reference - to this object. This level of coupling may, however, be - undesirable since it could result in an only partially populated collection - in the referenced object. - $this->aFeature->addFeatureCategories($this); - */ - } - - return $this->aFeature; + return $this->aOrderProduct; } /** @@ -1321,8 +1359,10 @@ abstract class FeatureCategory implements ActiveRecordInterface public function clear() { $this->id = null; - $this->feature_id = null; - $this->category_id = null; + $this->order_product_id = null; + $this->title = null; + $this->description = null; + $this->amount = null; $this->created_at = null; $this->updated_at = null; $this->alreadyInSave = false; @@ -1346,8 +1386,7 @@ abstract class FeatureCategory implements ActiveRecordInterface if ($deep) { } // if ($deep) - $this->aCategory = null; - $this->aFeature = null; + $this->aOrderProduct = null; } /** @@ -1357,7 +1396,7 @@ abstract class FeatureCategory implements ActiveRecordInterface */ public function __toString() { - return (string) $this->exportTo(FeatureCategoryTableMap::DEFAULT_STRING_FORMAT); + return (string) $this->exportTo(OrderProductTaxTableMap::DEFAULT_STRING_FORMAT); } // timestampable behavior @@ -1365,11 +1404,11 @@ abstract class FeatureCategory implements ActiveRecordInterface /** * Mark the current object so that the update date doesn't get updated during next save * - * @return ChildFeatureCategory The current object (for fluent API support) + * @return ChildOrderProductTax The current object (for fluent API support) */ public function keepUpdateDateUnchanged() { - $this->modifiedColumns[] = FeatureCategoryTableMap::UPDATED_AT; + $this->modifiedColumns[] = OrderProductTaxTableMap::UPDATED_AT; return $this; } diff --git a/core/lib/Thelia/Model/Base/FeatureCategoryQuery.php b/core/lib/Thelia/Model/Base/OrderProductTaxQuery.php similarity index 56% rename from core/lib/Thelia/Model/Base/FeatureCategoryQuery.php rename to core/lib/Thelia/Model/Base/OrderProductTaxQuery.php index b9c9a67be..d37c2c501 100644 --- a/core/lib/Thelia/Model/Base/FeatureCategoryQuery.php +++ b/core/lib/Thelia/Model/Base/OrderProductTaxQuery.php @@ -12,84 +12,88 @@ use Propel\Runtime\Collection\Collection; use Propel\Runtime\Collection\ObjectCollection; use Propel\Runtime\Connection\ConnectionInterface; use Propel\Runtime\Exception\PropelException; -use Thelia\Model\FeatureCategory as ChildFeatureCategory; -use Thelia\Model\FeatureCategoryQuery as ChildFeatureCategoryQuery; -use Thelia\Model\Map\FeatureCategoryTableMap; +use Thelia\Model\OrderProductTax as ChildOrderProductTax; +use Thelia\Model\OrderProductTaxQuery as ChildOrderProductTaxQuery; +use Thelia\Model\Map\OrderProductTaxTableMap; /** - * Base class that represents a query for the 'feature_category' table. + * Base class that represents a query for the 'order_product_tax' table. * * * - * @method ChildFeatureCategoryQuery orderById($order = Criteria::ASC) Order by the id column - * @method ChildFeatureCategoryQuery orderByFeatureId($order = Criteria::ASC) Order by the feature_id column - * @method ChildFeatureCategoryQuery orderByCategoryId($order = Criteria::ASC) Order by the category_id column - * @method ChildFeatureCategoryQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column - * @method ChildFeatureCategoryQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column + * @method ChildOrderProductTaxQuery orderById($order = Criteria::ASC) Order by the id column + * @method ChildOrderProductTaxQuery orderByOrderProductId($order = Criteria::ASC) Order by the order_product_id column + * @method ChildOrderProductTaxQuery orderByTitle($order = Criteria::ASC) Order by the title column + * @method ChildOrderProductTaxQuery orderByDescription($order = Criteria::ASC) Order by the description column + * @method ChildOrderProductTaxQuery orderByAmount($order = Criteria::ASC) Order by the amount column + * @method ChildOrderProductTaxQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column + * @method ChildOrderProductTaxQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column * - * @method ChildFeatureCategoryQuery groupById() Group by the id column - * @method ChildFeatureCategoryQuery groupByFeatureId() Group by the feature_id column - * @method ChildFeatureCategoryQuery groupByCategoryId() Group by the category_id column - * @method ChildFeatureCategoryQuery groupByCreatedAt() Group by the created_at column - * @method ChildFeatureCategoryQuery groupByUpdatedAt() Group by the updated_at column + * @method ChildOrderProductTaxQuery groupById() Group by the id column + * @method ChildOrderProductTaxQuery groupByOrderProductId() Group by the order_product_id column + * @method ChildOrderProductTaxQuery groupByTitle() Group by the title column + * @method ChildOrderProductTaxQuery groupByDescription() Group by the description column + * @method ChildOrderProductTaxQuery groupByAmount() Group by the amount column + * @method ChildOrderProductTaxQuery groupByCreatedAt() Group by the created_at column + * @method ChildOrderProductTaxQuery groupByUpdatedAt() Group by the updated_at column * - * @method ChildFeatureCategoryQuery leftJoin($relation) Adds a LEFT JOIN clause to the query - * @method ChildFeatureCategoryQuery rightJoin($relation) Adds a RIGHT JOIN clause to the query - * @method ChildFeatureCategoryQuery innerJoin($relation) Adds a INNER JOIN clause to the query + * @method ChildOrderProductTaxQuery leftJoin($relation) Adds a LEFT JOIN clause to the query + * @method ChildOrderProductTaxQuery rightJoin($relation) Adds a RIGHT JOIN clause to the query + * @method ChildOrderProductTaxQuery innerJoin($relation) Adds a INNER JOIN clause to the query * - * @method ChildFeatureCategoryQuery leftJoinCategory($relationAlias = null) Adds a LEFT JOIN clause to the query using the Category relation - * @method ChildFeatureCategoryQuery rightJoinCategory($relationAlias = null) Adds a RIGHT JOIN clause to the query using the Category relation - * @method ChildFeatureCategoryQuery innerJoinCategory($relationAlias = null) Adds a INNER JOIN clause to the query using the Category relation + * @method ChildOrderProductTaxQuery leftJoinOrderProduct($relationAlias = null) Adds a LEFT JOIN clause to the query using the OrderProduct relation + * @method ChildOrderProductTaxQuery rightJoinOrderProduct($relationAlias = null) Adds a RIGHT JOIN clause to the query using the OrderProduct relation + * @method ChildOrderProductTaxQuery innerJoinOrderProduct($relationAlias = null) Adds a INNER JOIN clause to the query using the OrderProduct relation * - * @method ChildFeatureCategoryQuery leftJoinFeature($relationAlias = null) Adds a LEFT JOIN clause to the query using the Feature relation - * @method ChildFeatureCategoryQuery rightJoinFeature($relationAlias = null) Adds a RIGHT JOIN clause to the query using the Feature relation - * @method ChildFeatureCategoryQuery innerJoinFeature($relationAlias = null) Adds a INNER JOIN clause to the query using the Feature relation + * @method ChildOrderProductTax findOne(ConnectionInterface $con = null) Return the first ChildOrderProductTax matching the query + * @method ChildOrderProductTax findOneOrCreate(ConnectionInterface $con = null) Return the first ChildOrderProductTax matching the query, or a new ChildOrderProductTax object populated from the query conditions when no match is found * - * @method ChildFeatureCategory findOne(ConnectionInterface $con = null) Return the first ChildFeatureCategory matching the query - * @method ChildFeatureCategory findOneOrCreate(ConnectionInterface $con = null) Return the first ChildFeatureCategory matching the query, or a new ChildFeatureCategory object populated from the query conditions when no match is found + * @method ChildOrderProductTax findOneById(int $id) Return the first ChildOrderProductTax filtered by the id column + * @method ChildOrderProductTax findOneByOrderProductId(int $order_product_id) Return the first ChildOrderProductTax filtered by the order_product_id column + * @method ChildOrderProductTax findOneByTitle(string $title) Return the first ChildOrderProductTax filtered by the title column + * @method ChildOrderProductTax findOneByDescription(string $description) Return the first ChildOrderProductTax filtered by the description column + * @method ChildOrderProductTax findOneByAmount(double $amount) Return the first ChildOrderProductTax filtered by the amount column + * @method ChildOrderProductTax findOneByCreatedAt(string $created_at) Return the first ChildOrderProductTax filtered by the created_at column + * @method ChildOrderProductTax findOneByUpdatedAt(string $updated_at) Return the first ChildOrderProductTax filtered by the updated_at column * - * @method ChildFeatureCategory findOneById(int $id) Return the first ChildFeatureCategory filtered by the id column - * @method ChildFeatureCategory findOneByFeatureId(int $feature_id) Return the first ChildFeatureCategory filtered by the feature_id column - * @method ChildFeatureCategory findOneByCategoryId(int $category_id) Return the first ChildFeatureCategory filtered by the category_id column - * @method ChildFeatureCategory findOneByCreatedAt(string $created_at) Return the first ChildFeatureCategory filtered by the created_at column - * @method ChildFeatureCategory findOneByUpdatedAt(string $updated_at) Return the first ChildFeatureCategory filtered by the updated_at column - * - * @method array findById(int $id) Return ChildFeatureCategory objects filtered by the id column - * @method array findByFeatureId(int $feature_id) Return ChildFeatureCategory objects filtered by the feature_id column - * @method array findByCategoryId(int $category_id) Return ChildFeatureCategory objects filtered by the category_id column - * @method array findByCreatedAt(string $created_at) Return ChildFeatureCategory objects filtered by the created_at column - * @method array findByUpdatedAt(string $updated_at) Return ChildFeatureCategory objects filtered by the updated_at column + * @method array findById(int $id) Return ChildOrderProductTax objects filtered by the id column + * @method array findByOrderProductId(int $order_product_id) Return ChildOrderProductTax objects filtered by the order_product_id column + * @method array findByTitle(string $title) Return ChildOrderProductTax objects filtered by the title column + * @method array findByDescription(string $description) Return ChildOrderProductTax objects filtered by the description column + * @method array findByAmount(double $amount) Return ChildOrderProductTax objects filtered by the amount column + * @method array findByCreatedAt(string $created_at) Return ChildOrderProductTax objects filtered by the created_at column + * @method array findByUpdatedAt(string $updated_at) Return ChildOrderProductTax objects filtered by the updated_at column * */ -abstract class FeatureCategoryQuery extends ModelCriteria +abstract class OrderProductTaxQuery extends ModelCriteria { /** - * Initializes internal state of \Thelia\Model\Base\FeatureCategoryQuery object. + * Initializes internal state of \Thelia\Model\Base\OrderProductTaxQuery object. * * @param string $dbName The database name * @param string $modelName The phpName of a model, e.g. 'Book' * @param string $modelAlias The alias for the model in this query, e.g. 'b' */ - public function __construct($dbName = 'thelia', $modelName = '\\Thelia\\Model\\FeatureCategory', $modelAlias = null) + public function __construct($dbName = 'thelia', $modelName = '\\Thelia\\Model\\OrderProductTax', $modelAlias = null) { parent::__construct($dbName, $modelName, $modelAlias); } /** - * Returns a new ChildFeatureCategoryQuery object. + * Returns a new ChildOrderProductTaxQuery object. * * @param string $modelAlias The alias of a model in the query * @param Criteria $criteria Optional Criteria to build the query from * - * @return ChildFeatureCategoryQuery + * @return ChildOrderProductTaxQuery */ public static function create($modelAlias = null, $criteria = null) { - if ($criteria instanceof \Thelia\Model\FeatureCategoryQuery) { + if ($criteria instanceof \Thelia\Model\OrderProductTaxQuery) { return $criteria; } - $query = new \Thelia\Model\FeatureCategoryQuery(); + $query = new \Thelia\Model\OrderProductTaxQuery(); if (null !== $modelAlias) { $query->setModelAlias($modelAlias); } @@ -112,19 +116,19 @@ abstract class FeatureCategoryQuery extends ModelCriteria * @param mixed $key Primary key to use for the query * @param ConnectionInterface $con an optional connection object * - * @return ChildFeatureCategory|array|mixed the result, formatted by the current formatter + * @return ChildOrderProductTax|array|mixed the result, formatted by the current formatter */ public function findPk($key, $con = null) { if ($key === null) { return null; } - if ((null !== ($obj = FeatureCategoryTableMap::getInstanceFromPool((string) $key))) && !$this->formatter) { + if ((null !== ($obj = OrderProductTaxTableMap::getInstanceFromPool((string) $key))) && !$this->formatter) { // the object is already in the instance pool return $obj; } if ($con === null) { - $con = Propel::getServiceContainer()->getReadConnection(FeatureCategoryTableMap::DATABASE_NAME); + $con = Propel::getServiceContainer()->getReadConnection(OrderProductTaxTableMap::DATABASE_NAME); } $this->basePreSelect($con); if ($this->formatter || $this->modelAlias || $this->with || $this->select @@ -143,11 +147,11 @@ abstract class FeatureCategoryQuery extends ModelCriteria * @param mixed $key Primary key to use for the query * @param ConnectionInterface $con A connection object * - * @return ChildFeatureCategory A model object, or null if the key is not found + * @return ChildOrderProductTax A model object, or null if the key is not found */ protected function findPkSimple($key, $con) { - $sql = 'SELECT ID, FEATURE_ID, CATEGORY_ID, CREATED_AT, UPDATED_AT FROM feature_category WHERE ID = :p0'; + $sql = 'SELECT ID, ORDER_PRODUCT_ID, TITLE, DESCRIPTION, AMOUNT, CREATED_AT, UPDATED_AT FROM order_product_tax WHERE ID = :p0'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key, PDO::PARAM_INT); @@ -158,9 +162,9 @@ abstract class FeatureCategoryQuery extends ModelCriteria } $obj = null; if ($row = $stmt->fetch(\PDO::FETCH_NUM)) { - $obj = new ChildFeatureCategory(); + $obj = new ChildOrderProductTax(); $obj->hydrate($row); - FeatureCategoryTableMap::addInstanceToPool($obj, (string) $key); + OrderProductTaxTableMap::addInstanceToPool($obj, (string) $key); } $stmt->closeCursor(); @@ -173,7 +177,7 @@ abstract class FeatureCategoryQuery extends ModelCriteria * @param mixed $key Primary key to use for the query * @param ConnectionInterface $con A connection object * - * @return ChildFeatureCategory|array|mixed the result, formatted by the current formatter + * @return ChildOrderProductTax|array|mixed the result, formatted by the current formatter */ protected function findPkComplex($key, $con) { @@ -215,12 +219,12 @@ abstract class FeatureCategoryQuery extends ModelCriteria * * @param mixed $key Primary key to use for the query * - * @return ChildFeatureCategoryQuery The current query, for fluid interface + * @return ChildOrderProductTaxQuery The current query, for fluid interface */ public function filterByPrimaryKey($key) { - return $this->addUsingAlias(FeatureCategoryTableMap::ID, $key, Criteria::EQUAL); + return $this->addUsingAlias(OrderProductTaxTableMap::ID, $key, Criteria::EQUAL); } /** @@ -228,12 +232,12 @@ abstract class FeatureCategoryQuery extends ModelCriteria * * @param array $keys The list of primary key to use for the query * - * @return ChildFeatureCategoryQuery The current query, for fluid interface + * @return ChildOrderProductTaxQuery The current query, for fluid interface */ public function filterByPrimaryKeys($keys) { - return $this->addUsingAlias(FeatureCategoryTableMap::ID, $keys, Criteria::IN); + return $this->addUsingAlias(OrderProductTaxTableMap::ID, $keys, Criteria::IN); } /** @@ -252,18 +256,18 @@ abstract class FeatureCategoryQuery extends ModelCriteria * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL * - * @return ChildFeatureCategoryQuery The current query, for fluid interface + * @return ChildOrderProductTaxQuery The current query, for fluid interface */ public function filterById($id = null, $comparison = null) { if (is_array($id)) { $useMinMax = false; if (isset($id['min'])) { - $this->addUsingAlias(FeatureCategoryTableMap::ID, $id['min'], Criteria::GREATER_EQUAL); + $this->addUsingAlias(OrderProductTaxTableMap::ID, $id['min'], Criteria::GREATER_EQUAL); $useMinMax = true; } if (isset($id['max'])) { - $this->addUsingAlias(FeatureCategoryTableMap::ID, $id['max'], Criteria::LESS_EQUAL); + $this->addUsingAlias(OrderProductTaxTableMap::ID, $id['max'], Criteria::LESS_EQUAL); $useMinMax = true; } if ($useMinMax) { @@ -274,39 +278,39 @@ abstract class FeatureCategoryQuery extends ModelCriteria } } - return $this->addUsingAlias(FeatureCategoryTableMap::ID, $id, $comparison); + return $this->addUsingAlias(OrderProductTaxTableMap::ID, $id, $comparison); } /** - * Filter the query on the feature_id column + * Filter the query on the order_product_id column * * Example usage: * - * $query->filterByFeatureId(1234); // WHERE feature_id = 1234 - * $query->filterByFeatureId(array(12, 34)); // WHERE feature_id IN (12, 34) - * $query->filterByFeatureId(array('min' => 12)); // WHERE feature_id > 12 + * $query->filterByOrderProductId(1234); // WHERE order_product_id = 1234 + * $query->filterByOrderProductId(array(12, 34)); // WHERE order_product_id IN (12, 34) + * $query->filterByOrderProductId(array('min' => 12)); // WHERE order_product_id > 12 * * - * @see filterByFeature() + * @see filterByOrderProduct() * - * @param mixed $featureId The value to use as filter. + * @param mixed $orderProductId The value to use as filter. * Use scalar values for equality. * Use array values for in_array() equivalent. * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL * - * @return ChildFeatureCategoryQuery The current query, for fluid interface + * @return ChildOrderProductTaxQuery The current query, for fluid interface */ - public function filterByFeatureId($featureId = null, $comparison = null) + public function filterByOrderProductId($orderProductId = null, $comparison = null) { - if (is_array($featureId)) { + if (is_array($orderProductId)) { $useMinMax = false; - if (isset($featureId['min'])) { - $this->addUsingAlias(FeatureCategoryTableMap::FEATURE_ID, $featureId['min'], Criteria::GREATER_EQUAL); + if (isset($orderProductId['min'])) { + $this->addUsingAlias(OrderProductTaxTableMap::ORDER_PRODUCT_ID, $orderProductId['min'], Criteria::GREATER_EQUAL); $useMinMax = true; } - if (isset($featureId['max'])) { - $this->addUsingAlias(FeatureCategoryTableMap::FEATURE_ID, $featureId['max'], Criteria::LESS_EQUAL); + if (isset($orderProductId['max'])) { + $this->addUsingAlias(OrderProductTaxTableMap::ORDER_PRODUCT_ID, $orderProductId['max'], Criteria::LESS_EQUAL); $useMinMax = true; } if ($useMinMax) { @@ -317,39 +321,95 @@ abstract class FeatureCategoryQuery extends ModelCriteria } } - return $this->addUsingAlias(FeatureCategoryTableMap::FEATURE_ID, $featureId, $comparison); + return $this->addUsingAlias(OrderProductTaxTableMap::ORDER_PRODUCT_ID, $orderProductId, $comparison); } /** - * Filter the query on the category_id column + * Filter the query on the title column * * Example usage: * - * $query->filterByCategoryId(1234); // WHERE category_id = 1234 - * $query->filterByCategoryId(array(12, 34)); // WHERE category_id IN (12, 34) - * $query->filterByCategoryId(array('min' => 12)); // WHERE category_id > 12 + * $query->filterByTitle('fooValue'); // WHERE title = 'fooValue' + * $query->filterByTitle('%fooValue%'); // WHERE title LIKE '%fooValue%' * * - * @see filterByCategory() + * @param string $title The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL * - * @param mixed $categoryId The value to use as filter. + * @return ChildOrderProductTaxQuery The current query, for fluid interface + */ + public function filterByTitle($title = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($title)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $title)) { + $title = str_replace('*', '%', $title); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductTaxTableMap::TITLE, $title, $comparison); + } + + /** + * Filter the query on the description column + * + * Example usage: + * + * $query->filterByDescription('fooValue'); // WHERE description = 'fooValue' + * $query->filterByDescription('%fooValue%'); // WHERE description LIKE '%fooValue%' + * + * + * @param string $description The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildOrderProductTaxQuery The current query, for fluid interface + */ + public function filterByDescription($description = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($description)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $description)) { + $description = str_replace('*', '%', $description); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductTaxTableMap::DESCRIPTION, $description, $comparison); + } + + /** + * Filter the query on the amount column + * + * Example usage: + * + * $query->filterByAmount(1234); // WHERE amount = 1234 + * $query->filterByAmount(array(12, 34)); // WHERE amount IN (12, 34) + * $query->filterByAmount(array('min' => 12)); // WHERE amount > 12 + * + * + * @param mixed $amount The value to use as filter. * Use scalar values for equality. * Use array values for in_array() equivalent. * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL * - * @return ChildFeatureCategoryQuery The current query, for fluid interface + * @return ChildOrderProductTaxQuery The current query, for fluid interface */ - public function filterByCategoryId($categoryId = null, $comparison = null) + public function filterByAmount($amount = null, $comparison = null) { - if (is_array($categoryId)) { + if (is_array($amount)) { $useMinMax = false; - if (isset($categoryId['min'])) { - $this->addUsingAlias(FeatureCategoryTableMap::CATEGORY_ID, $categoryId['min'], Criteria::GREATER_EQUAL); + if (isset($amount['min'])) { + $this->addUsingAlias(OrderProductTaxTableMap::AMOUNT, $amount['min'], Criteria::GREATER_EQUAL); $useMinMax = true; } - if (isset($categoryId['max'])) { - $this->addUsingAlias(FeatureCategoryTableMap::CATEGORY_ID, $categoryId['max'], Criteria::LESS_EQUAL); + if (isset($amount['max'])) { + $this->addUsingAlias(OrderProductTaxTableMap::AMOUNT, $amount['max'], Criteria::LESS_EQUAL); $useMinMax = true; } if ($useMinMax) { @@ -360,7 +420,7 @@ abstract class FeatureCategoryQuery extends ModelCriteria } } - return $this->addUsingAlias(FeatureCategoryTableMap::CATEGORY_ID, $categoryId, $comparison); + return $this->addUsingAlias(OrderProductTaxTableMap::AMOUNT, $amount, $comparison); } /** @@ -381,18 +441,18 @@ abstract class FeatureCategoryQuery extends ModelCriteria * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL * - * @return ChildFeatureCategoryQuery The current query, for fluid interface + * @return ChildOrderProductTaxQuery The current query, for fluid interface */ public function filterByCreatedAt($createdAt = null, $comparison = null) { if (is_array($createdAt)) { $useMinMax = false; if (isset($createdAt['min'])) { - $this->addUsingAlias(FeatureCategoryTableMap::CREATED_AT, $createdAt['min'], Criteria::GREATER_EQUAL); + $this->addUsingAlias(OrderProductTaxTableMap::CREATED_AT, $createdAt['min'], Criteria::GREATER_EQUAL); $useMinMax = true; } if (isset($createdAt['max'])) { - $this->addUsingAlias(FeatureCategoryTableMap::CREATED_AT, $createdAt['max'], Criteria::LESS_EQUAL); + $this->addUsingAlias(OrderProductTaxTableMap::CREATED_AT, $createdAt['max'], Criteria::LESS_EQUAL); $useMinMax = true; } if ($useMinMax) { @@ -403,7 +463,7 @@ abstract class FeatureCategoryQuery extends ModelCriteria } } - return $this->addUsingAlias(FeatureCategoryTableMap::CREATED_AT, $createdAt, $comparison); + return $this->addUsingAlias(OrderProductTaxTableMap::CREATED_AT, $createdAt, $comparison); } /** @@ -424,18 +484,18 @@ abstract class FeatureCategoryQuery extends ModelCriteria * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL * - * @return ChildFeatureCategoryQuery The current query, for fluid interface + * @return ChildOrderProductTaxQuery The current query, for fluid interface */ public function filterByUpdatedAt($updatedAt = null, $comparison = null) { if (is_array($updatedAt)) { $useMinMax = false; if (isset($updatedAt['min'])) { - $this->addUsingAlias(FeatureCategoryTableMap::UPDATED_AT, $updatedAt['min'], Criteria::GREATER_EQUAL); + $this->addUsingAlias(OrderProductTaxTableMap::UPDATED_AT, $updatedAt['min'], Criteria::GREATER_EQUAL); $useMinMax = true; } if (isset($updatedAt['max'])) { - $this->addUsingAlias(FeatureCategoryTableMap::UPDATED_AT, $updatedAt['max'], Criteria::LESS_EQUAL); + $this->addUsingAlias(OrderProductTaxTableMap::UPDATED_AT, $updatedAt['max'], Criteria::LESS_EQUAL); $useMinMax = true; } if ($useMinMax) { @@ -446,46 +506,46 @@ abstract class FeatureCategoryQuery extends ModelCriteria } } - return $this->addUsingAlias(FeatureCategoryTableMap::UPDATED_AT, $updatedAt, $comparison); + return $this->addUsingAlias(OrderProductTaxTableMap::UPDATED_AT, $updatedAt, $comparison); } /** - * Filter the query by a related \Thelia\Model\Category object + * Filter the query by a related \Thelia\Model\OrderProduct object * - * @param \Thelia\Model\Category|ObjectCollection $category The related object(s) to use as filter + * @param \Thelia\Model\OrderProduct|ObjectCollection $orderProduct The related object(s) to use as filter * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL * - * @return ChildFeatureCategoryQuery The current query, for fluid interface + * @return ChildOrderProductTaxQuery The current query, for fluid interface */ - public function filterByCategory($category, $comparison = null) + public function filterByOrderProduct($orderProduct, $comparison = null) { - if ($category instanceof \Thelia\Model\Category) { + if ($orderProduct instanceof \Thelia\Model\OrderProduct) { return $this - ->addUsingAlias(FeatureCategoryTableMap::CATEGORY_ID, $category->getId(), $comparison); - } elseif ($category instanceof ObjectCollection) { + ->addUsingAlias(OrderProductTaxTableMap::ORDER_PRODUCT_ID, $orderProduct->getId(), $comparison); + } elseif ($orderProduct instanceof ObjectCollection) { if (null === $comparison) { $comparison = Criteria::IN; } return $this - ->addUsingAlias(FeatureCategoryTableMap::CATEGORY_ID, $category->toKeyValue('PrimaryKey', 'Id'), $comparison); + ->addUsingAlias(OrderProductTaxTableMap::ORDER_PRODUCT_ID, $orderProduct->toKeyValue('PrimaryKey', 'Id'), $comparison); } else { - throw new PropelException('filterByCategory() only accepts arguments of type \Thelia\Model\Category or Collection'); + throw new PropelException('filterByOrderProduct() only accepts arguments of type \Thelia\Model\OrderProduct or Collection'); } } /** - * Adds a JOIN clause to the query using the Category relation + * Adds a JOIN clause to the query using the OrderProduct relation * * @param string $relationAlias optional alias for the relation * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' * - * @return ChildFeatureCategoryQuery The current query, for fluid interface + * @return ChildOrderProductTaxQuery The current query, for fluid interface */ - public function joinCategory($relationAlias = null, $joinType = Criteria::INNER_JOIN) + public function joinOrderProduct($relationAlias = null, $joinType = Criteria::INNER_JOIN) { $tableMap = $this->getTableMap(); - $relationMap = $tableMap->getRelation('Category'); + $relationMap = $tableMap->getRelation('OrderProduct'); // create a ModelJoin object for this join $join = new ModelJoin(); @@ -500,14 +560,14 @@ abstract class FeatureCategoryQuery extends ModelCriteria $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); $this->addJoinObject($join, $relationAlias); } else { - $this->addJoinObject($join, 'Category'); + $this->addJoinObject($join, 'OrderProduct'); } return $this; } /** - * Use the Category relation Category object + * Use the OrderProduct relation OrderProduct object * * @see useQuery() * @@ -515,108 +575,33 @@ abstract class FeatureCategoryQuery extends ModelCriteria * to be used as main alias in the secondary query * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' * - * @return \Thelia\Model\CategoryQuery A secondary query class using the current class as primary query + * @return \Thelia\Model\OrderProductQuery A secondary query class using the current class as primary query */ - public function useCategoryQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) + public function useOrderProductQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) { return $this - ->joinCategory($relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'Category', '\Thelia\Model\CategoryQuery'); - } - - /** - * Filter the query by a related \Thelia\Model\Feature object - * - * @param \Thelia\Model\Feature|ObjectCollection $feature The related object(s) to use as filter - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return ChildFeatureCategoryQuery The current query, for fluid interface - */ - public function filterByFeature($feature, $comparison = null) - { - if ($feature instanceof \Thelia\Model\Feature) { - return $this - ->addUsingAlias(FeatureCategoryTableMap::FEATURE_ID, $feature->getId(), $comparison); - } elseif ($feature instanceof ObjectCollection) { - if (null === $comparison) { - $comparison = Criteria::IN; - } - - return $this - ->addUsingAlias(FeatureCategoryTableMap::FEATURE_ID, $feature->toKeyValue('PrimaryKey', 'Id'), $comparison); - } else { - throw new PropelException('filterByFeature() only accepts arguments of type \Thelia\Model\Feature or Collection'); - } - } - - /** - * Adds a JOIN clause to the query using the Feature relation - * - * @param string $relationAlias optional alias for the relation - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return ChildFeatureCategoryQuery The current query, for fluid interface - */ - public function joinFeature($relationAlias = null, $joinType = Criteria::INNER_JOIN) - { - $tableMap = $this->getTableMap(); - $relationMap = $tableMap->getRelation('Feature'); - - // create a ModelJoin object for this join - $join = new ModelJoin(); - $join->setJoinType($joinType); - $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); - if ($previousJoin = $this->getPreviousJoin()) { - $join->setPreviousJoin($previousJoin); - } - - // add the ModelJoin to the current object - if ($relationAlias) { - $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); - $this->addJoinObject($join, $relationAlias); - } else { - $this->addJoinObject($join, 'Feature'); - } - - return $this; - } - - /** - * Use the Feature relation Feature object - * - * @see useQuery() - * - * @param string $relationAlias optional alias for the relation, - * to be used as main alias in the secondary query - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return \Thelia\Model\FeatureQuery A secondary query class using the current class as primary query - */ - public function useFeatureQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) - { - return $this - ->joinFeature($relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'Feature', '\Thelia\Model\FeatureQuery'); + ->joinOrderProduct($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'OrderProduct', '\Thelia\Model\OrderProductQuery'); } /** * Exclude object from result * - * @param ChildFeatureCategory $featureCategory Object to remove from the list of results + * @param ChildOrderProductTax $orderProductTax Object to remove from the list of results * - * @return ChildFeatureCategoryQuery The current query, for fluid interface + * @return ChildOrderProductTaxQuery The current query, for fluid interface */ - public function prune($featureCategory = null) + public function prune($orderProductTax = null) { - if ($featureCategory) { - $this->addUsingAlias(FeatureCategoryTableMap::ID, $featureCategory->getId(), Criteria::NOT_EQUAL); + if ($orderProductTax) { + $this->addUsingAlias(OrderProductTaxTableMap::ID, $orderProductTax->getId(), Criteria::NOT_EQUAL); } return $this; } /** - * Deletes all rows from the feature_category table. + * Deletes all rows from the order_product_tax table. * * @param ConnectionInterface $con the connection to use * @return int The number of affected rows (if supported by underlying database driver). @@ -624,7 +609,7 @@ abstract class FeatureCategoryQuery extends ModelCriteria public function doDeleteAll(ConnectionInterface $con = null) { if (null === $con) { - $con = Propel::getServiceContainer()->getWriteConnection(FeatureCategoryTableMap::DATABASE_NAME); + $con = Propel::getServiceContainer()->getWriteConnection(OrderProductTaxTableMap::DATABASE_NAME); } $affectedRows = 0; // initialize var to track total num of affected rows try { @@ -635,8 +620,8 @@ abstract class FeatureCategoryQuery extends ModelCriteria // Because this db requires some delete cascade/set null emulation, we have to // clear the cached instance *after* the emulation has happened (since // instances get re-added by the select statement contained therein). - FeatureCategoryTableMap::clearInstancePool(); - FeatureCategoryTableMap::clearRelatedInstancePool(); + OrderProductTaxTableMap::clearInstancePool(); + OrderProductTaxTableMap::clearRelatedInstancePool(); $con->commit(); } catch (PropelException $e) { @@ -648,9 +633,9 @@ abstract class FeatureCategoryQuery extends ModelCriteria } /** - * Performs a DELETE on the database, given a ChildFeatureCategory or Criteria object OR a primary key value. + * Performs a DELETE on the database, given a ChildOrderProductTax or Criteria object OR a primary key value. * - * @param mixed $values Criteria or ChildFeatureCategory object or primary key or array of primary keys + * @param mixed $values Criteria or ChildOrderProductTax object or primary key or array of primary keys * which is used to create the DELETE statement * @param ConnectionInterface $con the connection to use * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows @@ -661,13 +646,13 @@ abstract class FeatureCategoryQuery extends ModelCriteria public function delete(ConnectionInterface $con = null) { if (null === $con) { - $con = Propel::getServiceContainer()->getWriteConnection(FeatureCategoryTableMap::DATABASE_NAME); + $con = Propel::getServiceContainer()->getWriteConnection(OrderProductTaxTableMap::DATABASE_NAME); } $criteria = $this; // Set the correct dbName - $criteria->setDbName(FeatureCategoryTableMap::DATABASE_NAME); + $criteria->setDbName(OrderProductTaxTableMap::DATABASE_NAME); $affectedRows = 0; // initialize var to track total num of affected rows @@ -677,10 +662,10 @@ abstract class FeatureCategoryQuery extends ModelCriteria $con->beginTransaction(); - FeatureCategoryTableMap::removeInstanceFromPool($criteria); + OrderProductTaxTableMap::removeInstanceFromPool($criteria); $affectedRows += ModelCriteria::delete($con); - FeatureCategoryTableMap::clearRelatedInstancePool(); + OrderProductTaxTableMap::clearRelatedInstancePool(); $con->commit(); return $affectedRows; @@ -697,11 +682,11 @@ abstract class FeatureCategoryQuery extends ModelCriteria * * @param int $nbDays Maximum age of the latest update in days * - * @return ChildFeatureCategoryQuery The current query, for fluid interface + * @return ChildOrderProductTaxQuery The current query, for fluid interface */ public function recentlyUpdated($nbDays = 7) { - return $this->addUsingAlias(FeatureCategoryTableMap::UPDATED_AT, time() - $nbDays * 24 * 60 * 60, Criteria::GREATER_EQUAL); + return $this->addUsingAlias(OrderProductTaxTableMap::UPDATED_AT, time() - $nbDays * 24 * 60 * 60, Criteria::GREATER_EQUAL); } /** @@ -709,51 +694,51 @@ abstract class FeatureCategoryQuery extends ModelCriteria * * @param int $nbDays Maximum age of in days * - * @return ChildFeatureCategoryQuery The current query, for fluid interface + * @return ChildOrderProductTaxQuery The current query, for fluid interface */ public function recentlyCreated($nbDays = 7) { - return $this->addUsingAlias(FeatureCategoryTableMap::CREATED_AT, time() - $nbDays * 24 * 60 * 60, Criteria::GREATER_EQUAL); + return $this->addUsingAlias(OrderProductTaxTableMap::CREATED_AT, time() - $nbDays * 24 * 60 * 60, Criteria::GREATER_EQUAL); } /** * Order by update date desc * - * @return ChildFeatureCategoryQuery The current query, for fluid interface + * @return ChildOrderProductTaxQuery The current query, for fluid interface */ public function lastUpdatedFirst() { - return $this->addDescendingOrderByColumn(FeatureCategoryTableMap::UPDATED_AT); + return $this->addDescendingOrderByColumn(OrderProductTaxTableMap::UPDATED_AT); } /** * Order by update date asc * - * @return ChildFeatureCategoryQuery The current query, for fluid interface + * @return ChildOrderProductTaxQuery The current query, for fluid interface */ public function firstUpdatedFirst() { - return $this->addAscendingOrderByColumn(FeatureCategoryTableMap::UPDATED_AT); + return $this->addAscendingOrderByColumn(OrderProductTaxTableMap::UPDATED_AT); } /** * Order by create date desc * - * @return ChildFeatureCategoryQuery The current query, for fluid interface + * @return ChildOrderProductTaxQuery The current query, for fluid interface */ public function lastCreatedFirst() { - return $this->addDescendingOrderByColumn(FeatureCategoryTableMap::CREATED_AT); + return $this->addDescendingOrderByColumn(OrderProductTaxTableMap::CREATED_AT); } /** * Order by create date asc * - * @return ChildFeatureCategoryQuery The current query, for fluid interface + * @return ChildOrderProductTaxQuery The current query, for fluid interface */ public function firstCreatedFirst() { - return $this->addAscendingOrderByColumn(FeatureCategoryTableMap::CREATED_AT); + return $this->addAscendingOrderByColumn(OrderProductTaxTableMap::CREATED_AT); } -} // FeatureCategoryQuery +} // OrderProductTaxQuery diff --git a/core/lib/Thelia/Model/Base/ProductQuery.php b/core/lib/Thelia/Model/Base/ProductQuery.php index 9b1710f03..9c3b0759c 100644 --- a/core/lib/Thelia/Model/Base/ProductQuery.php +++ b/core/lib/Thelia/Model/Base/ProductQuery.php @@ -857,7 +857,7 @@ abstract class ProductQuery extends ModelCriteria * * @return ChildProductQuery The current query, for fluid interface */ - public function joinTemplate($relationAlias = null, $joinType = Criteria::INNER_JOIN) + public function joinTemplate($relationAlias = null, $joinType = Criteria::LEFT_JOIN) { $tableMap = $this->getTableMap(); $relationMap = $tableMap->getRelation('Template'); @@ -892,7 +892,7 @@ abstract class ProductQuery extends ModelCriteria * * @return \Thelia\Model\TemplateQuery A secondary query class using the current class as primary query */ - public function useTemplateQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) + public function useTemplateQuery($relationAlias = null, $joinType = Criteria::LEFT_JOIN) { return $this ->joinTemplate($relationAlias, $joinType) diff --git a/core/lib/Thelia/Model/Base/ProductSaleElements.php b/core/lib/Thelia/Model/Base/ProductSaleElements.php index fa887dc8a..eb6aa2b1a 100644 --- a/core/lib/Thelia/Model/Base/ProductSaleElements.php +++ b/core/lib/Thelia/Model/Base/ProductSaleElements.php @@ -103,10 +103,18 @@ abstract class ProductSaleElements implements ActiveRecordInterface /** * The value for the weight field. + * Note: this column has a database default value of: 0 * @var double */ protected $weight; + /** + * The value for the is_default field. + * Note: this column has a database default value of: false + * @var boolean + */ + protected $is_default; + /** * The value for the created_at field. * @var string @@ -178,6 +186,8 @@ abstract class ProductSaleElements implements ActiveRecordInterface { $this->promo = 0; $this->newness = 0; + $this->weight = 0; + $this->is_default = false; } /** @@ -513,6 +523,17 @@ abstract class ProductSaleElements implements ActiveRecordInterface return $this->weight; } + /** + * Get the [is_default] column value. + * + * @return boolean + */ + public function getIsDefault() + { + + return $this->is_default; + } + /** * Get the [optionally formatted] temporal [created_at] column value. * @@ -704,6 +725,35 @@ abstract class ProductSaleElements implements ActiveRecordInterface return $this; } // setWeight() + /** + * Sets the value of the [is_default] column. + * Non-boolean arguments are converted using the following rules: + * * 1, '1', 'true', 'on', and 'yes' are converted to boolean true + * * 0, '0', 'false', 'off', and 'no' are converted to boolean false + * Check on string values is case insensitive (so 'FaLsE' is seen as 'false'). + * + * @param boolean|integer|string $v The new value + * @return \Thelia\Model\ProductSaleElements The current object (for fluent API support) + */ + public function setIsDefault($v) + { + if ($v !== null) { + if (is_string($v)) { + $v = in_array(strtolower($v), array('false', 'off', '-', 'no', 'n', '0', '')) ? false : true; + } else { + $v = (boolean) $v; + } + } + + if ($this->is_default !== $v) { + $this->is_default = $v; + $this->modifiedColumns[] = ProductSaleElementsTableMap::IS_DEFAULT; + } + + + return $this; + } // setIsDefault() + /** * Sets the value of [created_at] column to a normalized version of the date/time value specified. * @@ -764,6 +814,14 @@ abstract class ProductSaleElements implements ActiveRecordInterface return false; } + if ($this->weight !== 0) { + return false; + } + + if ($this->is_default !== false) { + return false; + } + // otherwise, everything was equal, so return TRUE return true; } // hasOnlyDefaultValues() @@ -812,13 +870,16 @@ abstract class ProductSaleElements implements ActiveRecordInterface $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : ProductSaleElementsTableMap::translateFieldName('Weight', TableMap::TYPE_PHPNAME, $indexType)]; $this->weight = (null !== $col) ? (double) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : ProductSaleElementsTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : ProductSaleElementsTableMap::translateFieldName('IsDefault', TableMap::TYPE_PHPNAME, $indexType)]; + $this->is_default = (null !== $col) ? (boolean) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 8 + $startcol : ProductSaleElementsTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } $this->created_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 8 + $startcol : ProductSaleElementsTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 9 + $startcol : ProductSaleElementsTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } @@ -831,7 +892,7 @@ abstract class ProductSaleElements implements ActiveRecordInterface $this->ensureConsistency(); } - return $startcol + 9; // 9 = ProductSaleElementsTableMap::NUM_HYDRATE_COLUMNS. + return $startcol + 10; // 10 = ProductSaleElementsTableMap::NUM_HYDRATE_COLUMNS. } catch (Exception $e) { throw new PropelException("Error populating \Thelia\Model\ProductSaleElements object", 0, $e); @@ -1145,6 +1206,9 @@ abstract class ProductSaleElements implements ActiveRecordInterface if ($this->isColumnModified(ProductSaleElementsTableMap::WEIGHT)) { $modifiedColumns[':p' . $index++] = 'WEIGHT'; } + if ($this->isColumnModified(ProductSaleElementsTableMap::IS_DEFAULT)) { + $modifiedColumns[':p' . $index++] = 'IS_DEFAULT'; + } if ($this->isColumnModified(ProductSaleElementsTableMap::CREATED_AT)) { $modifiedColumns[':p' . $index++] = 'CREATED_AT'; } @@ -1183,6 +1247,9 @@ abstract class ProductSaleElements implements ActiveRecordInterface case 'WEIGHT': $stmt->bindValue($identifier, $this->weight, PDO::PARAM_STR); break; + case 'IS_DEFAULT': + $stmt->bindValue($identifier, (int) $this->is_default, PDO::PARAM_INT); + break; case 'CREATED_AT': $stmt->bindValue($identifier, $this->created_at ? $this->created_at->format("Y-m-d H:i:s") : null, PDO::PARAM_STR); break; @@ -1273,9 +1340,12 @@ abstract class ProductSaleElements implements ActiveRecordInterface return $this->getWeight(); break; case 7: - return $this->getCreatedAt(); + return $this->getIsDefault(); break; case 8: + return $this->getCreatedAt(); + break; + case 9: return $this->getUpdatedAt(); break; default: @@ -1314,8 +1384,9 @@ abstract class ProductSaleElements implements ActiveRecordInterface $keys[4] => $this->getPromo(), $keys[5] => $this->getNewness(), $keys[6] => $this->getWeight(), - $keys[7] => $this->getCreatedAt(), - $keys[8] => $this->getUpdatedAt(), + $keys[7] => $this->getIsDefault(), + $keys[8] => $this->getCreatedAt(), + $keys[9] => $this->getUpdatedAt(), ); $virtualColumns = $this->virtualColumns; foreach($virtualColumns as $key => $virtualColumn) @@ -1392,9 +1463,12 @@ abstract class ProductSaleElements implements ActiveRecordInterface $this->setWeight($value); break; case 7: - $this->setCreatedAt($value); + $this->setIsDefault($value); break; case 8: + $this->setCreatedAt($value); + break; + case 9: $this->setUpdatedAt($value); break; } // switch() @@ -1428,8 +1502,9 @@ abstract class ProductSaleElements implements ActiveRecordInterface if (array_key_exists($keys[4], $arr)) $this->setPromo($arr[$keys[4]]); if (array_key_exists($keys[5], $arr)) $this->setNewness($arr[$keys[5]]); if (array_key_exists($keys[6], $arr)) $this->setWeight($arr[$keys[6]]); - if (array_key_exists($keys[7], $arr)) $this->setCreatedAt($arr[$keys[7]]); - if (array_key_exists($keys[8], $arr)) $this->setUpdatedAt($arr[$keys[8]]); + if (array_key_exists($keys[7], $arr)) $this->setIsDefault($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setCreatedAt($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setUpdatedAt($arr[$keys[9]]); } /** @@ -1448,6 +1523,7 @@ abstract class ProductSaleElements implements ActiveRecordInterface if ($this->isColumnModified(ProductSaleElementsTableMap::PROMO)) $criteria->add(ProductSaleElementsTableMap::PROMO, $this->promo); if ($this->isColumnModified(ProductSaleElementsTableMap::NEWNESS)) $criteria->add(ProductSaleElementsTableMap::NEWNESS, $this->newness); if ($this->isColumnModified(ProductSaleElementsTableMap::WEIGHT)) $criteria->add(ProductSaleElementsTableMap::WEIGHT, $this->weight); + if ($this->isColumnModified(ProductSaleElementsTableMap::IS_DEFAULT)) $criteria->add(ProductSaleElementsTableMap::IS_DEFAULT, $this->is_default); if ($this->isColumnModified(ProductSaleElementsTableMap::CREATED_AT)) $criteria->add(ProductSaleElementsTableMap::CREATED_AT, $this->created_at); if ($this->isColumnModified(ProductSaleElementsTableMap::UPDATED_AT)) $criteria->add(ProductSaleElementsTableMap::UPDATED_AT, $this->updated_at); @@ -1519,6 +1595,7 @@ abstract class ProductSaleElements implements ActiveRecordInterface $copyObj->setPromo($this->getPromo()); $copyObj->setNewness($this->getNewness()); $copyObj->setWeight($this->getWeight()); + $copyObj->setIsDefault($this->getIsDefault()); $copyObj->setCreatedAt($this->getCreatedAt()); $copyObj->setUpdatedAt($this->getUpdatedAt()); @@ -2445,6 +2522,7 @@ abstract class ProductSaleElements implements ActiveRecordInterface $this->promo = null; $this->newness = null; $this->weight = null; + $this->is_default = null; $this->created_at = null; $this->updated_at = null; $this->alreadyInSave = false; diff --git a/core/lib/Thelia/Model/Base/ProductSaleElementsQuery.php b/core/lib/Thelia/Model/Base/ProductSaleElementsQuery.php index 6e9068002..c8201ed0b 100644 --- a/core/lib/Thelia/Model/Base/ProductSaleElementsQuery.php +++ b/core/lib/Thelia/Model/Base/ProductSaleElementsQuery.php @@ -28,6 +28,7 @@ use Thelia\Model\Map\ProductSaleElementsTableMap; * @method ChildProductSaleElementsQuery orderByPromo($order = Criteria::ASC) Order by the promo column * @method ChildProductSaleElementsQuery orderByNewness($order = Criteria::ASC) Order by the newness column * @method ChildProductSaleElementsQuery orderByWeight($order = Criteria::ASC) Order by the weight column + * @method ChildProductSaleElementsQuery orderByIsDefault($order = Criteria::ASC) Order by the is_default column * @method ChildProductSaleElementsQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column * @method ChildProductSaleElementsQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column * @@ -38,6 +39,7 @@ use Thelia\Model\Map\ProductSaleElementsTableMap; * @method ChildProductSaleElementsQuery groupByPromo() Group by the promo column * @method ChildProductSaleElementsQuery groupByNewness() Group by the newness column * @method ChildProductSaleElementsQuery groupByWeight() Group by the weight column + * @method ChildProductSaleElementsQuery groupByIsDefault() Group by the is_default column * @method ChildProductSaleElementsQuery groupByCreatedAt() Group by the created_at column * @method ChildProductSaleElementsQuery groupByUpdatedAt() Group by the updated_at column * @@ -71,6 +73,7 @@ use Thelia\Model\Map\ProductSaleElementsTableMap; * @method ChildProductSaleElements findOneByPromo(int $promo) Return the first ChildProductSaleElements filtered by the promo column * @method ChildProductSaleElements findOneByNewness(int $newness) Return the first ChildProductSaleElements filtered by the newness column * @method ChildProductSaleElements findOneByWeight(double $weight) Return the first ChildProductSaleElements filtered by the weight column + * @method ChildProductSaleElements findOneByIsDefault(boolean $is_default) Return the first ChildProductSaleElements filtered by the is_default column * @method ChildProductSaleElements findOneByCreatedAt(string $created_at) Return the first ChildProductSaleElements filtered by the created_at column * @method ChildProductSaleElements findOneByUpdatedAt(string $updated_at) Return the first ChildProductSaleElements filtered by the updated_at column * @@ -81,6 +84,7 @@ use Thelia\Model\Map\ProductSaleElementsTableMap; * @method array findByPromo(int $promo) Return ChildProductSaleElements objects filtered by the promo column * @method array findByNewness(int $newness) Return ChildProductSaleElements objects filtered by the newness column * @method array findByWeight(double $weight) Return ChildProductSaleElements objects filtered by the weight column + * @method array findByIsDefault(boolean $is_default) Return ChildProductSaleElements objects filtered by the is_default column * @method array findByCreatedAt(string $created_at) Return ChildProductSaleElements objects filtered by the created_at column * @method array findByUpdatedAt(string $updated_at) Return ChildProductSaleElements objects filtered by the updated_at column * @@ -171,7 +175,7 @@ abstract class ProductSaleElementsQuery extends ModelCriteria */ protected function findPkSimple($key, $con) { - $sql = 'SELECT ID, PRODUCT_ID, REF, QUANTITY, PROMO, NEWNESS, WEIGHT, CREATED_AT, UPDATED_AT FROM product_sale_elements WHERE ID = :p0'; + $sql = 'SELECT ID, PRODUCT_ID, REF, QUANTITY, PROMO, NEWNESS, WEIGHT, IS_DEFAULT, CREATED_AT, UPDATED_AT FROM product_sale_elements WHERE ID = :p0'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key, PDO::PARAM_INT); @@ -537,6 +541,33 @@ abstract class ProductSaleElementsQuery extends ModelCriteria return $this->addUsingAlias(ProductSaleElementsTableMap::WEIGHT, $weight, $comparison); } + /** + * Filter the query on the is_default column + * + * Example usage: + * + * $query->filterByIsDefault(true); // WHERE is_default = true + * $query->filterByIsDefault('yes'); // WHERE is_default = true + * + * + * @param boolean|string $isDefault The value to use as filter. + * Non-boolean arguments are converted using the following rules: + * * 1, '1', 'true', 'on', and 'yes' are converted to boolean true + * * 0, '0', 'false', 'off', and 'no' are converted to boolean false + * Check on string values is case insensitive (so 'FaLsE' is seen as 'false'). + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildProductSaleElementsQuery The current query, for fluid interface + */ + public function filterByIsDefault($isDefault = null, $comparison = null) + { + if (is_string($isDefault)) { + $is_default = in_array(strtolower($isDefault), array('false', 'off', '-', 'no', 'n', '0', '')) ? false : true; + } + + return $this->addUsingAlias(ProductSaleElementsTableMap::IS_DEFAULT, $isDefault, $comparison); + } + /** * Filter the query on the created_at column * diff --git a/core/lib/Thelia/Model/Base/TaxRule.php b/core/lib/Thelia/Model/Base/TaxRule.php index 9edb7b2fc..b361567d8 100644 --- a/core/lib/Thelia/Model/Base/TaxRule.php +++ b/core/lib/Thelia/Model/Base/TaxRule.php @@ -67,6 +67,13 @@ abstract class TaxRule implements ActiveRecordInterface */ protected $id; + /** + * The value for the is_default field. + * Note: this column has a database default value of: false + * @var boolean + */ + protected $is_default; + /** * The value for the created_at field. * @var string @@ -137,11 +144,24 @@ abstract class TaxRule implements ActiveRecordInterface */ protected $taxRuleI18nsScheduledForDeletion = null; + /** + * Applies default values to this object. + * This method should be called from the object's constructor (or + * equivalent initialization method). + * @see __construct() + */ + public function applyDefaultValues() + { + $this->is_default = false; + } + /** * Initializes internal state of Thelia\Model\Base\TaxRule object. + * @see applyDefaults() */ public function __construct() { + $this->applyDefaultValues(); } /** @@ -402,6 +422,17 @@ abstract class TaxRule implements ActiveRecordInterface return $this->id; } + /** + * Get the [is_default] column value. + * + * @return boolean + */ + public function getIsDefault() + { + + return $this->is_default; + } + /** * Get the [optionally formatted] temporal [created_at] column value. * @@ -463,6 +494,35 @@ abstract class TaxRule implements ActiveRecordInterface return $this; } // setId() + /** + * Sets the value of the [is_default] column. + * Non-boolean arguments are converted using the following rules: + * * 1, '1', 'true', 'on', and 'yes' are converted to boolean true + * * 0, '0', 'false', 'off', and 'no' are converted to boolean false + * Check on string values is case insensitive (so 'FaLsE' is seen as 'false'). + * + * @param boolean|integer|string $v The new value + * @return \Thelia\Model\TaxRule The current object (for fluent API support) + */ + public function setIsDefault($v) + { + if ($v !== null) { + if (is_string($v)) { + $v = in_array(strtolower($v), array('false', 'off', '-', 'no', 'n', '0', '')) ? false : true; + } else { + $v = (boolean) $v; + } + } + + if ($this->is_default !== $v) { + $this->is_default = $v; + $this->modifiedColumns[] = TaxRuleTableMap::IS_DEFAULT; + } + + + return $this; + } // setIsDefault() + /** * Sets the value of [created_at] column to a normalized version of the date/time value specified. * @@ -515,6 +575,10 @@ abstract class TaxRule implements ActiveRecordInterface */ public function hasOnlyDefaultValues() { + if ($this->is_default !== false) { + return false; + } + // otherwise, everything was equal, so return TRUE return true; } // hasOnlyDefaultValues() @@ -545,13 +609,16 @@ abstract class TaxRule implements ActiveRecordInterface $col = $row[TableMap::TYPE_NUM == $indexType ? 0 + $startcol : TaxRuleTableMap::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)]; $this->id = (null !== $col) ? (int) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 1 + $startcol : TaxRuleTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 1 + $startcol : TaxRuleTableMap::translateFieldName('IsDefault', TableMap::TYPE_PHPNAME, $indexType)]; + $this->is_default = (null !== $col) ? (boolean) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : TaxRuleTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } $this->created_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : TaxRuleTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : TaxRuleTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } @@ -564,7 +631,7 @@ abstract class TaxRule implements ActiveRecordInterface $this->ensureConsistency(); } - return $startcol + 3; // 3 = TaxRuleTableMap::NUM_HYDRATE_COLUMNS. + return $startcol + 4; // 4 = TaxRuleTableMap::NUM_HYDRATE_COLUMNS. } catch (Exception $e) { throw new PropelException("Error populating \Thelia\Model\TaxRule object", 0, $e); @@ -845,6 +912,9 @@ abstract class TaxRule implements ActiveRecordInterface if ($this->isColumnModified(TaxRuleTableMap::ID)) { $modifiedColumns[':p' . $index++] = 'ID'; } + if ($this->isColumnModified(TaxRuleTableMap::IS_DEFAULT)) { + $modifiedColumns[':p' . $index++] = 'IS_DEFAULT'; + } if ($this->isColumnModified(TaxRuleTableMap::CREATED_AT)) { $modifiedColumns[':p' . $index++] = 'CREATED_AT'; } @@ -865,6 +935,9 @@ abstract class TaxRule implements ActiveRecordInterface case 'ID': $stmt->bindValue($identifier, $this->id, PDO::PARAM_INT); break; + case 'IS_DEFAULT': + $stmt->bindValue($identifier, (int) $this->is_default, PDO::PARAM_INT); + break; case 'CREATED_AT': $stmt->bindValue($identifier, $this->created_at ? $this->created_at->format("Y-m-d H:i:s") : null, PDO::PARAM_STR); break; @@ -937,9 +1010,12 @@ abstract class TaxRule implements ActiveRecordInterface return $this->getId(); break; case 1: - return $this->getCreatedAt(); + return $this->getIsDefault(); break; case 2: + return $this->getCreatedAt(); + break; + case 3: return $this->getUpdatedAt(); break; default: @@ -972,8 +1048,9 @@ abstract class TaxRule implements ActiveRecordInterface $keys = TaxRuleTableMap::getFieldNames($keyType); $result = array( $keys[0] => $this->getId(), - $keys[1] => $this->getCreatedAt(), - $keys[2] => $this->getUpdatedAt(), + $keys[1] => $this->getIsDefault(), + $keys[2] => $this->getCreatedAt(), + $keys[3] => $this->getUpdatedAt(), ); $virtualColumns = $this->virtualColumns; foreach($virtualColumns as $key => $virtualColumn) @@ -1029,9 +1106,12 @@ abstract class TaxRule implements ActiveRecordInterface $this->setId($value); break; case 1: - $this->setCreatedAt($value); + $this->setIsDefault($value); break; case 2: + $this->setCreatedAt($value); + break; + case 3: $this->setUpdatedAt($value); break; } // switch() @@ -1059,8 +1139,9 @@ abstract class TaxRule implements ActiveRecordInterface $keys = TaxRuleTableMap::getFieldNames($keyType); if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]); - if (array_key_exists($keys[1], $arr)) $this->setCreatedAt($arr[$keys[1]]); - if (array_key_exists($keys[2], $arr)) $this->setUpdatedAt($arr[$keys[2]]); + if (array_key_exists($keys[1], $arr)) $this->setIsDefault($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setCreatedAt($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setUpdatedAt($arr[$keys[3]]); } /** @@ -1073,6 +1154,7 @@ abstract class TaxRule implements ActiveRecordInterface $criteria = new Criteria(TaxRuleTableMap::DATABASE_NAME); if ($this->isColumnModified(TaxRuleTableMap::ID)) $criteria->add(TaxRuleTableMap::ID, $this->id); + if ($this->isColumnModified(TaxRuleTableMap::IS_DEFAULT)) $criteria->add(TaxRuleTableMap::IS_DEFAULT, $this->is_default); if ($this->isColumnModified(TaxRuleTableMap::CREATED_AT)) $criteria->add(TaxRuleTableMap::CREATED_AT, $this->created_at); if ($this->isColumnModified(TaxRuleTableMap::UPDATED_AT)) $criteria->add(TaxRuleTableMap::UPDATED_AT, $this->updated_at); @@ -1138,6 +1220,7 @@ abstract class TaxRule implements ActiveRecordInterface */ public function copyInto($copyObj, $deepCopy = false, $makeNew = true) { + $copyObj->setIsDefault($this->getIsDefault()); $copyObj->setCreatedAt($this->getCreatedAt()); $copyObj->setUpdatedAt($this->getUpdatedAt()); @@ -1961,10 +2044,12 @@ abstract class TaxRule implements ActiveRecordInterface public function clear() { $this->id = null; + $this->is_default = null; $this->created_at = null; $this->updated_at = null; $this->alreadyInSave = false; $this->clearAllReferences(); + $this->applyDefaultValues(); $this->resetModified(); $this->setNew(true); $this->setDeleted(false); diff --git a/core/lib/Thelia/Model/Base/TaxRuleQuery.php b/core/lib/Thelia/Model/Base/TaxRuleQuery.php index 8ee264415..bc20c44b1 100644 --- a/core/lib/Thelia/Model/Base/TaxRuleQuery.php +++ b/core/lib/Thelia/Model/Base/TaxRuleQuery.php @@ -23,10 +23,12 @@ use Thelia\Model\Map\TaxRuleTableMap; * * * @method ChildTaxRuleQuery orderById($order = Criteria::ASC) Order by the id column + * @method ChildTaxRuleQuery orderByIsDefault($order = Criteria::ASC) Order by the is_default column * @method ChildTaxRuleQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column * @method ChildTaxRuleQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column * * @method ChildTaxRuleQuery groupById() Group by the id column + * @method ChildTaxRuleQuery groupByIsDefault() Group by the is_default column * @method ChildTaxRuleQuery groupByCreatedAt() Group by the created_at column * @method ChildTaxRuleQuery groupByUpdatedAt() Group by the updated_at column * @@ -50,10 +52,12 @@ use Thelia\Model\Map\TaxRuleTableMap; * @method ChildTaxRule findOneOrCreate(ConnectionInterface $con = null) Return the first ChildTaxRule matching the query, or a new ChildTaxRule object populated from the query conditions when no match is found * * @method ChildTaxRule findOneById(int $id) Return the first ChildTaxRule filtered by the id column + * @method ChildTaxRule findOneByIsDefault(boolean $is_default) Return the first ChildTaxRule filtered by the is_default column * @method ChildTaxRule findOneByCreatedAt(string $created_at) Return the first ChildTaxRule filtered by the created_at column * @method ChildTaxRule findOneByUpdatedAt(string $updated_at) Return the first ChildTaxRule filtered by the updated_at column * * @method array findById(int $id) Return ChildTaxRule objects filtered by the id column + * @method array findByIsDefault(boolean $is_default) Return ChildTaxRule objects filtered by the is_default column * @method array findByCreatedAt(string $created_at) Return ChildTaxRule objects filtered by the created_at column * @method array findByUpdatedAt(string $updated_at) Return ChildTaxRule objects filtered by the updated_at column * @@ -144,7 +148,7 @@ abstract class TaxRuleQuery extends ModelCriteria */ protected function findPkSimple($key, $con) { - $sql = 'SELECT ID, CREATED_AT, UPDATED_AT FROM tax_rule WHERE ID = :p0'; + $sql = 'SELECT ID, IS_DEFAULT, CREATED_AT, UPDATED_AT FROM tax_rule WHERE ID = :p0'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key, PDO::PARAM_INT); @@ -274,6 +278,33 @@ abstract class TaxRuleQuery extends ModelCriteria return $this->addUsingAlias(TaxRuleTableMap::ID, $id, $comparison); } + /** + * Filter the query on the is_default column + * + * Example usage: + * + * $query->filterByIsDefault(true); // WHERE is_default = true + * $query->filterByIsDefault('yes'); // WHERE is_default = true + * + * + * @param boolean|string $isDefault The value to use as filter. + * Non-boolean arguments are converted using the following rules: + * * 1, '1', 'true', 'on', and 'yes' are converted to boolean true + * * 0, '0', 'false', 'off', and 'no' are converted to boolean false + * Check on string values is case insensitive (so 'FaLsE' is seen as 'false'). + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildTaxRuleQuery The current query, for fluid interface + */ + public function filterByIsDefault($isDefault = null, $comparison = null) + { + if (is_string($isDefault)) { + $is_default = in_array(strtolower($isDefault), array('false', 'off', '-', 'no', 'n', '0', '')) ? false : true; + } + + return $this->addUsingAlias(TaxRuleTableMap::IS_DEFAULT, $isDefault, $comparison); + } + /** * Filter the query on the created_at column * diff --git a/core/lib/Thelia/Model/Base/Template.php b/core/lib/Thelia/Model/Base/Template.php index 77efa7ba0..08bb0f3a0 100644 --- a/core/lib/Thelia/Model/Base/Template.php +++ b/core/lib/Thelia/Model/Base/Template.php @@ -864,9 +864,10 @@ abstract class Template implements ActiveRecordInterface if ($this->productsScheduledForDeletion !== null) { if (!$this->productsScheduledForDeletion->isEmpty()) { - \Thelia\Model\ProductQuery::create() - ->filterByPrimaryKeys($this->productsScheduledForDeletion->getPrimaryKeys(false)) - ->delete($con); + foreach ($this->productsScheduledForDeletion as $product) { + // need to save related object because we set the relation to null + $product->save($con); + } $this->productsScheduledForDeletion = null; } } @@ -1553,7 +1554,7 @@ abstract class Template implements ActiveRecordInterface $this->productsScheduledForDeletion = clone $this->collProducts; $this->productsScheduledForDeletion->clear(); } - $this->productsScheduledForDeletion[]= clone $product; + $this->productsScheduledForDeletion[]= $product; $product->setTemplate(null); } diff --git a/core/lib/Thelia/Model/Base/TemplateQuery.php b/core/lib/Thelia/Model/Base/TemplateQuery.php index 506d7d943..98c588dd8 100644 --- a/core/lib/Thelia/Model/Base/TemplateQuery.php +++ b/core/lib/Thelia/Model/Base/TemplateQuery.php @@ -395,7 +395,7 @@ abstract class TemplateQuery extends ModelCriteria * * @return ChildTemplateQuery The current query, for fluid interface */ - public function joinProduct($relationAlias = null, $joinType = Criteria::INNER_JOIN) + public function joinProduct($relationAlias = null, $joinType = Criteria::LEFT_JOIN) { $tableMap = $this->getTableMap(); $relationMap = $tableMap->getRelation('Product'); @@ -430,7 +430,7 @@ abstract class TemplateQuery extends ModelCriteria * * @return \Thelia\Model\ProductQuery A secondary query class using the current class as primary query */ - public function useProductQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) + public function useProductQuery($relationAlias = null, $joinType = Criteria::LEFT_JOIN) { return $this ->joinProduct($relationAlias, $joinType) diff --git a/core/lib/Thelia/Model/Category.php b/core/lib/Thelia/Model/Category.php index 042864de0..347a0f7f7 100755 --- a/core/lib/Thelia/Model/Category.php +++ b/core/lib/Thelia/Model/Category.php @@ -28,7 +28,7 @@ class Category extends BaseCategory /** * {@inheritDoc} */ - protected function getRewritenUrlViewName() { + protected function getRewrittenUrlViewName() { return 'category'; } @@ -69,8 +69,6 @@ class Category extends BaseCategory { $this->setPosition($this->getNextPosition()); - $this->generateRewritenUrl($this->getLocale()); - $this->dispatchEvent(TheliaEvents::BEFORE_CREATECATEGORY, new CategoryEvent($this)); return true; diff --git a/core/lib/Thelia/Model/CategoryAssociatedContent.php b/core/lib/Thelia/Model/CategoryAssociatedContent.php index 9296e6274..9154767bc 100644 --- a/core/lib/Thelia/Model/CategoryAssociatedContent.php +++ b/core/lib/Thelia/Model/CategoryAssociatedContent.php @@ -3,7 +3,66 @@ namespace Thelia\Model; use Thelia\Model\Base\CategoryAssociatedContent as BaseCategoryAssociatedContent; +use Thelia\Core\Event\CategoryAssociatedContentEvent; +use Thelia\Core\Event\TheliaEvents; +use Propel\Runtime\Connection\ConnectionInterface; class CategoryAssociatedContent extends BaseCategoryAssociatedContent { + use \Thelia\Model\Tools\ModelEventDispatcherTrait; + + /** + * {@inheritDoc} + */ + public function preInsert(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::BEFORE_CREATECATEGORY_ASSOCIATED_CONTENT, new CategoryAssociatedContentEvent($this)); + + return true; + } + + /** + * {@inheritDoc} + */ + public function postInsert(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_CREATECATEGORY_ASSOCIATED_CONTENT, new CategoryAssociatedContentEvent($this)); + } + + /** + * {@inheritDoc} + */ + public function preUpdate(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::BEFORE_UPDATECATEGORY_ASSOCIATED_CONTENT, new CategoryAssociatedContentEvent($this)); + + return true; + } + + /** + * {@inheritDoc} + */ + public function postUpdate(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_UPDATECATEGORY_ASSOCIATED_CONTENT, new CategoryAssociatedContentEvent($this)); + } + + /** + * {@inheritDoc} + */ + public function preDelete(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::BEFORE_DELETECATEGORY_ASSOCIATED_CONTENT, new CategoryAssociatedContentEvent($this)); + + return true; + } + + /** + * {@inheritDoc} + */ + public function postDelete(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_DELETECATEGORY_ASSOCIATED_CONTENT, new CategoryAssociatedContentEvent($this)); + } + } diff --git a/core/lib/Thelia/Model/CategoryDocument.php b/core/lib/Thelia/Model/CategoryDocument.php index 5724e2df1..0917ab30c 100755 --- a/core/lib/Thelia/Model/CategoryDocument.php +++ b/core/lib/Thelia/Model/CategoryDocument.php @@ -25,4 +25,28 @@ class CategoryDocument extends BaseCategoryDocument return true; } + + /** + * Set Document parent id + * + * @param int $parentId parent id + * + * @return $this + */ + public function setParentId($parentId) + { + $this->setCategoryId($parentId); + + return $this; + } + + /** + * Get Document parent id + * + * @return int parent id + */ + public function getParentId() + { + return $this->getCategoryId(); + } } \ No newline at end of file diff --git a/core/lib/Thelia/Model/CategoryI18n.php b/core/lib/Thelia/Model/CategoryI18n.php index bb4e7b3f3..de3e38663 100755 --- a/core/lib/Thelia/Model/CategoryI18n.php +++ b/core/lib/Thelia/Model/CategoryI18n.php @@ -2,8 +2,13 @@ namespace Thelia\Model; +use Propel\Runtime\Connection\ConnectionInterface; use Thelia\Model\Base\CategoryI18n as BaseCategoryI18n; class CategoryI18n extends BaseCategoryI18n { - + public function postInsert(ConnectionInterface $con = null) + { + $category = $this->getCategory(); + $category->generateRewrittenUrl($this->getLocale()); + } } diff --git a/core/lib/Thelia/Model/CategoryImage.php b/core/lib/Thelia/Model/CategoryImage.php index 5bf964e10..17ee387b5 100755 --- a/core/lib/Thelia/Model/CategoryImage.php +++ b/core/lib/Thelia/Model/CategoryImage.php @@ -2,6 +2,8 @@ namespace Thelia\Model; +use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\HttpFoundation\File\UploadedFile; use Thelia\Model\Base\CategoryImage as BaseCategoryImage; use Propel\Runtime\Connection\ConnectionInterface; @@ -25,4 +27,29 @@ class CategoryImage extends BaseCategoryImage return true; } + + /** + * Set Image parent id + * + * @param int $parentId parent id + * + * @return $this + */ + public function setParentId($parentId) + { + $this->setCategoryId($parentId); + + return $this; + } + + /** + * Get Image parent id + * + * @return int parent id + */ + public function getParentId() + { + return $this->getCategoryId(); + } + } diff --git a/core/lib/Thelia/Model/ConfigQuery.php b/core/lib/Thelia/Model/ConfigQuery.php index 7df592fd2..7f65b103d 100755 --- a/core/lib/Thelia/Model/ConfigQuery.php +++ b/core/lib/Thelia/Model/ConfigQuery.php @@ -56,9 +56,15 @@ class ConfigQuery extends BaseConfigQuery { public static function getPageNotFoundView() { - return self::read("page_not_found_view", '404.html'); + return self::read("page_not_found_view", '404'); } + public static function getPassedUrlView() + { + return self::read('passed_url_view', 'passed-url'); + } + + public static function getActiveTemplate() { return self::read('active-template', 'default'); diff --git a/core/lib/Thelia/Model/Content.php b/core/lib/Thelia/Model/Content.php index 79660f93a..69ef7d6d7 100755 --- a/core/lib/Thelia/Model/Content.php +++ b/core/lib/Thelia/Model/Content.php @@ -2,7 +2,12 @@ namespace Thelia\Model; +use Propel\Runtime\Propel; +use Thelia\Core\Event\Content\ContentEvent; +use Thelia\Core\Event\TheliaEvents; use Thelia\Model\Base\Content as BaseContent; +use Thelia\Model\ContentFolderQuery; +use Thelia\Model\Map\ContentTableMap; use Thelia\Tools\URL; use Propel\Runtime\Connection\ConnectionInterface; @@ -17,7 +22,7 @@ class Content extends BaseContent /** * {@inheritDoc} */ - protected function getRewritenUrlViewName() { + protected function getRewrittenUrlViewName() { return 'content'; } @@ -30,15 +35,78 @@ class Content extends BaseContent // and generate the position relative to this folder } - /** - * {@inheritDoc} - */ - public function preInsert(ConnectionInterface $con = null) + public function getDefaultFolderId() { - $this->setPosition($this->getNextPosition()); + // Find default folder + $default_folder = ContentFolderQuery::create() + ->filterByContentId($this->getId()) + ->filterByDefaultFolder(true) + ->findOne(); - $this->generateRewritenUrl($this->getLocale()); + return $default_folder == null ? 0 : $default_folder->getFolderId(); + } + + public function setDefaultFolder($folderId) + { +/* ContentFolderQuery::create() + ->filterByContentId($this->getId) + ->update(array("DefaultFolder" => 0));*/ + + return $this; + } + + public function create($defaultFolderId) + { + $con = Propel::getWriteConnection(ContentTableMap::DATABASE_NAME); + + $con->beginTransaction(); + + $this->dispatchEvent(TheliaEvents::BEFORE_CREATECONTENT, new ContentEvent($this)); + + try { + $this->save($con); + + $cf = new ContentFolder(); + $cf->setContentId($this->getId()) + ->setFolderId($defaultFolderId) + ->setDefaultFolder(1) + ->save($con); + + $this->setPosition($this->getNextPosition())->save($con); + + $con->commit(); + + $this->dispatchEvent(TheliaEvents::AFTER_CREATECONTENT,new ContentEvent($this)); + } catch(\Exception $ex) { + + $con->rollback(); + + throw $ex; + } + } + + + public function preUpdate(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::BEFORE_UPDATECONTENT, new ContentEvent($this)); return true; } + + public function postUpdate(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_UPDATECONTENT, new ContentEvent($this)); + } + + public function preDelete(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::BEFORE_DELETECONTENT, new ContentEvent($this)); + + return true; + } + + public function postDelete(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_DELETECONTENT, new ContentEvent($this)); + } } diff --git a/core/lib/Thelia/Model/ContentDocument.php b/core/lib/Thelia/Model/ContentDocument.php index 8ecf3a3a9..1409b2713 100755 --- a/core/lib/Thelia/Model/ContentDocument.php +++ b/core/lib/Thelia/Model/ContentDocument.php @@ -25,4 +25,28 @@ class ContentDocument extends BaseContentDocument return true; } + + /** + * Set Document parent id + * + * @param int $parentId parent id + * + * @return $this + */ + public function setParentId($parentId) + { + $this->setContentId($parentId); + + return $this; + } + + /** + * Get Document parent id + * + * @return int parent id + */ + public function getParentId() + { + return $this->getContentId(); + } } diff --git a/core/lib/Thelia/Model/ContentI18n.php b/core/lib/Thelia/Model/ContentI18n.php index 5b29d894f..11713d57b 100755 --- a/core/lib/Thelia/Model/ContentI18n.php +++ b/core/lib/Thelia/Model/ContentI18n.php @@ -2,8 +2,13 @@ namespace Thelia\Model; +use Propel\Runtime\Connection\ConnectionInterface; use Thelia\Model\Base\ContentI18n as BaseContentI18n; class ContentI18n extends BaseContentI18n { - + public function postInsert(ConnectionInterface $con = null) + { + $content = $this->getContent(); + $content->generateRewrittenUrl($this->getLocale()); + } } diff --git a/core/lib/Thelia/Model/ContentImage.php b/core/lib/Thelia/Model/ContentImage.php index ac1dcf755..b6a3085d4 100755 --- a/core/lib/Thelia/Model/ContentImage.php +++ b/core/lib/Thelia/Model/ContentImage.php @@ -25,4 +25,28 @@ class ContentImage extends BaseContentImage return true; } + + /** + * Set Image parent id + * + * @param int $parentId parent id + * + * @return $this + */ + public function setParentId($parentId) + { + $this->setContentId($parentId); + + return $this; + } + + /** + * Get Image parent id + * + * @return int parent id + */ + public function getParentId() + { + return $this->getContentId(); + } } \ No newline at end of file diff --git a/core/lib/Thelia/Model/CouponRule.php b/core/lib/Thelia/Model/CouponRule.php deleted file mode 100755 index 14c84deb2..000000000 --- a/core/lib/Thelia/Model/CouponRule.php +++ /dev/null @@ -1,9 +0,0 @@ -dispatchEvent(TheliaEvents::BEFORE_CREATEFEATURE_PRODUCT, new FeatureProductEvent($this)); + + return true; + } + + /** + * {@inheritDoc} + */ + public function postInsert(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_CREATEFEATURE_PRODUCT, new FeatureProductEvent($this)); + } + + /** + * {@inheritDoc} + */ + public function preUpdate(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::BEFORE_UPDATEFEATURE_PRODUCT, new FeatureProductEvent($this)); + + return true; + } + + /** + * {@inheritDoc} + */ + public function postUpdate(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_UPDATEFEATURE_PRODUCT, new FeatureProductEvent($this)); + } + + /** + * {@inheritDoc} + */ + public function preDelete(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::BEFORE_DELETEFEATURE_PRODUCT, new FeatureProductEvent($this)); + + return true; + } + + /** + * {@inheritDoc} + */ + public function postDelete(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_DELETEFEATURE_PRODUCT, new FeatureProductEvent($this)); + } } diff --git a/core/lib/Thelia/Model/FeatureTemplate.php b/core/lib/Thelia/Model/FeatureTemplate.php index 47a33027a..3f28a3a10 100644 --- a/core/lib/Thelia/Model/FeatureTemplate.php +++ b/core/lib/Thelia/Model/FeatureTemplate.php @@ -3,8 +3,30 @@ namespace Thelia\Model; use Thelia\Model\Base\FeatureTemplate as BaseFeatureTemplate; +use Propel\Runtime\Connection\ConnectionInterface; - class FeatureTemplate extends BaseFeatureTemplate +class FeatureTemplate extends BaseFeatureTemplate { + use \Thelia\Model\Tools\ModelEventDispatcherTrait; + use \Thelia\Model\Tools\PositionManagementTrait; + + /** + * Calculate next position relative to our template + */ + protected function addCriteriaToPositionQuery($query) + { + $query->filterByTemplateId($this->getTemplateId()); + } + + /** + * {@inheritDoc} + */ + public function preInsert(ConnectionInterface $con = null) + { + // Set the current position for the new object + $this->setPosition($this->getNextPosition()); + + return true; + } } diff --git a/core/lib/Thelia/Model/Folder.php b/core/lib/Thelia/Model/Folder.php index 1e73e7e23..ffd1c38ef 100755 --- a/core/lib/Thelia/Model/Folder.php +++ b/core/lib/Thelia/Model/Folder.php @@ -2,6 +2,8 @@ namespace Thelia\Model; +use Thelia\Core\Event\FolderEvent; +use Thelia\Core\Event\TheliaEvents; use Thelia\Model\Base\Folder as BaseFolder; use Thelia\Tools\URL; use Propel\Runtime\Connection\ConnectionInterface; @@ -17,7 +19,7 @@ class Folder extends BaseFolder /** * {@inheritDoc} */ - protected function getRewritenUrlViewName() { + protected function getRewrittenUrlViewName() { return 'folder'; } @@ -44,8 +46,8 @@ class Folder extends BaseFolder foreach($children as $child) { - $contentsCount += ProductQuery::create() - ->filterByCategory($child) + $contentsCount += ContentQuery::create() + ->filterByFolder($child) ->count(); } @@ -67,8 +69,37 @@ class Folder extends BaseFolder { $this->setPosition($this->getNextPosition()); - $this->generateRewritenUrl($this->getLocale()); + $this->dispatchEvent(TheliaEvents::BEFORE_CREATEFOLDER, new FolderEvent($this)); return true; } + + public function postInsert(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_CREATEFOLDER, new FolderEvent($this)); + } + + public function preUpdate(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::BEFORE_UPDATEFOLDER, new FolderEvent($this)); + + return true; + } + + public function postUpdate(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_UPDATEFOLDER, new FolderEvent($this)); + } + + public function preDelete(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::BEFORE_DELETEFOLDER, new FolderEvent($this)); + + return true; + } + + public function postDelete(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_DELETEFOLDER, new FolderEvent($this)); + } } diff --git a/core/lib/Thelia/Model/FolderDocument.php b/core/lib/Thelia/Model/FolderDocument.php index 0a86995d2..1d84d9e55 100755 --- a/core/lib/Thelia/Model/FolderDocument.php +++ b/core/lib/Thelia/Model/FolderDocument.php @@ -25,4 +25,28 @@ class FolderDocument extends BaseFolderDocument return true; } + + /** + * Set Document parent id + * + * @param int $parentId parent id + * + * @return $this + */ + public function setParentId($parentId) + { + $this->setFolderId($parentId); + + return $this; + } + + /** + * Get Document parent id + * + * @return int parent id + */ + public function getParentId() + { + return $this->getFolderId(); + } } diff --git a/core/lib/Thelia/Model/FolderI18n.php b/core/lib/Thelia/Model/FolderI18n.php index d1044452b..7ede39502 100755 --- a/core/lib/Thelia/Model/FolderI18n.php +++ b/core/lib/Thelia/Model/FolderI18n.php @@ -2,8 +2,14 @@ namespace Thelia\Model; +use Propel\Runtime\Connection\ConnectionInterface; use Thelia\Model\Base\FolderI18n as BaseFolderI18n; class FolderI18n extends BaseFolderI18n { + public function postInsert(ConnectionInterface $con = null) + { + $folder = $this->getFolder(); + $folder->generateRewrittenUrl($this->getLocale()); + } } diff --git a/core/lib/Thelia/Model/FolderImage.php b/core/lib/Thelia/Model/FolderImage.php index 58d8f928e..f9491c9a5 100755 --- a/core/lib/Thelia/Model/FolderImage.php +++ b/core/lib/Thelia/Model/FolderImage.php @@ -25,4 +25,28 @@ class FolderImage extends BaseFolderImage return true; } + + /** + * Set Image parent id + * + * @param int $parentId parent id + * + * @return $this + */ + public function setParentId($parentId) + { + $this->setFolderId($parentId); + + return $this; + } + + /** + * Get Image parent id + * + * @return int parent id + */ + public function getParentId() + { + return $this->getFolderId(); + } } diff --git a/core/lib/Thelia/Model/Map/AttributeTemplateTableMap.php b/core/lib/Thelia/Model/Map/AttributeTemplateTableMap.php index 04d3a9a4a..c0df89d8f 100644 --- a/core/lib/Thelia/Model/Map/AttributeTemplateTableMap.php +++ b/core/lib/Thelia/Model/Map/AttributeTemplateTableMap.php @@ -57,7 +57,7 @@ class AttributeTemplateTableMap extends TableMap /** * The total number of columns */ - const NUM_COLUMNS = 5; + const NUM_COLUMNS = 7; /** * The number of lazy-loaded columns @@ -67,7 +67,7 @@ class AttributeTemplateTableMap extends TableMap /** * The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */ - const NUM_HYDRATE_COLUMNS = 5; + const NUM_HYDRATE_COLUMNS = 7; /** * the column name for the ID field @@ -84,6 +84,16 @@ class AttributeTemplateTableMap extends TableMap */ const TEMPLATE_ID = 'attribute_template.TEMPLATE_ID'; + /** + * the column name for the POSITION field + */ + const POSITION = 'attribute_template.POSITION'; + + /** + * the column name for the ATTRIBUTE_TEMPLATECOL field + */ + const ATTRIBUTE_TEMPLATECOL = 'attribute_template.ATTRIBUTE_TEMPLATECOL'; + /** * the column name for the CREATED_AT field */ @@ -106,12 +116,12 @@ class AttributeTemplateTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('Id', 'AttributeId', 'TemplateId', 'CreatedAt', 'UpdatedAt', ), - self::TYPE_STUDLYPHPNAME => array('id', 'attributeId', 'templateId', 'createdAt', 'updatedAt', ), - self::TYPE_COLNAME => array(AttributeTemplateTableMap::ID, AttributeTemplateTableMap::ATTRIBUTE_ID, AttributeTemplateTableMap::TEMPLATE_ID, AttributeTemplateTableMap::CREATED_AT, AttributeTemplateTableMap::UPDATED_AT, ), - self::TYPE_RAW_COLNAME => array('ID', 'ATTRIBUTE_ID', 'TEMPLATE_ID', 'CREATED_AT', 'UPDATED_AT', ), - self::TYPE_FIELDNAME => array('id', 'attribute_id', 'template_id', 'created_at', 'updated_at', ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, ) + self::TYPE_PHPNAME => array('Id', 'AttributeId', 'TemplateId', 'Position', 'AttributeTemplatecol', 'CreatedAt', 'UpdatedAt', ), + self::TYPE_STUDLYPHPNAME => array('id', 'attributeId', 'templateId', 'position', 'attributeTemplatecol', 'createdAt', 'updatedAt', ), + self::TYPE_COLNAME => array(AttributeTemplateTableMap::ID, AttributeTemplateTableMap::ATTRIBUTE_ID, AttributeTemplateTableMap::TEMPLATE_ID, AttributeTemplateTableMap::POSITION, AttributeTemplateTableMap::ATTRIBUTE_TEMPLATECOL, AttributeTemplateTableMap::CREATED_AT, AttributeTemplateTableMap::UPDATED_AT, ), + self::TYPE_RAW_COLNAME => array('ID', 'ATTRIBUTE_ID', 'TEMPLATE_ID', 'POSITION', 'ATTRIBUTE_TEMPLATECOL', 'CREATED_AT', 'UPDATED_AT', ), + self::TYPE_FIELDNAME => array('id', 'attribute_id', 'template_id', 'position', 'attribute_templatecol', 'created_at', 'updated_at', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, ) ); /** @@ -121,12 +131,12 @@ class AttributeTemplateTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'AttributeId' => 1, 'TemplateId' => 2, 'CreatedAt' => 3, 'UpdatedAt' => 4, ), - self::TYPE_STUDLYPHPNAME => array('id' => 0, 'attributeId' => 1, 'templateId' => 2, 'createdAt' => 3, 'updatedAt' => 4, ), - self::TYPE_COLNAME => array(AttributeTemplateTableMap::ID => 0, AttributeTemplateTableMap::ATTRIBUTE_ID => 1, AttributeTemplateTableMap::TEMPLATE_ID => 2, AttributeTemplateTableMap::CREATED_AT => 3, AttributeTemplateTableMap::UPDATED_AT => 4, ), - self::TYPE_RAW_COLNAME => array('ID' => 0, 'ATTRIBUTE_ID' => 1, 'TEMPLATE_ID' => 2, 'CREATED_AT' => 3, 'UPDATED_AT' => 4, ), - self::TYPE_FIELDNAME => array('id' => 0, 'attribute_id' => 1, 'template_id' => 2, 'created_at' => 3, 'updated_at' => 4, ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, ) + self::TYPE_PHPNAME => array('Id' => 0, 'AttributeId' => 1, 'TemplateId' => 2, 'Position' => 3, 'AttributeTemplatecol' => 4, 'CreatedAt' => 5, 'UpdatedAt' => 6, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'attributeId' => 1, 'templateId' => 2, 'position' => 3, 'attributeTemplatecol' => 4, 'createdAt' => 5, 'updatedAt' => 6, ), + self::TYPE_COLNAME => array(AttributeTemplateTableMap::ID => 0, AttributeTemplateTableMap::ATTRIBUTE_ID => 1, AttributeTemplateTableMap::TEMPLATE_ID => 2, AttributeTemplateTableMap::POSITION => 3, AttributeTemplateTableMap::ATTRIBUTE_TEMPLATECOL => 4, AttributeTemplateTableMap::CREATED_AT => 5, AttributeTemplateTableMap::UPDATED_AT => 6, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'ATTRIBUTE_ID' => 1, 'TEMPLATE_ID' => 2, 'POSITION' => 3, 'ATTRIBUTE_TEMPLATECOL' => 4, 'CREATED_AT' => 5, 'UPDATED_AT' => 6, ), + self::TYPE_FIELDNAME => array('id' => 0, 'attribute_id' => 1, 'template_id' => 2, 'position' => 3, 'attribute_templatecol' => 4, 'created_at' => 5, 'updated_at' => 6, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, ) ); /** @@ -149,6 +159,8 @@ class AttributeTemplateTableMap extends TableMap $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); $this->addForeignKey('ATTRIBUTE_ID', 'AttributeId', 'INTEGER', 'attribute', 'ID', true, null, null); $this->addForeignKey('TEMPLATE_ID', 'TemplateId', 'INTEGER', 'template', 'ID', true, null, null); + $this->addColumn('POSITION', 'Position', 'INTEGER', false, null, null); + $this->addColumn('ATTRIBUTE_TEMPLATECOL', 'AttributeTemplatecol', 'VARCHAR', false, 45, null); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); } // initialize() @@ -316,12 +328,16 @@ class AttributeTemplateTableMap extends TableMap $criteria->addSelectColumn(AttributeTemplateTableMap::ID); $criteria->addSelectColumn(AttributeTemplateTableMap::ATTRIBUTE_ID); $criteria->addSelectColumn(AttributeTemplateTableMap::TEMPLATE_ID); + $criteria->addSelectColumn(AttributeTemplateTableMap::POSITION); + $criteria->addSelectColumn(AttributeTemplateTableMap::ATTRIBUTE_TEMPLATECOL); $criteria->addSelectColumn(AttributeTemplateTableMap::CREATED_AT); $criteria->addSelectColumn(AttributeTemplateTableMap::UPDATED_AT); } else { $criteria->addSelectColumn($alias . '.ID'); $criteria->addSelectColumn($alias . '.ATTRIBUTE_ID'); $criteria->addSelectColumn($alias . '.TEMPLATE_ID'); + $criteria->addSelectColumn($alias . '.POSITION'); + $criteria->addSelectColumn($alias . '.ATTRIBUTE_TEMPLATECOL'); $criteria->addSelectColumn($alias . '.CREATED_AT'); $criteria->addSelectColumn($alias . '.UPDATED_AT'); } diff --git a/core/lib/Thelia/Model/Map/FeatureProductTableMap.php b/core/lib/Thelia/Model/Map/FeatureProductTableMap.php index f0263b47c..9db4ec441 100644 --- a/core/lib/Thelia/Model/Map/FeatureProductTableMap.php +++ b/core/lib/Thelia/Model/Map/FeatureProductTableMap.php @@ -90,9 +90,9 @@ class FeatureProductTableMap extends TableMap const FEATURE_AV_ID = 'feature_product.FEATURE_AV_ID'; /** - * the column name for the BY_DEFAULT field + * the column name for the FREE_TEXT_VALUE field */ - const BY_DEFAULT = 'feature_product.BY_DEFAULT'; + const FREE_TEXT_VALUE = 'feature_product.FREE_TEXT_VALUE'; /** * the column name for the POSITION field @@ -121,11 +121,11 @@ class FeatureProductTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('Id', 'ProductId', 'FeatureId', 'FeatureAvId', 'ByDefault', 'Position', 'CreatedAt', 'UpdatedAt', ), - self::TYPE_STUDLYPHPNAME => array('id', 'productId', 'featureId', 'featureAvId', 'byDefault', 'position', 'createdAt', 'updatedAt', ), - self::TYPE_COLNAME => array(FeatureProductTableMap::ID, FeatureProductTableMap::PRODUCT_ID, FeatureProductTableMap::FEATURE_ID, FeatureProductTableMap::FEATURE_AV_ID, FeatureProductTableMap::BY_DEFAULT, FeatureProductTableMap::POSITION, FeatureProductTableMap::CREATED_AT, FeatureProductTableMap::UPDATED_AT, ), - self::TYPE_RAW_COLNAME => array('ID', 'PRODUCT_ID', 'FEATURE_ID', 'FEATURE_AV_ID', 'BY_DEFAULT', 'POSITION', 'CREATED_AT', 'UPDATED_AT', ), - self::TYPE_FIELDNAME => array('id', 'product_id', 'feature_id', 'feature_av_id', 'by_default', 'position', 'created_at', 'updated_at', ), + self::TYPE_PHPNAME => array('Id', 'ProductId', 'FeatureId', 'FeatureAvId', 'FreeTextValue', 'Position', 'CreatedAt', 'UpdatedAt', ), + self::TYPE_STUDLYPHPNAME => array('id', 'productId', 'featureId', 'featureAvId', 'freeTextValue', 'position', 'createdAt', 'updatedAt', ), + self::TYPE_COLNAME => array(FeatureProductTableMap::ID, FeatureProductTableMap::PRODUCT_ID, FeatureProductTableMap::FEATURE_ID, FeatureProductTableMap::FEATURE_AV_ID, FeatureProductTableMap::FREE_TEXT_VALUE, FeatureProductTableMap::POSITION, FeatureProductTableMap::CREATED_AT, FeatureProductTableMap::UPDATED_AT, ), + self::TYPE_RAW_COLNAME => array('ID', 'PRODUCT_ID', 'FEATURE_ID', 'FEATURE_AV_ID', 'FREE_TEXT_VALUE', 'POSITION', 'CREATED_AT', 'UPDATED_AT', ), + self::TYPE_FIELDNAME => array('id', 'product_id', 'feature_id', 'feature_av_id', 'free_text_value', 'position', 'created_at', 'updated_at', ), self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, ) ); @@ -136,11 +136,11 @@ class FeatureProductTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'ProductId' => 1, 'FeatureId' => 2, 'FeatureAvId' => 3, 'ByDefault' => 4, 'Position' => 5, 'CreatedAt' => 6, 'UpdatedAt' => 7, ), - self::TYPE_STUDLYPHPNAME => array('id' => 0, 'productId' => 1, 'featureId' => 2, 'featureAvId' => 3, 'byDefault' => 4, 'position' => 5, 'createdAt' => 6, 'updatedAt' => 7, ), - self::TYPE_COLNAME => array(FeatureProductTableMap::ID => 0, FeatureProductTableMap::PRODUCT_ID => 1, FeatureProductTableMap::FEATURE_ID => 2, FeatureProductTableMap::FEATURE_AV_ID => 3, FeatureProductTableMap::BY_DEFAULT => 4, FeatureProductTableMap::POSITION => 5, FeatureProductTableMap::CREATED_AT => 6, FeatureProductTableMap::UPDATED_AT => 7, ), - self::TYPE_RAW_COLNAME => array('ID' => 0, 'PRODUCT_ID' => 1, 'FEATURE_ID' => 2, 'FEATURE_AV_ID' => 3, 'BY_DEFAULT' => 4, 'POSITION' => 5, 'CREATED_AT' => 6, 'UPDATED_AT' => 7, ), - self::TYPE_FIELDNAME => array('id' => 0, 'product_id' => 1, 'feature_id' => 2, 'feature_av_id' => 3, 'by_default' => 4, 'position' => 5, 'created_at' => 6, 'updated_at' => 7, ), + self::TYPE_PHPNAME => array('Id' => 0, 'ProductId' => 1, 'FeatureId' => 2, 'FeatureAvId' => 3, 'FreeTextValue' => 4, 'Position' => 5, 'CreatedAt' => 6, 'UpdatedAt' => 7, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'productId' => 1, 'featureId' => 2, 'featureAvId' => 3, 'freeTextValue' => 4, 'position' => 5, 'createdAt' => 6, 'updatedAt' => 7, ), + self::TYPE_COLNAME => array(FeatureProductTableMap::ID => 0, FeatureProductTableMap::PRODUCT_ID => 1, FeatureProductTableMap::FEATURE_ID => 2, FeatureProductTableMap::FEATURE_AV_ID => 3, FeatureProductTableMap::FREE_TEXT_VALUE => 4, FeatureProductTableMap::POSITION => 5, FeatureProductTableMap::CREATED_AT => 6, FeatureProductTableMap::UPDATED_AT => 7, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'PRODUCT_ID' => 1, 'FEATURE_ID' => 2, 'FEATURE_AV_ID' => 3, 'FREE_TEXT_VALUE' => 4, 'POSITION' => 5, 'CREATED_AT' => 6, 'UPDATED_AT' => 7, ), + self::TYPE_FIELDNAME => array('id' => 0, 'product_id' => 1, 'feature_id' => 2, 'feature_av_id' => 3, 'free_text_value' => 4, 'position' => 5, 'created_at' => 6, 'updated_at' => 7, ), self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, ) ); @@ -164,7 +164,7 @@ class FeatureProductTableMap extends TableMap $this->addForeignKey('PRODUCT_ID', 'ProductId', 'INTEGER', 'product', 'ID', true, null, null); $this->addForeignKey('FEATURE_ID', 'FeatureId', 'INTEGER', 'feature', 'ID', true, null, null); $this->addForeignKey('FEATURE_AV_ID', 'FeatureAvId', 'INTEGER', 'feature_av', 'ID', false, null, null); - $this->addColumn('BY_DEFAULT', 'ByDefault', 'VARCHAR', false, 255, null); + $this->addColumn('FREE_TEXT_VALUE', 'FreeTextValue', 'LONGVARCHAR', false, null, null); $this->addColumn('POSITION', 'Position', 'INTEGER', false, null, null); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); @@ -335,7 +335,7 @@ class FeatureProductTableMap extends TableMap $criteria->addSelectColumn(FeatureProductTableMap::PRODUCT_ID); $criteria->addSelectColumn(FeatureProductTableMap::FEATURE_ID); $criteria->addSelectColumn(FeatureProductTableMap::FEATURE_AV_ID); - $criteria->addSelectColumn(FeatureProductTableMap::BY_DEFAULT); + $criteria->addSelectColumn(FeatureProductTableMap::FREE_TEXT_VALUE); $criteria->addSelectColumn(FeatureProductTableMap::POSITION); $criteria->addSelectColumn(FeatureProductTableMap::CREATED_AT); $criteria->addSelectColumn(FeatureProductTableMap::UPDATED_AT); @@ -344,7 +344,7 @@ class FeatureProductTableMap extends TableMap $criteria->addSelectColumn($alias . '.PRODUCT_ID'); $criteria->addSelectColumn($alias . '.FEATURE_ID'); $criteria->addSelectColumn($alias . '.FEATURE_AV_ID'); - $criteria->addSelectColumn($alias . '.BY_DEFAULT'); + $criteria->addSelectColumn($alias . '.FREE_TEXT_VALUE'); $criteria->addSelectColumn($alias . '.POSITION'); $criteria->addSelectColumn($alias . '.CREATED_AT'); $criteria->addSelectColumn($alias . '.UPDATED_AT'); diff --git a/core/lib/Thelia/Model/Map/FeatureTableMap.php b/core/lib/Thelia/Model/Map/FeatureTableMap.php index 067a242a3..c6a29e2f4 100644 --- a/core/lib/Thelia/Model/Map/FeatureTableMap.php +++ b/core/lib/Thelia/Model/Map/FeatureTableMap.php @@ -156,7 +156,7 @@ class FeatureTableMap extends TableMap // columns $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); $this->addColumn('VISIBLE', 'Visible', 'INTEGER', false, null, 0); - $this->addColumn('POSITION', 'Position', 'INTEGER', true, null, null); + $this->addColumn('POSITION', 'Position', 'INTEGER', false, null, null); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); } // initialize() diff --git a/core/lib/Thelia/Model/Map/FeatureTemplateTableMap.php b/core/lib/Thelia/Model/Map/FeatureTemplateTableMap.php index abb1a98b7..68f3b9a24 100644 --- a/core/lib/Thelia/Model/Map/FeatureTemplateTableMap.php +++ b/core/lib/Thelia/Model/Map/FeatureTemplateTableMap.php @@ -57,7 +57,7 @@ class FeatureTemplateTableMap extends TableMap /** * The total number of columns */ - const NUM_COLUMNS = 5; + const NUM_COLUMNS = 6; /** * The number of lazy-loaded columns @@ -67,7 +67,7 @@ class FeatureTemplateTableMap extends TableMap /** * The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */ - const NUM_HYDRATE_COLUMNS = 5; + const NUM_HYDRATE_COLUMNS = 6; /** * the column name for the ID field @@ -84,6 +84,11 @@ class FeatureTemplateTableMap extends TableMap */ const TEMPLATE_ID = 'feature_template.TEMPLATE_ID'; + /** + * the column name for the POSITION field + */ + const POSITION = 'feature_template.POSITION'; + /** * the column name for the CREATED_AT field */ @@ -106,12 +111,12 @@ class FeatureTemplateTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('Id', 'FeatureId', 'TemplateId', 'CreatedAt', 'UpdatedAt', ), - self::TYPE_STUDLYPHPNAME => array('id', 'featureId', 'templateId', 'createdAt', 'updatedAt', ), - self::TYPE_COLNAME => array(FeatureTemplateTableMap::ID, FeatureTemplateTableMap::FEATURE_ID, FeatureTemplateTableMap::TEMPLATE_ID, FeatureTemplateTableMap::CREATED_AT, FeatureTemplateTableMap::UPDATED_AT, ), - self::TYPE_RAW_COLNAME => array('ID', 'FEATURE_ID', 'TEMPLATE_ID', 'CREATED_AT', 'UPDATED_AT', ), - self::TYPE_FIELDNAME => array('id', 'feature_id', 'template_id', 'created_at', 'updated_at', ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, ) + self::TYPE_PHPNAME => array('Id', 'FeatureId', 'TemplateId', 'Position', 'CreatedAt', 'UpdatedAt', ), + self::TYPE_STUDLYPHPNAME => array('id', 'featureId', 'templateId', 'position', 'createdAt', 'updatedAt', ), + self::TYPE_COLNAME => array(FeatureTemplateTableMap::ID, FeatureTemplateTableMap::FEATURE_ID, FeatureTemplateTableMap::TEMPLATE_ID, FeatureTemplateTableMap::POSITION, FeatureTemplateTableMap::CREATED_AT, FeatureTemplateTableMap::UPDATED_AT, ), + self::TYPE_RAW_COLNAME => array('ID', 'FEATURE_ID', 'TEMPLATE_ID', 'POSITION', 'CREATED_AT', 'UPDATED_AT', ), + self::TYPE_FIELDNAME => array('id', 'feature_id', 'template_id', 'position', 'created_at', 'updated_at', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, ) ); /** @@ -121,12 +126,12 @@ class FeatureTemplateTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'FeatureId' => 1, 'TemplateId' => 2, 'CreatedAt' => 3, 'UpdatedAt' => 4, ), - self::TYPE_STUDLYPHPNAME => array('id' => 0, 'featureId' => 1, 'templateId' => 2, 'createdAt' => 3, 'updatedAt' => 4, ), - self::TYPE_COLNAME => array(FeatureTemplateTableMap::ID => 0, FeatureTemplateTableMap::FEATURE_ID => 1, FeatureTemplateTableMap::TEMPLATE_ID => 2, FeatureTemplateTableMap::CREATED_AT => 3, FeatureTemplateTableMap::UPDATED_AT => 4, ), - self::TYPE_RAW_COLNAME => array('ID' => 0, 'FEATURE_ID' => 1, 'TEMPLATE_ID' => 2, 'CREATED_AT' => 3, 'UPDATED_AT' => 4, ), - self::TYPE_FIELDNAME => array('id' => 0, 'feature_id' => 1, 'template_id' => 2, 'created_at' => 3, 'updated_at' => 4, ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, ) + self::TYPE_PHPNAME => array('Id' => 0, 'FeatureId' => 1, 'TemplateId' => 2, 'Position' => 3, 'CreatedAt' => 4, 'UpdatedAt' => 5, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'featureId' => 1, 'templateId' => 2, 'position' => 3, 'createdAt' => 4, 'updatedAt' => 5, ), + self::TYPE_COLNAME => array(FeatureTemplateTableMap::ID => 0, FeatureTemplateTableMap::FEATURE_ID => 1, FeatureTemplateTableMap::TEMPLATE_ID => 2, FeatureTemplateTableMap::POSITION => 3, FeatureTemplateTableMap::CREATED_AT => 4, FeatureTemplateTableMap::UPDATED_AT => 5, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'FEATURE_ID' => 1, 'TEMPLATE_ID' => 2, 'POSITION' => 3, 'CREATED_AT' => 4, 'UPDATED_AT' => 5, ), + self::TYPE_FIELDNAME => array('id' => 0, 'feature_id' => 1, 'template_id' => 2, 'position' => 3, 'created_at' => 4, 'updated_at' => 5, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, ) ); /** @@ -149,6 +154,7 @@ class FeatureTemplateTableMap extends TableMap $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); $this->addForeignKey('FEATURE_ID', 'FeatureId', 'INTEGER', 'feature', 'ID', true, null, null); $this->addForeignKey('TEMPLATE_ID', 'TemplateId', 'INTEGER', 'template', 'ID', true, null, null); + $this->addColumn('POSITION', 'Position', 'INTEGER', false, null, null); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); } // initialize() @@ -316,12 +322,14 @@ class FeatureTemplateTableMap extends TableMap $criteria->addSelectColumn(FeatureTemplateTableMap::ID); $criteria->addSelectColumn(FeatureTemplateTableMap::FEATURE_ID); $criteria->addSelectColumn(FeatureTemplateTableMap::TEMPLATE_ID); + $criteria->addSelectColumn(FeatureTemplateTableMap::POSITION); $criteria->addSelectColumn(FeatureTemplateTableMap::CREATED_AT); $criteria->addSelectColumn(FeatureTemplateTableMap::UPDATED_AT); } else { $criteria->addSelectColumn($alias . '.ID'); $criteria->addSelectColumn($alias . '.FEATURE_ID'); $criteria->addSelectColumn($alias . '.TEMPLATE_ID'); + $criteria->addSelectColumn($alias . '.POSITION'); $criteria->addSelectColumn($alias . '.CREATED_AT'); $criteria->addSelectColumn($alias . '.UPDATED_AT'); } diff --git a/core/lib/Thelia/Model/Map/ModuleImageI18nTableMap.php b/core/lib/Thelia/Model/Map/ModuleImageI18nTableMap.php new file mode 100644 index 000000000..76c29e11c --- /dev/null +++ b/core/lib/Thelia/Model/Map/ModuleImageI18nTableMap.php @@ -0,0 +1,497 @@ + array('Id', 'Locale', 'Title', 'Description', 'Chapo', 'Postscriptum', ), + self::TYPE_STUDLYPHPNAME => array('id', 'locale', 'title', 'description', 'chapo', 'postscriptum', ), + self::TYPE_COLNAME => array(ModuleImageI18nTableMap::ID, ModuleImageI18nTableMap::LOCALE, ModuleImageI18nTableMap::TITLE, ModuleImageI18nTableMap::DESCRIPTION, ModuleImageI18nTableMap::CHAPO, ModuleImageI18nTableMap::POSTSCRIPTUM, ), + self::TYPE_RAW_COLNAME => array('ID', 'LOCALE', 'TITLE', 'DESCRIPTION', 'CHAPO', 'POSTSCRIPTUM', ), + self::TYPE_FIELDNAME => array('id', 'locale', 'title', 'description', 'chapo', 'postscriptum', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 + */ + protected static $fieldKeys = array ( + self::TYPE_PHPNAME => array('Id' => 0, 'Locale' => 1, 'Title' => 2, 'Description' => 3, 'Chapo' => 4, 'Postscriptum' => 5, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'locale' => 1, 'title' => 2, 'description' => 3, 'chapo' => 4, 'postscriptum' => 5, ), + self::TYPE_COLNAME => array(ModuleImageI18nTableMap::ID => 0, ModuleImageI18nTableMap::LOCALE => 1, ModuleImageI18nTableMap::TITLE => 2, ModuleImageI18nTableMap::DESCRIPTION => 3, ModuleImageI18nTableMap::CHAPO => 4, ModuleImageI18nTableMap::POSTSCRIPTUM => 5, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'LOCALE' => 1, 'TITLE' => 2, 'DESCRIPTION' => 3, 'CHAPO' => 4, 'POSTSCRIPTUM' => 5, ), + self::TYPE_FIELDNAME => array('id' => 0, 'locale' => 1, 'title' => 2, 'description' => 3, 'chapo' => 4, 'postscriptum' => 5, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, ) + ); + + /** + * Initialize the table attributes and columns + * Relations are not initialized by this method since they are lazy loaded + * + * @return void + * @throws PropelException + */ + public function initialize() + { + // attributes + $this->setName('module_image_i18n'); + $this->setPhpName('ModuleImageI18n'); + $this->setClassName('\\Thelia\\Model\\ModuleImageI18n'); + $this->setPackage('Thelia.Model'); + $this->setUseIdGenerator(false); + // columns + $this->addForeignPrimaryKey('ID', 'Id', 'INTEGER' , 'module_image', 'ID', true, null, null); + $this->addPrimaryKey('LOCALE', 'Locale', 'VARCHAR', true, 5, 'en_US'); + $this->addColumn('TITLE', 'Title', 'VARCHAR', false, 255, null); + $this->addColumn('DESCRIPTION', 'Description', 'CLOB', false, null, null); + $this->addColumn('CHAPO', 'Chapo', 'LONGVARCHAR', false, null, null); + $this->addColumn('POSTSCRIPTUM', 'Postscriptum', 'LONGVARCHAR', false, null, null); + } // initialize() + + /** + * Build the RelationMap objects for this table relationships + */ + public function buildRelations() + { + $this->addRelation('ModuleImage', '\\Thelia\\Model\\ModuleImage', RelationMap::MANY_TO_ONE, array('id' => 'id', ), 'CASCADE', null); + } // buildRelations() + + /** + * Adds an object to the instance pool. + * + * Propel keeps cached copies of objects in an instance pool when they are retrieved + * from the database. In some cases you may need to explicitly add objects + * to the cache in order to ensure that the same objects are always returned by find*() + * and findPk*() calls. + * + * @param \Thelia\Model\ModuleImageI18n $obj A \Thelia\Model\ModuleImageI18n object. + * @param string $key (optional) key to use for instance map (for performance boost if key was already calculated externally). + */ + public static function addInstanceToPool($obj, $key = null) + { + if (Propel::isInstancePoolingEnabled()) { + if (null === $key) { + $key = serialize(array((string) $obj->getId(), (string) $obj->getLocale())); + } // if key === null + self::$instances[$key] = $obj; + } + } + + /** + * Removes an object from the instance pool. + * + * Propel keeps cached copies of objects in an instance pool when they are retrieved + * from the database. In some cases -- especially when you override doDelete + * methods in your stub classes -- you may need to explicitly remove objects + * from the cache in order to prevent returning objects that no longer exist. + * + * @param mixed $value A \Thelia\Model\ModuleImageI18n object or a primary key value. + */ + public static function removeInstanceFromPool($value) + { + if (Propel::isInstancePoolingEnabled() && null !== $value) { + if (is_object($value) && $value instanceof \Thelia\Model\ModuleImageI18n) { + $key = serialize(array((string) $value->getId(), (string) $value->getLocale())); + + } elseif (is_array($value) && count($value) === 2) { + // assume we've been passed a primary key"; + $key = serialize(array((string) $value[0], (string) $value[1])); + } elseif ($value instanceof Criteria) { + self::$instances = []; + + return; + } else { + $e = new PropelException("Invalid value passed to removeInstanceFromPool(). Expected primary key or \Thelia\Model\ModuleImageI18n object; got " . (is_object($value) ? get_class($value) . ' object.' : var_export($value, true))); + throw $e; + } + + unset(self::$instances[$key]); + } + } + + /** + * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. + * + * For tables with a single-column primary key, that simple pkey value will be returned. For tables with + * a multi-column primary key, a serialize()d version of the primary key will be returned. + * + * @param array $row resultset row. + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM + */ + public static function getPrimaryKeyHashFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + // If the PK cannot be derived from the row, return NULL. + if ($row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)] === null && $row[TableMap::TYPE_NUM == $indexType ? 1 + $offset : static::translateFieldName('Locale', TableMap::TYPE_PHPNAME, $indexType)] === null) { + return null; + } + + return serialize(array((string) $row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)], (string) $row[TableMap::TYPE_NUM == $indexType ? 1 + $offset : static::translateFieldName('Locale', TableMap::TYPE_PHPNAME, $indexType)])); + } + + /** + * Retrieves the primary key from the DB resultset row + * For tables with a single-column primary key, that simple pkey value will be returned. For tables with + * a multi-column primary key, an array of the primary key columns will be returned. + * + * @param array $row resultset row. + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM + * + * @return mixed The primary key of the row + */ + public static function getPrimaryKeyFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + + return $pks; + } + + /** + * The class that the tableMap will make instances of. + * + * If $withPrefix is true, the returned path + * uses a dot-path notation which is translated into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @param boolean $withPrefix Whether or not to return the path with the class name + * @return string path.to.ClassName + */ + public static function getOMClass($withPrefix = true) + { + return $withPrefix ? ModuleImageI18nTableMap::CLASS_DEFAULT : ModuleImageI18nTableMap::OM_CLASS; + } + + /** + * Populates an object of the default type or an object that inherit from the default. + * + * @param array $row row returned by DataFetcher->fetch(). + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType The index type of $row. Mostly DataFetcher->getIndexType(). + One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return array (ModuleImageI18n object, last column rank) + */ + public static function populateObject($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + $key = ModuleImageI18nTableMap::getPrimaryKeyHashFromRow($row, $offset, $indexType); + if (null !== ($obj = ModuleImageI18nTableMap::getInstanceFromPool($key))) { + // We no longer rehydrate the object, since this can cause data loss. + // See http://www.propelorm.org/ticket/509 + // $obj->hydrate($row, $offset, true); // rehydrate + $col = $offset + ModuleImageI18nTableMap::NUM_HYDRATE_COLUMNS; + } else { + $cls = ModuleImageI18nTableMap::OM_CLASS; + $obj = new $cls(); + $col = $obj->hydrate($row, $offset, false, $indexType); + ModuleImageI18nTableMap::addInstanceToPool($obj, $key); + } + + return array($obj, $col); + } + + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @param DataFetcherInterface $dataFetcher + * @return array + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(DataFetcherInterface $dataFetcher) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = static::getOMClass(false); + // populate the object(s) + while ($row = $dataFetcher->fetch()) { + $key = ModuleImageI18nTableMap::getPrimaryKeyHashFromRow($row, 0, $dataFetcher->getIndexType()); + if (null !== ($obj = ModuleImageI18nTableMap::getInstanceFromPool($key))) { + // We no longer rehydrate the object, since this can cause data loss. + // See http://www.propelorm.org/ticket/509 + // $obj->hydrate($row, 0, true); // rehydrate + $results[] = $obj; + } else { + $obj = new $cls(); + $obj->hydrate($row); + $results[] = $obj; + ModuleImageI18nTableMap::addInstanceToPool($obj, $key); + } // if key exists + } + + return $results; + } + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param Criteria $criteria object containing the columns to add. + * @param string $alias optional table alias + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria, $alias = null) + { + if (null === $alias) { + $criteria->addSelectColumn(ModuleImageI18nTableMap::ID); + $criteria->addSelectColumn(ModuleImageI18nTableMap::LOCALE); + $criteria->addSelectColumn(ModuleImageI18nTableMap::TITLE); + $criteria->addSelectColumn(ModuleImageI18nTableMap::DESCRIPTION); + $criteria->addSelectColumn(ModuleImageI18nTableMap::CHAPO); + $criteria->addSelectColumn(ModuleImageI18nTableMap::POSTSCRIPTUM); + } else { + $criteria->addSelectColumn($alias . '.ID'); + $criteria->addSelectColumn($alias . '.LOCALE'); + $criteria->addSelectColumn($alias . '.TITLE'); + $criteria->addSelectColumn($alias . '.DESCRIPTION'); + $criteria->addSelectColumn($alias . '.CHAPO'); + $criteria->addSelectColumn($alias . '.POSTSCRIPTUM'); + } + } + + /** + * Returns the TableMap related to this object. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getServiceContainer()->getDatabaseMap(ModuleImageI18nTableMap::DATABASE_NAME)->getTable(ModuleImageI18nTableMap::TABLE_NAME); + } + + /** + * Add a TableMap instance to the database for this tableMap class. + */ + public static function buildTableMap() + { + $dbMap = Propel::getServiceContainer()->getDatabaseMap(ModuleImageI18nTableMap::DATABASE_NAME); + if (!$dbMap->hasTable(ModuleImageI18nTableMap::TABLE_NAME)) { + $dbMap->addTableObject(new ModuleImageI18nTableMap()); + } + } + + /** + * Performs a DELETE on the database, given a ModuleImageI18n or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or ModuleImageI18n object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(ModuleImageI18nTableMap::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + // rename for clarity + $criteria = $values; + } elseif ($values instanceof \Thelia\Model\ModuleImageI18n) { // it's a model object + // create criteria based on pk values + $criteria = $values->buildPkeyCriteria(); + } else { // it's a primary key, or an array of pks + $criteria = new Criteria(ModuleImageI18nTableMap::DATABASE_NAME); + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey values + if (count($values) == count($values, COUNT_RECURSIVE)) { + // array is not multi-dimensional + $values = array($values); + } + foreach ($values as $value) { + $criterion = $criteria->getNewCriterion(ModuleImageI18nTableMap::ID, $value[0]); + $criterion->addAnd($criteria->getNewCriterion(ModuleImageI18nTableMap::LOCALE, $value[1])); + $criteria->addOr($criterion); + } + } + + $query = ModuleImageI18nQuery::create()->mergeWith($criteria); + + if ($values instanceof Criteria) { ModuleImageI18nTableMap::clearInstancePool(); + } elseif (!is_object($values)) { // it's a primary key, or an array of pks + foreach ((array) $values as $singleval) { ModuleImageI18nTableMap::removeInstanceFromPool($singleval); + } + } + + return $query->delete($con); + } + + /** + * Deletes all rows from the module_image_i18n table. + * + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll(ConnectionInterface $con = null) + { + return ModuleImageI18nQuery::create()->doDeleteAll($con); + } + + /** + * Performs an INSERT on the database, given a ModuleImageI18n or Criteria object. + * + * @param mixed $criteria Criteria or ModuleImageI18n object containing data that is used to create the INSERT statement. + * @param ConnectionInterface $con the ConnectionInterface connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($criteria, ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(ModuleImageI18nTableMap::DATABASE_NAME); + } + + if ($criteria instanceof Criteria) { + $criteria = clone $criteria; // rename for clarity + } else { + $criteria = $criteria->buildCriteria(); // build Criteria from ModuleImageI18n object + } + + + // Set the correct dbName + $query = ModuleImageI18nQuery::create()->mergeWith($criteria); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->beginTransaction(); + $pk = $query->doInsert($con); + $con->commit(); + } catch (PropelException $e) { + $con->rollBack(); + throw $e; + } + + return $pk; + } + +} // ModuleImageI18nTableMap +// This is the static code needed to register the TableMap for this table with the main Propel class. +// +ModuleImageI18nTableMap::buildTableMap(); diff --git a/core/lib/Thelia/Model/Map/AttributeCategoryTableMap.php b/core/lib/Thelia/Model/Map/ModuleImageTableMap.php similarity index 63% rename from core/lib/Thelia/Model/Map/AttributeCategoryTableMap.php rename to core/lib/Thelia/Model/Map/ModuleImageTableMap.php index b2525e8c3..718ac47c5 100644 --- a/core/lib/Thelia/Model/Map/AttributeCategoryTableMap.php +++ b/core/lib/Thelia/Model/Map/ModuleImageTableMap.php @@ -10,12 +10,12 @@ use Propel\Runtime\Exception\PropelException; use Propel\Runtime\Map\RelationMap; use Propel\Runtime\Map\TableMap; use Propel\Runtime\Map\TableMapTrait; -use Thelia\Model\AttributeCategory; -use Thelia\Model\AttributeCategoryQuery; +use Thelia\Model\ModuleImage; +use Thelia\Model\ModuleImageQuery; /** - * This class defines the structure of the 'attribute_category' table. + * This class defines the structure of the 'module_image' table. * * * @@ -25,14 +25,14 @@ use Thelia\Model\AttributeCategoryQuery; * (i.e. if it's a text column type). * */ -class AttributeCategoryTableMap extends TableMap +class ModuleImageTableMap extends TableMap { use InstancePoolTrait; use TableMapTrait; /** * The (dot-path) name of this class */ - const CLASS_NAME = 'Thelia.Model.Map.AttributeCategoryTableMap'; + const CLASS_NAME = 'Thelia.Model.Map.ModuleImageTableMap'; /** * The default database name for this class @@ -42,22 +42,22 @@ class AttributeCategoryTableMap extends TableMap /** * The table name for this class */ - const TABLE_NAME = 'attribute_category'; + const TABLE_NAME = 'module_image'; /** * The related Propel class for this table */ - const OM_CLASS = '\\Thelia\\Model\\AttributeCategory'; + const OM_CLASS = '\\Thelia\\Model\\ModuleImage'; /** * A class that can be returned by this tableMap */ - const CLASS_DEFAULT = 'Thelia.Model.AttributeCategory'; + const CLASS_DEFAULT = 'Thelia.Model.ModuleImage'; /** * The total number of columns */ - const NUM_COLUMNS = 5; + const NUM_COLUMNS = 6; /** * The number of lazy-loaded columns @@ -67,38 +67,52 @@ class AttributeCategoryTableMap extends TableMap /** * The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */ - const NUM_HYDRATE_COLUMNS = 5; + const NUM_HYDRATE_COLUMNS = 6; /** * the column name for the ID field */ - const ID = 'attribute_category.ID'; + const ID = 'module_image.ID'; /** - * the column name for the CATEGORY_ID field + * the column name for the MODULE_ID field */ - const CATEGORY_ID = 'attribute_category.CATEGORY_ID'; + const MODULE_ID = 'module_image.MODULE_ID'; /** - * the column name for the ATTRIBUTE_ID field + * the column name for the FILE field */ - const ATTRIBUTE_ID = 'attribute_category.ATTRIBUTE_ID'; + const FILE = 'module_image.FILE'; + + /** + * the column name for the POSITION field + */ + const POSITION = 'module_image.POSITION'; /** * the column name for the CREATED_AT field */ - const CREATED_AT = 'attribute_category.CREATED_AT'; + const CREATED_AT = 'module_image.CREATED_AT'; /** * the column name for the UPDATED_AT field */ - const UPDATED_AT = 'attribute_category.UPDATED_AT'; + const UPDATED_AT = 'module_image.UPDATED_AT'; /** * The default string format for model objects of the related table */ const DEFAULT_STRING_FORMAT = 'YAML'; + // i18n behavior + + /** + * The default locale to use for translations. + * + * @var string + */ + const DEFAULT_LOCALE = 'en_US'; + /** * holds an array of fieldnames * @@ -106,12 +120,12 @@ class AttributeCategoryTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('Id', 'CategoryId', 'AttributeId', 'CreatedAt', 'UpdatedAt', ), - self::TYPE_STUDLYPHPNAME => array('id', 'categoryId', 'attributeId', 'createdAt', 'updatedAt', ), - self::TYPE_COLNAME => array(AttributeCategoryTableMap::ID, AttributeCategoryTableMap::CATEGORY_ID, AttributeCategoryTableMap::ATTRIBUTE_ID, AttributeCategoryTableMap::CREATED_AT, AttributeCategoryTableMap::UPDATED_AT, ), - self::TYPE_RAW_COLNAME => array('ID', 'CATEGORY_ID', 'ATTRIBUTE_ID', 'CREATED_AT', 'UPDATED_AT', ), - self::TYPE_FIELDNAME => array('id', 'category_id', 'attribute_id', 'created_at', 'updated_at', ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, ) + self::TYPE_PHPNAME => array('Id', 'ModuleId', 'File', 'Position', 'CreatedAt', 'UpdatedAt', ), + self::TYPE_STUDLYPHPNAME => array('id', 'moduleId', 'file', 'position', 'createdAt', 'updatedAt', ), + self::TYPE_COLNAME => array(ModuleImageTableMap::ID, ModuleImageTableMap::MODULE_ID, ModuleImageTableMap::FILE, ModuleImageTableMap::POSITION, ModuleImageTableMap::CREATED_AT, ModuleImageTableMap::UPDATED_AT, ), + self::TYPE_RAW_COLNAME => array('ID', 'MODULE_ID', 'FILE', 'POSITION', 'CREATED_AT', 'UPDATED_AT', ), + self::TYPE_FIELDNAME => array('id', 'module_id', 'file', 'position', 'created_at', 'updated_at', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, ) ); /** @@ -121,12 +135,12 @@ class AttributeCategoryTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'CategoryId' => 1, 'AttributeId' => 2, 'CreatedAt' => 3, 'UpdatedAt' => 4, ), - self::TYPE_STUDLYPHPNAME => array('id' => 0, 'categoryId' => 1, 'attributeId' => 2, 'createdAt' => 3, 'updatedAt' => 4, ), - self::TYPE_COLNAME => array(AttributeCategoryTableMap::ID => 0, AttributeCategoryTableMap::CATEGORY_ID => 1, AttributeCategoryTableMap::ATTRIBUTE_ID => 2, AttributeCategoryTableMap::CREATED_AT => 3, AttributeCategoryTableMap::UPDATED_AT => 4, ), - self::TYPE_RAW_COLNAME => array('ID' => 0, 'CATEGORY_ID' => 1, 'ATTRIBUTE_ID' => 2, 'CREATED_AT' => 3, 'UPDATED_AT' => 4, ), - self::TYPE_FIELDNAME => array('id' => 0, 'category_id' => 1, 'attribute_id' => 2, 'created_at' => 3, 'updated_at' => 4, ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, ) + self::TYPE_PHPNAME => array('Id' => 0, 'ModuleId' => 1, 'File' => 2, 'Position' => 3, 'CreatedAt' => 4, 'UpdatedAt' => 5, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'moduleId' => 1, 'file' => 2, 'position' => 3, 'createdAt' => 4, 'updatedAt' => 5, ), + self::TYPE_COLNAME => array(ModuleImageTableMap::ID => 0, ModuleImageTableMap::MODULE_ID => 1, ModuleImageTableMap::FILE => 2, ModuleImageTableMap::POSITION => 3, ModuleImageTableMap::CREATED_AT => 4, ModuleImageTableMap::UPDATED_AT => 5, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'MODULE_ID' => 1, 'FILE' => 2, 'POSITION' => 3, 'CREATED_AT' => 4, 'UPDATED_AT' => 5, ), + self::TYPE_FIELDNAME => array('id' => 0, 'module_id' => 1, 'file' => 2, 'position' => 3, 'created_at' => 4, 'updated_at' => 5, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, ) ); /** @@ -139,16 +153,16 @@ class AttributeCategoryTableMap extends TableMap public function initialize() { // attributes - $this->setName('attribute_category'); - $this->setPhpName('AttributeCategory'); - $this->setClassName('\\Thelia\\Model\\AttributeCategory'); + $this->setName('module_image'); + $this->setPhpName('ModuleImage'); + $this->setClassName('\\Thelia\\Model\\ModuleImage'); $this->setPackage('Thelia.Model'); $this->setUseIdGenerator(true); - $this->setIsCrossRef(true); // columns $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); - $this->addForeignKey('CATEGORY_ID', 'CategoryId', 'INTEGER', 'category', 'ID', true, null, null); - $this->addForeignKey('ATTRIBUTE_ID', 'AttributeId', 'INTEGER', 'attribute', 'ID', true, null, null); + $this->addForeignKey('MODULE_ID', 'ModuleId', 'INTEGER', 'module', 'ID', true, null, null); + $this->addColumn('FILE', 'File', 'VARCHAR', true, 255, null); + $this->addColumn('POSITION', 'Position', 'INTEGER', false, null, null); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); } // initialize() @@ -158,8 +172,8 @@ class AttributeCategoryTableMap extends TableMap */ public function buildRelations() { - $this->addRelation('Category', '\\Thelia\\Model\\Category', RelationMap::MANY_TO_ONE, array('category_id' => 'id', ), 'CASCADE', 'RESTRICT'); - $this->addRelation('Attribute', '\\Thelia\\Model\\Attribute', RelationMap::MANY_TO_ONE, array('attribute_id' => 'id', ), 'CASCADE', 'RESTRICT'); + $this->addRelation('Module', '\\Thelia\\Model\\Module', RelationMap::MANY_TO_ONE, array('module_id' => 'id', ), 'CASCADE', 'RESTRICT'); + $this->addRelation('ModuleImageI18n', '\\Thelia\\Model\\ModuleImageI18n', RelationMap::ONE_TO_MANY, array('id' => 'id', ), 'CASCADE', null, 'ModuleImageI18ns'); } // buildRelations() /** @@ -172,8 +186,18 @@ class AttributeCategoryTableMap extends TableMap { return array( 'timestampable' => array('create_column' => 'created_at', 'update_column' => 'updated_at', ), + 'i18n' => array('i18n_table' => '%TABLE%_i18n', 'i18n_phpname' => '%PHPNAME%I18n', 'i18n_columns' => 'title, description, chapo, postscriptum', 'locale_column' => 'locale', 'locale_length' => '5', 'default_locale' => '', 'locale_alias' => '', ), ); } // getBehaviors() + /** + * Method to invalidate the instance pool of all tables related to module_image * by a foreign key with ON DELETE CASCADE + */ + public static function clearRelatedInstancePool() + { + // Invalidate objects in ".$this->getClassNameFromBuilder($joinedTableTableMapBuilder)." instance pool, + // since one or more of them may be deleted by ON DELETE CASCADE/SETNULL rule. + ModuleImageI18nTableMap::clearInstancePool(); + } /** * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. @@ -231,7 +255,7 @@ class AttributeCategoryTableMap extends TableMap */ public static function getOMClass($withPrefix = true) { - return $withPrefix ? AttributeCategoryTableMap::CLASS_DEFAULT : AttributeCategoryTableMap::OM_CLASS; + return $withPrefix ? ModuleImageTableMap::CLASS_DEFAULT : ModuleImageTableMap::OM_CLASS; } /** @@ -245,21 +269,21 @@ class AttributeCategoryTableMap extends TableMap * * @throws PropelException Any exceptions caught during processing will be * rethrown wrapped into a PropelException. - * @return array (AttributeCategory object, last column rank) + * @return array (ModuleImage object, last column rank) */ public static function populateObject($row, $offset = 0, $indexType = TableMap::TYPE_NUM) { - $key = AttributeCategoryTableMap::getPrimaryKeyHashFromRow($row, $offset, $indexType); - if (null !== ($obj = AttributeCategoryTableMap::getInstanceFromPool($key))) { + $key = ModuleImageTableMap::getPrimaryKeyHashFromRow($row, $offset, $indexType); + if (null !== ($obj = ModuleImageTableMap::getInstanceFromPool($key))) { // We no longer rehydrate the object, since this can cause data loss. // See http://www.propelorm.org/ticket/509 // $obj->hydrate($row, $offset, true); // rehydrate - $col = $offset + AttributeCategoryTableMap::NUM_HYDRATE_COLUMNS; + $col = $offset + ModuleImageTableMap::NUM_HYDRATE_COLUMNS; } else { - $cls = AttributeCategoryTableMap::OM_CLASS; + $cls = ModuleImageTableMap::OM_CLASS; $obj = new $cls(); $col = $obj->hydrate($row, $offset, false, $indexType); - AttributeCategoryTableMap::addInstanceToPool($obj, $key); + ModuleImageTableMap::addInstanceToPool($obj, $key); } return array($obj, $col); @@ -282,8 +306,8 @@ class AttributeCategoryTableMap extends TableMap $cls = static::getOMClass(false); // populate the object(s) while ($row = $dataFetcher->fetch()) { - $key = AttributeCategoryTableMap::getPrimaryKeyHashFromRow($row, 0, $dataFetcher->getIndexType()); - if (null !== ($obj = AttributeCategoryTableMap::getInstanceFromPool($key))) { + $key = ModuleImageTableMap::getPrimaryKeyHashFromRow($row, 0, $dataFetcher->getIndexType()); + if (null !== ($obj = ModuleImageTableMap::getInstanceFromPool($key))) { // We no longer rehydrate the object, since this can cause data loss. // See http://www.propelorm.org/ticket/509 // $obj->hydrate($row, 0, true); // rehydrate @@ -292,7 +316,7 @@ class AttributeCategoryTableMap extends TableMap $obj = new $cls(); $obj->hydrate($row); $results[] = $obj; - AttributeCategoryTableMap::addInstanceToPool($obj, $key); + ModuleImageTableMap::addInstanceToPool($obj, $key); } // if key exists } @@ -313,15 +337,17 @@ class AttributeCategoryTableMap extends TableMap public static function addSelectColumns(Criteria $criteria, $alias = null) { if (null === $alias) { - $criteria->addSelectColumn(AttributeCategoryTableMap::ID); - $criteria->addSelectColumn(AttributeCategoryTableMap::CATEGORY_ID); - $criteria->addSelectColumn(AttributeCategoryTableMap::ATTRIBUTE_ID); - $criteria->addSelectColumn(AttributeCategoryTableMap::CREATED_AT); - $criteria->addSelectColumn(AttributeCategoryTableMap::UPDATED_AT); + $criteria->addSelectColumn(ModuleImageTableMap::ID); + $criteria->addSelectColumn(ModuleImageTableMap::MODULE_ID); + $criteria->addSelectColumn(ModuleImageTableMap::FILE); + $criteria->addSelectColumn(ModuleImageTableMap::POSITION); + $criteria->addSelectColumn(ModuleImageTableMap::CREATED_AT); + $criteria->addSelectColumn(ModuleImageTableMap::UPDATED_AT); } else { $criteria->addSelectColumn($alias . '.ID'); - $criteria->addSelectColumn($alias . '.CATEGORY_ID'); - $criteria->addSelectColumn($alias . '.ATTRIBUTE_ID'); + $criteria->addSelectColumn($alias . '.MODULE_ID'); + $criteria->addSelectColumn($alias . '.FILE'); + $criteria->addSelectColumn($alias . '.POSITION'); $criteria->addSelectColumn($alias . '.CREATED_AT'); $criteria->addSelectColumn($alias . '.UPDATED_AT'); } @@ -336,7 +362,7 @@ class AttributeCategoryTableMap extends TableMap */ public static function getTableMap() { - return Propel::getServiceContainer()->getDatabaseMap(AttributeCategoryTableMap::DATABASE_NAME)->getTable(AttributeCategoryTableMap::TABLE_NAME); + return Propel::getServiceContainer()->getDatabaseMap(ModuleImageTableMap::DATABASE_NAME)->getTable(ModuleImageTableMap::TABLE_NAME); } /** @@ -344,16 +370,16 @@ class AttributeCategoryTableMap extends TableMap */ public static function buildTableMap() { - $dbMap = Propel::getServiceContainer()->getDatabaseMap(AttributeCategoryTableMap::DATABASE_NAME); - if (!$dbMap->hasTable(AttributeCategoryTableMap::TABLE_NAME)) { - $dbMap->addTableObject(new AttributeCategoryTableMap()); + $dbMap = Propel::getServiceContainer()->getDatabaseMap(ModuleImageTableMap::DATABASE_NAME); + if (!$dbMap->hasTable(ModuleImageTableMap::TABLE_NAME)) { + $dbMap->addTableObject(new ModuleImageTableMap()); } } /** - * Performs a DELETE on the database, given a AttributeCategory or Criteria object OR a primary key value. + * Performs a DELETE on the database, given a ModuleImage or Criteria object OR a primary key value. * - * @param mixed $values Criteria or AttributeCategory object or primary key or array of primary keys + * @param mixed $values Criteria or ModuleImage object or primary key or array of primary keys * which is used to create the DELETE statement * @param ConnectionInterface $con the connection to use * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows @@ -364,25 +390,25 @@ class AttributeCategoryTableMap extends TableMap public static function doDelete($values, ConnectionInterface $con = null) { if (null === $con) { - $con = Propel::getServiceContainer()->getWriteConnection(AttributeCategoryTableMap::DATABASE_NAME); + $con = Propel::getServiceContainer()->getWriteConnection(ModuleImageTableMap::DATABASE_NAME); } if ($values instanceof Criteria) { // rename for clarity $criteria = $values; - } elseif ($values instanceof \Thelia\Model\AttributeCategory) { // it's a model object + } elseif ($values instanceof \Thelia\Model\ModuleImage) { // it's a model object // create criteria based on pk values $criteria = $values->buildPkeyCriteria(); } else { // it's a primary key, or an array of pks - $criteria = new Criteria(AttributeCategoryTableMap::DATABASE_NAME); - $criteria->add(AttributeCategoryTableMap::ID, (array) $values, Criteria::IN); + $criteria = new Criteria(ModuleImageTableMap::DATABASE_NAME); + $criteria->add(ModuleImageTableMap::ID, (array) $values, Criteria::IN); } - $query = AttributeCategoryQuery::create()->mergeWith($criteria); + $query = ModuleImageQuery::create()->mergeWith($criteria); - if ($values instanceof Criteria) { AttributeCategoryTableMap::clearInstancePool(); + if ($values instanceof Criteria) { ModuleImageTableMap::clearInstancePool(); } elseif (!is_object($values)) { // it's a primary key, or an array of pks - foreach ((array) $values as $singleval) { AttributeCategoryTableMap::removeInstanceFromPool($singleval); + foreach ((array) $values as $singleval) { ModuleImageTableMap::removeInstanceFromPool($singleval); } } @@ -390,20 +416,20 @@ class AttributeCategoryTableMap extends TableMap } /** - * Deletes all rows from the attribute_category table. + * Deletes all rows from the module_image table. * * @param ConnectionInterface $con the connection to use * @return int The number of affected rows (if supported by underlying database driver). */ public static function doDeleteAll(ConnectionInterface $con = null) { - return AttributeCategoryQuery::create()->doDeleteAll($con); + return ModuleImageQuery::create()->doDeleteAll($con); } /** - * Performs an INSERT on the database, given a AttributeCategory or Criteria object. + * Performs an INSERT on the database, given a ModuleImage or Criteria object. * - * @param mixed $criteria Criteria or AttributeCategory object containing data that is used to create the INSERT statement. + * @param mixed $criteria Criteria or ModuleImage object containing data that is used to create the INSERT statement. * @param ConnectionInterface $con the ConnectionInterface connection to use * @return mixed The new primary key. * @throws PropelException Any exceptions caught during processing will be @@ -412,22 +438,22 @@ class AttributeCategoryTableMap extends TableMap public static function doInsert($criteria, ConnectionInterface $con = null) { if (null === $con) { - $con = Propel::getServiceContainer()->getWriteConnection(AttributeCategoryTableMap::DATABASE_NAME); + $con = Propel::getServiceContainer()->getWriteConnection(ModuleImageTableMap::DATABASE_NAME); } if ($criteria instanceof Criteria) { $criteria = clone $criteria; // rename for clarity } else { - $criteria = $criteria->buildCriteria(); // build Criteria from AttributeCategory object + $criteria = $criteria->buildCriteria(); // build Criteria from ModuleImage object } - if ($criteria->containsKey(AttributeCategoryTableMap::ID) && $criteria->keyContainsValue(AttributeCategoryTableMap::ID) ) { - throw new PropelException('Cannot insert a value for auto-increment primary key ('.AttributeCategoryTableMap::ID.')'); + if ($criteria->containsKey(ModuleImageTableMap::ID) && $criteria->keyContainsValue(ModuleImageTableMap::ID) ) { + throw new PropelException('Cannot insert a value for auto-increment primary key ('.ModuleImageTableMap::ID.')'); } // Set the correct dbName - $query = AttributeCategoryQuery::create()->mergeWith($criteria); + $query = ModuleImageQuery::create()->mergeWith($criteria); try { // use transaction because $criteria could contain info @@ -443,7 +469,7 @@ class AttributeCategoryTableMap extends TableMap return $pk; } -} // AttributeCategoryTableMap +} // ModuleImageTableMap // This is the static code needed to register the TableMap for this table with the main Propel class. // -AttributeCategoryTableMap::buildTableMap(); +ModuleImageTableMap::buildTableMap(); diff --git a/core/lib/Thelia/Model/Map/ModuleTableMap.php b/core/lib/Thelia/Model/Map/ModuleTableMap.php index 1a2f63692..788048e28 100644 --- a/core/lib/Thelia/Model/Map/ModuleTableMap.php +++ b/core/lib/Thelia/Model/Map/ModuleTableMap.php @@ -188,6 +188,7 @@ class ModuleTableMap extends TableMap $this->addRelation('OrderRelatedByDeliveryModuleId', '\\Thelia\\Model\\Order', RelationMap::ONE_TO_MANY, array('id' => 'delivery_module_id', ), 'RESTRICT', 'RESTRICT', 'OrdersRelatedByDeliveryModuleId'); $this->addRelation('AreaDeliveryModule', '\\Thelia\\Model\\AreaDeliveryModule', RelationMap::ONE_TO_MANY, array('id' => 'delivery_module_id', ), 'CASCADE', 'RESTRICT', 'AreaDeliveryModules'); $this->addRelation('GroupModule', '\\Thelia\\Model\\GroupModule', RelationMap::ONE_TO_MANY, array('id' => 'module_id', ), 'CASCADE', 'RESTRICT', 'GroupModules'); + $this->addRelation('ModuleImage', '\\Thelia\\Model\\ModuleImage', RelationMap::ONE_TO_MANY, array('id' => 'module_id', ), 'CASCADE', 'RESTRICT', 'ModuleImages'); $this->addRelation('ModuleI18n', '\\Thelia\\Model\\ModuleI18n', RelationMap::ONE_TO_MANY, array('id' => 'id', ), 'CASCADE', null, 'ModuleI18ns'); } // buildRelations() @@ -213,6 +214,7 @@ class ModuleTableMap extends TableMap // since one or more of them may be deleted by ON DELETE CASCADE/SETNULL rule. AreaDeliveryModuleTableMap::clearInstancePool(); GroupModuleTableMap::clearInstancePool(); + ModuleImageTableMap::clearInstancePool(); ModuleI18nTableMap::clearInstancePool(); } diff --git a/core/lib/Thelia/Model/Map/OrderProductAttributeCombinationTableMap.php b/core/lib/Thelia/Model/Map/OrderProductAttributeCombinationTableMap.php new file mode 100644 index 000000000..582bd2305 --- /dev/null +++ b/core/lib/Thelia/Model/Map/OrderProductAttributeCombinationTableMap.php @@ -0,0 +1,503 @@ + array('Id', 'OrderProductId', 'AttributeTitle', 'AttributeChapo', 'AttributeDescription', 'AttributePostscriptumn', 'AttributeAvTitle', 'AttributeAvChapo', 'AttributeAvDescription', 'AttributeAvPostscriptum', 'CreatedAt', 'UpdatedAt', ), + self::TYPE_STUDLYPHPNAME => array('id', 'orderProductId', 'attributeTitle', 'attributeChapo', 'attributeDescription', 'attributePostscriptumn', 'attributeAvTitle', 'attributeAvChapo', 'attributeAvDescription', 'attributeAvPostscriptum', 'createdAt', 'updatedAt', ), + self::TYPE_COLNAME => array(OrderProductAttributeCombinationTableMap::ID, OrderProductAttributeCombinationTableMap::ORDER_PRODUCT_ID, OrderProductAttributeCombinationTableMap::ATTRIBUTE_TITLE, OrderProductAttributeCombinationTableMap::ATTRIBUTE_CHAPO, OrderProductAttributeCombinationTableMap::ATTRIBUTE_DESCRIPTION, OrderProductAttributeCombinationTableMap::ATTRIBUTE_POSTSCRIPTUMN, OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_TITLE, OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_CHAPO, OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_DESCRIPTION, OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_POSTSCRIPTUM, OrderProductAttributeCombinationTableMap::CREATED_AT, OrderProductAttributeCombinationTableMap::UPDATED_AT, ), + self::TYPE_RAW_COLNAME => array('ID', 'ORDER_PRODUCT_ID', 'ATTRIBUTE_TITLE', 'ATTRIBUTE_CHAPO', 'ATTRIBUTE_DESCRIPTION', 'ATTRIBUTE_POSTSCRIPTUMN', 'ATTRIBUTE_AV_TITLE', 'ATTRIBUTE_AV_CHAPO', 'ATTRIBUTE_AV_DESCRIPTION', 'ATTRIBUTE_AV_POSTSCRIPTUM', 'CREATED_AT', 'UPDATED_AT', ), + self::TYPE_FIELDNAME => array('id', 'order_product_id', 'attribute_title', 'attribute_chapo', 'attribute_description', 'attribute_postscriptumn', 'attribute_av_title', 'attribute_av_chapo', 'attribute_av_description', 'attribute_av_postscriptum', 'created_at', 'updated_at', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 + */ + protected static $fieldKeys = array ( + self::TYPE_PHPNAME => array('Id' => 0, 'OrderProductId' => 1, 'AttributeTitle' => 2, 'AttributeChapo' => 3, 'AttributeDescription' => 4, 'AttributePostscriptumn' => 5, 'AttributeAvTitle' => 6, 'AttributeAvChapo' => 7, 'AttributeAvDescription' => 8, 'AttributeAvPostscriptum' => 9, 'CreatedAt' => 10, 'UpdatedAt' => 11, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'orderProductId' => 1, 'attributeTitle' => 2, 'attributeChapo' => 3, 'attributeDescription' => 4, 'attributePostscriptumn' => 5, 'attributeAvTitle' => 6, 'attributeAvChapo' => 7, 'attributeAvDescription' => 8, 'attributeAvPostscriptum' => 9, 'createdAt' => 10, 'updatedAt' => 11, ), + self::TYPE_COLNAME => array(OrderProductAttributeCombinationTableMap::ID => 0, OrderProductAttributeCombinationTableMap::ORDER_PRODUCT_ID => 1, OrderProductAttributeCombinationTableMap::ATTRIBUTE_TITLE => 2, OrderProductAttributeCombinationTableMap::ATTRIBUTE_CHAPO => 3, OrderProductAttributeCombinationTableMap::ATTRIBUTE_DESCRIPTION => 4, OrderProductAttributeCombinationTableMap::ATTRIBUTE_POSTSCRIPTUMN => 5, OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_TITLE => 6, OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_CHAPO => 7, OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_DESCRIPTION => 8, OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_POSTSCRIPTUM => 9, OrderProductAttributeCombinationTableMap::CREATED_AT => 10, OrderProductAttributeCombinationTableMap::UPDATED_AT => 11, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'ORDER_PRODUCT_ID' => 1, 'ATTRIBUTE_TITLE' => 2, 'ATTRIBUTE_CHAPO' => 3, 'ATTRIBUTE_DESCRIPTION' => 4, 'ATTRIBUTE_POSTSCRIPTUMN' => 5, 'ATTRIBUTE_AV_TITLE' => 6, 'ATTRIBUTE_AV_CHAPO' => 7, 'ATTRIBUTE_AV_DESCRIPTION' => 8, 'ATTRIBUTE_AV_POSTSCRIPTUM' => 9, 'CREATED_AT' => 10, 'UPDATED_AT' => 11, ), + self::TYPE_FIELDNAME => array('id' => 0, 'order_product_id' => 1, 'attribute_title' => 2, 'attribute_chapo' => 3, 'attribute_description' => 4, 'attribute_postscriptumn' => 5, 'attribute_av_title' => 6, 'attribute_av_chapo' => 7, 'attribute_av_description' => 8, 'attribute_av_postscriptum' => 9, 'created_at' => 10, 'updated_at' => 11, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ) + ); + + /** + * Initialize the table attributes and columns + * Relations are not initialized by this method since they are lazy loaded + * + * @return void + * @throws PropelException + */ + public function initialize() + { + // attributes + $this->setName('order_product_attribute_combination'); + $this->setPhpName('OrderProductAttributeCombination'); + $this->setClassName('\\Thelia\\Model\\OrderProductAttributeCombination'); + $this->setPackage('Thelia.Model'); + $this->setUseIdGenerator(true); + // columns + $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); + $this->addForeignKey('ORDER_PRODUCT_ID', 'OrderProductId', 'INTEGER', 'order_product', 'ID', true, null, null); + $this->addColumn('ATTRIBUTE_TITLE', 'AttributeTitle', 'VARCHAR', true, 255, null); + $this->addColumn('ATTRIBUTE_CHAPO', 'AttributeChapo', 'LONGVARCHAR', false, null, null); + $this->addColumn('ATTRIBUTE_DESCRIPTION', 'AttributeDescription', 'CLOB', false, null, null); + $this->addColumn('ATTRIBUTE_POSTSCRIPTUMN', 'AttributePostscriptumn', 'LONGVARCHAR', false, null, null); + $this->addColumn('ATTRIBUTE_AV_TITLE', 'AttributeAvTitle', 'VARCHAR', true, 255, null); + $this->addColumn('ATTRIBUTE_AV_CHAPO', 'AttributeAvChapo', 'LONGVARCHAR', false, null, null); + $this->addColumn('ATTRIBUTE_AV_DESCRIPTION', 'AttributeAvDescription', 'CLOB', false, null, null); + $this->addColumn('ATTRIBUTE_AV_POSTSCRIPTUM', 'AttributeAvPostscriptum', 'LONGVARCHAR', false, null, null); + $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); + $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); + } // initialize() + + /** + * Build the RelationMap objects for this table relationships + */ + public function buildRelations() + { + $this->addRelation('OrderProduct', '\\Thelia\\Model\\OrderProduct', RelationMap::MANY_TO_ONE, array('order_product_id' => 'id', ), 'CASCADE', 'RESTRICT'); + } // buildRelations() + + /** + * + * Gets the list of behaviors registered for this table + * + * @return array Associative array (name => parameters) of behaviors + */ + public function getBehaviors() + { + return array( + 'timestampable' => array('create_column' => 'created_at', 'update_column' => 'updated_at', ), + ); + } // getBehaviors() + + /** + * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. + * + * For tables with a single-column primary key, that simple pkey value will be returned. For tables with + * a multi-column primary key, a serialize()d version of the primary key will be returned. + * + * @param array $row resultset row. + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM + */ + public static function getPrimaryKeyHashFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + // If the PK cannot be derived from the row, return NULL. + if ($row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)] === null) { + return null; + } + + return (string) $row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)]; + } + + /** + * Retrieves the primary key from the DB resultset row + * For tables with a single-column primary key, that simple pkey value will be returned. For tables with + * a multi-column primary key, an array of the primary key columns will be returned. + * + * @param array $row resultset row. + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM + * + * @return mixed The primary key of the row + */ + public static function getPrimaryKeyFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + + return (int) $row[ + $indexType == TableMap::TYPE_NUM + ? 0 + $offset + : self::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType) + ]; + } + + /** + * The class that the tableMap will make instances of. + * + * If $withPrefix is true, the returned path + * uses a dot-path notation which is translated into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @param boolean $withPrefix Whether or not to return the path with the class name + * @return string path.to.ClassName + */ + public static function getOMClass($withPrefix = true) + { + return $withPrefix ? OrderProductAttributeCombinationTableMap::CLASS_DEFAULT : OrderProductAttributeCombinationTableMap::OM_CLASS; + } + + /** + * Populates an object of the default type or an object that inherit from the default. + * + * @param array $row row returned by DataFetcher->fetch(). + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType The index type of $row. Mostly DataFetcher->getIndexType(). + One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return array (OrderProductAttributeCombination object, last column rank) + */ + public static function populateObject($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + $key = OrderProductAttributeCombinationTableMap::getPrimaryKeyHashFromRow($row, $offset, $indexType); + if (null !== ($obj = OrderProductAttributeCombinationTableMap::getInstanceFromPool($key))) { + // We no longer rehydrate the object, since this can cause data loss. + // See http://www.propelorm.org/ticket/509 + // $obj->hydrate($row, $offset, true); // rehydrate + $col = $offset + OrderProductAttributeCombinationTableMap::NUM_HYDRATE_COLUMNS; + } else { + $cls = OrderProductAttributeCombinationTableMap::OM_CLASS; + $obj = new $cls(); + $col = $obj->hydrate($row, $offset, false, $indexType); + OrderProductAttributeCombinationTableMap::addInstanceToPool($obj, $key); + } + + return array($obj, $col); + } + + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @param DataFetcherInterface $dataFetcher + * @return array + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(DataFetcherInterface $dataFetcher) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = static::getOMClass(false); + // populate the object(s) + while ($row = $dataFetcher->fetch()) { + $key = OrderProductAttributeCombinationTableMap::getPrimaryKeyHashFromRow($row, 0, $dataFetcher->getIndexType()); + if (null !== ($obj = OrderProductAttributeCombinationTableMap::getInstanceFromPool($key))) { + // We no longer rehydrate the object, since this can cause data loss. + // See http://www.propelorm.org/ticket/509 + // $obj->hydrate($row, 0, true); // rehydrate + $results[] = $obj; + } else { + $obj = new $cls(); + $obj->hydrate($row); + $results[] = $obj; + OrderProductAttributeCombinationTableMap::addInstanceToPool($obj, $key); + } // if key exists + } + + return $results; + } + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param Criteria $criteria object containing the columns to add. + * @param string $alias optional table alias + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria, $alias = null) + { + if (null === $alias) { + $criteria->addSelectColumn(OrderProductAttributeCombinationTableMap::ID); + $criteria->addSelectColumn(OrderProductAttributeCombinationTableMap::ORDER_PRODUCT_ID); + $criteria->addSelectColumn(OrderProductAttributeCombinationTableMap::ATTRIBUTE_TITLE); + $criteria->addSelectColumn(OrderProductAttributeCombinationTableMap::ATTRIBUTE_CHAPO); + $criteria->addSelectColumn(OrderProductAttributeCombinationTableMap::ATTRIBUTE_DESCRIPTION); + $criteria->addSelectColumn(OrderProductAttributeCombinationTableMap::ATTRIBUTE_POSTSCRIPTUMN); + $criteria->addSelectColumn(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_TITLE); + $criteria->addSelectColumn(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_CHAPO); + $criteria->addSelectColumn(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_DESCRIPTION); + $criteria->addSelectColumn(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_POSTSCRIPTUM); + $criteria->addSelectColumn(OrderProductAttributeCombinationTableMap::CREATED_AT); + $criteria->addSelectColumn(OrderProductAttributeCombinationTableMap::UPDATED_AT); + } else { + $criteria->addSelectColumn($alias . '.ID'); + $criteria->addSelectColumn($alias . '.ORDER_PRODUCT_ID'); + $criteria->addSelectColumn($alias . '.ATTRIBUTE_TITLE'); + $criteria->addSelectColumn($alias . '.ATTRIBUTE_CHAPO'); + $criteria->addSelectColumn($alias . '.ATTRIBUTE_DESCRIPTION'); + $criteria->addSelectColumn($alias . '.ATTRIBUTE_POSTSCRIPTUMN'); + $criteria->addSelectColumn($alias . '.ATTRIBUTE_AV_TITLE'); + $criteria->addSelectColumn($alias . '.ATTRIBUTE_AV_CHAPO'); + $criteria->addSelectColumn($alias . '.ATTRIBUTE_AV_DESCRIPTION'); + $criteria->addSelectColumn($alias . '.ATTRIBUTE_AV_POSTSCRIPTUM'); + $criteria->addSelectColumn($alias . '.CREATED_AT'); + $criteria->addSelectColumn($alias . '.UPDATED_AT'); + } + } + + /** + * Returns the TableMap related to this object. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getServiceContainer()->getDatabaseMap(OrderProductAttributeCombinationTableMap::DATABASE_NAME)->getTable(OrderProductAttributeCombinationTableMap::TABLE_NAME); + } + + /** + * Add a TableMap instance to the database for this tableMap class. + */ + public static function buildTableMap() + { + $dbMap = Propel::getServiceContainer()->getDatabaseMap(OrderProductAttributeCombinationTableMap::DATABASE_NAME); + if (!$dbMap->hasTable(OrderProductAttributeCombinationTableMap::TABLE_NAME)) { + $dbMap->addTableObject(new OrderProductAttributeCombinationTableMap()); + } + } + + /** + * Performs a DELETE on the database, given a OrderProductAttributeCombination or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or OrderProductAttributeCombination object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(OrderProductAttributeCombinationTableMap::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + // rename for clarity + $criteria = $values; + } elseif ($values instanceof \Thelia\Model\OrderProductAttributeCombination) { // it's a model object + // create criteria based on pk values + $criteria = $values->buildPkeyCriteria(); + } else { // it's a primary key, or an array of pks + $criteria = new Criteria(OrderProductAttributeCombinationTableMap::DATABASE_NAME); + $criteria->add(OrderProductAttributeCombinationTableMap::ID, (array) $values, Criteria::IN); + } + + $query = OrderProductAttributeCombinationQuery::create()->mergeWith($criteria); + + if ($values instanceof Criteria) { OrderProductAttributeCombinationTableMap::clearInstancePool(); + } elseif (!is_object($values)) { // it's a primary key, or an array of pks + foreach ((array) $values as $singleval) { OrderProductAttributeCombinationTableMap::removeInstanceFromPool($singleval); + } + } + + return $query->delete($con); + } + + /** + * Deletes all rows from the order_product_attribute_combination table. + * + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll(ConnectionInterface $con = null) + { + return OrderProductAttributeCombinationQuery::create()->doDeleteAll($con); + } + + /** + * Performs an INSERT on the database, given a OrderProductAttributeCombination or Criteria object. + * + * @param mixed $criteria Criteria or OrderProductAttributeCombination object containing data that is used to create the INSERT statement. + * @param ConnectionInterface $con the ConnectionInterface connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($criteria, ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(OrderProductAttributeCombinationTableMap::DATABASE_NAME); + } + + if ($criteria instanceof Criteria) { + $criteria = clone $criteria; // rename for clarity + } else { + $criteria = $criteria->buildCriteria(); // build Criteria from OrderProductAttributeCombination object + } + + if ($criteria->containsKey(OrderProductAttributeCombinationTableMap::ID) && $criteria->keyContainsValue(OrderProductAttributeCombinationTableMap::ID) ) { + throw new PropelException('Cannot insert a value for auto-increment primary key ('.OrderProductAttributeCombinationTableMap::ID.')'); + } + + + // Set the correct dbName + $query = OrderProductAttributeCombinationQuery::create()->mergeWith($criteria); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->beginTransaction(); + $pk = $query->doInsert($con); + $con->commit(); + } catch (PropelException $e) { + $con->rollBack(); + throw $e; + } + + return $pk; + } + +} // OrderProductAttributeCombinationTableMap +// This is the static code needed to register the TableMap for this table with the main Propel class. +// +OrderProductAttributeCombinationTableMap::buildTableMap(); diff --git a/core/lib/Thelia/Model/Map/OrderProductTableMap.php b/core/lib/Thelia/Model/Map/OrderProductTableMap.php index 038d12863..8144f23a7 100644 --- a/core/lib/Thelia/Model/Map/OrderProductTableMap.php +++ b/core/lib/Thelia/Model/Map/OrderProductTableMap.php @@ -57,7 +57,7 @@ class OrderProductTableMap extends TableMap /** * The total number of columns */ - const NUM_COLUMNS = 12; + const NUM_COLUMNS = 19; /** * The number of lazy-loaded columns @@ -67,7 +67,7 @@ class OrderProductTableMap extends TableMap /** * The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */ - const NUM_HYDRATE_COLUMNS = 12; + const NUM_HYDRATE_COLUMNS = 19; /** * the column name for the ID field @@ -84,20 +84,30 @@ class OrderProductTableMap extends TableMap */ const PRODUCT_REF = 'order_product.PRODUCT_REF'; + /** + * the column name for the PRODUCT_SALE_ELEMENTS_REF field + */ + const PRODUCT_SALE_ELEMENTS_REF = 'order_product.PRODUCT_SALE_ELEMENTS_REF'; + /** * the column name for the TITLE field */ const TITLE = 'order_product.TITLE'; + /** + * the column name for the CHAPO field + */ + const CHAPO = 'order_product.CHAPO'; + /** * the column name for the DESCRIPTION field */ const DESCRIPTION = 'order_product.DESCRIPTION'; /** - * the column name for the CHAPO field + * the column name for the POSTSCRIPTUM field */ - const CHAPO = 'order_product.CHAPO'; + const POSTSCRIPTUM = 'order_product.POSTSCRIPTUM'; /** * the column name for the QUANTITY field @@ -110,9 +120,34 @@ class OrderProductTableMap extends TableMap const PRICE = 'order_product.PRICE'; /** - * the column name for the TAX field + * the column name for the PROMO_PRICE field */ - const TAX = 'order_product.TAX'; + const PROMO_PRICE = 'order_product.PROMO_PRICE'; + + /** + * the column name for the WAS_NEW field + */ + const WAS_NEW = 'order_product.WAS_NEW'; + + /** + * the column name for the WAS_IN_PROMO field + */ + const WAS_IN_PROMO = 'order_product.WAS_IN_PROMO'; + + /** + * the column name for the WEIGHT field + */ + const WEIGHT = 'order_product.WEIGHT'; + + /** + * the column name for the TAX_RULE_TITLE field + */ + const TAX_RULE_TITLE = 'order_product.TAX_RULE_TITLE'; + + /** + * the column name for the TAX_RULE_DESCRIPTION field + */ + const TAX_RULE_DESCRIPTION = 'order_product.TAX_RULE_DESCRIPTION'; /** * the column name for the PARENT field @@ -141,12 +176,12 @@ class OrderProductTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('Id', 'OrderId', 'ProductRef', 'Title', 'Description', 'Chapo', 'Quantity', 'Price', 'Tax', 'Parent', 'CreatedAt', 'UpdatedAt', ), - self::TYPE_STUDLYPHPNAME => array('id', 'orderId', 'productRef', 'title', 'description', 'chapo', 'quantity', 'price', 'tax', 'parent', 'createdAt', 'updatedAt', ), - self::TYPE_COLNAME => array(OrderProductTableMap::ID, OrderProductTableMap::ORDER_ID, OrderProductTableMap::PRODUCT_REF, OrderProductTableMap::TITLE, OrderProductTableMap::DESCRIPTION, OrderProductTableMap::CHAPO, OrderProductTableMap::QUANTITY, OrderProductTableMap::PRICE, OrderProductTableMap::TAX, OrderProductTableMap::PARENT, OrderProductTableMap::CREATED_AT, OrderProductTableMap::UPDATED_AT, ), - self::TYPE_RAW_COLNAME => array('ID', 'ORDER_ID', 'PRODUCT_REF', 'TITLE', 'DESCRIPTION', 'CHAPO', 'QUANTITY', 'PRICE', 'TAX', 'PARENT', 'CREATED_AT', 'UPDATED_AT', ), - self::TYPE_FIELDNAME => array('id', 'order_id', 'product_ref', 'title', 'description', 'chapo', 'quantity', 'price', 'tax', 'parent', 'created_at', 'updated_at', ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ) + self::TYPE_PHPNAME => array('Id', 'OrderId', 'ProductRef', 'ProductSaleElementsRef', 'Title', 'Chapo', 'Description', 'Postscriptum', 'Quantity', 'Price', 'PromoPrice', 'WasNew', 'WasInPromo', 'Weight', 'TaxRuleTitle', 'TaxRuleDescription', 'Parent', 'CreatedAt', 'UpdatedAt', ), + self::TYPE_STUDLYPHPNAME => array('id', 'orderId', 'productRef', 'productSaleElementsRef', 'title', 'chapo', 'description', 'postscriptum', 'quantity', 'price', 'promoPrice', 'wasNew', 'wasInPromo', 'weight', 'taxRuleTitle', 'taxRuleDescription', 'parent', 'createdAt', 'updatedAt', ), + self::TYPE_COLNAME => array(OrderProductTableMap::ID, OrderProductTableMap::ORDER_ID, OrderProductTableMap::PRODUCT_REF, OrderProductTableMap::PRODUCT_SALE_ELEMENTS_REF, OrderProductTableMap::TITLE, OrderProductTableMap::CHAPO, OrderProductTableMap::DESCRIPTION, OrderProductTableMap::POSTSCRIPTUM, OrderProductTableMap::QUANTITY, OrderProductTableMap::PRICE, OrderProductTableMap::PROMO_PRICE, OrderProductTableMap::WAS_NEW, OrderProductTableMap::WAS_IN_PROMO, OrderProductTableMap::WEIGHT, OrderProductTableMap::TAX_RULE_TITLE, OrderProductTableMap::TAX_RULE_DESCRIPTION, OrderProductTableMap::PARENT, OrderProductTableMap::CREATED_AT, OrderProductTableMap::UPDATED_AT, ), + self::TYPE_RAW_COLNAME => array('ID', 'ORDER_ID', 'PRODUCT_REF', 'PRODUCT_SALE_ELEMENTS_REF', 'TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM', 'QUANTITY', 'PRICE', 'PROMO_PRICE', 'WAS_NEW', 'WAS_IN_PROMO', 'WEIGHT', 'TAX_RULE_TITLE', 'TAX_RULE_DESCRIPTION', 'PARENT', 'CREATED_AT', 'UPDATED_AT', ), + self::TYPE_FIELDNAME => array('id', 'order_id', 'product_ref', 'product_sale_elements_ref', 'title', 'chapo', 'description', 'postscriptum', 'quantity', 'price', 'promo_price', 'was_new', 'was_in_promo', 'weight', 'tax_rule_title', 'tax_rule_description', 'parent', 'created_at', 'updated_at', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, ) ); /** @@ -156,12 +191,12 @@ class OrderProductTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'OrderId' => 1, 'ProductRef' => 2, 'Title' => 3, 'Description' => 4, 'Chapo' => 5, 'Quantity' => 6, 'Price' => 7, 'Tax' => 8, 'Parent' => 9, 'CreatedAt' => 10, 'UpdatedAt' => 11, ), - self::TYPE_STUDLYPHPNAME => array('id' => 0, 'orderId' => 1, 'productRef' => 2, 'title' => 3, 'description' => 4, 'chapo' => 5, 'quantity' => 6, 'price' => 7, 'tax' => 8, 'parent' => 9, 'createdAt' => 10, 'updatedAt' => 11, ), - self::TYPE_COLNAME => array(OrderProductTableMap::ID => 0, OrderProductTableMap::ORDER_ID => 1, OrderProductTableMap::PRODUCT_REF => 2, OrderProductTableMap::TITLE => 3, OrderProductTableMap::DESCRIPTION => 4, OrderProductTableMap::CHAPO => 5, OrderProductTableMap::QUANTITY => 6, OrderProductTableMap::PRICE => 7, OrderProductTableMap::TAX => 8, OrderProductTableMap::PARENT => 9, OrderProductTableMap::CREATED_AT => 10, OrderProductTableMap::UPDATED_AT => 11, ), - self::TYPE_RAW_COLNAME => array('ID' => 0, 'ORDER_ID' => 1, 'PRODUCT_REF' => 2, 'TITLE' => 3, 'DESCRIPTION' => 4, 'CHAPO' => 5, 'QUANTITY' => 6, 'PRICE' => 7, 'TAX' => 8, 'PARENT' => 9, 'CREATED_AT' => 10, 'UPDATED_AT' => 11, ), - self::TYPE_FIELDNAME => array('id' => 0, 'order_id' => 1, 'product_ref' => 2, 'title' => 3, 'description' => 4, 'chapo' => 5, 'quantity' => 6, 'price' => 7, 'tax' => 8, 'parent' => 9, 'created_at' => 10, 'updated_at' => 11, ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ) + self::TYPE_PHPNAME => array('Id' => 0, 'OrderId' => 1, 'ProductRef' => 2, 'ProductSaleElementsRef' => 3, 'Title' => 4, 'Chapo' => 5, 'Description' => 6, 'Postscriptum' => 7, 'Quantity' => 8, 'Price' => 9, 'PromoPrice' => 10, 'WasNew' => 11, 'WasInPromo' => 12, 'Weight' => 13, 'TaxRuleTitle' => 14, 'TaxRuleDescription' => 15, 'Parent' => 16, 'CreatedAt' => 17, 'UpdatedAt' => 18, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'orderId' => 1, 'productRef' => 2, 'productSaleElementsRef' => 3, 'title' => 4, 'chapo' => 5, 'description' => 6, 'postscriptum' => 7, 'quantity' => 8, 'price' => 9, 'promoPrice' => 10, 'wasNew' => 11, 'wasInPromo' => 12, 'weight' => 13, 'taxRuleTitle' => 14, 'taxRuleDescription' => 15, 'parent' => 16, 'createdAt' => 17, 'updatedAt' => 18, ), + self::TYPE_COLNAME => array(OrderProductTableMap::ID => 0, OrderProductTableMap::ORDER_ID => 1, OrderProductTableMap::PRODUCT_REF => 2, OrderProductTableMap::PRODUCT_SALE_ELEMENTS_REF => 3, OrderProductTableMap::TITLE => 4, OrderProductTableMap::CHAPO => 5, OrderProductTableMap::DESCRIPTION => 6, OrderProductTableMap::POSTSCRIPTUM => 7, OrderProductTableMap::QUANTITY => 8, OrderProductTableMap::PRICE => 9, OrderProductTableMap::PROMO_PRICE => 10, OrderProductTableMap::WAS_NEW => 11, OrderProductTableMap::WAS_IN_PROMO => 12, OrderProductTableMap::WEIGHT => 13, OrderProductTableMap::TAX_RULE_TITLE => 14, OrderProductTableMap::TAX_RULE_DESCRIPTION => 15, OrderProductTableMap::PARENT => 16, OrderProductTableMap::CREATED_AT => 17, OrderProductTableMap::UPDATED_AT => 18, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'ORDER_ID' => 1, 'PRODUCT_REF' => 2, 'PRODUCT_SALE_ELEMENTS_REF' => 3, 'TITLE' => 4, 'CHAPO' => 5, 'DESCRIPTION' => 6, 'POSTSCRIPTUM' => 7, 'QUANTITY' => 8, 'PRICE' => 9, 'PROMO_PRICE' => 10, 'WAS_NEW' => 11, 'WAS_IN_PROMO' => 12, 'WEIGHT' => 13, 'TAX_RULE_TITLE' => 14, 'TAX_RULE_DESCRIPTION' => 15, 'PARENT' => 16, 'CREATED_AT' => 17, 'UPDATED_AT' => 18, ), + self::TYPE_FIELDNAME => array('id' => 0, 'order_id' => 1, 'product_ref' => 2, 'product_sale_elements_ref' => 3, 'title' => 4, 'chapo' => 5, 'description' => 6, 'postscriptum' => 7, 'quantity' => 8, 'price' => 9, 'promo_price' => 10, 'was_new' => 11, 'was_in_promo' => 12, 'weight' => 13, 'tax_rule_title' => 14, 'tax_rule_description' => 15, 'parent' => 16, 'created_at' => 17, 'updated_at' => 18, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, ) ); /** @@ -182,13 +217,20 @@ class OrderProductTableMap extends TableMap // columns $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); $this->addForeignKey('ORDER_ID', 'OrderId', 'INTEGER', 'order', 'ID', true, null, null); - $this->addColumn('PRODUCT_REF', 'ProductRef', 'VARCHAR', false, 255, null); + $this->addColumn('PRODUCT_REF', 'ProductRef', 'VARCHAR', true, 255, null); + $this->addColumn('PRODUCT_SALE_ELEMENTS_REF', 'ProductSaleElementsRef', 'VARCHAR', true, 255, null); $this->addColumn('TITLE', 'Title', 'VARCHAR', false, 255, null); - $this->addColumn('DESCRIPTION', 'Description', 'LONGVARCHAR', false, null, null); $this->addColumn('CHAPO', 'Chapo', 'LONGVARCHAR', false, null, null); + $this->addColumn('DESCRIPTION', 'Description', 'CLOB', false, null, null); + $this->addColumn('POSTSCRIPTUM', 'Postscriptum', 'LONGVARCHAR', false, null, null); $this->addColumn('QUANTITY', 'Quantity', 'FLOAT', true, null, null); $this->addColumn('PRICE', 'Price', 'FLOAT', true, null, null); - $this->addColumn('TAX', 'Tax', 'FLOAT', false, null, null); + $this->addColumn('PROMO_PRICE', 'PromoPrice', 'VARCHAR', false, 45, null); + $this->addColumn('WAS_NEW', 'WasNew', 'TINYINT', true, null, null); + $this->addColumn('WAS_IN_PROMO', 'WasInPromo', 'TINYINT', true, null, null); + $this->addColumn('WEIGHT', 'Weight', 'VARCHAR', false, 45, null); + $this->addColumn('TAX_RULE_TITLE', 'TaxRuleTitle', 'VARCHAR', false, 255, null); + $this->addColumn('TAX_RULE_DESCRIPTION', 'TaxRuleDescription', 'CLOB', false, null, null); $this->addColumn('PARENT', 'Parent', 'INTEGER', false, null, null); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); @@ -200,7 +242,8 @@ class OrderProductTableMap extends TableMap public function buildRelations() { $this->addRelation('Order', '\\Thelia\\Model\\Order', RelationMap::MANY_TO_ONE, array('order_id' => 'id', ), 'CASCADE', 'RESTRICT'); - $this->addRelation('OrderFeature', '\\Thelia\\Model\\OrderFeature', RelationMap::ONE_TO_MANY, array('id' => 'order_product_id', ), 'CASCADE', 'RESTRICT', 'OrderFeatures'); + $this->addRelation('OrderProductAttributeCombination', '\\Thelia\\Model\\OrderProductAttributeCombination', RelationMap::ONE_TO_MANY, array('id' => 'order_product_id', ), 'CASCADE', 'RESTRICT', 'OrderProductAttributeCombinations'); + $this->addRelation('OrderProductTax', '\\Thelia\\Model\\OrderProductTax', RelationMap::ONE_TO_MANY, array('id' => 'order_product_id', ), 'CASCADE', 'RESTRICT', 'OrderProductTaxes'); } // buildRelations() /** @@ -222,7 +265,8 @@ class OrderProductTableMap extends TableMap { // Invalidate objects in ".$this->getClassNameFromBuilder($joinedTableTableMapBuilder)." instance pool, // since one or more of them may be deleted by ON DELETE CASCADE/SETNULL rule. - OrderFeatureTableMap::clearInstancePool(); + OrderProductAttributeCombinationTableMap::clearInstancePool(); + OrderProductTaxTableMap::clearInstancePool(); } /** @@ -366,12 +410,19 @@ class OrderProductTableMap extends TableMap $criteria->addSelectColumn(OrderProductTableMap::ID); $criteria->addSelectColumn(OrderProductTableMap::ORDER_ID); $criteria->addSelectColumn(OrderProductTableMap::PRODUCT_REF); + $criteria->addSelectColumn(OrderProductTableMap::PRODUCT_SALE_ELEMENTS_REF); $criteria->addSelectColumn(OrderProductTableMap::TITLE); - $criteria->addSelectColumn(OrderProductTableMap::DESCRIPTION); $criteria->addSelectColumn(OrderProductTableMap::CHAPO); + $criteria->addSelectColumn(OrderProductTableMap::DESCRIPTION); + $criteria->addSelectColumn(OrderProductTableMap::POSTSCRIPTUM); $criteria->addSelectColumn(OrderProductTableMap::QUANTITY); $criteria->addSelectColumn(OrderProductTableMap::PRICE); - $criteria->addSelectColumn(OrderProductTableMap::TAX); + $criteria->addSelectColumn(OrderProductTableMap::PROMO_PRICE); + $criteria->addSelectColumn(OrderProductTableMap::WAS_NEW); + $criteria->addSelectColumn(OrderProductTableMap::WAS_IN_PROMO); + $criteria->addSelectColumn(OrderProductTableMap::WEIGHT); + $criteria->addSelectColumn(OrderProductTableMap::TAX_RULE_TITLE); + $criteria->addSelectColumn(OrderProductTableMap::TAX_RULE_DESCRIPTION); $criteria->addSelectColumn(OrderProductTableMap::PARENT); $criteria->addSelectColumn(OrderProductTableMap::CREATED_AT); $criteria->addSelectColumn(OrderProductTableMap::UPDATED_AT); @@ -379,12 +430,19 @@ class OrderProductTableMap extends TableMap $criteria->addSelectColumn($alias . '.ID'); $criteria->addSelectColumn($alias . '.ORDER_ID'); $criteria->addSelectColumn($alias . '.PRODUCT_REF'); + $criteria->addSelectColumn($alias . '.PRODUCT_SALE_ELEMENTS_REF'); $criteria->addSelectColumn($alias . '.TITLE'); - $criteria->addSelectColumn($alias . '.DESCRIPTION'); $criteria->addSelectColumn($alias . '.CHAPO'); + $criteria->addSelectColumn($alias . '.DESCRIPTION'); + $criteria->addSelectColumn($alias . '.POSTSCRIPTUM'); $criteria->addSelectColumn($alias . '.QUANTITY'); $criteria->addSelectColumn($alias . '.PRICE'); - $criteria->addSelectColumn($alias . '.TAX'); + $criteria->addSelectColumn($alias . '.PROMO_PRICE'); + $criteria->addSelectColumn($alias . '.WAS_NEW'); + $criteria->addSelectColumn($alias . '.WAS_IN_PROMO'); + $criteria->addSelectColumn($alias . '.WEIGHT'); + $criteria->addSelectColumn($alias . '.TAX_RULE_TITLE'); + $criteria->addSelectColumn($alias . '.TAX_RULE_DESCRIPTION'); $criteria->addSelectColumn($alias . '.PARENT'); $criteria->addSelectColumn($alias . '.CREATED_AT'); $criteria->addSelectColumn($alias . '.UPDATED_AT'); diff --git a/core/lib/Thelia/Model/Map/FeatureCategoryTableMap.php b/core/lib/Thelia/Model/Map/OrderProductTaxTableMap.php similarity index 64% rename from core/lib/Thelia/Model/Map/FeatureCategoryTableMap.php rename to core/lib/Thelia/Model/Map/OrderProductTaxTableMap.php index 3e20805b6..2e8460a6a 100644 --- a/core/lib/Thelia/Model/Map/FeatureCategoryTableMap.php +++ b/core/lib/Thelia/Model/Map/OrderProductTaxTableMap.php @@ -10,12 +10,12 @@ use Propel\Runtime\Exception\PropelException; use Propel\Runtime\Map\RelationMap; use Propel\Runtime\Map\TableMap; use Propel\Runtime\Map\TableMapTrait; -use Thelia\Model\FeatureCategory; -use Thelia\Model\FeatureCategoryQuery; +use Thelia\Model\OrderProductTax; +use Thelia\Model\OrderProductTaxQuery; /** - * This class defines the structure of the 'feature_category' table. + * This class defines the structure of the 'order_product_tax' table. * * * @@ -25,14 +25,14 @@ use Thelia\Model\FeatureCategoryQuery; * (i.e. if it's a text column type). * */ -class FeatureCategoryTableMap extends TableMap +class OrderProductTaxTableMap extends TableMap { use InstancePoolTrait; use TableMapTrait; /** * The (dot-path) name of this class */ - const CLASS_NAME = 'Thelia.Model.Map.FeatureCategoryTableMap'; + const CLASS_NAME = 'Thelia.Model.Map.OrderProductTaxTableMap'; /** * The default database name for this class @@ -42,22 +42,22 @@ class FeatureCategoryTableMap extends TableMap /** * The table name for this class */ - const TABLE_NAME = 'feature_category'; + const TABLE_NAME = 'order_product_tax'; /** * The related Propel class for this table */ - const OM_CLASS = '\\Thelia\\Model\\FeatureCategory'; + const OM_CLASS = '\\Thelia\\Model\\OrderProductTax'; /** * A class that can be returned by this tableMap */ - const CLASS_DEFAULT = 'Thelia.Model.FeatureCategory'; + const CLASS_DEFAULT = 'Thelia.Model.OrderProductTax'; /** * The total number of columns */ - const NUM_COLUMNS = 5; + const NUM_COLUMNS = 7; /** * The number of lazy-loaded columns @@ -67,32 +67,42 @@ class FeatureCategoryTableMap extends TableMap /** * The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */ - const NUM_HYDRATE_COLUMNS = 5; + const NUM_HYDRATE_COLUMNS = 7; /** * the column name for the ID field */ - const ID = 'feature_category.ID'; + const ID = 'order_product_tax.ID'; /** - * the column name for the FEATURE_ID field + * the column name for the ORDER_PRODUCT_ID field */ - const FEATURE_ID = 'feature_category.FEATURE_ID'; + const ORDER_PRODUCT_ID = 'order_product_tax.ORDER_PRODUCT_ID'; /** - * the column name for the CATEGORY_ID field + * the column name for the TITLE field */ - const CATEGORY_ID = 'feature_category.CATEGORY_ID'; + const TITLE = 'order_product_tax.TITLE'; + + /** + * the column name for the DESCRIPTION field + */ + const DESCRIPTION = 'order_product_tax.DESCRIPTION'; + + /** + * the column name for the AMOUNT field + */ + const AMOUNT = 'order_product_tax.AMOUNT'; /** * the column name for the CREATED_AT field */ - const CREATED_AT = 'feature_category.CREATED_AT'; + const CREATED_AT = 'order_product_tax.CREATED_AT'; /** * the column name for the UPDATED_AT field */ - const UPDATED_AT = 'feature_category.UPDATED_AT'; + const UPDATED_AT = 'order_product_tax.UPDATED_AT'; /** * The default string format for model objects of the related table @@ -106,12 +116,12 @@ class FeatureCategoryTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('Id', 'FeatureId', 'CategoryId', 'CreatedAt', 'UpdatedAt', ), - self::TYPE_STUDLYPHPNAME => array('id', 'featureId', 'categoryId', 'createdAt', 'updatedAt', ), - self::TYPE_COLNAME => array(FeatureCategoryTableMap::ID, FeatureCategoryTableMap::FEATURE_ID, FeatureCategoryTableMap::CATEGORY_ID, FeatureCategoryTableMap::CREATED_AT, FeatureCategoryTableMap::UPDATED_AT, ), - self::TYPE_RAW_COLNAME => array('ID', 'FEATURE_ID', 'CATEGORY_ID', 'CREATED_AT', 'UPDATED_AT', ), - self::TYPE_FIELDNAME => array('id', 'feature_id', 'category_id', 'created_at', 'updated_at', ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, ) + self::TYPE_PHPNAME => array('Id', 'OrderProductId', 'Title', 'Description', 'Amount', 'CreatedAt', 'UpdatedAt', ), + self::TYPE_STUDLYPHPNAME => array('id', 'orderProductId', 'title', 'description', 'amount', 'createdAt', 'updatedAt', ), + self::TYPE_COLNAME => array(OrderProductTaxTableMap::ID, OrderProductTaxTableMap::ORDER_PRODUCT_ID, OrderProductTaxTableMap::TITLE, OrderProductTaxTableMap::DESCRIPTION, OrderProductTaxTableMap::AMOUNT, OrderProductTaxTableMap::CREATED_AT, OrderProductTaxTableMap::UPDATED_AT, ), + self::TYPE_RAW_COLNAME => array('ID', 'ORDER_PRODUCT_ID', 'TITLE', 'DESCRIPTION', 'AMOUNT', 'CREATED_AT', 'UPDATED_AT', ), + self::TYPE_FIELDNAME => array('id', 'order_product_id', 'title', 'description', 'amount', 'created_at', 'updated_at', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, ) ); /** @@ -121,12 +131,12 @@ class FeatureCategoryTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'FeatureId' => 1, 'CategoryId' => 2, 'CreatedAt' => 3, 'UpdatedAt' => 4, ), - self::TYPE_STUDLYPHPNAME => array('id' => 0, 'featureId' => 1, 'categoryId' => 2, 'createdAt' => 3, 'updatedAt' => 4, ), - self::TYPE_COLNAME => array(FeatureCategoryTableMap::ID => 0, FeatureCategoryTableMap::FEATURE_ID => 1, FeatureCategoryTableMap::CATEGORY_ID => 2, FeatureCategoryTableMap::CREATED_AT => 3, FeatureCategoryTableMap::UPDATED_AT => 4, ), - self::TYPE_RAW_COLNAME => array('ID' => 0, 'FEATURE_ID' => 1, 'CATEGORY_ID' => 2, 'CREATED_AT' => 3, 'UPDATED_AT' => 4, ), - self::TYPE_FIELDNAME => array('id' => 0, 'feature_id' => 1, 'category_id' => 2, 'created_at' => 3, 'updated_at' => 4, ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, ) + self::TYPE_PHPNAME => array('Id' => 0, 'OrderProductId' => 1, 'Title' => 2, 'Description' => 3, 'Amount' => 4, 'CreatedAt' => 5, 'UpdatedAt' => 6, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'orderProductId' => 1, 'title' => 2, 'description' => 3, 'amount' => 4, 'createdAt' => 5, 'updatedAt' => 6, ), + self::TYPE_COLNAME => array(OrderProductTaxTableMap::ID => 0, OrderProductTaxTableMap::ORDER_PRODUCT_ID => 1, OrderProductTaxTableMap::TITLE => 2, OrderProductTaxTableMap::DESCRIPTION => 3, OrderProductTaxTableMap::AMOUNT => 4, OrderProductTaxTableMap::CREATED_AT => 5, OrderProductTaxTableMap::UPDATED_AT => 6, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'ORDER_PRODUCT_ID' => 1, 'TITLE' => 2, 'DESCRIPTION' => 3, 'AMOUNT' => 4, 'CREATED_AT' => 5, 'UPDATED_AT' => 6, ), + self::TYPE_FIELDNAME => array('id' => 0, 'order_product_id' => 1, 'title' => 2, 'description' => 3, 'amount' => 4, 'created_at' => 5, 'updated_at' => 6, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, ) ); /** @@ -139,16 +149,17 @@ class FeatureCategoryTableMap extends TableMap public function initialize() { // attributes - $this->setName('feature_category'); - $this->setPhpName('FeatureCategory'); - $this->setClassName('\\Thelia\\Model\\FeatureCategory'); + $this->setName('order_product_tax'); + $this->setPhpName('OrderProductTax'); + $this->setClassName('\\Thelia\\Model\\OrderProductTax'); $this->setPackage('Thelia.Model'); $this->setUseIdGenerator(true); - $this->setIsCrossRef(true); // columns $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); - $this->addForeignKey('FEATURE_ID', 'FeatureId', 'INTEGER', 'feature', 'ID', true, null, null); - $this->addForeignKey('CATEGORY_ID', 'CategoryId', 'INTEGER', 'category', 'ID', true, null, null); + $this->addForeignKey('ORDER_PRODUCT_ID', 'OrderProductId', 'INTEGER', 'order_product', 'ID', true, null, null); + $this->addColumn('TITLE', 'Title', 'VARCHAR', true, 255, null); + $this->addColumn('DESCRIPTION', 'Description', 'CLOB', false, null, null); + $this->addColumn('AMOUNT', 'Amount', 'FLOAT', true, null, null); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); } // initialize() @@ -158,8 +169,7 @@ class FeatureCategoryTableMap extends TableMap */ public function buildRelations() { - $this->addRelation('Category', '\\Thelia\\Model\\Category', RelationMap::MANY_TO_ONE, array('category_id' => 'id', ), 'CASCADE', 'RESTRICT'); - $this->addRelation('Feature', '\\Thelia\\Model\\Feature', RelationMap::MANY_TO_ONE, array('feature_id' => 'id', ), 'CASCADE', 'RESTRICT'); + $this->addRelation('OrderProduct', '\\Thelia\\Model\\OrderProduct', RelationMap::MANY_TO_ONE, array('order_product_id' => 'id', ), 'CASCADE', 'RESTRICT'); } // buildRelations() /** @@ -231,7 +241,7 @@ class FeatureCategoryTableMap extends TableMap */ public static function getOMClass($withPrefix = true) { - return $withPrefix ? FeatureCategoryTableMap::CLASS_DEFAULT : FeatureCategoryTableMap::OM_CLASS; + return $withPrefix ? OrderProductTaxTableMap::CLASS_DEFAULT : OrderProductTaxTableMap::OM_CLASS; } /** @@ -245,21 +255,21 @@ class FeatureCategoryTableMap extends TableMap * * @throws PropelException Any exceptions caught during processing will be * rethrown wrapped into a PropelException. - * @return array (FeatureCategory object, last column rank) + * @return array (OrderProductTax object, last column rank) */ public static function populateObject($row, $offset = 0, $indexType = TableMap::TYPE_NUM) { - $key = FeatureCategoryTableMap::getPrimaryKeyHashFromRow($row, $offset, $indexType); - if (null !== ($obj = FeatureCategoryTableMap::getInstanceFromPool($key))) { + $key = OrderProductTaxTableMap::getPrimaryKeyHashFromRow($row, $offset, $indexType); + if (null !== ($obj = OrderProductTaxTableMap::getInstanceFromPool($key))) { // We no longer rehydrate the object, since this can cause data loss. // See http://www.propelorm.org/ticket/509 // $obj->hydrate($row, $offset, true); // rehydrate - $col = $offset + FeatureCategoryTableMap::NUM_HYDRATE_COLUMNS; + $col = $offset + OrderProductTaxTableMap::NUM_HYDRATE_COLUMNS; } else { - $cls = FeatureCategoryTableMap::OM_CLASS; + $cls = OrderProductTaxTableMap::OM_CLASS; $obj = new $cls(); $col = $obj->hydrate($row, $offset, false, $indexType); - FeatureCategoryTableMap::addInstanceToPool($obj, $key); + OrderProductTaxTableMap::addInstanceToPool($obj, $key); } return array($obj, $col); @@ -282,8 +292,8 @@ class FeatureCategoryTableMap extends TableMap $cls = static::getOMClass(false); // populate the object(s) while ($row = $dataFetcher->fetch()) { - $key = FeatureCategoryTableMap::getPrimaryKeyHashFromRow($row, 0, $dataFetcher->getIndexType()); - if (null !== ($obj = FeatureCategoryTableMap::getInstanceFromPool($key))) { + $key = OrderProductTaxTableMap::getPrimaryKeyHashFromRow($row, 0, $dataFetcher->getIndexType()); + if (null !== ($obj = OrderProductTaxTableMap::getInstanceFromPool($key))) { // We no longer rehydrate the object, since this can cause data loss. // See http://www.propelorm.org/ticket/509 // $obj->hydrate($row, 0, true); // rehydrate @@ -292,7 +302,7 @@ class FeatureCategoryTableMap extends TableMap $obj = new $cls(); $obj->hydrate($row); $results[] = $obj; - FeatureCategoryTableMap::addInstanceToPool($obj, $key); + OrderProductTaxTableMap::addInstanceToPool($obj, $key); } // if key exists } @@ -313,15 +323,19 @@ class FeatureCategoryTableMap extends TableMap public static function addSelectColumns(Criteria $criteria, $alias = null) { if (null === $alias) { - $criteria->addSelectColumn(FeatureCategoryTableMap::ID); - $criteria->addSelectColumn(FeatureCategoryTableMap::FEATURE_ID); - $criteria->addSelectColumn(FeatureCategoryTableMap::CATEGORY_ID); - $criteria->addSelectColumn(FeatureCategoryTableMap::CREATED_AT); - $criteria->addSelectColumn(FeatureCategoryTableMap::UPDATED_AT); + $criteria->addSelectColumn(OrderProductTaxTableMap::ID); + $criteria->addSelectColumn(OrderProductTaxTableMap::ORDER_PRODUCT_ID); + $criteria->addSelectColumn(OrderProductTaxTableMap::TITLE); + $criteria->addSelectColumn(OrderProductTaxTableMap::DESCRIPTION); + $criteria->addSelectColumn(OrderProductTaxTableMap::AMOUNT); + $criteria->addSelectColumn(OrderProductTaxTableMap::CREATED_AT); + $criteria->addSelectColumn(OrderProductTaxTableMap::UPDATED_AT); } else { $criteria->addSelectColumn($alias . '.ID'); - $criteria->addSelectColumn($alias . '.FEATURE_ID'); - $criteria->addSelectColumn($alias . '.CATEGORY_ID'); + $criteria->addSelectColumn($alias . '.ORDER_PRODUCT_ID'); + $criteria->addSelectColumn($alias . '.TITLE'); + $criteria->addSelectColumn($alias . '.DESCRIPTION'); + $criteria->addSelectColumn($alias . '.AMOUNT'); $criteria->addSelectColumn($alias . '.CREATED_AT'); $criteria->addSelectColumn($alias . '.UPDATED_AT'); } @@ -336,7 +350,7 @@ class FeatureCategoryTableMap extends TableMap */ public static function getTableMap() { - return Propel::getServiceContainer()->getDatabaseMap(FeatureCategoryTableMap::DATABASE_NAME)->getTable(FeatureCategoryTableMap::TABLE_NAME); + return Propel::getServiceContainer()->getDatabaseMap(OrderProductTaxTableMap::DATABASE_NAME)->getTable(OrderProductTaxTableMap::TABLE_NAME); } /** @@ -344,16 +358,16 @@ class FeatureCategoryTableMap extends TableMap */ public static function buildTableMap() { - $dbMap = Propel::getServiceContainer()->getDatabaseMap(FeatureCategoryTableMap::DATABASE_NAME); - if (!$dbMap->hasTable(FeatureCategoryTableMap::TABLE_NAME)) { - $dbMap->addTableObject(new FeatureCategoryTableMap()); + $dbMap = Propel::getServiceContainer()->getDatabaseMap(OrderProductTaxTableMap::DATABASE_NAME); + if (!$dbMap->hasTable(OrderProductTaxTableMap::TABLE_NAME)) { + $dbMap->addTableObject(new OrderProductTaxTableMap()); } } /** - * Performs a DELETE on the database, given a FeatureCategory or Criteria object OR a primary key value. + * Performs a DELETE on the database, given a OrderProductTax or Criteria object OR a primary key value. * - * @param mixed $values Criteria or FeatureCategory object or primary key or array of primary keys + * @param mixed $values Criteria or OrderProductTax object or primary key or array of primary keys * which is used to create the DELETE statement * @param ConnectionInterface $con the connection to use * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows @@ -364,25 +378,25 @@ class FeatureCategoryTableMap extends TableMap public static function doDelete($values, ConnectionInterface $con = null) { if (null === $con) { - $con = Propel::getServiceContainer()->getWriteConnection(FeatureCategoryTableMap::DATABASE_NAME); + $con = Propel::getServiceContainer()->getWriteConnection(OrderProductTaxTableMap::DATABASE_NAME); } if ($values instanceof Criteria) { // rename for clarity $criteria = $values; - } elseif ($values instanceof \Thelia\Model\FeatureCategory) { // it's a model object + } elseif ($values instanceof \Thelia\Model\OrderProductTax) { // it's a model object // create criteria based on pk values $criteria = $values->buildPkeyCriteria(); } else { // it's a primary key, or an array of pks - $criteria = new Criteria(FeatureCategoryTableMap::DATABASE_NAME); - $criteria->add(FeatureCategoryTableMap::ID, (array) $values, Criteria::IN); + $criteria = new Criteria(OrderProductTaxTableMap::DATABASE_NAME); + $criteria->add(OrderProductTaxTableMap::ID, (array) $values, Criteria::IN); } - $query = FeatureCategoryQuery::create()->mergeWith($criteria); + $query = OrderProductTaxQuery::create()->mergeWith($criteria); - if ($values instanceof Criteria) { FeatureCategoryTableMap::clearInstancePool(); + if ($values instanceof Criteria) { OrderProductTaxTableMap::clearInstancePool(); } elseif (!is_object($values)) { // it's a primary key, or an array of pks - foreach ((array) $values as $singleval) { FeatureCategoryTableMap::removeInstanceFromPool($singleval); + foreach ((array) $values as $singleval) { OrderProductTaxTableMap::removeInstanceFromPool($singleval); } } @@ -390,20 +404,20 @@ class FeatureCategoryTableMap extends TableMap } /** - * Deletes all rows from the feature_category table. + * Deletes all rows from the order_product_tax table. * * @param ConnectionInterface $con the connection to use * @return int The number of affected rows (if supported by underlying database driver). */ public static function doDeleteAll(ConnectionInterface $con = null) { - return FeatureCategoryQuery::create()->doDeleteAll($con); + return OrderProductTaxQuery::create()->doDeleteAll($con); } /** - * Performs an INSERT on the database, given a FeatureCategory or Criteria object. + * Performs an INSERT on the database, given a OrderProductTax or Criteria object. * - * @param mixed $criteria Criteria or FeatureCategory object containing data that is used to create the INSERT statement. + * @param mixed $criteria Criteria or OrderProductTax object containing data that is used to create the INSERT statement. * @param ConnectionInterface $con the ConnectionInterface connection to use * @return mixed The new primary key. * @throws PropelException Any exceptions caught during processing will be @@ -412,22 +426,22 @@ class FeatureCategoryTableMap extends TableMap public static function doInsert($criteria, ConnectionInterface $con = null) { if (null === $con) { - $con = Propel::getServiceContainer()->getWriteConnection(FeatureCategoryTableMap::DATABASE_NAME); + $con = Propel::getServiceContainer()->getWriteConnection(OrderProductTaxTableMap::DATABASE_NAME); } if ($criteria instanceof Criteria) { $criteria = clone $criteria; // rename for clarity } else { - $criteria = $criteria->buildCriteria(); // build Criteria from FeatureCategory object + $criteria = $criteria->buildCriteria(); // build Criteria from OrderProductTax object } - if ($criteria->containsKey(FeatureCategoryTableMap::ID) && $criteria->keyContainsValue(FeatureCategoryTableMap::ID) ) { - throw new PropelException('Cannot insert a value for auto-increment primary key ('.FeatureCategoryTableMap::ID.')'); + if ($criteria->containsKey(OrderProductTaxTableMap::ID) && $criteria->keyContainsValue(OrderProductTaxTableMap::ID) ) { + throw new PropelException('Cannot insert a value for auto-increment primary key ('.OrderProductTaxTableMap::ID.')'); } // Set the correct dbName - $query = FeatureCategoryQuery::create()->mergeWith($criteria); + $query = OrderProductTaxQuery::create()->mergeWith($criteria); try { // use transaction because $criteria could contain info @@ -443,7 +457,7 @@ class FeatureCategoryTableMap extends TableMap return $pk; } -} // FeatureCategoryTableMap +} // OrderProductTaxTableMap // This is the static code needed to register the TableMap for this table with the main Propel class. // -FeatureCategoryTableMap::buildTableMap(); +OrderProductTaxTableMap::buildTableMap(); diff --git a/core/lib/Thelia/Model/Map/OrderStatusTableMap.php b/core/lib/Thelia/Model/Map/OrderStatusTableMap.php index bc283a3e8..f29ed9464 100644 --- a/core/lib/Thelia/Model/Map/OrderStatusTableMap.php +++ b/core/lib/Thelia/Model/Map/OrderStatusTableMap.php @@ -150,7 +150,7 @@ class OrderStatusTableMap extends TableMap $this->setUseIdGenerator(true); // columns $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); - $this->addColumn('CODE', 'Code', 'VARCHAR', false, 45, null); + $this->addColumn('CODE', 'Code', 'VARCHAR', true, 45, null); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); } // initialize() diff --git a/core/lib/Thelia/Model/Map/OrderTableMap.php b/core/lib/Thelia/Model/Map/OrderTableMap.php index ae43bd768..7daabb665 100644 --- a/core/lib/Thelia/Model/Map/OrderTableMap.php +++ b/core/lib/Thelia/Model/Map/OrderTableMap.php @@ -215,7 +215,7 @@ class OrderTableMap extends TableMap $this->addForeignKey('CUSTOMER_ID', 'CustomerId', 'INTEGER', 'customer', 'ID', true, null, null); $this->addForeignKey('INVOICE_ORDER_ADDRESS_ID', 'InvoiceOrderAddressId', 'INTEGER', 'order_address', 'ID', true, null, null); $this->addForeignKey('DELIVERY_ORDER_ADDRESS_ID', 'DeliveryOrderAddressId', 'INTEGER', 'order_address', 'ID', true, null, null); - $this->addColumn('INVOICE_DATE', 'InvoiceDate', 'DATE', true, null, null); + $this->addColumn('INVOICE_DATE', 'InvoiceDate', 'DATE', false, null, null); $this->addForeignKey('CURRENCY_ID', 'CurrencyId', 'INTEGER', 'currency', 'ID', true, null, null); $this->addColumn('CURRENCY_RATE', 'CurrencyRate', 'FLOAT', true, null, null); $this->addColumn('TRANSACTION_REF', 'TransactionRef', 'VARCHAR', false, 100, null); diff --git a/core/lib/Thelia/Model/Map/ProductSaleElementsTableMap.php b/core/lib/Thelia/Model/Map/ProductSaleElementsTableMap.php index fc23ae569..1e894ef24 100644 --- a/core/lib/Thelia/Model/Map/ProductSaleElementsTableMap.php +++ b/core/lib/Thelia/Model/Map/ProductSaleElementsTableMap.php @@ -57,7 +57,7 @@ class ProductSaleElementsTableMap extends TableMap /** * The total number of columns */ - const NUM_COLUMNS = 9; + const NUM_COLUMNS = 10; /** * The number of lazy-loaded columns @@ -67,7 +67,7 @@ class ProductSaleElementsTableMap extends TableMap /** * The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */ - const NUM_HYDRATE_COLUMNS = 9; + const NUM_HYDRATE_COLUMNS = 10; /** * the column name for the ID field @@ -104,6 +104,11 @@ class ProductSaleElementsTableMap extends TableMap */ const WEIGHT = 'product_sale_elements.WEIGHT'; + /** + * the column name for the IS_DEFAULT field + */ + const IS_DEFAULT = 'product_sale_elements.IS_DEFAULT'; + /** * the column name for the CREATED_AT field */ @@ -126,12 +131,12 @@ class ProductSaleElementsTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('Id', 'ProductId', 'Ref', 'Quantity', 'Promo', 'Newness', 'Weight', 'CreatedAt', 'UpdatedAt', ), - self::TYPE_STUDLYPHPNAME => array('id', 'productId', 'ref', 'quantity', 'promo', 'newness', 'weight', 'createdAt', 'updatedAt', ), - self::TYPE_COLNAME => array(ProductSaleElementsTableMap::ID, ProductSaleElementsTableMap::PRODUCT_ID, ProductSaleElementsTableMap::REF, ProductSaleElementsTableMap::QUANTITY, ProductSaleElementsTableMap::PROMO, ProductSaleElementsTableMap::NEWNESS, ProductSaleElementsTableMap::WEIGHT, ProductSaleElementsTableMap::CREATED_AT, ProductSaleElementsTableMap::UPDATED_AT, ), - self::TYPE_RAW_COLNAME => array('ID', 'PRODUCT_ID', 'REF', 'QUANTITY', 'PROMO', 'NEWNESS', 'WEIGHT', 'CREATED_AT', 'UPDATED_AT', ), - self::TYPE_FIELDNAME => array('id', 'product_id', 'ref', 'quantity', 'promo', 'newness', 'weight', 'created_at', 'updated_at', ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, ) + self::TYPE_PHPNAME => array('Id', 'ProductId', 'Ref', 'Quantity', 'Promo', 'Newness', 'Weight', 'IsDefault', 'CreatedAt', 'UpdatedAt', ), + self::TYPE_STUDLYPHPNAME => array('id', 'productId', 'ref', 'quantity', 'promo', 'newness', 'weight', 'isDefault', 'createdAt', 'updatedAt', ), + self::TYPE_COLNAME => array(ProductSaleElementsTableMap::ID, ProductSaleElementsTableMap::PRODUCT_ID, ProductSaleElementsTableMap::REF, ProductSaleElementsTableMap::QUANTITY, ProductSaleElementsTableMap::PROMO, ProductSaleElementsTableMap::NEWNESS, ProductSaleElementsTableMap::WEIGHT, ProductSaleElementsTableMap::IS_DEFAULT, ProductSaleElementsTableMap::CREATED_AT, ProductSaleElementsTableMap::UPDATED_AT, ), + self::TYPE_RAW_COLNAME => array('ID', 'PRODUCT_ID', 'REF', 'QUANTITY', 'PROMO', 'NEWNESS', 'WEIGHT', 'IS_DEFAULT', 'CREATED_AT', 'UPDATED_AT', ), + self::TYPE_FIELDNAME => array('id', 'product_id', 'ref', 'quantity', 'promo', 'newness', 'weight', 'is_default', 'created_at', 'updated_at', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ) ); /** @@ -141,12 +146,12 @@ class ProductSaleElementsTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'ProductId' => 1, 'Ref' => 2, 'Quantity' => 3, 'Promo' => 4, 'Newness' => 5, 'Weight' => 6, 'CreatedAt' => 7, 'UpdatedAt' => 8, ), - self::TYPE_STUDLYPHPNAME => array('id' => 0, 'productId' => 1, 'ref' => 2, 'quantity' => 3, 'promo' => 4, 'newness' => 5, 'weight' => 6, 'createdAt' => 7, 'updatedAt' => 8, ), - self::TYPE_COLNAME => array(ProductSaleElementsTableMap::ID => 0, ProductSaleElementsTableMap::PRODUCT_ID => 1, ProductSaleElementsTableMap::REF => 2, ProductSaleElementsTableMap::QUANTITY => 3, ProductSaleElementsTableMap::PROMO => 4, ProductSaleElementsTableMap::NEWNESS => 5, ProductSaleElementsTableMap::WEIGHT => 6, ProductSaleElementsTableMap::CREATED_AT => 7, ProductSaleElementsTableMap::UPDATED_AT => 8, ), - self::TYPE_RAW_COLNAME => array('ID' => 0, 'PRODUCT_ID' => 1, 'REF' => 2, 'QUANTITY' => 3, 'PROMO' => 4, 'NEWNESS' => 5, 'WEIGHT' => 6, 'CREATED_AT' => 7, 'UPDATED_AT' => 8, ), - self::TYPE_FIELDNAME => array('id' => 0, 'product_id' => 1, 'ref' => 2, 'quantity' => 3, 'promo' => 4, 'newness' => 5, 'weight' => 6, 'created_at' => 7, 'updated_at' => 8, ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, ) + self::TYPE_PHPNAME => array('Id' => 0, 'ProductId' => 1, 'Ref' => 2, 'Quantity' => 3, 'Promo' => 4, 'Newness' => 5, 'Weight' => 6, 'IsDefault' => 7, 'CreatedAt' => 8, 'UpdatedAt' => 9, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'productId' => 1, 'ref' => 2, 'quantity' => 3, 'promo' => 4, 'newness' => 5, 'weight' => 6, 'isDefault' => 7, 'createdAt' => 8, 'updatedAt' => 9, ), + self::TYPE_COLNAME => array(ProductSaleElementsTableMap::ID => 0, ProductSaleElementsTableMap::PRODUCT_ID => 1, ProductSaleElementsTableMap::REF => 2, ProductSaleElementsTableMap::QUANTITY => 3, ProductSaleElementsTableMap::PROMO => 4, ProductSaleElementsTableMap::NEWNESS => 5, ProductSaleElementsTableMap::WEIGHT => 6, ProductSaleElementsTableMap::IS_DEFAULT => 7, ProductSaleElementsTableMap::CREATED_AT => 8, ProductSaleElementsTableMap::UPDATED_AT => 9, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'PRODUCT_ID' => 1, 'REF' => 2, 'QUANTITY' => 3, 'PROMO' => 4, 'NEWNESS' => 5, 'WEIGHT' => 6, 'IS_DEFAULT' => 7, 'CREATED_AT' => 8, 'UPDATED_AT' => 9, ), + self::TYPE_FIELDNAME => array('id' => 0, 'product_id' => 1, 'ref' => 2, 'quantity' => 3, 'promo' => 4, 'newness' => 5, 'weight' => 6, 'is_default' => 7, 'created_at' => 8, 'updated_at' => 9, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ) ); /** @@ -167,11 +172,12 @@ class ProductSaleElementsTableMap extends TableMap // columns $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); $this->addForeignKey('PRODUCT_ID', 'ProductId', 'INTEGER', 'product', 'ID', true, null, null); - $this->addColumn('REF', 'Ref', 'VARCHAR', true, 45, null); + $this->addColumn('REF', 'Ref', 'VARCHAR', true, 255, null); $this->addColumn('QUANTITY', 'Quantity', 'FLOAT', true, null, null); $this->addColumn('PROMO', 'Promo', 'TINYINT', false, null, 0); $this->addColumn('NEWNESS', 'Newness', 'TINYINT', false, null, 0); - $this->addColumn('WEIGHT', 'Weight', 'FLOAT', false, null, null); + $this->addColumn('WEIGHT', 'Weight', 'FLOAT', false, null, 0); + $this->addColumn('IS_DEFAULT', 'IsDefault', 'BOOLEAN', false, 1, false); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); } // initialize() @@ -355,6 +361,7 @@ class ProductSaleElementsTableMap extends TableMap $criteria->addSelectColumn(ProductSaleElementsTableMap::PROMO); $criteria->addSelectColumn(ProductSaleElementsTableMap::NEWNESS); $criteria->addSelectColumn(ProductSaleElementsTableMap::WEIGHT); + $criteria->addSelectColumn(ProductSaleElementsTableMap::IS_DEFAULT); $criteria->addSelectColumn(ProductSaleElementsTableMap::CREATED_AT); $criteria->addSelectColumn(ProductSaleElementsTableMap::UPDATED_AT); } else { @@ -365,6 +372,7 @@ class ProductSaleElementsTableMap extends TableMap $criteria->addSelectColumn($alias . '.PROMO'); $criteria->addSelectColumn($alias . '.NEWNESS'); $criteria->addSelectColumn($alias . '.WEIGHT'); + $criteria->addSelectColumn($alias . '.IS_DEFAULT'); $criteria->addSelectColumn($alias . '.CREATED_AT'); $criteria->addSelectColumn($alias . '.UPDATED_AT'); } diff --git a/core/lib/Thelia/Model/Map/ProductTableMap.php b/core/lib/Thelia/Model/Map/ProductTableMap.php index 17c4585f0..59ac236ac 100644 --- a/core/lib/Thelia/Model/Map/ProductTableMap.php +++ b/core/lib/Thelia/Model/Map/ProductTableMap.php @@ -189,7 +189,7 @@ class ProductTableMap extends TableMap $this->addColumn('REF', 'Ref', 'VARCHAR', true, 255, null); $this->addColumn('VISIBLE', 'Visible', 'TINYINT', true, null, 0); $this->addColumn('POSITION', 'Position', 'INTEGER', true, null, null); - $this->addForeignKey('TEMPLATE_ID', 'TemplateId', 'INTEGER', 'template', 'ID', true, null, null); + $this->addForeignKey('TEMPLATE_ID', 'TemplateId', 'INTEGER', 'template', 'ID', false, null, null); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('VERSION', 'Version', 'INTEGER', false, null, 0); diff --git a/core/lib/Thelia/Model/Map/ProductVersionTableMap.php b/core/lib/Thelia/Model/Map/ProductVersionTableMap.php index 4e84b4db8..14d38a764 100644 --- a/core/lib/Thelia/Model/Map/ProductVersionTableMap.php +++ b/core/lib/Thelia/Model/Map/ProductVersionTableMap.php @@ -180,7 +180,7 @@ class ProductVersionTableMap extends TableMap $this->addColumn('REF', 'Ref', 'VARCHAR', true, 255, null); $this->addColumn('VISIBLE', 'Visible', 'TINYINT', true, null, 0); $this->addColumn('POSITION', 'Position', 'INTEGER', true, null, null); - $this->addColumn('TEMPLATE_ID', 'TemplateId', 'INTEGER', true, null, null); + $this->addColumn('TEMPLATE_ID', 'TemplateId', 'INTEGER', false, null, null); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); $this->addPrimaryKey('VERSION', 'Version', 'INTEGER', true, null, 0); diff --git a/core/lib/Thelia/Model/Map/TaxI18nTableMap.php b/core/lib/Thelia/Model/Map/TaxI18nTableMap.php index a06230c37..c50a30c90 100644 --- a/core/lib/Thelia/Model/Map/TaxI18nTableMap.php +++ b/core/lib/Thelia/Model/Map/TaxI18nTableMap.php @@ -143,7 +143,7 @@ class TaxI18nTableMap extends TableMap $this->addForeignPrimaryKey('ID', 'Id', 'INTEGER' , 'tax', 'ID', true, null, null); $this->addPrimaryKey('LOCALE', 'Locale', 'VARCHAR', true, 5, 'en_US'); $this->addColumn('TITLE', 'Title', 'VARCHAR', false, 255, null); - $this->addColumn('DESCRIPTION', 'Description', 'LONGVARCHAR', false, null, null); + $this->addColumn('DESCRIPTION', 'Description', 'CLOB', false, null, null); } // initialize() /** diff --git a/core/lib/Thelia/Model/Map/TaxRuleI18nTableMap.php b/core/lib/Thelia/Model/Map/TaxRuleI18nTableMap.php index 012ad2e72..24f8a41d7 100644 --- a/core/lib/Thelia/Model/Map/TaxRuleI18nTableMap.php +++ b/core/lib/Thelia/Model/Map/TaxRuleI18nTableMap.php @@ -143,7 +143,7 @@ class TaxRuleI18nTableMap extends TableMap $this->addForeignPrimaryKey('ID', 'Id', 'INTEGER' , 'tax_rule', 'ID', true, null, null); $this->addPrimaryKey('LOCALE', 'Locale', 'VARCHAR', true, 5, 'en_US'); $this->addColumn('TITLE', 'Title', 'VARCHAR', false, 255, null); - $this->addColumn('DESCRIPTION', 'Description', 'LONGVARCHAR', false, null, null); + $this->addColumn('DESCRIPTION', 'Description', 'CLOB', false, null, null); } // initialize() /** diff --git a/core/lib/Thelia/Model/Map/TaxRuleTableMap.php b/core/lib/Thelia/Model/Map/TaxRuleTableMap.php index 391e23b6d..ccc41e013 100644 --- a/core/lib/Thelia/Model/Map/TaxRuleTableMap.php +++ b/core/lib/Thelia/Model/Map/TaxRuleTableMap.php @@ -57,7 +57,7 @@ class TaxRuleTableMap extends TableMap /** * The total number of columns */ - const NUM_COLUMNS = 3; + const NUM_COLUMNS = 4; /** * The number of lazy-loaded columns @@ -67,13 +67,18 @@ class TaxRuleTableMap extends TableMap /** * The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */ - const NUM_HYDRATE_COLUMNS = 3; + const NUM_HYDRATE_COLUMNS = 4; /** * the column name for the ID field */ const ID = 'tax_rule.ID'; + /** + * the column name for the IS_DEFAULT field + */ + const IS_DEFAULT = 'tax_rule.IS_DEFAULT'; + /** * the column name for the CREATED_AT field */ @@ -105,12 +110,12 @@ class TaxRuleTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('Id', 'CreatedAt', 'UpdatedAt', ), - self::TYPE_STUDLYPHPNAME => array('id', 'createdAt', 'updatedAt', ), - self::TYPE_COLNAME => array(TaxRuleTableMap::ID, TaxRuleTableMap::CREATED_AT, TaxRuleTableMap::UPDATED_AT, ), - self::TYPE_RAW_COLNAME => array('ID', 'CREATED_AT', 'UPDATED_AT', ), - self::TYPE_FIELDNAME => array('id', 'created_at', 'updated_at', ), - self::TYPE_NUM => array(0, 1, 2, ) + self::TYPE_PHPNAME => array('Id', 'IsDefault', 'CreatedAt', 'UpdatedAt', ), + self::TYPE_STUDLYPHPNAME => array('id', 'isDefault', 'createdAt', 'updatedAt', ), + self::TYPE_COLNAME => array(TaxRuleTableMap::ID, TaxRuleTableMap::IS_DEFAULT, TaxRuleTableMap::CREATED_AT, TaxRuleTableMap::UPDATED_AT, ), + self::TYPE_RAW_COLNAME => array('ID', 'IS_DEFAULT', 'CREATED_AT', 'UPDATED_AT', ), + self::TYPE_FIELDNAME => array('id', 'is_default', 'created_at', 'updated_at', ), + self::TYPE_NUM => array(0, 1, 2, 3, ) ); /** @@ -120,12 +125,12 @@ class TaxRuleTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'CreatedAt' => 1, 'UpdatedAt' => 2, ), - self::TYPE_STUDLYPHPNAME => array('id' => 0, 'createdAt' => 1, 'updatedAt' => 2, ), - self::TYPE_COLNAME => array(TaxRuleTableMap::ID => 0, TaxRuleTableMap::CREATED_AT => 1, TaxRuleTableMap::UPDATED_AT => 2, ), - self::TYPE_RAW_COLNAME => array('ID' => 0, 'CREATED_AT' => 1, 'UPDATED_AT' => 2, ), - self::TYPE_FIELDNAME => array('id' => 0, 'created_at' => 1, 'updated_at' => 2, ), - self::TYPE_NUM => array(0, 1, 2, ) + self::TYPE_PHPNAME => array('Id' => 0, 'IsDefault' => 1, 'CreatedAt' => 2, 'UpdatedAt' => 3, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'isDefault' => 1, 'createdAt' => 2, 'updatedAt' => 3, ), + self::TYPE_COLNAME => array(TaxRuleTableMap::ID => 0, TaxRuleTableMap::IS_DEFAULT => 1, TaxRuleTableMap::CREATED_AT => 2, TaxRuleTableMap::UPDATED_AT => 3, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'IS_DEFAULT' => 1, 'CREATED_AT' => 2, 'UPDATED_AT' => 3, ), + self::TYPE_FIELDNAME => array('id' => 0, 'is_default' => 1, 'created_at' => 2, 'updated_at' => 3, ), + self::TYPE_NUM => array(0, 1, 2, 3, ) ); /** @@ -145,6 +150,7 @@ class TaxRuleTableMap extends TableMap $this->setUseIdGenerator(true); // columns $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); + $this->addColumn('IS_DEFAULT', 'IsDefault', 'BOOLEAN', true, 1, false); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); } // initialize() @@ -323,10 +329,12 @@ class TaxRuleTableMap extends TableMap { if (null === $alias) { $criteria->addSelectColumn(TaxRuleTableMap::ID); + $criteria->addSelectColumn(TaxRuleTableMap::IS_DEFAULT); $criteria->addSelectColumn(TaxRuleTableMap::CREATED_AT); $criteria->addSelectColumn(TaxRuleTableMap::UPDATED_AT); } else { $criteria->addSelectColumn($alias . '.ID'); + $criteria->addSelectColumn($alias . '.IS_DEFAULT'); $criteria->addSelectColumn($alias . '.CREATED_AT'); $criteria->addSelectColumn($alias . '.UPDATED_AT'); } diff --git a/core/lib/Thelia/Model/ModuleImage.php b/core/lib/Thelia/Model/ModuleImage.php new file mode 100644 index 000000000..7ea5415bc --- /dev/null +++ b/core/lib/Thelia/Model/ModuleImage.php @@ -0,0 +1,10 @@ +setRef($this->generateRef()); + + $this->dispatchEvent(TheliaEvents::ORDER_BEFORE_CREATE, new OrderEvent($this)); + + return true; + } + + /** + * {@inheritDoc} + */ + public function postInsert(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::ORDER_AFTER_CREATE, new OrderEvent($this)); + } + + public function generateRef() + { + /* order addresses are unique */ + return uniqid('ORD', true); + } /** * calculate the total amount * - * @TODO create body method + * @param int $tax * - * @return int + * @return int|string|Base\double */ - public function getTotalAmount() + public function getTotalAmount(&$tax = 0) { - return 2; + $amount = 0; + $tax = 0; + + /* browse all products */ + $orderProductIds = array(); + foreach($this->getOrderProducts() as $orderProduct) { + $taxAmount = OrderProductTaxQuery::create() + ->withColumn('SUM(' . OrderProductTaxTableMap::AMOUNT . ')', 'total_tax') + ->filterByOrderProductId($orderProduct->getId(), Criteria::EQUAL) + ->findOne(); + $amount += ($orderProduct->getWasInPromo() == 1 ? $orderProduct->getPromoPrice() : $orderProduct->getPrice()) * $orderProduct->getQuantity(); + $tax += round($taxAmount->getVirtualColumn('total_tax'), 2) * $orderProduct->getQuantity(); + } + + return $amount + $tax + $this->getPostage(); // @todo : manage discount + } + + /** + * PROPEL SHOULD FIX IT + * + * Insert the row in the database. + * + * @param ConnectionInterface $con + * + * @throws PropelException + * @see doSave() + */ + protected function doInsert(ConnectionInterface $con) + { + $modifiedColumns = array(); + $index = 0; + + $this->modifiedColumns[] = OrderTableMap::ID; + if (null !== $this->id) { + throw new PropelException('Cannot insert a value for auto-increment primary key (' . OrderTableMap::ID . ')'); + } + + // check the columns in natural order for more readable SQL queries + if ($this->isColumnModified(OrderTableMap::ID)) { + $modifiedColumns[':p' . $index++] = 'ID'; + } + if ($this->isColumnModified(OrderTableMap::REF)) { + $modifiedColumns[':p' . $index++] = 'REF'; + } + if ($this->isColumnModified(OrderTableMap::CUSTOMER_ID)) { + $modifiedColumns[':p' . $index++] = 'CUSTOMER_ID'; + } + if ($this->isColumnModified(OrderTableMap::INVOICE_ORDER_ADDRESS_ID)) { + $modifiedColumns[':p' . $index++] = 'INVOICE_ORDER_ADDRESS_ID'; + } + if ($this->isColumnModified(OrderTableMap::DELIVERY_ORDER_ADDRESS_ID)) { + $modifiedColumns[':p' . $index++] = 'DELIVERY_ORDER_ADDRESS_ID'; + } + if ($this->isColumnModified(OrderTableMap::INVOICE_DATE)) { + $modifiedColumns[':p' . $index++] = 'INVOICE_DATE'; + } + if ($this->isColumnModified(OrderTableMap::CURRENCY_ID)) { + $modifiedColumns[':p' . $index++] = 'CURRENCY_ID'; + } + if ($this->isColumnModified(OrderTableMap::CURRENCY_RATE)) { + $modifiedColumns[':p' . $index++] = 'CURRENCY_RATE'; + } + if ($this->isColumnModified(OrderTableMap::TRANSACTION_REF)) { + $modifiedColumns[':p' . $index++] = 'TRANSACTION_REF'; + } + if ($this->isColumnModified(OrderTableMap::DELIVERY_REF)) { + $modifiedColumns[':p' . $index++] = 'DELIVERY_REF'; + } + if ($this->isColumnModified(OrderTableMap::INVOICE_REF)) { + $modifiedColumns[':p' . $index++] = 'INVOICE_REF'; + } + if ($this->isColumnModified(OrderTableMap::POSTAGE)) { + $modifiedColumns[':p' . $index++] = 'POSTAGE'; + } + if ($this->isColumnModified(OrderTableMap::PAYMENT_MODULE_ID)) { + $modifiedColumns[':p' . $index++] = 'PAYMENT_MODULE_ID'; + } + if ($this->isColumnModified(OrderTableMap::DELIVERY_MODULE_ID)) { + $modifiedColumns[':p' . $index++] = 'DELIVERY_MODULE_ID'; + } + if ($this->isColumnModified(OrderTableMap::STATUS_ID)) { + $modifiedColumns[':p' . $index++] = 'STATUS_ID'; + } + if ($this->isColumnModified(OrderTableMap::LANG_ID)) { + $modifiedColumns[':p' . $index++] = 'LANG_ID'; + } + if ($this->isColumnModified(OrderTableMap::CREATED_AT)) { + $modifiedColumns[':p' . $index++] = 'CREATED_AT'; + } + if ($this->isColumnModified(OrderTableMap::UPDATED_AT)) { + $modifiedColumns[':p' . $index++] = 'UPDATED_AT'; + } + + $db = Propel::getServiceContainer()->getAdapter(OrderTableMap::DATABASE_NAME); + + if ($db->useQuoteIdentifier()) { + $tableName = $db->quoteIdentifierTable(OrderTableMap::TABLE_NAME); + } else { + $tableName = OrderTableMap::TABLE_NAME; + } + + $sql = sprintf( + 'INSERT INTO %s (%s) VALUES (%s)', + $tableName, + implode(', ', $modifiedColumns), + implode(', ', array_keys($modifiedColumns)) + ); + + try { + $stmt = $con->prepare($sql); + foreach ($modifiedColumns as $identifier => $columnName) { + switch ($columnName) { + case 'ID': + $stmt->bindValue($identifier, $this->id, PDO::PARAM_INT); + break; + case 'REF': + $stmt->bindValue($identifier, $this->ref, PDO::PARAM_STR); + break; + case 'CUSTOMER_ID': + $stmt->bindValue($identifier, $this->customer_id, PDO::PARAM_INT); + break; + case 'INVOICE_ORDER_ADDRESS_ID': + $stmt->bindValue($identifier, $this->invoice_order_address_id, PDO::PARAM_INT); + break; + case 'DELIVERY_ORDER_ADDRESS_ID': + $stmt->bindValue($identifier, $this->delivery_order_address_id, PDO::PARAM_INT); + break; + case 'INVOICE_DATE': + $stmt->bindValue($identifier, $this->invoice_date ? $this->invoice_date->format("Y-m-d H:i:s") : null, PDO::PARAM_STR); + break; + case 'CURRENCY_ID': + $stmt->bindValue($identifier, $this->currency_id, PDO::PARAM_INT); + break; + case 'CURRENCY_RATE': + $stmt->bindValue($identifier, $this->currency_rate, PDO::PARAM_STR); + break; + case 'TRANSACTION_REF': + $stmt->bindValue($identifier, $this->transaction_ref, PDO::PARAM_STR); + break; + case 'DELIVERY_REF': + $stmt->bindValue($identifier, $this->delivery_ref, PDO::PARAM_STR); + break; + case 'INVOICE_REF': + $stmt->bindValue($identifier, $this->invoice_ref, PDO::PARAM_STR); + break; + case 'POSTAGE': + $stmt->bindValue($identifier, $this->postage, PDO::PARAM_STR); + break; + case 'PAYMENT_MODULE_ID': + $stmt->bindValue($identifier, $this->payment_module_id, PDO::PARAM_INT); + break; + case 'DELIVERY_MODULE_ID': + $stmt->bindValue($identifier, $this->delivery_module_id, PDO::PARAM_INT); + break; + case 'STATUS_ID': + $stmt->bindValue($identifier, $this->status_id, PDO::PARAM_INT); + break; + case 'LANG_ID': + $stmt->bindValue($identifier, $this->lang_id, PDO::PARAM_INT); + break; + case 'CREATED_AT': + $stmt->bindValue($identifier, $this->created_at ? $this->created_at->format("Y-m-d H:i:s") : null, PDO::PARAM_STR); + break; + case 'UPDATED_AT': + $stmt->bindValue($identifier, $this->updated_at ? $this->updated_at->format("Y-m-d H:i:s") : null, PDO::PARAM_STR); + break; + } + } + $stmt->execute(); + } catch (Exception $e) { + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException(sprintf('Unable to execute INSERT statement [%s]', $sql), 0, $e); + } + + try { + $pk = $con->lastInsertId(); + } catch (Exception $e) { + throw new PropelException('Unable to get autoincrement id.', 0, $e); + } + $this->setId($pk); + + $this->setNew(false); } } diff --git a/core/lib/Thelia/Model/OrderProduct.php b/core/lib/Thelia/Model/OrderProduct.php old mode 100755 new mode 100644 index 2c0e189aa..235eaf259 --- a/core/lib/Thelia/Model/OrderProduct.php +++ b/core/lib/Thelia/Model/OrderProduct.php @@ -2,8 +2,30 @@ namespace Thelia\Model; +use Propel\Runtime\Connection\ConnectionInterface; +use Thelia\Core\Event\OrderEvent; +use Thelia\Core\Event\TheliaEvents; use Thelia\Model\Base\OrderProduct as BaseOrderProduct; -class OrderProduct extends BaseOrderProduct { +class OrderProduct extends BaseOrderProduct +{ + use \Thelia\Model\Tools\ModelEventDispatcherTrait; + /** + * {@inheritDoc} + */ + public function preInsert(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::ORDER_PRODUCT_BEFORE_CREATE, new OrderEvent($this->getOrder())); + + return true; + } + + /** + * {@inheritDoc} + */ + public function postInsert(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::ORDER_PRODUCT_AFTER_CREATE, new OrderEvent($this->getOrder())); + } } diff --git a/core/lib/Thelia/Model/OrderProductAttributeCombination.php b/core/lib/Thelia/Model/OrderProductAttributeCombination.php new file mode 100644 index 000000000..1f9cee13d --- /dev/null +++ b/core/lib/Thelia/Model/OrderProductAttributeCombination.php @@ -0,0 +1,10 @@ +prepare($sql); + $stmt->bindValue(':p0', $key, PDO::PARAM_INT); + $stmt->execute(); + } catch (\Exception $e) { + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException(sprintf('Unable to execute SELECT statement [%s]', $sql), 0, $e); + } + $obj = null; + if ($row = $stmt->fetch(\PDO::FETCH_NUM)) { + $obj = new Order(); + $obj->hydrate($row); + OrderTableMap::addInstanceToPool($obj, (string) $key); + } + $stmt->closeCursor(); + return $obj; + } } // OrderQuery diff --git a/core/lib/Thelia/Model/OrderStatus.php b/core/lib/Thelia/Model/OrderStatus.php index 2927019d0..f78e9c79d 100755 --- a/core/lib/Thelia/Model/OrderStatus.php +++ b/core/lib/Thelia/Model/OrderStatus.php @@ -4,6 +4,11 @@ namespace Thelia\Model; use Thelia\Model\Base\OrderStatus as BaseOrderStatus; -class OrderStatus extends BaseOrderStatus { - +class OrderStatus extends BaseOrderStatus +{ + const CODE_NOT_PAID = "not_paid"; + const CODE_PAID = "paid"; + const CODE_PROCESSED = "processed"; + const CODE_SENT = "sent"; + const CODE_CANCELED = "canceled"; } diff --git a/core/lib/Thelia/Model/Product.php b/core/lib/Thelia/Model/Product.php index 541668ddb..2348a9c0d 100755 --- a/core/lib/Thelia/Model/Product.php +++ b/core/lib/Thelia/Model/Product.php @@ -10,6 +10,8 @@ use Propel\Runtime\Connection\ConnectionInterface; use Thelia\Core\Event\TheliaEvents; use Thelia\Core\Event\ProductEvent; use Propel\Runtime\ActiveQuery\Criteria; +use Propel\Runtime\Propel; +use Thelia\Model\Map\ProductTableMap; class Product extends BaseProduct { @@ -22,7 +24,7 @@ class Product extends BaseProduct /** * {@inheritDoc} */ - protected function getRewritenUrlViewName() { + protected function getRewrittenUrlViewName() { return 'product'; } @@ -41,11 +43,12 @@ class Product extends BaseProduct public function getTaxedPrice(Country $country) { $taxCalculator = new Calculator(); - return round($taxCalculator->load($this, $country)->getTaxedPrice($this->getRealLowestPrice()), 2); + + return $taxCalculator->load($this, $country)->getTaxedPrice($this->getRealLowestPrice()); } /** - * @return the current default category for this product + * @return the current default category ID for this product */ public function getDefaultCategoryId() { @@ -84,6 +87,102 @@ class Product extends BaseProduct return $this; } + public function updateDefaultCategory($defaultCategoryId) { + + // Allow uncategorized products (NULL instead of 0, to bypass delete cascade constraint) + if ($defaultCategoryId <= 0) $defaultCategoryId = NULL; + + // Update the default category + $productCategory = ProductCategoryQuery::create() + ->filterByProductId($this->getId()) + ->filterByDefaultCategory(true) + ->findOne() + ; + + if ($productCategory == null || $productCategory->getCategoryId() != $defaultCategoryId) { + exit; + // Delete the old default category + if ($productCategory !== null) $productCategory->delete(); + + // Add the new default category + $productCategory = new ProductCategory(); + + $productCategory + ->setProduct($this) + ->setCategoryId($defaultCategoryId) + ->setDefaultCategory(true) + ->save() + ; + } + } + + /** + * Create a new product, along with the default category ID + * + * @param int $defaultCategoryId the default category ID of this product + * @param float $basePrice the product base price + * @param int $priceCurrencyId the price currency Id + * @param int $taxRuleId the product tax rule ID + * @param float $baseWeight base weight in Kg + */ + + public function create($defaultCategoryId, $basePrice, $priceCurrencyId, $taxRuleId, $baseWeight) { + + $con = Propel::getWriteConnection(ProductTableMap::DATABASE_NAME); + + $con->beginTransaction(); + + $this->dispatchEvent(TheliaEvents::BEFORE_CREATEPRODUCT, new ProductEvent($this)); + + try { + // Create the product + $this->save($con); + + // Add the default category + $this->updateDefaultCategory($defaultCategoryId); + + // Set the position + $this->setPosition($this->getNextPosition())->save($con); + + $this->setTaxRuleId($taxRuleId); + + // Create an empty product sale element + $sale_elements = new ProductSaleElements(); + + $sale_elements + ->setProduct($this) + ->setRef($this->getRef()) + ->setPromo(0) + ->setNewness(0) + ->setWeight($baseWeight) + ->setIsDefault(true) + ->save($con) + ; + + // Create an empty product price in the default currency + $product_price = new ProductPrice(); + + $product_price + ->setProductSaleElements($sale_elements) + ->setPromoPrice($basePrice) + ->setPrice($basePrice) + ->setCurrencyId($priceCurrencyId) + ->save($con) + ; + + // Store all the stuff ! + $con->commit(); + + $this->dispatchEvent(TheliaEvents::AFTER_CREATEPRODUCT, new ProductEvent($this)); + } + catch(\Exception $ex) { + + $con->rollback(); + + throw $ex; + } + } + /** * Calculate next position relative to our default category */ @@ -100,31 +199,7 @@ class Product extends BaseProduct if ($produits != null) $query->filterById($produits, Criteria::IN); } - /** - * {@inheritDoc} - */ - public function preInsert(ConnectionInterface $con = null) - { - $this->setPosition($this->getNextPosition()); - $this->generateRewritenUrl($this->getLocale()); - - $this->dispatchEvent(TheliaEvents::BEFORE_CREATEPRODUCT, new ProductEvent($this)); - - return true; - } - - /** - * {@inheritDoc} - */ - public function postInsert(ConnectionInterface $con = null) - { - $this->dispatchEvent(TheliaEvents::AFTER_CREATEPRODUCT, new ProductEvent($this)); - } - - /** - * {@inheritDoc} - */ public function preUpdate(ConnectionInterface $con = null) { $this->dispatchEvent(TheliaEvents::BEFORE_UPDATEPRODUCT, new ProductEvent($this)); @@ -155,7 +230,12 @@ class Product extends BaseProduct */ public function postDelete(ConnectionInterface $con = null) { + RewritingUrlQuery::create() + ->filterByView($this->getRewrittenUrlViewName()) + ->filterByViewId($this->getId()) + ->update(array( + "View" => ConfigQuery::getPassedUrlView() + )); $this->dispatchEvent(TheliaEvents::AFTER_DELETEPRODUCT, new ProductEvent($this)); } - } diff --git a/core/lib/Thelia/Model/ProductAssociatedContent.php b/core/lib/Thelia/Model/ProductAssociatedContent.php index 9b007baf1..843d76ba1 100644 --- a/core/lib/Thelia/Model/ProductAssociatedContent.php +++ b/core/lib/Thelia/Model/ProductAssociatedContent.php @@ -3,7 +3,76 @@ namespace Thelia\Model; use Thelia\Model\Base\ProductAssociatedContent as BaseProductAssociatedContent; +use Propel\Runtime\Connection\ConnectionInterface; +use Thelia\Core\Event\ProductAssociatedContentEvent; +use Thelia\Core\Event\TheliaEvents; class ProductAssociatedContent extends BaseProductAssociatedContent { + use \Thelia\Model\Tools\ModelEventDispatcherTrait; + + use \Thelia\Model\Tools\PositionManagementTrait; + + /** + * Calculate next position relative to our product + */ + protected function addCriteriaToPositionQuery($query) { + $query->filterByProductId($this->getProductId()); + } + + /** + * {@inheritDoc} + */ + public function preInsert(ConnectionInterface $con = null) + { + $this->setPosition($this->getNextPosition()); + + $this->dispatchEvent(TheliaEvents::BEFORE_CREATEPRODUCT_ASSOCIATED_CONTENT, new ProductAssociatedContentEvent($this)); + + return true; + } + + /** + * {@inheritDoc} + */ + public function postInsert(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_CREATEPRODUCT_ASSOCIATED_CONTENT, new ProductAssociatedContentEvent($this)); + } + + /** + * {@inheritDoc} + */ + public function preUpdate(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::BEFORE_UPDATEPRODUCT_ASSOCIATED_CONTENT, new ProductAssociatedContentEvent($this)); + + return true; + } + + /** + * {@inheritDoc} + */ + public function postUpdate(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_UPDATEPRODUCT_ASSOCIATED_CONTENT, new ProductAssociatedContentEvent($this)); + } + + /** + * {@inheritDoc} + */ + public function preDelete(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::BEFORE_DELETEPRODUCT_ASSOCIATED_CONTENT, new ProductAssociatedContentEvent($this)); + + return true; + } + + /** + * {@inheritDoc} + */ + public function postDelete(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_DELETEPRODUCT_ASSOCIATED_CONTENT, new ProductAssociatedContentEvent($this)); + } } diff --git a/core/lib/Thelia/Model/ProductDocument.php b/core/lib/Thelia/Model/ProductDocument.php index 53515ff3c..b0f8032da 100755 --- a/core/lib/Thelia/Model/ProductDocument.php +++ b/core/lib/Thelia/Model/ProductDocument.php @@ -26,4 +26,28 @@ class ProductDocument extends BaseProductDocument return true; } + /** + * Set Document parent id + * + * @param int $parentId parent id + * + * @return $this + */ + public function setParentId($parentId) + { + $this->setProductId($parentId); + + return $this; + } + + /** + * Get Document parent id + * + * @return int parent id + */ + public function getParentId() + { + return $this->getProductId(); + } + } diff --git a/core/lib/Thelia/Model/ProductI18n.php b/core/lib/Thelia/Model/ProductI18n.php index 7507bceb1..6ec3ac4a3 100755 --- a/core/lib/Thelia/Model/ProductI18n.php +++ b/core/lib/Thelia/Model/ProductI18n.php @@ -2,8 +2,14 @@ namespace Thelia\Model; +use Propel\Runtime\Connection\ConnectionInterface; use Thelia\Model\Base\ProductI18n as BaseProductI18n; class ProductI18n extends BaseProductI18n { + public function postInsert(ConnectionInterface $con = null) + { + $product = $this->getProduct(); + $product->generateRewrittenUrl($this->getLocale()); + } } diff --git a/core/lib/Thelia/Model/ProductImage.php b/core/lib/Thelia/Model/ProductImage.php index 4bf0c40a6..6cc3ddd8c 100755 --- a/core/lib/Thelia/Model/ProductImage.php +++ b/core/lib/Thelia/Model/ProductImage.php @@ -25,4 +25,28 @@ class ProductImage extends BaseProductImage return true; } + + /** + * Set Image parent id + * + * @param int $parentId parent id + * + * @return $this + */ + public function setParentId($parentId) + { + $this->setProductId($parentId); + + return $this; + } + + /** + * Get Image parent id + * + * @return int parent id + */ + public function getParentId() + { + return $this->getProductId(); + } } diff --git a/core/lib/Thelia/Model/Rewriting.php b/core/lib/Thelia/Model/Rewriting.php deleted file mode 100644 index 8d6f75fab..000000000 --- a/core/lib/Thelia/Model/Rewriting.php +++ /dev/null @@ -1,9 +0,0 @@ -getRedirected()) { + //check if rewriting url alredy exists and put redirect to the new one + RewritingUrlQuery::create() + ->filterByView($this->getView()) + ->filterByViewId($this->getViewId()) + ->filterByViewLocale($this->getViewLocale()) + ->filterByRedirected($this->getId(), Criteria::NOT_IN) + ->update(array( + "Redirected" => $this->getId() + )); + } + } } diff --git a/core/lib/Thelia/Model/TaxRule.php b/core/lib/Thelia/Model/TaxRule.php index 36f80a044..024fd8923 100755 --- a/core/lib/Thelia/Model/TaxRule.php +++ b/core/lib/Thelia/Model/TaxRule.php @@ -3,7 +3,25 @@ namespace Thelia\Model; use Thelia\Model\Base\TaxRule as BaseTaxRule; +use Thelia\TaxEngine\Calculator; +use Thelia\TaxEngine\OrderProductTaxCollection; -class TaxRule extends BaseTaxRule { +class TaxRule extends BaseTaxRule +{ + /** + * @param Country $country + * @param $untaxedAmount + * @param null $askedLocale + * + * @return OrderProductTaxCollection + */ + public function getTaxDetail(Country $country, $untaxedAmount, $askedLocale = null) + { + $taxCalculator = new Calculator(); + $taxCollection = new OrderProductTaxCollection(); + $taxCalculator->loadTaxRule($this, $country)->getTaxedPrice($untaxedAmount, $taxCollection, $askedLocale); + + return $taxCollection; + } } diff --git a/core/lib/Thelia/Model/TaxRuleQuery.php b/core/lib/Thelia/Model/TaxRuleQuery.php index d5ce47546..572500003 100755 --- a/core/lib/Thelia/Model/TaxRuleQuery.php +++ b/core/lib/Thelia/Model/TaxRuleQuery.php @@ -21,13 +21,19 @@ class TaxRuleQuery extends BaseTaxRuleQuery { const ALIAS_FOR_TAX_RULE_COUNTRY_POSITION = 'taxRuleCountryPosition'; - public function getTaxCalculatorCollection(Product $product, Country $country) + /** + * @param TaxRule $taxRule + * @param Country $country + * + * @return array|mixed|\Propel\Runtime\Collection\ObjectCollection + */ + public function getTaxCalculatorCollection(TaxRule $taxRule, Country $country) { $search = TaxQuery::create() ->filterByTaxRuleCountry( TaxRuleCountryQuery::create() ->filterByCountry($country, Criteria::EQUAL) - ->filterByTaxRuleId($product->getTaxRuleId()) + ->filterByTaxRuleId($taxRule->getId()) ->orderByPosition() ->find() ) diff --git a/core/lib/Thelia/Model/Tools/PositionManagementTrait.php b/core/lib/Thelia/Model/Tools/PositionManagementTrait.php index 70da830ac..642d07402 100644 --- a/core/lib/Thelia/Model/Tools/PositionManagementTrait.php +++ b/core/lib/Thelia/Model/Tools/PositionManagementTrait.php @@ -126,7 +126,8 @@ trait PositionManagementTrait { $result->setDispatcher($this->getDispatcher())->setPosition($my_position)->save(); $cnx->commit(); - } catch (Exception $e) { + } + catch (Exception $e) { $cnx->rollback(); } } @@ -179,7 +180,10 @@ trait PositionManagementTrait { try { foreach ($results as $result) { - $result->setDispatcher($this->getDispatcher())->setPosition($result->getPosition() + $delta)->save($cnx); + + $objNewPosition = $result->getPosition() + $delta; + + $result->setDispatcher($this->getDispatcher())->setPosition($objNewPosition)->save($cnx); } $this @@ -188,7 +192,8 @@ trait PositionManagementTrait { ; $cnx->commit(); - } catch (Exception $e) { + } + catch (Exception $e) { $cnx->rollback(); } } diff --git a/core/lib/Thelia/Model/Tools/UrlRewritingTrait.php b/core/lib/Thelia/Model/Tools/UrlRewritingTrait.php index 6ab24fbc4..0a8af40c8 100644 --- a/core/lib/Thelia/Model/Tools/UrlRewritingTrait.php +++ b/core/lib/Thelia/Model/Tools/UrlRewritingTrait.php @@ -23,6 +23,11 @@ namespace Thelia\Model\Tools; +use Thelia\Core\Event\GenerateRewrittenUrlEvent; +use Thelia\Core\Event\TheliaEvents; +use Thelia\Exception\UrlRewritingException; +use Thelia\Model\RewritingUrlQuery; +use Thelia\Model\RewritingUrl; use Thelia\Tools\URL; /** * A trait for managing Rewriten URLs from model classes @@ -32,16 +37,19 @@ trait UrlRewritingTrait { /** * @returns string the view name of the rewriten object (e.g., 'category', 'product') */ - protected abstract function getRewritenUrlViewName(); + protected abstract function getRewrittenUrlViewName(); /** * Get the object URL for the given locale, rewriten if rewriting is enabled. * * @param string $locale a valid locale (e.g. en_US) */ - public function getUrl($locale) + public function getUrl($locale = null) { - return URL::getInstance()->retrieve($this->getRewritenUrlViewName(), $this->getId(), $locale)->toString(); + if(null === $locale) { + $locale = $this->getLocale(); + } + return URL::getInstance()->retrieve($this->getRewrittenUrlViewName(), $this->getId(), $locale)->toString(); } /** @@ -49,27 +57,93 @@ trait UrlRewritingTrait { * * @param string $locale a valid locale (e.g. en_US) */ - public function generateRewritenUrl($locale) + public function generateRewrittenUrl($locale) { - URL::getInstance()->generateRewritenUrl($this->getRewritenUrlViewName(), $this->getId(), $locale, $this->getTitle()); + if ($this->isNew()) { + throw new \RuntimeException(sprintf('Object %s must be saved before generating url', $this->getRewrittenUrlViewName())); + } + // Borrowed from http://stackoverflow.com/questions/2668854/sanitizing-strings-to-make-them-url-and-filename-safe + + $this->setLocale($locale); + + $generateEvent = new GenerateRewrittenUrlEvent($this, $locale); + + $this->dispatchEvent(TheliaEvents::GENERATE_REWRITTENURL, $generateEvent); + + + if($generateEvent->isRewritten()) + { + return $generateEvent->getUrl(); + } + + $title = $this->getTitle(); + + if(null == $title) { + throw new \RuntimeException('Impossible to create an url if title is null'); + } + // Replace all weird characters with dashes + $string = preg_replace('/[^\w\-~_\.]+/u', '-', $title); + + // Only allow one dash separator at a time (and make string lowercase) + $cleanString = mb_strtolower(preg_replace('/--+/u', '-', $string), 'UTF-8'); + + $urlFilePart = rtrim($cleanString, '.-~_') . ".html"; + + // TODO : + // check if URL url already exists, and add a numeric suffix, or the like + try{ + $i=0; + while(URL::getInstance()->resolve($urlFilePart)) { + $i++; + $urlFilePart = sprintf("%s-%d.html",$cleanString, $i); + } + } catch (UrlRewritingException $e) { + $rewritingUrl = new RewritingUrl(); + $rewritingUrl->setUrl($urlFilePart) + ->setView($this->getRewrittenUrlViewName()) + ->setViewId($this->getId()) + ->setViewLocale($locale) + ->save() + ; + } + + return $urlFilePart; + } /** * return the rewriten URL for the given locale * * @param string $locale a valid locale (e.g. en_US) + * @return null */ - public function getRewritenUrl($locale) + public function getRewrittenUrl($locale) { - return "fake url - TODO"; + $rewritingUrl = RewritingUrlQuery::create() + ->filterByViewLocale($locale) + ->filterByView($this->getRewrittenUrlViewName()) + ->filterByViewId($this->getId()) + ->filterByRedirected(null) + ->findOne() + ; + + if($rewritingUrl) { + $url = $rewritingUrl->getUrl(); + } else { + $url = null; + } + + return $url; } /** * Set the rewriten URL for the given locale * * @param string $locale a valid locale (e.g. en_US) + * @param $url the wanted url + * @return $this */ - public function setRewritenUrl($locale, $url) + public function setRewrittenUrl($locale, $url) { // TODO - code me ! diff --git a/core/lib/Thelia/Module/BaseModule.php b/core/lib/Thelia/Module/BaseModule.php index a13403482..8efc76e6e 100755 --- a/core/lib/Thelia/Module/BaseModule.php +++ b/core/lib/Thelia/Module/BaseModule.php @@ -25,6 +25,14 @@ namespace Thelia\Module; use Symfony\Component\DependencyInjection\ContainerAware; +use Thelia\Model\ModuleI18nQuery; +use Thelia\Model\Map\ModuleImageTableMap; +use Thelia\Model\ModuleI18n; +use Thelia\Tools\Image; +use Thelia\Exception\ModuleException; +use Thelia\Model\Module; +use Thelia\Model\ModuleImage; +use Thelia\Model\ModuleQuery; abstract class BaseModule extends ContainerAware { @@ -32,14 +40,28 @@ abstract class BaseModule extends ContainerAware const DELIVERY_MODULE_TYPE = 2; const PAYMENT_MODULE_TYPE = 3; + const IS_ACTIVATED = 1; + const IS_NOT_ACTIVATED = 0; + public function __construct() { } - protected function activate() + public function activate() { - + $moduleModel = $this->getModuleModel(); + if($moduleModel->getActivate() == self::IS_NOT_ACTIVATED) { + $moduleModel->setActivate(self::IS_ACTIVATED); + $moduleModel->save(); + try { + $this->afterActivation(); + } catch(\Exception $e) { + $moduleModel->setActivate(self::IS_NOT_ACTIVATED); + $moduleModel->save(); + throw $e; + } + } } public function hasContainer() @@ -56,7 +78,109 @@ abstract class BaseModule extends ContainerAware return $this->container; } + public function setTitle(Module $module, $titles) + { + if(is_array($titles)) { + foreach($titles as $locale => $title) { + $moduleI18n = ModuleI18nQuery::create()->filterById($module->getId())->filterByLocale($locale)->findOne(); + if(null === $moduleI18n) { + $moduleI18n = new ModuleI18n(); + $moduleI18n + ->setId($module->getId()) + ->setLocale($locale) + ->setTitle($title) + ; + $moduleI18n->save(); + } else { + $moduleI18n->setTitle($title); + $moduleI18n->save(); + } + } + } + } + + public function deployImageFolder(Module $module, $folderPath) + { + try { + $directoryBrowser = new \DirectoryIterator($folderPath); + } catch(\UnexpectedValueException $e) { + throw $e; + } + + $con = \Propel\Runtime\Propel::getConnection( + ModuleImageTableMap::DATABASE_NAME + ); + + /* browse the directory */ + $imagePosition = 1; + foreach($directoryBrowser as $directoryContent) { + /* is it a file ? */ + if ($directoryContent->isFile()) { + + $fileName = $directoryContent->getFilename(); + $filePath = $directoryContent->getPathName(); + + /* is it a picture ? */ + if( Image::isImage($filePath) ) { + + $con->beginTransaction(); + + $image = new ModuleImage(); + $image->setModuleId($module->getId()); + $image->setPosition($imagePosition); + $image->save($con); + + $imageDirectory = sprintf("%s/../../../../local/media/images/module", __DIR__); + $imageFileName = sprintf("%s-%d-%s", $module->getCode(), $image->getId(), $fileName); + + $increment = 0; + while(file_exists($imageDirectory . '/' . $imageFileName)) { + $imageFileName = sprintf("%s-%d-%d-%s", $module->getCode(), $image->getId(), $increment, $fileName); + $increment++; + } + + $imagePath = sprintf('%s/%s', $imageDirectory, $imageFileName); + + if (! is_dir($imageDirectory)) { + if(! @mkdir($imageDirectory, 0777, true)) { + $con->rollBack(); + throw new ModuleException(sprintf("Cannot create directory : %s", $imageDirectory), ModuleException::CODE_NOT_FOUND); + } + } + + if(! @copy($filePath, $imagePath)) { + $con->rollBack(); + throw new ModuleException(sprintf("Cannot copy file : %s to : %s", $filePath, $imagePath), ModuleException::CODE_NOT_FOUND); + } + + $image->setFile($imageFileName); + $image->save($con); + + $con->commit(); + $imagePosition++; + } + } + } + } + + /** + * @return Module + * @throws \Thelia\Exception\ModuleException + */ + public function getModuleModel() + { + $moduleModel = ModuleQuery::create()->findOneByCode($this->getCode()); + + if(null === $moduleModel) { + throw new ModuleException(sprintf("Module Code `%s` not found", $this->getCode()), ModuleException::CODE_NOT_FOUND); + } + + return $moduleModel; + } + + abstract public function getCode(); abstract public function install(); + abstract public function afterActivation(); abstract public function destroy(); } diff --git a/core/lib/Thelia/Module/DeliveryModuleInterface.php b/core/lib/Thelia/Module/DeliveryModuleInterface.php index 72f8769bc..17b000d4f 100644 --- a/core/lib/Thelia/Module/DeliveryModuleInterface.php +++ b/core/lib/Thelia/Module/DeliveryModuleInterface.php @@ -34,5 +34,5 @@ interface DeliveryModuleInterface extends BaseModuleInterface * * @return mixed */ - public function calculate(Country $country); + public function getPostage(Country $country); } diff --git a/core/lib/Thelia/Module/PaymentModuleInterface.php b/core/lib/Thelia/Module/PaymentModuleInterface.php new file mode 100644 index 000000000..d864ae50a --- /dev/null +++ b/core/lib/Thelia/Module/PaymentModuleInterface.php @@ -0,0 +1,34 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Module; + +use Thelia\Model\Country; + +interface PaymentModuleInterface extends BaseModuleInterface +{ + /** + * @return mixed + */ + public function pay(); +} diff --git a/core/lib/Thelia/TaxEngine/Calculator.php b/core/lib/Thelia/TaxEngine/Calculator.php index b5a2f995e..8039dec39 100755 --- a/core/lib/Thelia/TaxEngine/Calculator.php +++ b/core/lib/Thelia/TaxEngine/Calculator.php @@ -24,8 +24,11 @@ namespace Thelia\TaxEngine; use Thelia\Exception\TaxEngineException; use Thelia\Model\Country; +use Thelia\Model\OrderProductTax; use Thelia\Model\Product; +use Thelia\Model\TaxRule; use Thelia\Model\TaxRuleQuery; +use Thelia\Tools\I18n; /** * Class Calculator @@ -68,14 +71,34 @@ class Calculator $this->product = $product; $this->country = $country; - $this->taxRulesCollection = $this->taxRuleQuery->getTaxCalculatorCollection($product, $country); + $this->taxRulesCollection = $this->taxRuleQuery->getTaxCalculatorCollection($product->getTaxRule(), $country); return $this; } - public function getTaxAmountFromUntaxedPrice($untaxedPrice) + public function loadTaxRule(TaxRule $taxRule, Country $country) { - return $this->getTaxedPrice($untaxedPrice) - $untaxedPrice; + $this->product = null; + $this->country = null; + $this->taxRulesCollection = null; + + if($taxRule->getId() === null) { + throw new TaxEngineException('TaxRule id is empty in Calculator::loadTaxRule', TaxEngineException::UNDEFINED_TAX_RULE); + } + if($country->getId() === null) { + throw new TaxEngineException('Country id is empty in Calculator::loadTaxRule', TaxEngineException::UNDEFINED_COUNTRY); + } + + $this->country = $country; + + $this->taxRulesCollection = $this->taxRuleQuery->getTaxCalculatorCollection($taxRule, $country); + + return $this; + } + + public function getTaxAmountFromUntaxedPrice($untaxedPrice, &$taxCollection = null) + { + return $this->getTaxedPrice($untaxedPrice, $taxCollection) - $untaxedPrice; } public function getTaxAmountFromTaxedPrice($taxedPrice) @@ -83,7 +106,15 @@ class Calculator return $taxedPrice - $this->getUntaxedPrice($taxedPrice); } - public function getTaxedPrice($untaxedPrice) + /** + * @param $untaxedPrice + * @param null $taxCollection returns OrderProductTaxCollection + * @param null $askedLocale + * + * @return int + * @throws \Thelia\Exception\TaxEngineException + */ + public function getTaxedPrice($untaxedPrice, &$taxCollection = null, $askedLocale = null) { if(null === $this->taxRulesCollection) { throw new TaxEngineException('Tax rules collection is empty in Calculator::getTaxAmount', TaxEngineException::UNDEFINED_TAX_RULES_COLLECTION); @@ -97,6 +128,9 @@ class Calculator $currentPosition = 1; $currentTax = 0; + if(null !== $taxCollection) { + $taxCollection = new OrderProductTaxCollection(); + } foreach($this->taxRulesCollection as $taxRule) { $position = (int)$taxRule->getTaxRuleCountryPosition(); @@ -109,7 +143,17 @@ class Calculator $currentPosition = $position; } - $currentTax += $taxType->calculate($taxedPrice); + $taxAmount = round($taxType->calculate($taxedPrice), 2); + $currentTax += $taxAmount; + + if(null !== $taxCollection) { + $taxI18n = I18n::forceI18nRetrieving($askedLocale, 'Tax', $taxRule->getId()); + $orderProductTax = new OrderProductTax(); + $orderProductTax->setTitle($taxI18n->getTitle()); + $orderProductTax->setDescription($taxI18n->getDescription()); + $orderProductTax->setAmount($taxAmount); + $taxCollection->addTax($orderProductTax); + } } $taxedPrice += $currentTax; diff --git a/core/lib/Thelia/TaxEngine/OrderProductTaxCollection.php b/core/lib/Thelia/TaxEngine/OrderProductTaxCollection.php new file mode 100755 index 000000000..5c4ac2022 --- /dev/null +++ b/core/lib/Thelia/TaxEngine/OrderProductTaxCollection.php @@ -0,0 +1,126 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\TaxEngine; + +use Thelia\Model\OrderProductTax; + +/** + * + * @author Etienne Roudeix + * + */ +class OrderProductTaxCollection implements \Iterator +{ + private $position; + protected $taxes = array(); + + public function __construct() + { + foreach (func_get_args() as $tax) { + $this->addTax($tax); + } + } + + public function isEmpty() + { + return count($this->taxes) == 0; + } + + /** + * @param OrderProductTax $tax + * + * @return OrderProductTaxCollection + */ + public function addTax(OrderProductTax $tax) + { + $this->taxes[] = $tax; + + return $this; + } + + public function getCount() + { + return count($this->taxes); + } + + /** + * (PHP 5 >= 5.0.0)
+ * Return the current element + * @link http://php.net/manual/en/iterator.current.php + * @return OrderProductTax + */ + public function current() + { + return $this->taxes[$this->position]; + } + + /** + * (PHP 5 >= 5.0.0)
+ * Move forward to next element + * @link http://php.net/manual/en/iterator.next.php + * @return void Any returned value is ignored. + */ + public function next() + { + $this->position++; + } + + /** + * (PHP 5 >= 5.0.0)
+ * Return the key of the current element + * @link http://php.net/manual/en/iterator.key.php + * @return mixed scalar on success, or null on failure. + */ + public function key() + { + return $this->position; + } + + /** + * (PHP 5 >= 5.0.0)
+ * Checks if current position is valid + * @link http://php.net/manual/en/iterator.valid.php + * @return boolean The return value will be casted to boolean and then evaluated. + * Returns true on success or false on failure. + */ + public function valid() + { + return isset($this->taxes[$this->position]); + } + + /** + * (PHP 5 >= 5.0.0)
+ * Rewind the Iterator to the first element + * @link http://php.net/manual/en/iterator.rewind.php + * @return void Any returned value is ignored. + */ + public function rewind() + { + $this->position = 0; + } + + public function getKey($key) + { + return isset($this->taxes[$key]) ? $this->taxes[$key] : null; + } +} diff --git a/core/lib/Thelia/Tests/Action/OrderTest.php b/core/lib/Thelia/Tests/Action/OrderTest.php new file mode 100644 index 000000000..3802b362f --- /dev/null +++ b/core/lib/Thelia/Tests/Action/OrderTest.php @@ -0,0 +1,353 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Tests\Action; +use Propel\Runtime\ActiveQuery\Criteria; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage; +use Thelia\Core\Event\OrderEvent; +use Thelia\Core\HttpFoundation\Request; +use Thelia\Core\HttpFoundation\Session\Session; +use Thelia\Core\Security\SecurityContext; +use Thelia\Model\AddressQuery; +use Thelia\Model\Base\OrderProductQuery; +use Thelia\Model\OrderStatus; +use Thelia\Model\ProductSaleElementsQuery; +use Thelia\Model\Cart; +use Thelia\Model\CartItem; +use Thelia\Model\CurrencyQuery; +use Thelia\Model\CustomerQuery; +use Thelia\Model\ModuleQuery; +use Thelia\Model\Order as OrderModel; +use Thelia\Model\Customer as CustomerModel; +use Thelia\Action\Order; +use Thelia\Model\ProductQuery; +use Thelia\Module\BaseModule; + +/** + * Class CustomerTest + * @package Thelia\Tests\Action + * @author Etienne Roudeix + */ +class OrderTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var ContainerBuilder $container + */ + protected $container; + + /** + * @var Order $orderAction + */ + protected $orderAction; + + /** + * @var OrderEvent $orderEvent + */ + protected $orderEvent; + + /** + * @var CustomerModel $customer + */ + protected $customer; + + /** + * @var Cart $customer + */ + protected $cart; + + /** + * @var CartItem[] + */ + protected $cartItems; + + public function setUp() + { + $container = new ContainerBuilder(); + + $session = new Session(new MockArraySessionStorage()); + $request = new Request(); + $dispatcher = $this->getMock("Symfony\Component\EventDispatcher\EventDispatcherInterface"); + + $request->setSession($session); + + $container->set("event_dispatcher", $dispatcher); + $container->set('request', $request); + $container->set('thelia.securityContext', new SecurityContext($request)); + + $this->container = $container; + + $this->orderEvent = new OrderEvent(new OrderModel()); + + $this->orderAction = new Order($this->container); + + /* load customer */ + $this->customer = $this->loadCustomer(); + if(null === $this->customer) { + return; + } + + /* fill cart */ + $this->cart = $this->fillCart(); + + } + + public function loadCustomer() + { + $customer = CustomerQuery::create()->findOne(); + if(null === $customer) { + return null; + } + + $this->container->get('thelia.securityContext')->setCustomerUser($customer); + + return $customer; + } + + public function fillCart() + { + $currency = CurrencyQuery::create()->findOne(); + + //create a fake cart in database; + $cart = new Cart(); + $cart->setToken(uniqid("createorder", true)) + ->setCustomer($this->customer) + ->setCurrency($currency) + ->save(); + + /* add 3 items */ + $productList = array(); + for($i=0; $i<3; $i++) { + $pse = ProductSaleElementsQuery::create() + ->filterByProduct( + ProductQuery::create() + ->filterByVisible(1) + ->filterById($productList, Criteria::NOT_IN) + ->find() + ) + ->filterByQuantity(5, Criteria::GREATER_EQUAL) + ->joinProductPrice('pp', Criteria::INNER_JOIN) + ->addJoinCondition('pp', 'currency_id = ?', $currency->getId(), null, \PDO::PARAM_INT) + ->withColumn('`pp`.price', 'price_PRICE') + ->withColumn('`pp`.promo_price', 'price_PROMO_PRICE') + ->findOne(); + + $productList[] = $pse->getProductId(); + + $cartItem = new CartItem(); + $cartItem + ->setCart($cart) + ->setProduct($pse->getProduct()) + ->setProductSaleElements($pse) + ->setQuantity($i) + ->setPrice($pse->getPrice()) + ->setPromoPrice($pse->getPromoPrice()) + ->setPromo($pse->getPromo()) + ->setPriceEndOfLife(time() + 60*60*24*30) + ->save(); + $this->cartItems[] = $cartItem; + } + + $this->container->get('request')->getSession()->setCart($cart->getId()); + + return $cart; + } + + public function testSetDeliveryAddress() + { + //$validAddressId = AddressQuery::create()->findOneByCustomerId($this->customer->getId()); + + $this->orderEvent->setDeliveryAddress(321); + + $this->orderAction->setDeliveryAddress($this->orderEvent); + + $this->assertEquals( + 321, + $this->orderEvent->getOrder()->chosenDeliveryAddress + ); + } + + public function testSetinvoiceAddress() + { + $this->orderEvent->setInvoiceAddress(654); + + $this->orderAction->setInvoiceAddress($this->orderEvent); + + $this->assertEquals( + 654, + $this->orderEvent->getOrder()->chosenInvoiceAddress + ); + } + + public function testSetDeliveryModule() + { + $this->orderEvent->setDeliveryModule(123); + + $this->orderAction->setDeliveryModule($this->orderEvent); + + $this->assertEquals( + 123, + $this->orderEvent->getOrder()->getDeliveryModuleId() + ); + } + + public function testSetPaymentModule() + { + $this->orderEvent->setPaymentModule(456); + + $this->orderAction->setPaymentModule($this->orderEvent); + + $this->assertEquals( + 456, + $this->orderEvent->getOrder()->getPaymentModuleId() + ); + } + + public function testCreate() + { + $validDeliveryAddress = AddressQuery::create()->findOneByCustomerId($this->customer->getId()); + $validInvoiceAddress = AddressQuery::create()->filterById($validDeliveryAddress->getId(), Criteria::NOT_EQUAL)->findOneByCustomerId($this->customer->getId()); + + $deliveryModule = ModuleQuery::create() + ->filterByType(BaseModule::DELIVERY_MODULE_TYPE) + ->filterByActivate(1) + ->findOne(); + + if(null === $deliveryModule) { + return; + } + + $paymentModule = ModuleQuery::create() + ->filterByType(BaseModule::PAYMENT_MODULE_TYPE) + ->filterByActivate(1) + ->findOne(); + + if(null === $paymentModule) { + return; + } + + $this->orderEvent->getOrder()->chosenDeliveryAddress = $validDeliveryAddress->getId(); + $this->orderEvent->getOrder()->chosenInvoiceAddress = $validInvoiceAddress->getId(); + $this->orderEvent->getOrder()->setDeliveryModuleId($deliveryModule->getId()); + $this->orderEvent->getOrder()->setPostage(20); + $this->orderEvent->getOrder()->setPaymentModuleId($paymentModule->getId()); + + /* memorize current stocks */ + $itemsStock = array(); + foreach($this->cartItems as $index => $cartItem) { + $itemsStock[$index] = $cartItem->getProductSaleElements()->getQuantity(); + } + + $this->orderAction->create($this->orderEvent); + + $placedOrder = $this->orderEvent->getPlacedOrder(); + + $this->assertNotNull($placedOrder); + $this->assertNotNull($placedOrder->getId()); + + /* check customer */ + $this->assertEquals($this->customer->getId(), $placedOrder->getCustomerId(), 'customer i does not match'); + + /* check delivery address */ + $deliveryOrderAddress = $placedOrder->getOrderAddressRelatedByDeliveryOrderAddressId(); + $this->assertEquals($validDeliveryAddress->getCustomerTitle()->getId(), $deliveryOrderAddress->getCustomerTitleId(), 'delivery address title does not match'); + $this->assertEquals($validDeliveryAddress->getCompany(), $deliveryOrderAddress->getCompany(), 'delivery address company does not match'); + $this->assertEquals($validDeliveryAddress->getFirstname(), $deliveryOrderAddress->getFirstname(), 'delivery address fistname does not match'); + $this->assertEquals($validDeliveryAddress->getLastname(), $deliveryOrderAddress->getLastname(), 'delivery address lastname does not match'); + $this->assertEquals($validDeliveryAddress->getAddress1(), $deliveryOrderAddress->getAddress1(), 'delivery address address1 does not match'); + $this->assertEquals($validDeliveryAddress->getAddress2(), $deliveryOrderAddress->getAddress2(), 'delivery address address2 does not match'); + $this->assertEquals($validDeliveryAddress->getAddress3(), $deliveryOrderAddress->getAddress3(), 'delivery address address3 does not match'); + $this->assertEquals($validDeliveryAddress->getZipcode(), $deliveryOrderAddress->getZipcode(), 'delivery address zipcode does not match'); + $this->assertEquals($validDeliveryAddress->getCity(), $deliveryOrderAddress->getCity(), 'delivery address city does not match'); + $this->assertEquals($validDeliveryAddress->getPhone(), $deliveryOrderAddress->getPhone(), 'delivery address phone does not match'); + $this->assertEquals($validDeliveryAddress->getCountryId(), $deliveryOrderAddress->getCountryId(), 'delivery address country does not match'); + + /* check invoice address */ + $invoiceOrderAddress = $placedOrder->getOrderAddressRelatedByInvoiceOrderAddressId(); + $this->assertEquals($validInvoiceAddress->getCustomerTitle()->getId(), $invoiceOrderAddress->getCustomerTitleId(), 'invoice address title does not match'); + $this->assertEquals($validInvoiceAddress->getCompany(), $invoiceOrderAddress->getCompany(), 'invoice address company does not match'); + $this->assertEquals($validInvoiceAddress->getFirstname(), $invoiceOrderAddress->getFirstname(), 'invoice address fistname does not match'); + $this->assertEquals($validInvoiceAddress->getLastname(), $invoiceOrderAddress->getLastname(), 'invoice address lastname does not match'); + $this->assertEquals($validInvoiceAddress->getAddress1(), $invoiceOrderAddress->getAddress1(), 'invoice address address1 does not match'); + $this->assertEquals($validInvoiceAddress->getAddress2(), $invoiceOrderAddress->getAddress2(), 'invoice address address2 does not match'); + $this->assertEquals($validInvoiceAddress->getAddress3(), $invoiceOrderAddress->getAddress3(), 'invoice address address3 does not match'); + $this->assertEquals($validInvoiceAddress->getZipcode(), $invoiceOrderAddress->getZipcode(), 'invoice address zipcode does not match'); + $this->assertEquals($validInvoiceAddress->getCity(), $invoiceOrderAddress->getCity(), 'invoice address city does not match'); + $this->assertEquals($validInvoiceAddress->getPhone(), $invoiceOrderAddress->getPhone(), 'invoice address phone does not match'); + $this->assertEquals($validInvoiceAddress->getCountryId(), $invoiceOrderAddress->getCountryId(), 'invoice address country does not match'); + + /* check currency */ + $this->assertEquals($this->cart->getCurrencyId(), $placedOrder->getCurrencyId(), 'currency id does not match'); + $this->assertEquals($this->cart->getCurrency()->getRate(), $placedOrder->getCurrencyRate(), 'currency rate does not match'); + + /* check delivery module */ + $this->assertEquals(20, $placedOrder->getPostage(), 'postage does not match'); + $this->assertEquals($deliveryModule->getId(), $placedOrder->getDeliveryModuleId(), 'delivery module does not match'); + + /* check payment module */ + $this->assertEquals($paymentModule->getId(), $placedOrder->getPaymentModuleId(), 'payment module does not match'); + + /* check status */ + $this->assertEquals(OrderStatus::CODE_NOT_PAID, $placedOrder->getOrderStatus()->getCode(), 'status does not match'); + + /* check lang */ + $this->assertEquals($this->container->get('request')->getSession()->getLang()->getId(), $placedOrder->getLangId(), 'lang does not match'); + + /* check ordered product */ + foreach($this->cartItems as $index => $cartItem) { + $orderProduct = OrderProductQuery::create() + ->filterByOrderId($placedOrder->getId()) + ->filterByProductRef($cartItem->getProduct()->getRef()) + ->filterByProductSaleElementsRef($cartItem->getProductSaleElements()->getRef()) + ->filterByQuantity($cartItem->getQuantity()) + ->filterByPrice($cartItem->getPrice(), Criteria::LIKE) + ->filterByPromoPrice($cartItem->getPromoPrice(), Criteria::LIKE) + ->filterByWasNew($cartItem->getProductSaleElements()->getNewness()) + ->filterByWasInPromo($cartItem->getPromo()) + ->filterByWeight($cartItem->getProductSaleElements()->getWeight()) + ->findOne(); + + $this->assertNotNull($orderProduct); + + /* check attribute combinations */ + $this->assertEquals( + $cartItem->getProductSaleElements()->getAttributeCombinations()->count(), + $orderProduct->getOrderProductAttributeCombinations()->count() + ); + + /* check stock decrease */ + $this->assertEquals( + $itemsStock[$index] - $orderProduct->getQuantity(), + $cartItem->getProductSaleElements()->getQuantity() + ); + + /* check tax */ + $orderProductTaxList = $orderProduct->getOrderProductTaxes(); + foreach($cartItem->getProduct()->getTaxRule()->getTaxDetail($validDeliveryAddress->getCountry(), $cartItem->getPromo() == 1 ? $cartItem->getPromoPrice() : $cartItem->getPrice()) as $index => $tax) { + $orderProductTax = $orderProductTaxList[$index]; + $this->assertEquals($tax->getAmount(), $orderProductTax->getAmount()); + } + } + + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Tests/Command/ModuleActivateCommandTest.php b/core/lib/Thelia/Tests/Command/ModuleActivateCommandTest.php new file mode 100755 index 000000000..1d6d08e92 --- /dev/null +++ b/core/lib/Thelia/Tests/Command/ModuleActivateCommandTest.php @@ -0,0 +1,106 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Tests\Command; + +use Symfony\Component\Console\Tester\CommandTester; +use Thelia\Command\ModuleActivateCommand; +use Thelia\Core\Application; +use Thelia\Model\ModuleQuery; +use Thelia\Module\BaseModule; + +/** + * Class ModuleActivateCommandTest + * + * @package Thelia\Tests\Command + * @author Etienne Roudeix + */ +class ModuleActivateCommandTest extends \PHPUnit_Framework_TestCase +{ + public function testModuleActivateCommand() + { + $module = ModuleQuery::create()->findOne(); + + if(null !== $module) { + $application = new Application($this->getKernel()); + + $module->setActivate(BaseModule::IS_NOT_ACTIVATED); + $module->save(); + + $moduleActivate = new ModuleActivateCommand(); + $moduleActivate->setContainer($this->getContainer()); + + $application->add($moduleActivate); + + $command = $application->find("module:activate"); + $commandTester = new CommandTester($command); + $commandTester->execute(array( + "command" => $command->getName(), + "module" => $module->getCode(), + )); + + $this->assertEquals(BaseModule::IS_ACTIVATED, ModuleQuery::create()->findPk($module->getId())->getActivate()); + } + } + + /** + * @expectedException \RuntimeException + * @expectedExceptionMessage module Letshopethismoduledoesnotexists not found + */ + public function testModuleActivateCommandUnknownModule() + { + $testedModule = ModuleQuery::create()->findOneByCode('Letshopethismoduledoesnotexists'); + + if(null == $testedModule) { + $application = new Application($this->getKernel()); + + + $moduleActivate = new ModuleActivateCommand(); + $moduleActivate->setContainer($this->getContainer()); + + $application->add($moduleActivate); + + $command = $application->find("module:activate"); + $commandTester = new CommandTester($command); + $commandTester->execute(array( + "command" => $command->getName(), + "module" => "letshopethismoduledoesnotexists", + )); + + $out = true; + } + } + + public function getKernel() + { + $kernel = $this->getMock("Symfony\Component\HttpKernel\KernelInterface"); + + return $kernel; + } + + public function getContainer() + { + $container = new \Symfony\Component\DependencyInjection\ContainerBuilder(); + + return $container; + } +} diff --git a/core/lib/Thelia/Tests/Core/Template/Element/BaseLoopTestor.php b/core/lib/Thelia/Tests/Core/Template/Element/BaseLoopTestor.php index 2b31d265a..eb271d4c1 100755 --- a/core/lib/Thelia/Tests/Core/Template/Element/BaseLoopTestor.php +++ b/core/lib/Thelia/Tests/Core/Template/Element/BaseLoopTestor.php @@ -132,7 +132,7 @@ abstract class BaseLoopTestor extends \PHPUnit_Framework_TestCase $this->assertInstanceOf('\Thelia\Core\Template\Element\LoopResult', $methodReturn); } - public function baseTestSearchById($id) + public function baseTestSearchById($id, $other_args = array()) { $this->instance->initializeArgs(array_merge( $this->getMandatoryArguments(), @@ -140,7 +140,8 @@ abstract class BaseLoopTestor extends \PHPUnit_Framework_TestCase "type" => "foo", "name" => "foo", "id" => $id, - ) + ), + $other_args )); $dummy = null; diff --git a/core/lib/Thelia/Tests/Core/Template/Loop/DocumentTest.php b/core/lib/Thelia/Tests/Core/Template/Loop/DocumentTest.php index 04e41b6f8..2b7019879 100644 --- a/core/lib/Thelia/Tests/Core/Template/Loop/DocumentTest.php +++ b/core/lib/Thelia/Tests/Core/Template/Loop/DocumentTest.php @@ -58,32 +58,27 @@ class DocumentTest extends BaseLoopTestor { $document = ProductDocumentQuery::create()->findOne(); - $this->baseTestSearchById($document->getId()); + $this->baseTestSearchById($document->getId(), array('source' => 'product')); } public function testSearchByFolderId() { $document = FolderDocumentQuery::create()->findOne(); - $this->baseTestSearchById($document->getId()); + $this->baseTestSearchById($document->getId(), array('source' => 'folder')); } public function testSearchByContentId() { $document = ContentDocumentQuery::create()->findOne(); - $this->baseTestSearchById($document->getId()); + $this->baseTestSearchById($document->getId(), array('source' => 'content')); } public function testSearchByCategoryId() { $document = CategoryDocumentQuery::create()->findOne(); - $this->baseTestSearchById($document->getId()); - } - - public function testSearchLimit() - { - $this->baseTestSearchWithLimit(1); + $this->baseTestSearchById($document->getId(), array('source' => 'category')); } } diff --git a/core/lib/Thelia/Tests/Core/Template/Loop/ImageTest.php b/core/lib/Thelia/Tests/Core/Template/Loop/ImageTest.php index 3d2517c0a..ba4bfadc5 100644 --- a/core/lib/Thelia/Tests/Core/Template/Loop/ImageTest.php +++ b/core/lib/Thelia/Tests/Core/Template/Loop/ImageTest.php @@ -58,32 +58,27 @@ class ImageTest extends BaseLoopTestor { $image = ProductImageQuery::create()->findOne(); - $this->baseTestSearchById($image->getId()); + $this->baseTestSearchById($image->getId(), array('source' => 'product')); } public function testSearchByFolderId() { $image = FolderImageQuery::create()->findOne(); - $this->baseTestSearchById($image->getId()); + $this->baseTestSearchById($image->getId(), array('source' => 'folder')); } public function testSearchByContentId() { $image = ContentImageQuery::create()->findOne(); - $this->baseTestSearchById($image->getId()); + $this->baseTestSearchById($image->getId(), array('source' => 'content')); } public function testSearchByCategoryId() { $image = CategoryImageQuery::create()->findOne(); - $this->baseTestSearchById($image->getId()); - } - - public function testSearchLimit() - { - $this->baseTestSearchWithLimit(1); + $this->baseTestSearchById($image->getId(), array('source' => 'category')); } } diff --git a/core/lib/Thelia/Tests/Core/Template/Loop/ProductTest.php b/core/lib/Thelia/Tests/Core/Template/Loop/ProductTest.php index 1b307c5b5..07e179cbd 100755 --- a/core/lib/Thelia/Tests/Core/Template/Loop/ProductTest.php +++ b/core/lib/Thelia/Tests/Core/Template/Loop/ProductTest.php @@ -27,6 +27,7 @@ use Thelia\Model\ProductQuery; use Thelia\Tests\Core\Template\Element\BaseLoopTestor; use Thelia\Core\Template\Loop\Product; +use Propel\Runtime\ActiveQuery\Criteria; /** * @@ -52,7 +53,7 @@ class ProductTest extends BaseLoopTestor public function testSearchById() { - $product = ProductQuery::create()->findOne(); + $product = ProductQuery::create()->orderById(Criteria::ASC)->findOne(); $this->baseTestSearchById($product->getId()); } diff --git a/core/lib/Thelia/Tests/Core/Template/Loop/TaxRuleTest.php b/core/lib/Thelia/Tests/Core/Template/Loop/TaxRuleTest.php new file mode 100644 index 000000000..fa24d72ee --- /dev/null +++ b/core/lib/Thelia/Tests/Core/Template/Loop/TaxRuleTest.php @@ -0,0 +1,60 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Tests\Core\Template\Loop; + +use Thelia\Tests\Core\Template\Element\BaseLoopTestor; + +use Thelia\Core\Template\Loop\TaxRule; +use Thelia\Model\TaxRuleQuery; + +/** + * + * @author Etienne Roudeix + * + */ +class TaxRuleTest extends BaseLoopTestor +{ + public function getTestedClassName() + { + return 'Thelia\Core\Template\Loop\TaxRule'; + } + + public function getTestedInstance() + { + return new TaxRule($this->container); + } + + public function getMandatoryArguments() + { + return array(); + } + + public function testSearchById() + { + $tr = TaxRuleQuery::create()->findOne(); + + $this->baseTestSearchById($tr->getId(), array('force_return' => true)); + } + +} diff --git a/core/lib/Thelia/Tests/Form/OrderDeliveryTest.php b/core/lib/Thelia/Tests/Form/OrderDeliveryTest.php new file mode 100755 index 000000000..980c17d88 --- /dev/null +++ b/core/lib/Thelia/Tests/Form/OrderDeliveryTest.php @@ -0,0 +1,32 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Tests\Form; + +class OrderDeliveryTest extends \PHPUnit_Framework_TestCase +{ + + public function testOrderDelivery() + { + + } +} diff --git a/core/lib/Thelia/Tests/Module/BaseModuleTestor.php b/core/lib/Thelia/Tests/Module/BaseModuleTestor.php new file mode 100644 index 000000000..ce70cd4ad --- /dev/null +++ b/core/lib/Thelia/Tests/Module/BaseModuleTestor.php @@ -0,0 +1,53 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Tests\Module; + + +/** + * + * @author Etienne Roudeix + * + */ +abstract class BaseModuleTestor extends \PHPUnit_Framework_TestCase +{ + protected $instance; + + abstract public function getTestedClassName(); + abstract public function getTestedInstance(); + + /*protected function getMethod($name) + { + $class = new \ReflectionClass($this->getTestedClassName()); + $method = $class->getMethod($name); + $method->setAccessible(true); + + return $method; + }*/ + + public function setUp() + { + $this->instance = $this->getTestedInstance(); + } +} + diff --git a/core/lib/Thelia/Tests/Rewriting/BaseRewritingObject.php b/core/lib/Thelia/Tests/Rewriting/BaseRewritingObject.php new file mode 100644 index 000000000..449a9162d --- /dev/null +++ b/core/lib/Thelia/Tests/Rewriting/BaseRewritingObject.php @@ -0,0 +1,108 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Tests\Rewriting; + + +/** + * Class BaseRewritingObject + * @package Thelia\Tests\Rewriting + * @author Manuel Raynaud + */ +abstract class BaseRewritingObject extends \PHPUnit_Framework_TestCase +{ + + /** + * @return mixed an instance of Product, Folder, Content or Category Model + */ + abstract function getObject(); + + /** + * @covers Thelia\Model\Tools\UrlRewritingTrait::generateRewrittenUrl + */ + public function testSimpleFrenchRewrittenUrl() + { + $object = $this->getObject(); + $object->setVisible(1) + ->setPosition(1) + ->setLocale('fr_FR') + ->setTitle('Mon super titre en français') + ->save(); + + $this->assertRegExp('/^mon-super-titre-en-français(-[0-9]+)?\.html$/', $object->getRewrittenUrl('fr_FR')); + + $rewrittenUrl = $object->generateRewrittenUrl('fr_FR'); + $this->assertNotNull($rewrittenUrl, "rewritten url can not be null"); + $this->assertRegExp('/^mon-super-titre-en-français(-[0-9]+)?\.html$/', $rewrittenUrl); + //mon-super-titre-en-français-2.html + + $object->delete(); + } + + /** + * @covers Thelia\Model\Tools\UrlRewritingTrait::generateRewrittenUrl + */ + public function testSimpleEnglishRewrittenUrl() + { + $object = $this->getObject(); + $object->setVisible(1) + ->setPosition(1) + ->setLocale('en_US') + ->setTitle('My english super Title') + ->save(); + + $this->assertRegExp('/^my-english-super-title(-[0-9]+)?\.html$/', $object->getRewrittenUrl('en_US')); + + $rewrittenUrl = $object->generateRewrittenUrl('en_US'); + $this->assertNotNull($rewrittenUrl, "rewritten url can not be null"); + $this->assertRegExp('/^my-english-super-title(-[0-9]+)?\.html$/', $rewrittenUrl); + + $object->delete(); + } + + /** + * @covers Thelia\Model\Tools\UrlRewritingTrait::generateRewrittenUrl + * @expectedException \RuntimeException + * @expectedExceptionMessage Impossible to create an url if title is null + */ + public function testRewrittenWithoutTitle() + { + $object = $this->getObject(); + $object->setVisible(1) + ->setPosition(1) + ->setLocale('en_US') + ->setDescription('My english super Description') + ->save(); + } + + /** + * @covers Thelia\Model\Tools\UrlRewritingTrait::generateRewrittenUrl + * @expectedException \RuntimeException + */ + public function testOnNotSavedObject() + { + $object = $this->getObject(); + + $object->generateRewrittenUrl('fr_FR'); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Tests/Rewriting/CategoryRewritingTest.php b/core/lib/Thelia/Tests/Rewriting/CategoryRewritingTest.php new file mode 100644 index 000000000..247fdc8a9 --- /dev/null +++ b/core/lib/Thelia/Tests/Rewriting/CategoryRewritingTest.php @@ -0,0 +1,43 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Tests\Rewriting; +use Thelia\Model\Category; + + +/** + * Class CategoryRewritingTest + * @package Thelia\Tests\Rewriting + * @author Manuel Raynaud + */ +class CategoryRewritingTest extends BaseRewritingObject +{ + + /** + * @return \Thelia\Model\Category + */ + function getObject() + { + return new Category(); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Tests/Rewriting/ContentRewritingTest.php b/core/lib/Thelia/Tests/Rewriting/ContentRewritingTest.php new file mode 100644 index 000000000..e06ff62b2 --- /dev/null +++ b/core/lib/Thelia/Tests/Rewriting/ContentRewritingTest.php @@ -0,0 +1,43 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Tests\Rewriting; +use Thelia\Model\Content; + + +/** + * Class ContentRewritingTest + * @package Thelia\Tests\Rewriting + * @author Manuel Raynaud + */ +class ContentRewritingTest extends BaseRewritingObject +{ + + /** + * @return \Thelia\Model\Content + */ + function getObject() + { + return new Content(); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Tests/Rewriting/FolderRewritingTest.php b/core/lib/Thelia/Tests/Rewriting/FolderRewritingTest.php new file mode 100644 index 000000000..db0dbc897 --- /dev/null +++ b/core/lib/Thelia/Tests/Rewriting/FolderRewritingTest.php @@ -0,0 +1,43 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Tests\Rewriting; +use Thelia\Model\Folder; + + +/** + * Class FolderRewritingTest + * @package Thelia\Tests\Rewriting + * @author Manuel Raynaud + */ +class FolderRewritingTest extends BaseRewritingObject +{ + + /** + * @return mixed an instance of Product, Folder, Content or Category Model + */ + function getObject() + { + return new Folder(); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Tests/Rewriting/ProductRewriteTest.php b/core/lib/Thelia/Tests/Rewriting/ProductRewriteTest.php new file mode 100644 index 000000000..2bff1bf5c --- /dev/null +++ b/core/lib/Thelia/Tests/Rewriting/ProductRewriteTest.php @@ -0,0 +1,44 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Tests\Rewriting; +use Thelia\Model\Product; +use Thelia\Model\ProductQuery; + + +/** + * Class ProductRewriteTest + * @package Thelia\Tests\Rewriting + * @author Manuel Raynaud + */ +class ProductRewriteTest extends BaseRewritingObject +{ + + /** + * @return mixed an instance of Product, Folder, Content or Category Model + */ + function getObject() + { + return new Product(); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Tests/TaxEngine/CalculatorTest.php b/core/lib/Thelia/Tests/TaxEngine/CalculatorTest.php index e0443c5ba..f8c6ec6c0 100755 --- a/core/lib/Thelia/Tests/TaxEngine/CalculatorTest.php +++ b/core/lib/Thelia/Tests/TaxEngine/CalculatorTest.php @@ -78,7 +78,7 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase public function testLoad() { - $productQuery = ProductQuery::create()->findOneById(1); + $productQuery = ProductQuery::create()->findOne(); $countryQuery = CountryQuery::create()->findOneById(64); $calculator = new Calculator(); @@ -86,7 +86,7 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase $taxRuleQuery = $this->getMock('\Thelia\Model\TaxRuleQuery', array('getTaxCalculatorCollection')); $taxRuleQuery->expects($this->once()) ->method('getTaxCalculatorCollection') - ->with($productQuery, $countryQuery) + ->with($productQuery->getTaxRule(), $countryQuery) ->will($this->returnValue('foo')); $rewritingUrlQuery = $this->getProperty('taxRuleQuery'); diff --git a/core/lib/Thelia/Tests/Tools/FileManagerTest.php b/core/lib/Thelia/Tests/Tools/FileManagerTest.php new file mode 100644 index 000000000..8dce5afcc --- /dev/null +++ b/core/lib/Thelia/Tests/Tools/FileManagerTest.php @@ -0,0 +1,906 @@ + + */ + +namespace Thelia\Tests\Type; + + +use Thelia\Core\Event\DocumentCreateOrUpdateEvent; +use Thelia\Core\Event\ImageCreateOrUpdateEvent; +use Thelia\Core\Translation\Translator; +use Thelia\Exception\ImageException; +use Thelia\Model\Admin; +use Thelia\Tools\FileManager; + +/** + * Class FileManagerTest + * + * @package Thelia\Tests\Type + */ +class FileManagerTest extends \PHPUnit_Framework_TestCase { + + + /** + * @covers Thelia\Tools\FileManager::copyUploadedFile + */ + public function testCopyUploadedFile() + { + $this->markTestIncomplete( + 'Mock issue' + ); + + $stubTranslator = $this->getMockBuilder('\Thelia\Core\Translation\Translator') + ->disableOriginalConstructor() + ->getMock(); + $stubTranslator->expects($this->any()) + ->method('trans') + ->will($this->returnValue('translated')); + + $stubRequest = $this->getMockBuilder('\Thelia\Core\HttpFoundation\Request') + ->disableOriginalConstructor() + ->getMock(); + + $stubSecurity = $this->getMockBuilder('\Thelia\Core\Security\SecurityContext') + ->disableOriginalConstructor() + ->getMock(); + $stubSecurity->expects($this->any()) + ->method('getAdminUser') + ->will($this->returnValue(new Admin())); + + + + // Create a map of arguments to return values. + $map = array( + array('thelia.translator', $stubTranslator), + array('request', $stubRequest), + array('thelia.securityContext', $stubSecurity) + ); + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + $stubContainer->expects($this->any()) + ->method('get') + ->will($this->returnValueMap($map)); + + $stubProductImage = $this->getMockBuilder('\Thelia\Model\ProductImage') + ->disableOriginalConstructor() + ->getMock(); + $stubProductImage->expects($this->any()) + ->method('getUploadDir') + ->will($this->returnValue(THELIA_LOCAL_DIR . 'media/images/product')); + $stubProductImage->expects($this->any()) + ->method('getId') + ->will($this->returnValue(42)); + $stubProductImage->expects($this->any()) + ->method('setFile') + ->will($this->returnValue(true)); + $stubProductImage->expects($this->any()) + ->method('save') + ->will($this->returnValue(0)); + + $stubUploadedFile = $this->getMockBuilder('\Symfony\Component\HttpFoundation\File\UploadedFile') + ->disableOriginalConstructor() + ->getMock(); + $stubUploadedFile->expects($this->any()) + ->method('getClientOriginalName') + ->will($this->returnValue('goodName')); + $stubUploadedFile->expects($this->any()) + ->method('getClientOriginalExtension') + ->will($this->returnValue('png')); + $stubUploadedFile->expects($this->any()) + ->method('move') + ->will($this->returnValue($stubUploadedFile)); + + $fileManager = new FileManager($stubContainer); + + $newUploadedFiles = array(); + + $actual = $fileManager->copyUploadedFile(24, FileManager::TYPE_PRODUCT, $stubProductImage, $stubUploadedFile, $newUploadedFiles, FileManager::FILE_TYPE_IMAGES); + + $this->assertCount(1, $actual); + } + + + /** + * @covers Thelia\Tools\FileManager::copyUploadedFile + * @expectedException \Thelia\Exception\ImageException + */ + public function testCopyUploadedFileExceptionImageException() + { + $this->markTestIncomplete( + 'Mock issue' + ); + + $stubTranslator = $this->getMockBuilder('\Thelia\Core\Translation\Translator') + ->disableOriginalConstructor() + ->getMock(); + $stubTranslator->expects($this->any()) + ->method('trans') + ->will($this->returnValue('translated')); + + $stubRequest = $this->getMockBuilder('\Thelia\Core\HttpFoundation\Request') + ->disableOriginalConstructor() + ->getMock(); + + $stubSecurity = $this->getMockBuilder('\Thelia\Core\Security\SecurityContext') + ->disableOriginalConstructor() + ->getMock(); + $stubSecurity->expects($this->any()) + ->method('getAdminUser') + ->will($this->returnValue(new Admin())); + + + + // Create a map of arguments to return values. + $map = array( + array('thelia.translator', $stubTranslator), + array('request', $stubRequest), + array('thelia.securityContext', $stubSecurity) + ); + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + $stubContainer->expects($this->any()) + ->method('get') + ->will($this->returnValueMap($map)); + + $stubProductImage = $this->getMockBuilder('\Thelia\Model\ProductImage') + ->disableOriginalConstructor() + ->getMock(); + $stubProductImage->expects($this->any()) + ->method('getUploadDir') + ->will($this->returnValue(THELIA_LOCAL_DIR . 'media/images/product')); + $stubProductImage->expects($this->any()) + ->method('getId') + ->will($this->returnValue(42)); + $stubProductImage->expects($this->any()) + ->method('setFile') + ->will($this->returnValue(true)); + $stubProductImage->expects($this->any()) + ->method('save') + ->will($this->returnValue(0)); + + $stubUploadedFile = $this->getMockBuilder('\Symfony\Component\HttpFoundation\File\UploadedFile') + ->disableOriginalConstructor() + ->getMock(); + $stubUploadedFile->expects($this->any()) + ->method('getClientOriginalName') + ->will($this->returnValue('goodName')); + $stubUploadedFile->expects($this->any()) + ->method('getClientOriginalExtension') + ->will($this->returnValue('png')); + $stubUploadedFile->expects($this->any()) + ->method('move') + ->will($this->returnValue($stubUploadedFile)); + + $fileManager = new FileManager($stubContainer); + + $newUploadedFiles = array(); + + $actual = $fileManager->copyUploadedFile(24, FileManager::TYPE_PRODUCT, $stubProductImage, $stubUploadedFile, $newUploadedFiles, FileManager::FILE_TYPE_DOCUMENTS); + + } + + /** + * @covers Thelia\Tools\FileManager::saveImage + */ + public function testSaveImageProductImage() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + + $stubProductImage = $this->getMockBuilder('\Thelia\Model\ProductImage') + ->disableOriginalConstructor() + ->getMock(); + $stubProductImage->expects($this->any()) + ->method('save') + ->will($this->returnValue(10)); + $stubProductImage->expects($this->any()) + ->method('getFile') + ->will($this->returnValue('file')); + + $fileManager = new FileManager($stubContainer); + + $event = new ImageCreateOrUpdateEvent(FileManager::TYPE_PRODUCT, 24); + + $expected = 10; + $actual = $fileManager->saveImage($event, $stubProductImage); + + $this->assertEquals($expected, $actual); + } + + /** + * @covers Thelia\Tools\FileManager::saveDocument + */ + public function testSaveDocumentProductDocument() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + + $stubProductDocument = $this->getMockBuilder('\Thelia\Model\ProductDocument') + ->disableOriginalConstructor() + ->getMock(); + $stubProductDocument->expects($this->any()) + ->method('save') + ->will($this->returnValue(10)); + $stubProductDocument->expects($this->any()) + ->method('getFile') + ->will($this->returnValue('file')); + + $fileManager = new FileManager($stubContainer); + + $event = new DocumentCreateOrUpdateEvent(FileManager::TYPE_PRODUCT, 24); + + $expected = 10; + $actual = $fileManager->saveDocument($event, $stubProductDocument); + + $this->assertEquals($expected, $actual); + } + + /** + * @covers Thelia\Tools\FileManager::saveImage + */ + public function testSaveImageCategoryImage() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + + $stubCategoryImage = $this->getMockBuilder('\Thelia\Model\CategoryImage') + ->disableOriginalConstructor() + ->getMock(); + $stubCategoryImage->expects($this->any()) + ->method('save') + ->will($this->returnValue(10)); + $stubCategoryImage->expects($this->any()) + ->method('getFile') + ->will($this->returnValue('file')); + + $fileManager = new FileManager($stubContainer); + + $event = new ImageCreateOrUpdateEvent(FileManager::TYPE_CATEGORY, 24); + + $expected = 10; + $actual = $fileManager->saveImage($event, $stubCategoryImage); + + $this->assertEquals($expected, $actual); + } + + /** + * @covers Thelia\Tools\FileManager::saveDocument + */ + public function testSaveDocumentCategoryDocument() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + + $stubCategoryDocument = $this->getMockBuilder('\Thelia\Model\CategoryDocument') + ->disableOriginalConstructor() + ->getMock(); + $stubCategoryDocument->expects($this->any()) + ->method('save') + ->will($this->returnValue(10)); + $stubCategoryDocument->expects($this->any()) + ->method('getFile') + ->will($this->returnValue('file')); + + $fileManager = new FileManager($stubContainer); + + $event = new DocumentCreateOrUpdateEvent(FileManager::TYPE_CATEGORY, 24); + + $expected = 10; + $actual = $fileManager->saveDocument($event, $stubCategoryDocument); + + $this->assertEquals($expected, $actual); + } + + /** + * @covers Thelia\Tools\FileManager::saveImage + */ + public function testSaveImageFolderImage() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + + $stubFolderImage = $this->getMockBuilder('\Thelia\Model\FolderImage') + ->disableOriginalConstructor() + ->getMock(); + $stubFolderImage->expects($this->any()) + ->method('save') + ->will($this->returnValue(10)); + $stubFolderImage->expects($this->any()) + ->method('getFile') + ->will($this->returnValue('file')); + + $fileManager = new FileManager($stubContainer); + + $event = new ImageCreateOrUpdateEvent(FileManager::TYPE_FOLDER, 24); + + $expected = 10; + $actual = $fileManager->saveImage($event, $stubFolderImage); + + $this->assertEquals($expected, $actual); + } + + /** + * @covers Thelia\Tools\FileManager::saveDocument + */ + public function testSaveDocumentFolderDocument() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + + $stubFolderDocument = $this->getMockBuilder('\Thelia\Model\FolderDocument') + ->disableOriginalConstructor() + ->getMock(); + $stubFolderDocument->expects($this->any()) + ->method('save') + ->will($this->returnValue(10)); + $stubFolderDocument->expects($this->any()) + ->method('getFile') + ->will($this->returnValue('file')); + + $fileManager = new FileManager($stubContainer); + + $event = new DocumentCreateOrUpdateEvent(FileManager::TYPE_FOLDER, 24); + + $expected = 10; + $actual = $fileManager->saveDocument($event, $stubFolderDocument); + + $this->assertEquals($expected, $actual); + } + + /** + * @covers Thelia\Tools\FileManager::saveImage + */ + public function testSaveImageContentImage() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + + $stubContentImage = $this->getMockBuilder('\Thelia\Model\ContentImage') + ->disableOriginalConstructor() + ->getMock(); + $stubContentImage->expects($this->any()) + ->method('save') + ->will($this->returnValue(10)); + $stubContentImage->expects($this->any()) + ->method('getFile') + ->will($this->returnValue('file')); + + $fileManager = new FileManager($stubContainer); + + $event = new ImageCreateOrUpdateEvent(FileManager::TYPE_CONTENT, 24); + + $expected = 10; + $actual = $fileManager->saveImage($event, $stubContentImage); + + $this->assertEquals($expected, $actual); + } + + /** + * @covers Thelia\Tools\FileManager::saveDocument + */ + public function testSaveDocumentContentDocument() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + + $stubContentDocument = $this->getMockBuilder('\Thelia\Model\ContentDocument') + ->disableOriginalConstructor() + ->getMock(); + $stubContentDocument->expects($this->any()) + ->method('save') + ->will($this->returnValue(10)); + $stubContentDocument->expects($this->any()) + ->method('getFile') + ->will($this->returnValue('file')); + + $fileManager = new FileManager($stubContainer); + + $event = new DocumentCreateOrUpdateEvent(FileManager::TYPE_CONTENT, 24); + + $expected = 10; + $actual = $fileManager->saveDocument($event, $stubContentDocument); + + $this->assertEquals($expected, $actual); + } + + /** + * @covers Thelia\Tools\FileManager::saveImage + * @expectedException \Thelia\Exception\ImageException + */ + public function testSaveImageExceptionImageException() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + $fileManager = new FileManager($stubContainer); + + $stubProductImage = $this->getMockBuilder('\Thelia\Model\ProductImage') + ->disableOriginalConstructor() + ->getMock(); + $stubProductImage->expects($this->any()) + ->method('save') + ->will($this->returnValue(10)); + $stubProductImage->expects($this->any()) + ->method('getFile') + ->will($this->returnValue('file')); + + $event = new ImageCreateOrUpdateEvent('bad', 24); + + $fileManager->saveImage($event, $stubProductImage); + } + + /** + * @covers Thelia\Tools\FileManager::saveDocument + * @expectedException \Thelia\Model\Exception\InvalidArgumentException + */ + public function testSaveDocumentExceptionDocumentException() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + $fileManager = new FileManager($stubContainer); + + $stubProductDocument = $this->getMockBuilder('\Thelia\Model\ProductDocument') + ->disableOriginalConstructor() + ->getMock(); + $stubProductDocument->expects($this->any()) + ->method('save') + ->will($this->returnValue(10)); + $stubProductDocument->expects($this->any()) + ->method('getFile') + ->will($this->returnValue('file')); + + $event = new DocumentCreateOrUpdateEvent('bad', 24); + + $fileManager->saveDocument($event, $stubProductDocument); + } + + /** + * @covers Thelia\Tools\FileManager::saveImage + * @expectedException \Thelia\Exception\ImageException + */ + public function testSaveImageExceptionImageException2() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + $fileManager = new FileManager($stubContainer); + + $stubProductImage = $this->getMockBuilder('\Thelia\Model\ProductImage') + ->disableOriginalConstructor() + ->getMock(); + $stubProductImage->expects($this->any()) + ->method('save') + ->will($this->returnValue(0)); + $stubProductImage->expects($this->any()) + ->method('getFile') + ->will($this->returnValue('file')); + + $event = new ImageCreateOrUpdateEvent(FileManager::TYPE_PRODUCT, 24); + + $fileManager->saveImage($event, $stubProductImage); + } + + /** + * @covers Thelia\Tools\FileManager::saveDocument + * @expectedException \Thelia\Model\Exception\InvalidArgumentException + */ + public function testSaveDocumentExceptionDocumentException2() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + $fileManager = new FileManager($stubContainer); + + $stubProductDocument = $this->getMockBuilder('\Thelia\Model\ProductDocument') + ->disableOriginalConstructor() + ->getMock(); + $stubProductDocument->expects($this->any()) + ->method('save') + ->will($this->returnValue(0)); + $stubProductDocument->expects($this->any()) + ->method('getFile') + ->will($this->returnValue('file')); + + $event = new DocumentCreateOrUpdateEvent(FileManager::TYPE_PRODUCT, 24); + + $fileManager->saveDocument($event, $stubProductDocument); + } + + /** + * @covers Thelia\Tools\FileManager::sanitizeFileName + */ + public function testSanitizeFileName() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + + $fileManager = new FileManager($stubContainer); + $badFileName = 'azeéràçè§^"$*+-_°)(&é<>@#ty'; + + $expected = 'azeyryZyy-_yty'; + $actual = $fileManager->sanitizeFileName($badFileName); + + $this->assertEquals($expected, $actual); + } + + /** + * @covers Thelia\Tools\FileManager::getImageModel + */ + public function testGetImageModel() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + + $fileManager = new FileManager($stubContainer); + $actual = $fileManager->getImageModel(FileManager::TYPE_PRODUCT); + $this->assertInstanceOf('\Thelia\Model\ProductImage', $actual); + $actual = $fileManager->getImageModel(FileManager::TYPE_CATEGORY); + $this->assertInstanceOf('\Thelia\Model\CategoryImage', $actual); + $actual = $fileManager->getImageModel(FileManager::TYPE_CONTENT); + $this->assertInstanceOf('\Thelia\Model\ContentImage', $actual); + $actual = $fileManager->getImageModel(FileManager::TYPE_FOLDER); + $this->assertInstanceOf('\Thelia\Model\FolderImage', $actual); + $actual = $fileManager->getImageModel('bad'); + $this->assertNull($actual); + } + + /** + * @covers Thelia\Tools\FileManager::getDocumentModel + */ + public function testGetDocumentModel() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + + $fileManager = new FileManager($stubContainer); + $actual = $fileManager->getDocumentModel(FileManager::TYPE_PRODUCT); + $this->assertInstanceOf('\Thelia\Model\ProductDocument', $actual); + $actual = $fileManager->getDocumentModel(FileManager::TYPE_CATEGORY); + $this->assertInstanceOf('\Thelia\Model\CategoryDocument', $actual); + $actual = $fileManager->getDocumentModel(FileManager::TYPE_CONTENT); + $this->assertInstanceOf('\Thelia\Model\ContentDocument', $actual); + $actual = $fileManager->getDocumentModel(FileManager::TYPE_FOLDER); + $this->assertInstanceOf('\Thelia\Model\FolderDocument', $actual); + $actual = $fileManager->getDocumentModel('bad'); + $this->assertNull($actual); + } + + /** + * @covers Thelia\Tools\FileManager::getImageModelQuery + */ + public function testGetImageModelQuery() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + + $fileManager = new FileManager($stubContainer); + $actual = $fileManager->getImageModelQuery(FileManager::TYPE_PRODUCT); + $this->assertInstanceOf('\Thelia\Model\ProductImageQuery', $actual); + $actual = $fileManager->getImageModelQuery(FileManager::TYPE_CATEGORY); + $this->assertInstanceOf('\Thelia\Model\CategoryImageQuery', $actual); + $actual = $fileManager->getImageModelQuery(FileManager::TYPE_CONTENT); + $this->assertInstanceOf('\Thelia\Model\ContentImageQuery', $actual); + $actual = $fileManager->getImageModelQuery(FileManager::TYPE_FOLDER); + $this->assertInstanceOf('\Thelia\Model\FolderImageQuery', $actual); + $actual = $fileManager->getImageModelQuery('bad'); + $this->assertNull($actual); + } + + /** + * @covers Thelia\Tools\FileManager::getDocumentModelQuery + */ + public function testGetDocumentModelQuery() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + + $fileManager = new FileManager($stubContainer); + $actual = $fileManager->getDocumentModelQuery(FileManager::TYPE_PRODUCT); + $this->assertInstanceOf('\Thelia\Model\ProductDocumentQuery', $actual); + $actual = $fileManager->getDocumentModelQuery(FileManager::TYPE_CATEGORY); + $this->assertInstanceOf('\Thelia\Model\CategoryDocumentQuery', $actual); + $actual = $fileManager->getDocumentModelQuery(FileManager::TYPE_CONTENT); + $this->assertInstanceOf('\Thelia\Model\ContentDocumentQuery', $actual); + $actual = $fileManager->getDocumentModelQuery(FileManager::TYPE_FOLDER); + $this->assertInstanceOf('\Thelia\Model\FolderDocumentQuery', $actual); + $actual = $fileManager->getDocumentModelQuery('bad'); + $this->assertNull($actual); + } + + /** + * @covers Thelia\Tools\FileManager::getParentFileModel + */ + public function testGetParentFileModel() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + + $fileManager = new FileManager($stubContainer); + $actual = $fileManager->getParentFileModel(FileManager::TYPE_PRODUCT, 1); + $this->assertInstanceOf('\Thelia\Model\Product', $actual); + $actual = $fileManager->getParentFileModel(FileManager::TYPE_CATEGORY, 1); + $this->assertInstanceOf('\Thelia\Model\Category', $actual); + $actual = $fileManager->getParentFileModel(FileManager::TYPE_CONTENT, 1); + $this->assertInstanceOf('\Thelia\Model\Content', $actual); + $actual = $fileManager->getParentFileModel(FileManager::TYPE_FOLDER, 1); + $this->assertInstanceOf('\Thelia\Model\Folder', $actual, 1); + $actual = $fileManager->getParentFileModel('bad', 1); + $this->assertNull($actual); + } + + /** + * @covers Thelia\Tools\FileManager::getImageForm + */ + public function testGetImageForm() + { + // Mock issue + $this->markTestIncomplete( + 'This test has not been implemented yet.' + ); + } + /** + * @covers Thelia\Tools\FileManager::getDocumentForm + */ + public function testGetDocumentForm() + { + // Mock issue + $this->markTestIncomplete( + 'This test has not been implemented yet.' + ); + } + + /** + * @covers Thelia\Tools\FileManager::getUploadDir + */ + public function testGetUploadDir() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + + $fileManager = new FileManager($stubContainer); + + $actual = $fileManager->getUploadDir(FileManager::TYPE_PRODUCT, FileManager::FILE_TYPE_IMAGES); + $this->assertEquals(THELIA_LOCAL_DIR . 'media/images/product', $actual); + $actual = $fileManager->getUploadDir(FileManager::TYPE_CATEGORY, FileManager::FILE_TYPE_IMAGES); + $this->assertEquals(THELIA_LOCAL_DIR . 'media/images/category', $actual); + $actual = $fileManager->getUploadDir(FileManager::TYPE_CONTENT, FileManager::FILE_TYPE_IMAGES); + $this->assertEquals(THELIA_LOCAL_DIR . 'media/images/content', $actual); + $actual = $fileManager->getUploadDir(FileManager::TYPE_FOLDER, FileManager::FILE_TYPE_IMAGES); + $this->assertEquals(THELIA_LOCAL_DIR . 'media/images/folder', $actual); + $actual = $fileManager->getUploadDir('bad', FileManager::FILE_TYPE_IMAGES); + $this->assertEquals(false, $actual); + + $actual = $fileManager->getUploadDir(FileManager::TYPE_PRODUCT, FileManager::FILE_TYPE_DOCUMENTS); + $this->assertEquals(THELIA_LOCAL_DIR . 'media/documents/product', $actual); + $actual = $fileManager->getUploadDir(FileManager::TYPE_CATEGORY, FileManager::FILE_TYPE_DOCUMENTS); + $this->assertEquals(THELIA_LOCAL_DIR . 'media/documents/category', $actual); + $actual = $fileManager->getUploadDir(FileManager::TYPE_CONTENT, FileManager::FILE_TYPE_DOCUMENTS); + $this->assertEquals(THELIA_LOCAL_DIR . 'media/documents/content', $actual); + $actual = $fileManager->getUploadDir(FileManager::TYPE_FOLDER, FileManager::FILE_TYPE_DOCUMENTS); + $this->assertEquals(THELIA_LOCAL_DIR . 'media/documents/folder', $actual); + $actual = $fileManager->getUploadDir('bad', FileManager::FILE_TYPE_DOCUMENTS); + $this->assertEquals(false, $actual); + + $actual = $fileManager->getUploadDir(FileManager::TYPE_FOLDER, 'bad'); + $this->assertEquals(false, $actual); + } + + /** + * @covers Thelia\Tools\FileManager::getRedirectionUrl + */ + public function testGetRedirectionUrl() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + + $fileManager = new FileManager($stubContainer); + + $actual = $fileManager->getRedirectionUrl(FileManager::TYPE_PRODUCT, 1, FileManager::FILE_TYPE_IMAGES); + $this->assertEquals('/admin/products/update?product_id=1¤t_tab=images', $actual); + $actual = $fileManager->getRedirectionUrl(FileManager::TYPE_CATEGORY, 1, FileManager::FILE_TYPE_IMAGES); + $this->assertEquals('/admin/categories/update?category_id=1¤t_tab=images', $actual); + $actual = $fileManager->getRedirectionUrl(FileManager::TYPE_CONTENT, 1, FileManager::FILE_TYPE_IMAGES); + $this->assertEquals('/admin/content/update/1?current_tab=images', $actual); + $actual = $fileManager->getRedirectionUrl(FileManager::TYPE_FOLDER, 1, FileManager::FILE_TYPE_IMAGES); + $this->assertEquals('/admin/folders/update/1?current_tab=images', $actual); + $actual = $fileManager->getRedirectionUrl('bad', 1, FileManager::FILE_TYPE_IMAGES); + $this->assertEquals(false, $actual); + + $actual = $fileManager->getRedirectionUrl(FileManager::TYPE_PRODUCT, 1, FileManager::FILE_TYPE_DOCUMENTS); + $this->assertEquals('/admin/products/update?product_id=1¤t_tab=documents', $actual); + $actual = $fileManager->getRedirectionUrl(FileManager::TYPE_CATEGORY, 1, FileManager::FILE_TYPE_DOCUMENTS); + $this->assertEquals('/admin/categories/update?category_id=1¤t_tab=documents', $actual); + $actual = $fileManager->getRedirectionUrl(FileManager::TYPE_CONTENT, 1, FileManager::FILE_TYPE_DOCUMENTS); + $this->assertEquals('/admin/content/update/1?current_tab=documents', $actual); + $actual = $fileManager->getRedirectionUrl(FileManager::TYPE_FOLDER, 1, FileManager::FILE_TYPE_DOCUMENTS); + $this->assertEquals('/admin/folders/update/1?current_tab=documents', $actual); + $actual = $fileManager->getRedirectionUrl('bad', 1, FileManager::FILE_TYPE_DOCUMENTS); + $this->assertEquals(false, $actual); + + $actual = $fileManager->getRedirectionUrl(FileManager::TYPE_FOLDER, 1, 'bad'); + $this->assertEquals(false, $actual); + } + + + /** + * @covers Thelia\Tools\FileManager::getFormId + */ + public function testGetFormId() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + + $fileManager = new FileManager($stubContainer); + + $actual = $fileManager->getFormId(FileManager::TYPE_PRODUCT, FileManager::FILE_TYPE_IMAGES); + $this->assertEquals('thelia.admin.product.image.modification', $actual); + $actual = $fileManager->getFormId(FileManager::TYPE_CATEGORY, FileManager::FILE_TYPE_IMAGES); + $this->assertEquals('thelia.admin.category.image.modification', $actual); + $actual = $fileManager->getFormId(FileManager::TYPE_CONTENT, FileManager::FILE_TYPE_IMAGES); + $this->assertEquals('thelia.admin.content.image.modification', $actual); + $actual = $fileManager->getFormId(FileManager::TYPE_FOLDER, FileManager::FILE_TYPE_IMAGES); + $this->assertEquals('thelia.admin.folder.image.modification', $actual); + $actual = $fileManager->getFormId('bad', FileManager::FILE_TYPE_IMAGES); + $this->assertEquals(false, $actual); + + $actual = $fileManager->getFormId(FileManager::TYPE_PRODUCT, FileManager::FILE_TYPE_DOCUMENTS); + $this->assertEquals('thelia.admin.product.document.modification', $actual); + $actual = $fileManager->getFormId(FileManager::TYPE_CATEGORY, FileManager::FILE_TYPE_DOCUMENTS); + $this->assertEquals('thelia.admin.category.document.modification', $actual); + $actual = $fileManager->getFormId(FileManager::TYPE_CONTENT, FileManager::FILE_TYPE_DOCUMENTS); + $this->assertEquals('thelia.admin.content.document.modification', $actual); + $actual = $fileManager->getFormId(FileManager::TYPE_FOLDER, FileManager::FILE_TYPE_DOCUMENTS); + $this->assertEquals('thelia.admin.folder.document.modification', $actual); + $actual = $fileManager->getFormId('bad', FileManager::FILE_TYPE_DOCUMENTS); + $this->assertEquals(false, $actual); + } + + /** + * @covers Thelia\Tools\FileManager::renameFile + */ + public function testRenameFile() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + + $stubUploadedFile = $this->getMockBuilder('\Symfony\Component\HttpFoundation\File\UploadedFile') + ->disableOriginalConstructor() + ->getMock(); + $stubUploadedFile->expects($this->any()) + ->method('getClientOriginalExtension') + ->will($this->returnValue('yml')); + $stubUploadedFile->expects($this->any()) + ->method('getClientOriginalName') + ->will($this->returnValue('or1-g_n?al*/&é"filen@me#')); + + + $fileManager = new FileManager($stubContainer); + + $expected = 'or1-g_nalyfilenme-1.yml'; + $actual = $fileManager->renameFile(1, $stubUploadedFile); + + $this->assertEquals($expected, $actual); + } + + /** + * @covers Thelia\Tools\FileManager::renameFile + */ + public function testRenameFileWithoutExtension() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + + $stubUploadedFile = $this->getMockBuilder('\Symfony\Component\HttpFoundation\File\UploadedFile') + ->disableOriginalConstructor() + ->getMock(); + $stubUploadedFile->expects($this->any()) + ->method('getClientOriginalExtension') + ->will($this->returnValue('')); + $stubUploadedFile->expects($this->any()) + ->method('getClientOriginalName') + ->will($this->returnValue('or1-g_n?al*/&é"filen@me#')); + + + $fileManager = new FileManager($stubContainer); + + $expected = 'or1-g_nalyfilenme-1'; + $actual = $fileManager->renameFile(1, $stubUploadedFile); + + $this->assertEquals($expected, $actual); + } + + /** + * @covers Thelia\Tools\FileManager::isImage + */ + public function testIsImage() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + + $fileManager = new FileManager($stubContainer); + + $actual = $fileManager->isImage('image/jpeg'); + $this->assertTrue($actual); + $actual = $fileManager->isImage('image/png'); + $this->assertTrue($actual); + $actual = $fileManager->isImage('image/gif'); + $this->assertTrue($actual); + + $actual = $fileManager->isImage('bad'); + $this->assertFalse($actual); + $actual = $fileManager->isImage('image/jpg'); + $this->assertFalse($actual); + $actual = $fileManager->isImage('application/x-msdownload'); + $this->assertFalse($actual); + $actual = $fileManager->isImage('application/x-sh'); + $this->assertFalse($actual); + + } + + + /** + * @covers Thelia\Tools\FileManager::getAvailableTypes + */ + public function testGetAvailableTypes() + { + $expected = array( + FileManager::TYPE_CATEGORY, + FileManager::TYPE_CONTENT, + FileManager::TYPE_FOLDER, + FileManager::TYPE_PRODUCT, + FileManager::TYPE_MODULE, + ); + $actual = FileManager::getAvailableTypes(); + + $this->assertEquals($expected, $actual); + } + + /** + * @covers Thelia\Tools\FileManager::adminLogAppend + */ + public function testAdminLogAppend() + { + $this->markTestIncomplete( + 'This test has not been implemented yet.' + ); + } + + /** + * @covers Thelia\Tools\FileManager::deleteFile + */ + public function testDeleteFile() + { + // @todo see http://tech.vg.no/2011/03/09/mocking-the-file-system-using-phpunit-and-vfsstream/ + $this->markTestIncomplete( + 'This test has not been implemented yet.' + ); + } +} diff --git a/core/lib/Thelia/Tools/FileManager.php b/core/lib/Thelia/Tools/FileManager.php new file mode 100644 index 000000000..6c06fb416 --- /dev/null +++ b/core/lib/Thelia/Tools/FileManager.php @@ -0,0 +1,731 @@ +. */ +/* */ +/**********************************************************************************/ +namespace Thelia\Tools; + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpFoundation\File\UploadedFile; +use Thelia\Core\Event\DocumentCreateOrUpdateEvent; +use Thelia\Core\Event\ImageCreateOrUpdateEvent; +use Thelia\Core\HttpFoundation\Request; +use Thelia\Core\Translation\Translator; +use Thelia\Exception\ImageException; +use Thelia\Form\CategoryDocumentModification; +use Thelia\Form\CategoryImageModification; +use Thelia\Form\ContentDocumentModification; +use Thelia\Form\ContentImageModification; +use Thelia\Form\FolderDocumentModification; +use Thelia\Form\FolderImageModification; +use Thelia\Form\ProductDocumentModification; +use Thelia\Form\ProductImageModification; +use Thelia\Model\AdminLog; +use Thelia\Model\CategoryDocument; +use Thelia\Model\CategoryDocumentQuery; +use Thelia\Model\CategoryImage; +use Thelia\Model\CategoryImageQuery; +use Thelia\Model\CategoryQuery; +use Thelia\Model\ContentDocument; +use Thelia\Model\ContentDocumentQuery; +use Thelia\Model\ContentImage; +use Thelia\Model\ContentImageQuery; +use Thelia\Model\ContentQuery; +use Thelia\Model\Exception\InvalidArgumentException; +use Thelia\Model\FolderDocument; +use Thelia\Model\FolderDocumentQuery; +use Thelia\Model\FolderImage; +use Thelia\Model\FolderImageQuery; +use Thelia\Model\FolderQuery; +use Thelia\Model\ProductDocument; +use Thelia\Model\ProductDocumentQuery; +use Thelia\Model\ProductImage; +use Thelia\Model\ProductImageQuery; +use Thelia\Model\ProductQuery; + +/** + * Created by JetBrains PhpStorm. + * Date: 9/19/13 + * Time: 3:24 PM + * + * File Manager + * + * @package File + * @author Guillaume MOREL + * + */ +class FileManager +{ + CONST TYPE_PRODUCT = 'product'; + CONST TYPE_CATEGORY = 'category'; + CONST TYPE_CONTENT = 'content'; + CONST TYPE_FOLDER = 'folder'; + CONST TYPE_MODULE = 'module'; + + CONST FILE_TYPE_IMAGES = 'images'; + CONST FILE_TYPE_DOCUMENTS = 'documents'; + + /** @var ContainerInterface Service Container */ + protected $container = null; + + /** @var Translator Service Translator */ + protected $translator = null; + + /** + * Constructor + * + * @param ContainerInterface $container Service container + */ + public function __construct(ContainerInterface $container) + { + $this->container = $container; + $this->translator = $this->container->get('thelia.translator'); + } + + /** + * Copy UploadedFile into the server storage directory + * + * @param int $parentId Parent id + * @param string $parentType Image type + * @param FolderImage|ContentImage|CategoryImage|ProductImage|FolderDocument|ContentDocument|CategoryDocument|ProductDocument $model Model saved + * @param UploadedFile $uploadedFile Ready to be uploaded file + * @param string $fileType File type ex FileManager::FILE_TYPE_IMAGES + * + * @throws \Thelia\Exception\ImageException + * @return UploadedFile + */ + public function copyUploadedFile($parentId, $parentType, $model, $uploadedFile, $fileType) + { + $newUploadedFile = null; + if ($uploadedFile !== null) { + $directory = $this->getUploadDir($parentType, $fileType); + $fileName = $this->renameFile($model->getId(), $uploadedFile); + + $this->adminLogAppend( + $this->translator->trans( + 'Uploading %type% %fileName% to %directory% for parent_id %parentId% (%parentType%)', + array( + '%type%' => $fileType, + '%fileName%' => $uploadedFile->getClientOriginalName(), + '%directory%' => $directory . '/' . $fileName, + '%parentId%' => $parentId, + '%parentType%' => $parentType + ), + 'image' + ) + ); + + $newUploadedFile = $uploadedFile->move($directory, $fileName); + $model->setFile($fileName); + + if (!$model->save()) { + throw new ImageException( + sprintf( + '%s %s (%s) failed to be saved (image file)', + ucfirst($parentType), + $model->getFile(), + $fileType + ) + ); + } + } + + return $newUploadedFile; + } + + /** + * Save image into the database + * + * @param ImageCreateOrUpdateEvent $event Image event + * @param FolderImage|ContentImage|CategoryImage|ProductImage $modelImage Image to save + * + * @return int Nb lines modified + * @throws \Thelia\Exception\ImageException + * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action + */ + public function saveImage(ImageCreateOrUpdateEvent $event, $modelImage) + { + $nbModifiedLines = 0; + + if ($modelImage->getFile() !== null) { + switch ($event->getImageType()) { + case self::TYPE_PRODUCT: + /** @var ProductImage $modelImage */ + $modelImage->setProductId($event->getParentId()); + break; + case self::TYPE_CATEGORY: + /** @var CategoryImage $modelImage */ + $modelImage->setCategoryId($event->getParentId()); + break; + case self::TYPE_CONTENT: + /** @var ContentImage $modelImage */ + $modelImage->setContentId($event->getParentId()); + break; + case self::TYPE_FOLDER: + /** @var FolderImage $modelImage */ + $modelImage->setFolderId($event->getParentId()); + break; + default: + throw new ImageException( + sprintf( + 'Picture parent type is unknown (available types : %s)', + implode( + ',', + self::getAvailableTypes() + ) + ) + ); + } + + $nbModifiedLines = $modelImage->save(); + if (!$nbModifiedLines) { + throw new ImageException( + sprintf( + 'Image %s failed to be saved (image content)', + $modelImage->getFile() + ) + ); + } + } + + return $nbModifiedLines; + } + + /** + * Save document into the database + * + * @param DocumentCreateOrUpdateEvent $event Image event + * @param FolderDocument|ContentDocument|CategoryDocument|ProductDocument $modelDocument Document to save + * + * @throws \Thelia\Model\Exception\InvalidArgumentException + * @return int Nb lines modified + * @todo refactor make all documents using propel inheritance and factorise image behaviour into one single clean action + */ + public function saveDocument(DocumentCreateOrUpdateEvent $event, $modelDocument) + { + $nbModifiedLines = 0; + + if ($modelDocument->getFile() !== null) { + switch ($event->getDocumentType()) { + case self::TYPE_PRODUCT: + /** @var ProductImage $modelImage */ + $modelDocument->setProductId($event->getParentId()); + break; + case self::TYPE_CATEGORY: + /** @var CategoryImage $modelImage */ + $modelDocument->setCategoryId($event->getParentId()); + break; + case self::TYPE_CONTENT: + /** @var ContentImage $modelImage */ + $modelDocument->setContentId($event->getParentId()); + break; + case self::TYPE_FOLDER: + /** @var FolderImage $modelImage */ + $modelDocument->setFolderId($event->getParentId()); + break; + default: + throw new InvalidArgumentException( + sprintf( + 'Document parent type is unknown (available types : %s)', + implode( + ',', + self::getAvailableTypes() + ) + ) + ); + } + + $nbModifiedLines = $modelDocument->save(); + if (!$nbModifiedLines) { + throw new InvalidArgumentException( + sprintf( + 'Document %s failed to be saved (document content)', + $modelDocument->getFile() + ) + ); + } + } + + return $nbModifiedLines; + } + + /** + * Sanitizes a filename replacing whitespace with dashes + * + * Removes special characters that are illegal in filenames on certain + * operating systems and special characters requiring special escaping + * to manipulate at the command line. + * + * @param string $string The filename to be sanitized + * + * @return string The sanitized filename + */ + public function sanitizeFileName($string) + { + $cleanName = strtr($string, 'ŠŽšžŸÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖØÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöøùúûüýÿ', 'SZszYAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy'); + $cleanName = strtr($cleanName, array('Þ' => 'TH', 'þ' => 'th', 'Ð' => 'DH', 'ð' => 'dh', 'ß' => 'ss', 'Œ' => 'OE', 'œ' => 'oe', 'Æ' => 'AE', 'æ' => 'ae', 'µ' => 'u')); + + $cleanName = preg_replace(array('/\s/', '/\.[\.]+/', '/[^\w_\.\-]/'), array('_', '.', ''), $cleanName); + + return $cleanName; + } + + /** + * Helper to append a message to the admin log. + * + * @param string $message + */ + public function adminLogAppend($message) + { + AdminLog::append( + $message, + $this->container->get('request'), + $this->container->get('thelia.securityContext')->getAdminUser() + ); + } + + + /** + * Delete image from file storage and database + * + * @param CategoryImage|ProductImage|ContentImage|FolderImage|CategoryDocument|ProductDocument|ContentDocument|FolderDocument $model File being deleted + * @param string $parentType Parent type ex : self::TYPE_PRODUCT + * @param string $fileType File type ex FileManager::FILE_TYPE_DOCUMENTS + * + * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action + */ + public function deleteFile($model, $parentType, $fileType) + { + $url = $this->getUploadDir($parentType, $fileType) . '/' . $model->getFile(); + unlink(str_replace('..', '', $url)); + $model->delete(); + } + + + /** + * Get image model from type + * + * @param string $parentType Parent type ex : self::TYPE_PRODUCT + * + * @return null|\Thelia\Model\CategoryImage|\Thelia\Model\ContentImage|\Thelia\Model\FolderImage|\Thelia\Model\ProductImage + * + * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action + */ + public function getImageModel($parentType) + { + switch ($parentType) { + case self::TYPE_PRODUCT: + $model = new ProductImage(); + break; + case self::TYPE_CATEGORY: + $model = new CategoryImage(); + break; + case self::TYPE_CONTENT: + $model = new ContentImage(); + break; + case self::TYPE_FOLDER: + $model = new FolderImage(); + break; + default: + $model = null; + } + + return $model; + } + + /** + * Get document model from type + * + * @param string $parentType Parent type ex : self::TYPE_PRODUCT + * + * @return null|ProductDocument|CategoryDocument|ContentDocument|FolderDocument + * + * @todo refactor make all documents using propel inheritance and factorise image behaviour into one single clean action + */ + public function getDocumentModel($parentType) + { + switch ($parentType) { + case self::TYPE_PRODUCT: + $model = new ProductDocument(); + break; + case self::TYPE_CATEGORY: + $model = new CategoryDocument(); + break; + case self::TYPE_CONTENT: + $model = new ContentDocument(); + break; + case self::TYPE_FOLDER: + $model = new FolderDocument(); + break; + default: + $model = null; + } + + return $model; + } + + /** + * Get image model query from type + * + * @param string $parentType Parent type ex : self::TYPE_PRODUCT + * + * @return null|\Thelia\Model\CategoryImageQuery|\Thelia\Model\ContentImageQuery|\Thelia\Model\FolderImageQuery|\Thelia\Model\ProductImageQuery + * + * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action + */ + public function getImageModelQuery($parentType) + { + switch ($parentType) { + case self::TYPE_PRODUCT: + $model = new ProductImageQuery(); + break; + case self::TYPE_CATEGORY: + $model = new CategoryImageQuery(); + break; + case self::TYPE_CONTENT: + $model = new ContentImageQuery(); + break; + case self::TYPE_FOLDER: + $model = new FolderImageQuery(); + break; + default: + $model = null; + } + + return $model; + } + + /** + * Get document model query from type + * + * @param string $parentType Parent type ex : self::TYPE_PRODUCT + * + * @return null|ProductDocumentQuery|CategoryDocumentQuery|ContentDocumentQuery|FolderDocumentQuery + * + * @todo refactor make all documents using propel inheritance and factorise image behaviour into one single clean action + */ + public function getDocumentModelQuery($parentType) + { + switch ($parentType) { + case self::TYPE_PRODUCT: + $model = new ProductDocumentQuery(); + break; + case self::TYPE_CATEGORY: + $model = new CategoryDocumentQuery(); + break; + case self::TYPE_CONTENT: + $model = new ContentDocumentQuery(); + break; + case self::TYPE_FOLDER: + $model = new FolderDocumentQuery(); + break; + default: + $model = null; + } + + return $model; + } + + /** + * Get form service id from type + * + * @param string $parentType Parent type ex : self::TYPE_PRODUCT + * @param string $fileType Parent id + * + * @return string + * + * @todo refactor make all documents using propel inheritance and factorise image behaviour into one single clean action + */ + public function getFormId($parentType, $fileType) + { + switch ($fileType) { + case self::FILE_TYPE_IMAGES: + $type = 'image'; + break; + case self::FILE_TYPE_DOCUMENTS: + $type = 'document'; + break; + default: + return false; + } + + switch ($parentType) { + case self::TYPE_PRODUCT: + $formId = 'thelia.admin.product.' . $type . '.modification'; + break; + case self::TYPE_CATEGORY: + $formId = 'thelia.admin.category.' . $type . '.modification'; + break; + case self::TYPE_CONTENT: + $formId = 'thelia.admin.content.' . $type . '.modification'; + break; + case self::TYPE_FOLDER: + $formId = 'thelia.admin.folder.' . $type . '.modification'; + break; + default: + $formId = false; + } + + return $formId; + } + + /** + * Get image parent model from type + * + * @param string $parentType Parent type ex : self::TYPE_PRODUCT + * @param int $parentId Parent Id + * + * @return null|\Thelia\Model\Category|\Thelia\Model\Content|\Thelia\Model\Folder|\Thelia\Model\Product + * + * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action + */ + public function getParentFileModel($parentType, $parentId) + { + switch ($parentType) { + case self::TYPE_PRODUCT: + $model = ProductQuery::create()->findPk($parentId); + break; + case self::TYPE_CATEGORY: + $model = CategoryQuery::create()->findPk($parentId); + break; + case self::TYPE_CONTENT: + $model = ContentQuery::create()->findPk($parentId); + break; + case self::TYPE_FOLDER: + $model = FolderQuery::create()->findPk($parentId); + break; + default: + $model = null; + } + + return $model; + } + + /** + * Get image parent model from type + * + * @param string $parentType Parent type ex : self::TYPE_PRODUCT + * @param Request $request Request service + * + * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action + * @return ProductImageModification|CategoryImageModification|ContentImageModification|FolderImageModification + */ + public function getImageForm($parentType, Request $request) + { + switch ($parentType) { + case self::TYPE_PRODUCT: + $form = new ProductImageModification($request); + break; + case self::TYPE_CATEGORY: + $form = new CategoryImageModification($request); + break; + case self::TYPE_CONTENT: + $form = new ContentImageModification($request); + break; + case self::TYPE_FOLDER: + $form = new FolderImageModification($request); + break; + default: + $form = null; + } + + return $form; + + } + + /** + * Get document parent model from type + * + * @param string $parentType Parent type ex : self::TYPE_PRODUCT + * @param Request $request Request service + * + * @todo refactor make all document using propel inheritance and factorise image behaviour into one single clean action + * @return ProductDocumentModification|CategoryDocumentModification|ContentDocumentModification|FolderDocumentModification + */ + public function getDocumentForm($parentType, Request $request) + { + switch ($parentType) { + case self::TYPE_PRODUCT: + $form = new ProductDocumentModification($request); + break; + case self::TYPE_CATEGORY: + $form = new CategoryDocumentModification($request); + break; + case self::TYPE_CONTENT: + $form = new ContentDocumentModification($request); + break; + case self::TYPE_FOLDER: + $form = new FolderDocumentModification($request); + break; + default: + $form = null; + } + + return $form; + + } + + /** + * Get image upload dir + * + * @param string $parentType Parent type ex FileManager::TYPE_PRODUCT + * @param string $fileType File type ex : self::FILE_TYPE_DOCUMENTS + * + * @return string Uri + */ + public function getUploadDir($parentType, $fileType) + { + if (!in_array($fileType, self::$availableFileType)) { + return false; + } + + switch ($parentType) { + case self::TYPE_PRODUCT: + $uri = THELIA_LOCAL_DIR . 'media/' . $fileType . '/' . self::TYPE_PRODUCT; + break; + case self::TYPE_CATEGORY: + $uri = THELIA_LOCAL_DIR . 'media/' . $fileType . '/' . self::TYPE_CATEGORY; + break; + case self::TYPE_CONTENT: + $uri = THELIA_LOCAL_DIR . 'media/' . $fileType . '/' . self::TYPE_CONTENT; + break; + case self::TYPE_FOLDER: + $uri = THELIA_LOCAL_DIR . 'media/' . $fileType . '/' . self::TYPE_FOLDER; + break; + default: + $uri = false; + } + + return $uri; + + } + + /** + * Deduce image redirecting URL from parent type + * + * @param string $parentType Parent type ex : self::TYPE_PRODUCT + * @param int $parentId Parent id + * @param string $fileType File type ex : self::FILE_TYPE_DOCUMENTS + * + * @return string + */ + public function getRedirectionUrl($parentType, $parentId, $fileType) + { + if (!in_array($fileType, self::$availableFileType)) { + return false; + } + + switch ($parentType) { + case self::TYPE_PRODUCT: + $uri = '/admin/products/update?product_id=' . $parentId . '¤t_tab=' . $fileType; + break; + case self::TYPE_CATEGORY: + $uri = '/admin/categories/update?category_id=' . $parentId . '¤t_tab=' . $fileType; + break; + case self::TYPE_CONTENT: + $uri = '/admin/content/update/' . $parentId . '?current_tab=' . $fileType; + break; + case self::TYPE_FOLDER: + $uri = '/admin/folders/update/' . $parentId . '?current_tab=' . $fileType; + break; + default: + $uri = false; + } + + return $uri; + + } + + /** @var array Available file parent type */ + public static $availableType = array( + self::TYPE_PRODUCT, + self::TYPE_CATEGORY, + self::TYPE_CONTENT, + self::TYPE_FOLDER, + self::TYPE_MODULE + ); + + /** @var array Available file type type */ + public static $availableFileType = array( + self::FILE_TYPE_DOCUMENTS, + self::FILE_TYPE_IMAGES + ); + + /** + * Rename file with image model id + * + * @param int $modelId Model id + * @param UploadedFile $uploadedFile File being saved + * + * @return string + */ + public function renameFile($modelId, $uploadedFile) + { + $extension = $uploadedFile->getClientOriginalExtension(); + if (!empty($extension)) { + $extension = '.' . strtolower($extension); + } + $fileName = $this->sanitizeFileName( + str_replace( + $extension, + '', + $uploadedFile->getClientOriginalName() + ) . '-' . $modelId . $extension + ); + + return $fileName; + } + + /** + * Check if a file is an image + * Check based on mime type + * + * @param string $mimeType File mime type + * + * @return bool + */ + public function isImage($mimeType) + { + $isValid = false; + + $allowedType = array('image/jpeg' , 'image/png' ,'image/gif'); + if (in_array($mimeType, $allowedType)) { + $isValid = true; + } + + return $isValid; + } + + /** + * Return all document and image types + * + * @return array + */ + public static function getAvailableTypes() + { + return array( + self::TYPE_CATEGORY, + self::TYPE_CONTENT, + self::TYPE_FOLDER, + self::TYPE_PRODUCT, + self::TYPE_MODULE, + ); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Tools/I18n.php b/core/lib/Thelia/Tools/I18n.php index 1f3ff57dd..aeb79ca84 100644 --- a/core/lib/Thelia/Tools/I18n.php +++ b/core/lib/Thelia/Tools/I18n.php @@ -23,6 +23,8 @@ namespace Thelia\Tools; +use Propel\Runtime\ActiveQuery\ModelCriteria; +use Propel\Runtime\ActiveRecord\ActiveRecordInterface; use Thelia\Model\Lang; /** @@ -54,4 +56,39 @@ class I18n return \DateTime::createFromFormat($currentDateFormat, $date); } + + public static function forceI18nRetrieving($askedLocale, $modelName, $id, $needed = array('Title')) + { + $i18nQueryClass = sprintf("\\Thelia\\Model\\%sI18nQuery", $modelName); + $i18nClass = sprintf("\\Thelia\\Model\\%sI18n", $modelName); + + /* get customer language translation */ + $i18n = $i18nQueryClass::create() + ->filterById($id) + ->filterByLocale( + $askedLocale + )->findOne(); + /* or default translation */ + if(null === $i18n) { + $i18n = $i18nQueryClass::create() + ->filterById($id) + ->filterByLocale( + Lang::getDefaultLanguage()->getLocale() + )->findOne(); + } + if(null === $i18n) { // @todo something else ? + $i18n = new $i18nClass();; + $i18n->setId($id); + foreach($needed as $need) { + $method = sprintf('set%s', $need); + if(method_exists($i18n, $method)) { + $i18n->$method('DEFAULT ' . strtoupper($need)); + } else { + // @todo throw sg ? + } + } + } + + return $i18n; + } } diff --git a/core/lib/Thelia/Tools/Image.php b/core/lib/Thelia/Tools/Image.php new file mode 100755 index 000000000..5fa4d3c6c --- /dev/null +++ b/core/lib/Thelia/Tools/Image.php @@ -0,0 +1,44 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Tools; + +class Image +{ + static public function isImage($filePath, $allowedImageTypes = null) + { + $imageFile = getimagesize($filePath); + $imageType = $imageFile[2]; + + if(!is_array($allowedImageTypes) && $imageType != IMAGETYPE_UNKNOWN) { + return true; + } + + if(in_array($imageType , $allowedImageTypes)) + { + return true; + } + + return false; + } +} diff --git a/core/lib/Thelia/Tools/Rest/ResponseRest.php b/core/lib/Thelia/Tools/Rest/ResponseRest.php index 75d511d78..0c9186436 100644 --- a/core/lib/Thelia/Tools/Rest/ResponseRest.php +++ b/core/lib/Thelia/Tools/Rest/ResponseRest.php @@ -26,7 +26,7 @@ class ResponseRest extends Response * Constructor. * * @param array $data Array to be serialized - * @param string $format serialization format, xml or json available + * @param string $format serialization format, text, xml or json available * @param integer $status The response status code * @param array $headers An array of response headers * @@ -38,14 +38,22 @@ class ResponseRest extends Response { parent::__construct('', $status, $headers); - $this->format = $format; - $serializer = $this->getSerializer(); + if ($format == 'text') { + if (isset($data)) { + $this->setContent($data); + } - if (isset($data)) { - $this->setContent($serializer->serialize($data, $this->format)); + $this->headers->set('Content-Type', 'text/plain'); + } else { + $this->format = $format; + $serializer = $this->getSerializer(); + + if (isset($data)) { + $this->setContent($serializer->serialize($data, $this->format)); + } + + $this->headers->set('Content-Type', 'application/' . $this->format); } - - $this->headers->set('Content-Type', 'application/' . $this->format); } /** diff --git a/install/faker.php b/install/faker.php index 3d48fc0e1..55b60777e 100755 --- a/install/faker.php +++ b/install/faker.php @@ -160,6 +160,24 @@ try { "test@thelia.net", "azerty" ); + for ($j = 0; $j <= 3; $j++) { + $address = new Thelia\Model\Address(); + $address->setLabel($faker->text(20)) + ->setTitleId(rand(1,3)) + ->setFirstname($faker->firstname) + ->setLastname($faker->lastname) + ->setAddress1($faker->streetAddress) + ->setAddress2($faker->streetAddress) + ->setAddress3($faker->streetAddress) + ->setCellphone($faker->phoneNumber) + ->setPhone($faker->phoneNumber) + ->setZipcode($faker->postcode) + ->setCity($faker->city) + ->setCountryId(64) + ->setCustomer($customer) + ->save() + ; + } for($i = 0; $i < 50; $i++) { $customer = new Thelia\Model\Customer(); @@ -281,7 +299,7 @@ try { $folder = new Thelia\Model\Folder(); $folder->setParent(0); $folder->setVisible(1); - $folder->setPosition($i); + $folder->setPosition($i+1); setI18n($faker, $folder); $folder->save(); @@ -294,11 +312,11 @@ try { $document->setFolderId($folder->getId()); generate_document($document, 1, 'folder', $folder->getId()); - for($j=1; $jsetParent($folder->getId()); $subfolder->setVisible(1); - $subfolder->setPosition($j); + $subfolder->setPosition($j+1); setI18n($faker, $subfolder); $subfolder->save(); @@ -311,7 +329,7 @@ try { $document->setFolderId($folder->getId()); generate_document($document, 1, 'folder', $subfolder->getId()); - for($k=0; $kaddFolder($subfolder); @@ -320,8 +338,8 @@ try { $collection->prepend($contentFolders[0]->setDefaultFolder(1)); $content->setContentFolders($collection); - $content->setVisible(rand(1, 10)>7 ? 0 : 1); - $content->setPosition($k); + $content->setVisible(1); + $content->setPosition($k+1); setI18n($faker, $content); $content->save(); @@ -404,6 +422,7 @@ try { $stock->setPromo($faker->randomNumber(0,1)); $stock->setNewness($faker->randomNumber(0,1)); $stock->setWeight($faker->randomFloat(2, 100,10000)); + $stock->setIsDefault($i == 0); $stock->save(); $productPrice = new \Thelia\Model\ProductPrice(); @@ -442,7 +461,7 @@ try { $featureAvId[array_rand($featureAvId, 1)] ); } else { //no av - $featureProduct->setByDefault($faker->text(10)); + $featureProduct->setFreeTextValue($faker->text(10)); } $featureProduct->save(); diff --git a/install/import.php b/install/import.php new file mode 100644 index 000000000..c5fa3572a --- /dev/null +++ b/install/import.php @@ -0,0 +1,379 @@ +. */ +/* */ +/*************************************************************************************/ + +use Thelia\Constraint\ConstraintFactory; +use Thelia\Constraint\Rule\AvailableForTotalAmountManager; +use Thelia\Constraint\Rule\AvailableForXArticlesManager; +use Thelia\Constraint\Rule\Operators; +use Thelia\Coupon\CouponRuleCollection; + + +require __DIR__ . '/../core/bootstrap.php'; + +$thelia = new Thelia\Core\Thelia("dev", true); +$thelia->boot(); + +$faker = Faker\Factory::create(); +// Intialize URL management +$url = new Thelia\Tools\URL(); +$con = \Propel\Runtime\Propel::getConnection( + Thelia\Model\Map\ProductTableMap::DATABASE_NAME +); +$con->beginTransaction(); + +try { + $stmt = $con->prepare("SET foreign_key_checks = 0"); + $stmt->execute(); + clearTables(); + $stmt = $con->prepare("SET foreign_key_checks = 1"); + $stmt->execute(); + + + $categories = createCategories(); + $color = createColors(); + $brand = createBrand(); + + echo "creating templates\n"; + $template = new \Thelia\Model\Template(); + $template + ->setLocale('fr_FR') + ->setName('template de démo') + ->setLocale('en_US') + ->setName('demo template') + ->save(); + + $at = new Thelia\Model\AttributeTemplate(); + + $at + ->setTemplate($template) + ->setAttribute($color) + ->save(); + + $ft = new Thelia\Model\FeatureTemplate(); + + $ft + ->setTemplate($template) + ->setFeature($brand) + ->save(); + echo "end creating templates\n"; + + createProduct($faker, $categories, $template, $color, $brand); + + + + $con->commit(); +} catch (Exception $e) { + echo "error : ".$e->getMessage()."\n"; + $con->rollBack(); +} + +function createProduct($faker, $categories, $template, $attribute, $feature) +{ + echo "start creating products\n"; + $fileSystem = new \Symfony\Component\Filesystem\Filesystem(); + if (($handle = fopen(THELIA_ROOT . '/install/import/products.csv', "r")) !== FALSE) { + $row=0; + while (($data = fgetcsv($handle, 100000, ";")) !== FALSE) { + $row++; + if($row == 1) continue; + $product = new \Thelia\Model\Product(); + $productCategories = explode(';', $data[13]); + $product + ->setRef($data[0]) + ->setVisible(1) + ->setTaxRuleId(1) + ->setTemplate($template) + ; + foreach($productCategories as $productCategory) { + + $productCategory = trim($productCategory); + if(array_key_exists($productCategory, $categories)) { + $product->addCategory($categories[$productCategory]); + } + } + + + $product + ->setLocale('en_US') + ->setTitle($data[1]) + ->setChapo($data[2]) + ->setDescription($data[4]) + ->setPostscriptum($data[6]) + ->setLocale('fr_Fr') + ->setTitle($data[1]) + ->setChapo($data[3]) + ->setDescription($data[5]) + ->setPostscriptum($data[7]) + ->save(); + + $productCategories = $product->getProductCategories()->getFirst(); + $productCategories->setDefaultCategory(true) + ->save(); + + // Set the position + $product->setPosition($product->getNextPosition())->save(); + + $images = explode(';', $data[10]); + + foreach ($images as $image) { + $image = trim($image); + if(empty($image)) continue; + $productImage = new \Thelia\Model\ProductImage(); + $productImage + ->setProduct($product) + ->setFile($image) + ->save(); + $fileSystem->copy(THELIA_ROOT . 'install/import/images/'.$image, THELIA_ROOT . 'local/media/images/product/'.$image, true); + } + + $pses = explode(";", $data[12]); + + + foreach ($pses as $pse) { + if(empty($pse)) continue; + $stock = new \Thelia\Model\ProductSaleElements(); + $stock->setProduct($product); + $stock->setRef($product->getId() . '_' . uniqid('', true)); + $stock->setQuantity($faker->randomNumber(1,50)); + if(!empty($data[9])) { + $stock->setPromo(1); + } else { + $stock->setPromo(0); + } + + $stock->setNewness($faker->randomNumber(0,1)); + $stock->setWeight($faker->randomFloat(2, 100,10000)); + $stock->save(); + + $productPrice = new \Thelia\Model\ProductPrice(); + $productPrice->setProductSaleElements($stock); + $productPrice->setCurrencyId(1); + $productPrice->setPrice($data[8]); + $productPrice->setPromoPrice($data[9]); + $productPrice->save(); + + $attributeAv = \Thelia\Model\AttributeAvI18nQuery::create() + ->filterByLocale('en_US') + ->filterByTitle($pse) + ->findOne(); + + $attributeCombination = new \Thelia\Model\AttributeCombination(); + $attributeCombination + ->setAttributeId($attribute->getId()) + ->setAttributeAvId($attributeAv->getId()) + ->setProductSaleElements($stock) + ->save(); + } + + $brand = $data[11]; + $featurAv = \Thelia\Model\FeatureAvI18nQuery::create() + ->filterByLocale('en_US') + ->filterByTitle($brand) + ->findOne(); + + $featureProduct = new Thelia\Model\FeatureProduct(); + $featureProduct->setProduct($product) + ->setFeatureId($feature->getId()) + ->setFeatureAvId($featurAv->getId()) + ->save() + ; + + + + } + } + echo "end creating products\n"; +} + +function createBrand() +{ + echo "start creating brands feature\n"; + if (($handle = fopen(THELIA_ROOT . '/install/import/brand.csv', "r")) !== FALSE) { + $row=0; + $feature = new \Thelia\Model\Feature(); + $feature + ->setPosition(1) + ->setLocale('fr_FR') + ->setTitle('Marque') + ->setLocale('en_US') + ->setTitle('Brand'); + while (($data = fgetcsv($handle, 1000, ";")) !== FALSE) { + $row++; + $featureAv = new \Thelia\Model\FeatureAv(); + $featureAv + ->setPosition($row) + ->setLocale('fr_FR') + ->setTitle($data[0]) + ->setLocale('en_US') + ->setTitle($data[0]); + $feature->addFeatureAv($featureAv); + + } + $feature->save(); + fclose($handle); + } + echo "brands feature created successfully\n"; + + return $feature; +} + +function createCategories() +{ + echo "start creating categories\n"; + $categories = array(); + if (($handle = fopen(THELIA_ROOT . '/install/import/categories.csv', "r")) !== FALSE) { + $row=0; + while (($data = fgetcsv($handle, 1000, ";")) !== FALSE) { + $row++; + if($row==1) continue; + $category = new \Thelia\Model\Category(); + $category + ->setVisible(1) + ->setPosition($row-1) + ->setParent(0) + ->setLocale('fr_FR') + ->setTitle(trim($data[0])) + ->setLocale('en_US') + ->setTitle(trim($data[1])) + ->save(); + $categories[trim($data[1])] = $category; + } + fclose($handle); + } + echo "categories created successfully\n"; + return $categories; +} + +function createColors() +{ + echo "start creating colors attributes\n"; + if (($handle = fopen(THELIA_ROOT . '/install/import/colors.csv', "r")) !== FALSE) { + $row=0; + $attribute = new \Thelia\Model\Attribute(); + $attribute + ->setPosition(1) + ->setLocale('fr_FR') + ->setTitle('Couleur') + ->setLocale('en_US') + ->setTitle('Colors'); + + while (($data = fgetcsv($handle, 1000, ";")) !== FALSE) { + $row++; + $attributeAv = new \Thelia\Model\AttributeAv(); + $attributeAv + ->setPosition($row) + ->setLocale('fr_FR') + ->setTitle($data[0]) + ->setLocale('en_US') + ->setTitle($data[1]); + + $attribute->addAttributeAv($attributeAv); + } + $attribute->save(); + fclose($handle); + } + echo "colors attributes created with success\n"; + return $attribute; +} + +function clearTables() +{ + $productAssociatedContent = Thelia\Model\ProductAssociatedContentQuery::create() + ->find(); + $productAssociatedContent->delete(); + + $categoryAssociatedContent = Thelia\Model\CategoryAssociatedContentQuery::create() + ->find(); + $categoryAssociatedContent->delete(); + + $featureProduct = Thelia\Model\FeatureProductQuery::create() + ->find(); + $featureProduct->delete(); + + $attributeCombination = Thelia\Model\AttributeCombinationQuery::create() + ->find(); + $attributeCombination->delete(); + + $feature = Thelia\Model\FeatureQuery::create() + ->find(); + $feature->delete(); + + $feature = Thelia\Model\FeatureI18nQuery::create() + ->find(); + $feature->delete(); + + $featureAv = Thelia\Model\FeatureAvQuery::create() + ->find(); + $featureAv->delete(); + + $featureAv = Thelia\Model\FeatureAvI18nQuery::create() + ->find(); + $featureAv->delete(); + + $attribute = Thelia\Model\AttributeQuery::create() + ->find(); + $attribute->delete(); + + $attribute = Thelia\Model\AttributeI18nQuery::create() + ->find(); + $attribute->delete(); + + $attributeAv = Thelia\Model\AttributeAvQuery::create() + ->find(); + $attributeAv->delete(); + + $attributeAv = Thelia\Model\AttributeAvI18nQuery::create() + ->find(); + $attributeAv->delete(); + + $category = Thelia\Model\CategoryQuery::create() + ->find(); + $category->delete(); + + $category = Thelia\Model\CategoryI18nQuery::create() + ->find(); + $category->delete(); + + $product = Thelia\Model\ProductQuery::create() + ->find(); + $product->delete(); + + $product = Thelia\Model\ProductI18nQuery::create() + ->find(); + $product->delete(); + + + $accessory = Thelia\Model\AccessoryQuery::create() + ->find(); + $accessory->delete(); + + $stock = \Thelia\Model\ProductSaleElementsQuery::create() + ->find(); + $stock->delete(); + + $productPrice = \Thelia\Model\ProductPriceQuery::create() + ->find(); + $productPrice->delete(); + + \Thelia\Model\ProductImageQuery::create()->find()->delete(); +} \ No newline at end of file diff --git a/install/import/brand.csv b/install/import/brand.csv new file mode 100644 index 000000000..00cdf654b --- /dev/null +++ b/install/import/brand.csv @@ -0,0 +1,7 @@ +"MILAN" +"MAGIS" +"OXYO" +"OFFUS" +"PLINK" +"PARRY" +"TOKO" diff --git a/install/import/categories.csv b/install/import/categories.csv new file mode 100644 index 000000000..109e5c0f0 --- /dev/null +++ b/install/import/categories.csv @@ -0,0 +1,5 @@ +"CATEGORIES FR";"CATEGORIES UK" +"Chaises";"Chairs" +"Tabourets";"Stools" +"Fauteuils";"Armchairs" +"Canapés";"Sofas" diff --git a/install/import/colors.csv b/install/import/colors.csv new file mode 100644 index 000000000..9b5ebcb6a --- /dev/null +++ b/install/import/colors.csv @@ -0,0 +1,13 @@ +"Bleu";"Blue" +"Jaune";"Yellow" +"Orange";"Orange" +"Rose";"Pink" +"Vert";"Green" +"Violet";"Purple" +"Rouge";"Red" +"Gris";"Gray" +"Noir";"Black" +"Beige";"Beige" +"Turquoise";"Turquoise" +"Marron";"Brown" +"Blanc";"White" diff --git a/install/import/images/PROD001-1.jpg b/install/import/images/PROD001-1.jpg new file mode 100755 index 000000000..c340872f7 Binary files /dev/null and b/install/import/images/PROD001-1.jpg differ diff --git a/install/import/images/PROD001-2.jpg b/install/import/images/PROD001-2.jpg new file mode 100755 index 000000000..d1eba51b9 Binary files /dev/null and b/install/import/images/PROD001-2.jpg differ diff --git a/install/import/images/PROD001-3.jpg b/install/import/images/PROD001-3.jpg new file mode 100755 index 000000000..89f69a766 Binary files /dev/null and b/install/import/images/PROD001-3.jpg differ diff --git a/install/import/images/PROD001-4.jpg b/install/import/images/PROD001-4.jpg new file mode 100755 index 000000000..94eb80ce9 Binary files /dev/null and b/install/import/images/PROD001-4.jpg differ diff --git a/install/import/images/PROD001-5.jpg b/install/import/images/PROD001-5.jpg new file mode 100755 index 000000000..3036b2196 Binary files /dev/null and b/install/import/images/PROD001-5.jpg differ diff --git a/install/import/images/PROD002-1.jpg b/install/import/images/PROD002-1.jpg new file mode 100755 index 000000000..f38d005e0 Binary files /dev/null and b/install/import/images/PROD002-1.jpg differ diff --git a/install/import/images/PROD002-2.jpg b/install/import/images/PROD002-2.jpg new file mode 100755 index 000000000..61a57c5ad Binary files /dev/null and b/install/import/images/PROD002-2.jpg differ diff --git a/install/import/images/PROD002-3.jpg b/install/import/images/PROD002-3.jpg new file mode 100755 index 000000000..845a26031 Binary files /dev/null and b/install/import/images/PROD002-3.jpg differ diff --git a/install/import/images/PROD002-4.jpg b/install/import/images/PROD002-4.jpg new file mode 100755 index 000000000..f9570ca9b Binary files /dev/null and b/install/import/images/PROD002-4.jpg differ diff --git a/install/import/images/PROD002-5.jpg b/install/import/images/PROD002-5.jpg new file mode 100755 index 000000000..bbc71b065 Binary files /dev/null and b/install/import/images/PROD002-5.jpg differ diff --git a/install/import/images/PROD002-6.jpg b/install/import/images/PROD002-6.jpg new file mode 100755 index 000000000..73a1698c8 Binary files /dev/null and b/install/import/images/PROD002-6.jpg differ diff --git a/install/import/images/PROD003-1.jpg b/install/import/images/PROD003-1.jpg new file mode 100755 index 000000000..f968e29d5 Binary files /dev/null and b/install/import/images/PROD003-1.jpg differ diff --git a/install/import/images/PROD003-2.jpg b/install/import/images/PROD003-2.jpg new file mode 100755 index 000000000..aed200077 Binary files /dev/null and b/install/import/images/PROD003-2.jpg differ diff --git a/install/import/images/PROD003-3.jpg b/install/import/images/PROD003-3.jpg new file mode 100755 index 000000000..ff5f6a90c Binary files /dev/null and b/install/import/images/PROD003-3.jpg differ diff --git a/install/import/images/PROD004-1.jpg b/install/import/images/PROD004-1.jpg new file mode 100755 index 000000000..f33005c77 Binary files /dev/null and b/install/import/images/PROD004-1.jpg differ diff --git a/install/import/images/PROD004-2.jpg b/install/import/images/PROD004-2.jpg new file mode 100755 index 000000000..d844637a7 Binary files /dev/null and b/install/import/images/PROD004-2.jpg differ diff --git a/install/import/images/PROD005-1.jpg b/install/import/images/PROD005-1.jpg new file mode 100755 index 000000000..5e2e29dec Binary files /dev/null and b/install/import/images/PROD005-1.jpg differ diff --git a/install/import/images/PROD005-2.jpg b/install/import/images/PROD005-2.jpg new file mode 100755 index 000000000..c236abedd Binary files /dev/null and b/install/import/images/PROD005-2.jpg differ diff --git a/install/import/images/PROD005-3.jpg b/install/import/images/PROD005-3.jpg new file mode 100755 index 000000000..51697517f Binary files /dev/null and b/install/import/images/PROD005-3.jpg differ diff --git a/install/import/images/PROD005-4.jpg b/install/import/images/PROD005-4.jpg new file mode 100755 index 000000000..4f5165509 Binary files /dev/null and b/install/import/images/PROD005-4.jpg differ diff --git a/install/import/images/PROD005-5.jpg b/install/import/images/PROD005-5.jpg new file mode 100755 index 000000000..81c791943 Binary files /dev/null and b/install/import/images/PROD005-5.jpg differ diff --git a/install/import/images/PROD005-6.jpg b/install/import/images/PROD005-6.jpg new file mode 100755 index 000000000..f48cac242 Binary files /dev/null and b/install/import/images/PROD005-6.jpg differ diff --git a/install/import/images/PROD006-1.jpg b/install/import/images/PROD006-1.jpg new file mode 100755 index 000000000..ac75a7ba2 Binary files /dev/null and b/install/import/images/PROD006-1.jpg differ diff --git a/install/import/images/PROD006-2.jpg b/install/import/images/PROD006-2.jpg new file mode 100755 index 000000000..fb72ae255 Binary files /dev/null and b/install/import/images/PROD006-2.jpg differ diff --git a/install/import/images/PROD006-3.jpg b/install/import/images/PROD006-3.jpg new file mode 100755 index 000000000..bd7f5721e Binary files /dev/null and b/install/import/images/PROD006-3.jpg differ diff --git a/install/import/images/PROD006-4.jpg b/install/import/images/PROD006-4.jpg new file mode 100755 index 000000000..394283e56 Binary files /dev/null and b/install/import/images/PROD006-4.jpg differ diff --git a/install/import/images/PROD006-5.jpg b/install/import/images/PROD006-5.jpg new file mode 100755 index 000000000..d258db936 Binary files /dev/null and b/install/import/images/PROD006-5.jpg differ diff --git a/install/import/images/PROD006-6.jpg b/install/import/images/PROD006-6.jpg new file mode 100755 index 000000000..982815847 Binary files /dev/null and b/install/import/images/PROD006-6.jpg differ diff --git a/install/import/images/PROD007-1.jpg b/install/import/images/PROD007-1.jpg new file mode 100755 index 000000000..fda1d2880 Binary files /dev/null and b/install/import/images/PROD007-1.jpg differ diff --git a/install/import/images/PROD007-2.jpg b/install/import/images/PROD007-2.jpg new file mode 100755 index 000000000..a784790cf Binary files /dev/null and b/install/import/images/PROD007-2.jpg differ diff --git a/install/import/images/PROD007-3.jpg b/install/import/images/PROD007-3.jpg new file mode 100755 index 000000000..30b5637ae Binary files /dev/null and b/install/import/images/PROD007-3.jpg differ diff --git a/install/import/images/PROD007-4.jpg b/install/import/images/PROD007-4.jpg new file mode 100755 index 000000000..00556c665 Binary files /dev/null and b/install/import/images/PROD007-4.jpg differ diff --git a/install/import/images/PROD008-1.jpg b/install/import/images/PROD008-1.jpg new file mode 100755 index 000000000..dc8e0bead Binary files /dev/null and b/install/import/images/PROD008-1.jpg differ diff --git a/install/import/images/PROD008-2.jpg b/install/import/images/PROD008-2.jpg new file mode 100755 index 000000000..173bed1aa Binary files /dev/null and b/install/import/images/PROD008-2.jpg differ diff --git a/install/import/images/PROD008-3.jpg b/install/import/images/PROD008-3.jpg new file mode 100755 index 000000000..790d8add6 Binary files /dev/null and b/install/import/images/PROD008-3.jpg differ diff --git a/install/import/images/PROD008-4.jpg b/install/import/images/PROD008-4.jpg new file mode 100755 index 000000000..ec4af28cc Binary files /dev/null and b/install/import/images/PROD008-4.jpg differ diff --git a/install/import/images/PROD008-5.jpg b/install/import/images/PROD008-5.jpg new file mode 100755 index 000000000..91e7ebaa0 Binary files /dev/null and b/install/import/images/PROD008-5.jpg differ diff --git a/install/import/images/PROD009-1.jpg b/install/import/images/PROD009-1.jpg new file mode 100755 index 000000000..3a143de1a Binary files /dev/null and b/install/import/images/PROD009-1.jpg differ diff --git a/install/import/images/PROD009-2.jpg b/install/import/images/PROD009-2.jpg new file mode 100755 index 000000000..b5ccde667 Binary files /dev/null and b/install/import/images/PROD009-2.jpg differ diff --git a/install/import/images/PROD009-3.jpg b/install/import/images/PROD009-3.jpg new file mode 100755 index 000000000..76d465a47 Binary files /dev/null and b/install/import/images/PROD009-3.jpg differ diff --git a/install/import/images/PROD010-1.jpg b/install/import/images/PROD010-1.jpg new file mode 100755 index 000000000..5f9df3fbb Binary files /dev/null and b/install/import/images/PROD010-1.jpg differ diff --git a/install/import/images/PROD010-2.jpg b/install/import/images/PROD010-2.jpg new file mode 100755 index 000000000..3fe504716 Binary files /dev/null and b/install/import/images/PROD010-2.jpg differ diff --git a/install/import/images/PROD010-3.jpg b/install/import/images/PROD010-3.jpg new file mode 100755 index 000000000..867361eb9 Binary files /dev/null and b/install/import/images/PROD010-3.jpg differ diff --git a/install/import/images/PROD010-4.jpg b/install/import/images/PROD010-4.jpg new file mode 100755 index 000000000..f9681b9bf Binary files /dev/null and b/install/import/images/PROD010-4.jpg differ diff --git a/install/import/images/PROD011-1.jpg b/install/import/images/PROD011-1.jpg new file mode 100755 index 000000000..8130598bc Binary files /dev/null and b/install/import/images/PROD011-1.jpg differ diff --git a/install/import/images/PROD011-2.jpg b/install/import/images/PROD011-2.jpg new file mode 100755 index 000000000..e37c4baaf Binary files /dev/null and b/install/import/images/PROD011-2.jpg differ diff --git a/install/import/images/PROD011-3.jpg b/install/import/images/PROD011-3.jpg new file mode 100755 index 000000000..ba4530c3c Binary files /dev/null and b/install/import/images/PROD011-3.jpg differ diff --git a/install/import/images/PROD011-4.jpg b/install/import/images/PROD011-4.jpg new file mode 100755 index 000000000..b749649d8 Binary files /dev/null and b/install/import/images/PROD011-4.jpg differ diff --git a/install/import/images/PROD012-1.jpg b/install/import/images/PROD012-1.jpg new file mode 100755 index 000000000..ff885661d Binary files /dev/null and b/install/import/images/PROD012-1.jpg differ diff --git a/install/import/images/PROD012-2.jpg b/install/import/images/PROD012-2.jpg new file mode 100755 index 000000000..c27fd1cbb Binary files /dev/null and b/install/import/images/PROD012-2.jpg differ diff --git a/install/import/images/PROD013-1.jpg b/install/import/images/PROD013-1.jpg new file mode 100755 index 000000000..729fe97f7 Binary files /dev/null and b/install/import/images/PROD013-1.jpg differ diff --git a/install/import/images/PROD014-1.jpg b/install/import/images/PROD014-1.jpg new file mode 100755 index 000000000..384b1939e Binary files /dev/null and b/install/import/images/PROD014-1.jpg differ diff --git a/install/import/images/PROD014-2.jpg b/install/import/images/PROD014-2.jpg new file mode 100755 index 000000000..42de512f5 Binary files /dev/null and b/install/import/images/PROD014-2.jpg differ diff --git a/install/import/images/PROD014-3.jpg b/install/import/images/PROD014-3.jpg new file mode 100755 index 000000000..0270dc868 Binary files /dev/null and b/install/import/images/PROD014-3.jpg differ diff --git a/install/import/images/PROD014-4.jpg b/install/import/images/PROD014-4.jpg new file mode 100755 index 000000000..e845a8838 Binary files /dev/null and b/install/import/images/PROD014-4.jpg differ diff --git a/install/import/images/PROD015-1.jpg b/install/import/images/PROD015-1.jpg new file mode 100755 index 000000000..f99e9e275 Binary files /dev/null and b/install/import/images/PROD015-1.jpg differ diff --git a/install/import/images/PROD015-2.jpg b/install/import/images/PROD015-2.jpg new file mode 100755 index 000000000..b56a13951 Binary files /dev/null and b/install/import/images/PROD015-2.jpg differ diff --git a/install/import/images/PROD016-1.jpg b/install/import/images/PROD016-1.jpg new file mode 100755 index 000000000..3aff2648a Binary files /dev/null and b/install/import/images/PROD016-1.jpg differ diff --git a/install/import/images/PROD017-1.jpg b/install/import/images/PROD017-1.jpg new file mode 100755 index 000000000..1a620ab47 Binary files /dev/null and b/install/import/images/PROD017-1.jpg differ diff --git a/install/import/images/PROD017-2.jpg b/install/import/images/PROD017-2.jpg new file mode 100755 index 000000000..82a20f1fb Binary files /dev/null and b/install/import/images/PROD017-2.jpg differ diff --git a/install/import/images/PROD017-3.jpg b/install/import/images/PROD017-3.jpg new file mode 100755 index 000000000..d476eb773 Binary files /dev/null and b/install/import/images/PROD017-3.jpg differ diff --git a/install/import/images/PROD017-4.jpg b/install/import/images/PROD017-4.jpg new file mode 100755 index 000000000..b3a3e4707 Binary files /dev/null and b/install/import/images/PROD017-4.jpg differ diff --git a/install/import/images/PROD018-1.jpg b/install/import/images/PROD018-1.jpg new file mode 100755 index 000000000..cefa9992e Binary files /dev/null and b/install/import/images/PROD018-1.jpg differ diff --git a/install/import/images/PROD019-1.jpg b/install/import/images/PROD019-1.jpg new file mode 100755 index 000000000..2e45bb27f Binary files /dev/null and b/install/import/images/PROD019-1.jpg differ diff --git a/install/import/images/PROD019-2.jpg b/install/import/images/PROD019-2.jpg new file mode 100755 index 000000000..9b47f6ea1 Binary files /dev/null and b/install/import/images/PROD019-2.jpg differ diff --git a/install/import/images/PROD019-3.jpg b/install/import/images/PROD019-3.jpg new file mode 100755 index 000000000..02aa975da Binary files /dev/null and b/install/import/images/PROD019-3.jpg differ diff --git a/install/import/images/PROD019-4.jpg b/install/import/images/PROD019-4.jpg new file mode 100755 index 000000000..fad8bbf59 Binary files /dev/null and b/install/import/images/PROD019-4.jpg differ diff --git a/install/import/images/PROD019-5.jpg b/install/import/images/PROD019-5.jpg new file mode 100755 index 000000000..0e2377b8c Binary files /dev/null and b/install/import/images/PROD019-5.jpg differ diff --git a/install/import/images/PROD020-1.jpg b/install/import/images/PROD020-1.jpg new file mode 100755 index 000000000..14b7ae55b Binary files /dev/null and b/install/import/images/PROD020-1.jpg differ diff --git a/install/import/images/PROD021-1.jpg b/install/import/images/PROD021-1.jpg new file mode 100755 index 000000000..5cd5e27ed Binary files /dev/null and b/install/import/images/PROD021-1.jpg differ diff --git a/install/import/images/PROD021-2.jpg b/install/import/images/PROD021-2.jpg new file mode 100755 index 000000000..119afa3be Binary files /dev/null and b/install/import/images/PROD021-2.jpg differ diff --git a/install/import/images/PROD021-3.jpg b/install/import/images/PROD021-3.jpg new file mode 100755 index 000000000..0b4470d3c Binary files /dev/null and b/install/import/images/PROD021-3.jpg differ diff --git a/install/import/images/PROD021-4.jpg b/install/import/images/PROD021-4.jpg new file mode 100755 index 000000000..0cffa4dea Binary files /dev/null and b/install/import/images/PROD021-4.jpg differ diff --git a/install/import/images/PROD022-1.jpg b/install/import/images/PROD022-1.jpg new file mode 100755 index 000000000..72eb89cfe Binary files /dev/null and b/install/import/images/PROD022-1.jpg differ diff --git a/install/import/images/PROD022-2.jpg b/install/import/images/PROD022-2.jpg new file mode 100755 index 000000000..85292d60d Binary files /dev/null and b/install/import/images/PROD022-2.jpg differ diff --git a/install/import/images/PROD022-3.jpg b/install/import/images/PROD022-3.jpg new file mode 100755 index 000000000..e564ed1b6 Binary files /dev/null and b/install/import/images/PROD022-3.jpg differ diff --git a/install/import/images/PROD022-4.jpg b/install/import/images/PROD022-4.jpg new file mode 100755 index 000000000..09d39fd35 Binary files /dev/null and b/install/import/images/PROD022-4.jpg differ diff --git a/install/import/images/PROD022-5.jpg b/install/import/images/PROD022-5.jpg new file mode 100755 index 000000000..f47219289 Binary files /dev/null and b/install/import/images/PROD022-5.jpg differ diff --git a/install/import/images/PROD023-1.jpg b/install/import/images/PROD023-1.jpg new file mode 100755 index 000000000..e645f5eb9 Binary files /dev/null and b/install/import/images/PROD023-1.jpg differ diff --git a/install/import/images/PROD023-2.jpg b/install/import/images/PROD023-2.jpg new file mode 100755 index 000000000..ad438c981 Binary files /dev/null and b/install/import/images/PROD023-2.jpg differ diff --git a/install/import/images/PROD023-3.jpg b/install/import/images/PROD023-3.jpg new file mode 100755 index 000000000..ccafdb7fa Binary files /dev/null and b/install/import/images/PROD023-3.jpg differ diff --git a/install/import/images/PROD023-4.jpg b/install/import/images/PROD023-4.jpg new file mode 100755 index 000000000..a2fc55786 Binary files /dev/null and b/install/import/images/PROD023-4.jpg differ diff --git a/install/import/images/PROD023-5.jpg b/install/import/images/PROD023-5.jpg new file mode 100755 index 000000000..bf67ea4b0 Binary files /dev/null and b/install/import/images/PROD023-5.jpg differ diff --git a/install/import/images/PROD023-6.jpg b/install/import/images/PROD023-6.jpg new file mode 100755 index 000000000..5d037669b Binary files /dev/null and b/install/import/images/PROD023-6.jpg differ diff --git a/install/import/images/PROD024-1.jpg b/install/import/images/PROD024-1.jpg new file mode 100755 index 000000000..7f3874205 Binary files /dev/null and b/install/import/images/PROD024-1.jpg differ diff --git a/install/import/images/PROD024-2.jpg b/install/import/images/PROD024-2.jpg new file mode 100755 index 000000000..fcd4bd587 Binary files /dev/null and b/install/import/images/PROD024-2.jpg differ diff --git a/install/import/images/PROD024-3.jpg b/install/import/images/PROD024-3.jpg new file mode 100755 index 000000000..1d0c8deef Binary files /dev/null and b/install/import/images/PROD024-3.jpg differ diff --git a/install/import/images/PROD024-4.jpg b/install/import/images/PROD024-4.jpg new file mode 100755 index 000000000..7ff3957c1 Binary files /dev/null and b/install/import/images/PROD024-4.jpg differ diff --git a/install/import/images/PROD024-5.jpg b/install/import/images/PROD024-5.jpg new file mode 100755 index 000000000..53a63564c Binary files /dev/null and b/install/import/images/PROD024-5.jpg differ diff --git a/install/import/images/PROD025-1.jpg b/install/import/images/PROD025-1.jpg new file mode 100755 index 000000000..54fa325e5 Binary files /dev/null and b/install/import/images/PROD025-1.jpg differ diff --git a/install/import/images/PROD025-2.jpg b/install/import/images/PROD025-2.jpg new file mode 100755 index 000000000..fd3ba1611 Binary files /dev/null and b/install/import/images/PROD025-2.jpg differ diff --git a/install/import/images/PROD025-3.jpg b/install/import/images/PROD025-3.jpg new file mode 100755 index 000000000..6ec0c96ef Binary files /dev/null and b/install/import/images/PROD025-3.jpg differ diff --git a/install/import/images/PROD026-1.jpg b/install/import/images/PROD026-1.jpg new file mode 100755 index 000000000..96bb2b392 Binary files /dev/null and b/install/import/images/PROD026-1.jpg differ diff --git a/install/import/images/PROD027-1.jpg b/install/import/images/PROD027-1.jpg new file mode 100755 index 000000000..9ab635023 Binary files /dev/null and b/install/import/images/PROD027-1.jpg differ diff --git a/install/import/images/PROD028-1.jpg b/install/import/images/PROD028-1.jpg new file mode 100755 index 000000000..1a166e91b Binary files /dev/null and b/install/import/images/PROD028-1.jpg differ diff --git a/install/import/images/PROD029-1.jpg b/install/import/images/PROD029-1.jpg new file mode 100755 index 000000000..e25b56f18 Binary files /dev/null and b/install/import/images/PROD029-1.jpg differ diff --git a/install/import/images/PROD030-1.jpg b/install/import/images/PROD030-1.jpg new file mode 100755 index 000000000..731d82897 Binary files /dev/null and b/install/import/images/PROD030-1.jpg differ diff --git a/install/import/images/PROD030-2.jpg b/install/import/images/PROD030-2.jpg new file mode 100755 index 000000000..15ecbef26 Binary files /dev/null and b/install/import/images/PROD030-2.jpg differ diff --git a/install/import/images/PROD030-3.jpg b/install/import/images/PROD030-3.jpg new file mode 100755 index 000000000..8f3d9eb54 Binary files /dev/null and b/install/import/images/PROD030-3.jpg differ diff --git a/install/import/images/PROD030-4.jpg b/install/import/images/PROD030-4.jpg new file mode 100755 index 000000000..2d402e8d9 Binary files /dev/null and b/install/import/images/PROD030-4.jpg differ diff --git a/install/import/products.csv b/install/import/products.csv new file mode 100644 index 000000000..b085feee2 --- /dev/null +++ b/install/import/products.csv @@ -0,0 +1,35 @@ +"REF";"TITRE UK";"CHAPO UK";"CHAPO FR";"DESCRIPTIF UK";"DESCRIPTIF FR";"POSTSCRIPTUM UK";"POSTSCRIPTUM FR";"PRIX";"PRIX2";"PHOTO";"BRAND";"COULEUR UK";"CATEGORIE" +"PROD001";"Horatio";"Contemporary atypical chair";"Chaise contemporaine hors normes";"Its design is based on a very simple idea : atypical aesthetics for an everyday use. You may even choose to combine the various colours ! A specific look that will happily and impertinently fit with your furniture. ";"Son design est issu d'une idée très simple: un esthétique hors du commun pour un usage de tous les jours. On peut même choisir de combiner les différents coloris! Un look qui se mêle avec bonheur et impertinence à votre mobilier. +";"Dimensions : Width : 20'' – Depth: 19'' – Height: 42''";"Dimensions : Larg 52 cm - Prof 50 cm - Haut 108 cm";223;199;"PROD001-1.jpg;PROD001-2.jpg;PROD001-3.jpg;PROD001-4.jpg";"MILAN";"blue;pink;red;green;purple";"Chairs" +"PROD002";"Travis";"Ergonomic & affordable";"Ergonomique et économique";"Ergonomic, affordable, comfortable, stackable, easily dismantled, this little stool became a cult item. Decorative feature or occasional seat, it suits perfectly any room in the house. ";"Ergonomique, économique, confortable, empilable, démontable, ce petit tabouret est devenu un objet culte. Elément de décor ou siège d'appoint, il a sa place dans toute la maison. +";"Dimensions : Diam. 11'' – Height: 17''";"Dimensions : Diam 30 cm - Haut 45 cm";25;19;"PROD002-1.jpg;PROD002-2.jpg;PROD002-3.jpg;PROD002-4.jpg;PROD002-5.jpg;PROD002-6.jpg";"MAGIS";"blue;orange;yellow;pink;purple;green";"Stools" +"PROD003";"Stacy";"A successfull mix";"Un mariage réussi";"The ''Stacy'' armchair brings a taste of playfulness in the design's world for more than 20 years ! The successfull mix of French Regence style and ultra modern materials creates a strong charismatic personality. ";"Le fauteuil Stacy apporte une note de fantaisie dans le monde du design depuis plus de 20 ans ! Sa personnalité forte et charismatique s'exprime au travers de cette association de style Régence et de matériaux ultramoderne. ";"Dimensions : Width :44'' – Depth:31'' – Height: 42'' . Sitting : width : 25''– Height : 16'' . Armrests height : 27''";"Dimensions : Larg 114 cm x Prof 80 cm x H 108 cm - Assise : larg 65 cm x H 42 cm - Accoudoirs : H 69 cm";653;610;"PROD003-1.jpg;PROD003-2.jpg;PROD003-3.jpg;";"MILAN";"blue;purple;green";"Armchairs" +"PROD004";"Scarlett";"A timeless treasure";"Un trésor intemporel";"Treasured and timeless styling characterizes the luxury ''Scarlett'' Armchair. It will instantly add a dash of refined appeal to any living space. Beneath the luxurious fabric cover is a solid wood frame, ensuring that this piece will be passed on from generation to generation. ";"Un style précieux et intemporel caractérise la luxueuse banquette Scarlett. Elle apporte immédiatement une touche de raffinement à n'importe quel salon. Sous l'étoffe précieuse, un solide châssis bois vous assure que cette pièce traversera les époques et les générations. ";"Dimensions : Width :65'' – Depth:31''– Height: 38''";"Dimensions : Larg 165 cm x Prof 80 cm x H 95 cm";956;899;"PROD004-1.jpg;PROD004-2.jpg";"OXYO";"gray;black";"Armchairs" +"PROD005";"Owen";"An eye-catching armchair";"Un fauteuil surprenant";"Get a look at the future – retro style - with our cutout ''Owen'' armchair ! Eye-catching and incredibly fun, this armchair is a must-have for today's hottest living space ! ";"Revisitez le futur avec une note retro grâce à notre fauteuil Owen! Spectaculaire et incroyablement fun, ce fauteuil est incontournable pour un salon moderne et branché ! ";"Dimensions : Width :30'' – Depth:31''– Height: 35''";"Dimensions : Larg 75 cm - Prof 80 cm - Haut 90 cm";395;;"PROD005-1.jpg;PROD005-2.jpg;PROD005-3.jpg;PROD005-4.jpg;PROD005-5.jpg;PROD005-6.jpg";"OXYO";"blue;purple;green;pink;red;orange;";"Armchairs" +"PROD006";"Nigel";"A comfortable beauty";"Une beauté confortable";"This comfortable beauty does great solo as a lounger or in a book nook. With the ''Nigel'' sofa, you will get hours of cozy relaxation. This oversized seat is the ultimate lounger but the pure design still keeps it modern and hip. ";"La beauté confortable du sofa Nigel permet tous les solos dans votre salon ou votre bibliothèque. Relaxez vous tranquilement avec le canapé Nigel. Ce siège généreux est l'expression même du fauteuil mais ses lignes pures lui assurent un style moderne et tendance. ";"Dimensions: Width : 48"" - Depth : 32"" - Height : 28"" – 17"" seat Height";"Dimensions : Larg 120 cm – Prof  80 cm – Haut. 70 cm . Hauteur d'assise : 40 cm";638;;"PROD006-1.jpg;PROD006-2.jpg;PROD006-3.jpg;PROD006-4.jpg;PROD006-5.jpg;PROD006-6.jpg";"OXYO";"blue;beige;purple;green;pink;turquoise";"Sofas" +"PROD007";"Heathcliff";"A unique style";"Un style unique";"Provide a rich texture to any living space thanks to the tufting and velvet of the ''Heathcliff'' sofa. Arched roll arms and vibrant colours add to the fun and unique style of this sofa. ";"Enrichissez votre intérieur de velours et de textures capitonnées du canapé Heathcliff. Les accoudoirs arrondis en finition cloutée et la gamme de couleurs acidulées apportent un style et une fantaisie unique à ce sofa. ";"Dimensions: Width : 92"" - Depth : 43"" - Height : 36""";"Dimensions : Larg 230 cm – Prof. 110 cm – Haut. 90 cm";1120;;"PROD007-1.jpg;PROD007-2.jpg;PROD007-3.jpg;PROD007-4.jpg;";"OFFUS";"turquoise;blue;pink;purple";"Sofas" +"PROD008";"Wilson";"Pure luxury !";"Le luxe à l'état pur !";"Choose our ''Wilson'' armchair and surround yourself in luxury. You will appreciate it's high armrests that will keep you nestled in comfort. Beautiful coloured leather upholstery makes a fashion-forward design statement. ";"Adoptez notre fauteuil Wilson et plongez dans le luxe. Vous apprécierez ses hauts accoudoirs qui vous envelopperont de confort et de douceur. L'habillage en cuir de couleur vive en fait une pièce de design avant-gardiste. ";"Dimensions : Width : 38"" - Depth : 36"" - Height : 34""";"Dimensions : larg 95 cm – Prof. 90 cm – Haut. 90 cm";489;;"PROD008-1.jpg;PROD008-2.jpg;PROD008-3.jpg;PROD008-4.jpg;PROD008-5.jpg;";"PLINK";"blue;green;pink;purple;brown;";"Armchairs" +"PROD009";"Zoe";"An exceptional combination";"Une union exceptionnelle";"Contemporary ''Zoe'' armchair is an exceptional combination of function and design. +The seating is generously cushioned for comfort. Contoured, wrap-around back offers optimal support. The brushed stainless steel base ensures stability. +Swivel feature for added function. ";"Zoe est un fauteuil contemporain qui combine de manière exceptionnelle fonctionnalité et design. L'assise est garnie d'un coussin généreux pour plus de confort. Le dossier enveloppant offre un appui optimal. La stabilité de l'ensemble est assurée par une base en inox brossé. Siège pivotant. ";"Dimensions : Width : 30'' – Depth : 27'' – height : 31''";"Dimensions : Larg. 75 cm – Prof. 69 cm – Haut. 80 cm";520;;"PROD009-1.jpg;PROD009-2.jpg;PROD009-3.jpg";"PLINK";"blue;purple;orange";"Armchairs" +"PROD010";"Sigmund";"A fun project";"Un projet fou";"The contrast of a vintage couch and modern colours provides a really fun project called ''Sigmund'' ! It will instantly add a dash of impertinence for any hip living place. ";"Le projet fantastique appelé Sigmund provient d'un contraste étonnant entre un canapé vintage et un éventail de couleurs moderne. Ce canapé apportera immédiatement une touche d'impertinence à n'importe quel salon branché. ";"Dimensions: Width : 92"" - Depth : 43"" - Height : 36""";"Dimensions : Larg 230 cm – Prof. 110 cm – Haut. 90 cm";834;;"PROD010-1.jpg;PROD010-2.jpg;PROD010-3.jpg;PROD010-4.jpg";"OFFUS";"blue;purple;red;orange";"Armchairs ; Sofas" +"PROD011";"Tina";"The little plastic chair";"La petite chaise en plastique";"This little ''Tina'' plastic chair will become your new red hot favourite thanks to its efficient design. Stackable and made of recyclable material, Tina suits perfectly any room in the house ! ";"L'efficacité du design de cette petite chaise en plastique Tina en fera vite votre favorite. Empilable et recyclable, Tina se glissera parfaitement dans n'importe quelle pièce de votre maison ! ";"Dimensions : Width : 19'' – Depth : 23'' – Height : 31''";"Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm ";75;;"PROD011-1.jpg;PROD011-2.jpg;PROD011-3.jpg;PROD011-4.jpg";"PARRY";"blue;orange;red;purple";"Chairs" +"PROD012";"Victoria";"Pure lines";"Des lignes éûrées";"A successfull combination of Regence style and ultra modern material. The pure lines of the ''Victoria'' armchair together with its translucent brilliance make a fashion-forward design statement. ";"Un mariage réussit du style Régence et de matériaux ultra modernes. Les lignes pures de la chaise Victoria associées à la brillance translucide de sa matière en font une pièce de design avant-gardiste. ";"Dimensions : Width :44'' – Depth:31'' – Height: 42'' . Sitting : width : 25''– Height : 16'' . Armrests height : 27''";"Dimensions : Larg 114 cm x Prof 80 cm x H 108 cm - Assise : larg 65 cm x H 42 cm - Accoudoirs : H 69 cm";138;;"PROD012-1.jpg;PROD012-2.jpg";"MILAN";"black";"Armchairs" +"PROD013";"Violet";"A beautifull classic";"Une beauté classique";"A new edition of a classic. Beneath a beautiful colorfull leather, a strong walnut wood frame. You will appreciate the luxurious stylish details of the ''Violet'' armless chair. ";"La réédition d'un classique. Sous un superbe cuir aux couleurs chatoyantes, une solide structure en noyer. Vous apprécierez les détails stylistiques luxueux de notre chaise Violet. ";"Dimensions : Width : 19'' – Depth : 23'' – Height : 31''";"Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm";98;;"PROD013-1.jpg";"MAGIS";"Gray";"Chairs" +"PROD014";"Sally";"Contemporary atypical chair";"Chaise contemporaine hors normes";"Contemporary atypical chair. The atypical sitting of the ''Sally '' chair will nestled you in confort. Play with the vibrant colours range to create a unique dining room. ";"Chaise contemporaine hors normes. L'assise surprenante de la chaise Sally vous enveloppera de confort. Amusez vous avec l'éventail de couleurs lumineuses pour créer une salle à manger unique. ";"Dimensions : Width : 19'' – Depth : 23'' – Height : 31''";"Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm";112;;"PROD014-1.jpg;PROD014-2.jpg;PROD014-3.jpg;PROD014-4.jpg";"PARRY";"blue;purple;orange;yellow";"Chairs" +"PROD015";"Oliver";"Comfort & Design";"Confort et Design";"Surround yourself in ultra modern luxury with the ''Oliver'' armchair and get a look at the future ! Eye-catching, this unique combination of comfort and design is a must-have for today's book nook. ";"Abandonnez vous à un univers de luxe ultra moderne avec le fauteuil Oliver et voyagez dans le futur ! Cette combinaison unique de confort et de design est spectaculaire. Un élément incontournable pour votre bibliothèque. ";"Dimensions : Width : 30'' – Depth : 27'' – height : 31''";"Dimensions : Larg. 75 cm – Prof. 69 cm – Haut. 80 cm";340;;"PROD015-1.jpg;PROD015-2.jpg;";"MAGIS";"white;black";"Armchairs;Chairs" +"PROD016";"Lexie";"A modern style";"Un style moderne";"Demonstrate your flair for modern style with our ''Lexie'' chair in your dining room. A rectangular cushioned back offers a contemporary feel, while the comfortable seat provides complete comfort. ";"Montrez que vous avez le sens de la modernité en choisissant la chaise ''Lexie'' pour votre salle à manger. Le coussin rectangulaire sur le dossier apporte une touche contemporaine. L'assise généreuse apporte un confort complet. ";"Dimensions : Width : 19'' – Depth : 23'' – Height : 40''";"Dimensions : larg. 50 cm – Prof. 60 cm – Haut. 100 cm";159;;"PROD016-1.jpg";"PLINK";"Beige";"Chairs" +"PROD017";"Flynn";"A touch of retro vibe";"Un petit air rétro";"If your destination is up-to-date décor with a touch of retro vibe, look no further than our ''Flynn'' sofa. Sleek, low track arms and high tapering legs give this piece a mid-century flavor. The vibrant tones of the woven upholstery will easily blend with any interior décor. ";"Si vous recherchez une décoration actuelle avec une touche rétro, n'allez pas plus loin et opter pour notre canapé ''Flynn''. Ce canapé a un petit air des années 50 grâce à ses accoudoirs bas, ses pieds allongés et ses lignes pures. Les couleurs chatoyantes de son revêtement en laine lui permettent de se fondre dans tous les intérieurs. ";"Dimensions : Width : 89'' – Depth : 37'' – Height : 36''";"Dimensions : Larg. 225 cm – Prof. 95 cm – Haut. 90 cm";1299;;"PROD017-1.jpg;PROD017-2.jpg;PROD017-3.jpg;PROD017-4.jpg";"OFFUS";"blue;green;red;purple";"Sofas" +"PROD018";"Emily";"A old-world feel";"Une touche d'histoire";"Our ''Emily'' armlesschair adds a touch of a old-world feel to your space. Perfect for when defining the seating space in a larger room. A medium wood finish sets off the delicate embellishments at the base, while the luxurous upholstery keeps the look fresh. The cushions guarantee that this is a chair worth relaxing in, not just admiring from afar. ";"La chaise ''Emily'' apporte une touche d'histoire à votre intérieur. Elle est parfaite pour structurer votre espace, notamment dans une grande pièce. Les finitions bois font la part belle à de délicates arabesques, tandis que le luxueux revêtement apporte un look frais. Cette chaise n'est pas destinée à la figuration grâce à la mousse confortable de l'assise. ";"Dimensions : Width : 33'' – Depth : 27'' – Height : 40''";"Dimensions : Larg. 85 cm – Prof. 69 cm – Haut. 100 cm";690;;"PROD018-1.jpg";"PARRY";"red";"Armchairs" +"PROD019";"Edgar";"A special spot";"Un endroit à part";"A special spot for reading, lounging or chatting, our '' Edgar '' armchair has no reservations when it comes to style. The design starts with mid-century modern elements like lean arms, while the brushed stainless steel base ensures stability. Swivel feature for added function. ";"Un endroit spécial où lire, rêver ou discuter, notre fauteuil ''Edgar'' n'a pas de limite quand il s'agit de style. Son design part d'éléments contemporains comme ses accoudoirs bas et fins, tandis que sa base en inox brossé assure la stabilité de l'ensemble. Siège pivotant. ";"Dimensions : Width : 33'' – Depth : 27'' – Height : 40''";"Dimensions: Larg. 85 cm – Prof. 69 cm – Haut. 100 cm";275;;"PROD019-1.jpg;PROD019-2.jpg;PROD019-3.jpg;PROD019-4.jpg;PROD019-5.jpg";"TOKO";"blue;yellow;orange;pink;purple";"Armchairs" +"PROD020";"Pamela";"Clean lines";"Des lignes pures";"By making our ''Pamela'' chair a centerpiece of your dining area, you'll demonstrate your eye for clean lines and comfortable seating. The contemporary touches of this chair are provided by the light brown wool, a flared seat back and slightly curved wood back legs. The color of the uphostery is the perfect complement to the wood finish of the chair legs. ";"Choisissez notre chaise '' Pamela'' comme pièce maitresse de votre salle à manger et faites la démonstration de votre maitrise des lignes épurées et du confort d'assise. L'allure contemporaine de cette chaise provient de la laine beige, du dossier légèrement évasé et des pieds en bois arrières délicatement incurvés. La couleur du revêtement fait parfaitement écho à la finition bois des pieds. Dimensions : larg. 50 cm – Prof. 60 cm – Haut. 100 cm";"Dimensions : Width : 19'' – Depth : 23'' – Height : 40''";"Dimensions : Width : 19'' – Depth : 23'' – Height : 40''";189;;"PROD020-1.jpg";"OFFUS";"brown";"Chairs" +"PROD021";"Courtney";"Mil madness";"Douce folie";"Add a dash of mild madness to your kitchen ! Eye-catching, this ''Courtney'' armless chair is a must-have for hip dining area.";"Mettez une touche de douce folie dans votre cuisine ! Surprenante, notre chaise ''Courtney'' est incontournable pour un coin repas branché. ";"Dimensions : Width : 19'' – Depth : 23'' – Height : 31''";"Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm ";89;;"PROD021-1.jpg;PROD021-2.jpg;PROD021-3.jpg;PROD021-4.jpg";"TOKO";"blue;orange;green;purple";"Chairs" +"PROD022";"Barbara";"An amazing look";"Un look détonnant";"An amazing look for our ''Barbara'' chair ! A cut-out oval in the back provides a distinctive character, while the lively range of colours and the mat finish makes a big style statement. Dimensions : Width : 19'' – Depth : 23'' – Height : 31''";"Un look hors du commun pour la chaise ''Barbara'' ! L'ouverture oval du dossier apporte une personnalité toute particulière tandis que la large gamme de couleurs vives et le rendu mat provoque un vrai effet de style. Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm ";"Width : 19'' – Depth : 23'' – Height : 31''";"Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm ";122;;"PROD022-1.jpg;PROD022-2.jpg;PROD022-3.jpg;PROD022-4.jpg;PROD022-5.jpg";"MAGIS";"blue;turquoise;yellow;orange;red";"Chairs" +"PROD023";"Haley";"An armless chair coming from outer space !";"Une chaise cosmique !";"This ''Haley'' amazing chair is as light as paper but sturdy as steel. Play with the vibrant colours range to create a unique dining area. ";"La chaise ''Haley'' est étonnante : légère comme le papier mais solide comme l'acier. Jouez avec la gamme de couleurs vibrantes pour composer un espace repas unique.";"Dimensions : Width : 19'' – Depth : 23'' – Height : 31''";"Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm ";93;;"PROD023-1.jpg;PROD023-2.jpg;PROD023-3.jpg;PROD023-4.jpg;PROD023-5.jpg;PROD023-6.jpg";"MILAN";"purple;green;pink;red;orange;turquoise";"Chairs" +"PROD024";"Kyle";"A modern silhouette";"Un look moderne";"The modern silhouette of the ''Kyle'' sofa features cantilevered legs in a mirror chrome finish and pillow armrests. The button-tufted seat and back cushions highlight the detailed craftsmanship. ";"Le canapé ''Kyle'' offre une silhouette moderne grâce à ses pieds chromés en porte-à-faux et ses accoudoirs moelleux. L'assise et le dossier capitonnés mettent en valeur le travail précis de l'artisan.";"Dimensions: Width : 92"" - Depth : 43"" - Height : 36""";"Dimensions : Larg 230 cm – Prof. 110 cm – Haut. 90 cm";1799;;"PROD024-1.jpg;PROD024-2.jpg;PROD024-3.jpg;PROD024-4.jpg;PROD024-5.jpg";"TOKO";"blue;pink;red;green;purple";"Sofas" +"PROD025";"Kenny";"A fresh take on a classic chair ";"Un classique revisité";"Chic design elements and a lovely pattern bring cool interest to this ''Kenny'' chair. The well-lofted seat cushion offers ultimate comfort and support.";"Des éléments de design élégants et un motif chic apporte un nouvel intérêt à notre chaise ''Kenny''. Un coussin d'assise bien positionné offre un confort suprême.";"Dimensions : Width : 19'' – Depth : 23'' – Height : 31''";"Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm";299;;"PROD025-1.jpg;PROD025-2.jpg;PROD025-3.jpg";"PLINK";"blue;purple;green";"Chairs" +"PROD026";"Stuart";"A masterpiece of furniture design";"Une pièce de designer !";"Get the on-trend look of modern masterpieces of furniture design with our ''Stuart'' chair. Paying homage to the classic design, this piece has an architecturally inspired silhouette with its sculptural wood frame and the clean lines of seat and back cushions. The crisp white hue will blend easily with a range of color schemes. ";"Offrez vous le look branché d'une grande pièce de designer avec la chaise ''Stuart''. Rendant hommage aux classiques du Design, cette chaise a une silhouette inspirée de l'architecture par son cadre bois sculptural et par les lignes pures de son assise et de son dossier. La fraiche nuance de blanc se fondera facilement dans toutes les harmonies de couleurs.";"Dimensions : Width : 19'' – Depth : 23'' – Height : 31''";"Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm";189;;"PROD026-1.jpg";"PLINK";"white";"Chairs" +"PROD027";"Marie-Claire";"A naturally appealing";"Une sobre élégance";"There's no denying the naturally appealing of our Marie-Claire chair! Its organic feeling is enhanced by the pretty wood veneers and faux leather upholstery, adding rustic charm and comfort.";"On ne peut nier l'élégance sobre de notre chaise Marie-Claire. Son allure naturelle est rehaussée par les finitions bois et le revêtement imitation cuir ajoute à son charme rustique et son confort.";"Dimensions : Width : 19'' – Depth : 23'' – Height : 31''";"Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm";104;;"PROD027-1.jpg";"TOKO";"green";"Chairs" +"PROD028";"Leela";"Contemporary fun chair";"Une fantaisie contemporaine";"At once contemporary and chic, The ''Leela'' chair makes your strong sense of personal style evident. Stylish, easy-clean, leather-like upholstery makes the cut-out in the back more stunning in the light of its vibrant yellow.";"Tout à la fois chic et contemporaine, la chaise ''Leela'' rend votre sens du style évident. Le revêtement en similicuir, facile d'entretien met en valeur l'ouverture du dossier par son jaune lumineux.";"Width : 19'' – Depth : 23'' – Height : 31''";"Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm ";144;;"PROD028-1.jpg";"MILAN";"yellow";"Chairs;Armchairs" +"PROD029";"Nibbler";"A modern bar stool";"Un tabouret de bar moderne";"If you're looking for a chic, counter height stool that features clean lines and a modern sensibility, look no further than our ''Nibbler'' stool. A chrome-finished base, oval footrest and adjustable, gas-lift mechanism add to its modern look.";"Si vous recherchez un tabouret haut et chic, n'allez pas plus loin que notre tabouret ''Nibbler'' avec ses lignes pures et sa modernité. Une base chromée, un repose-pieds oval ajustable et un mécanisme à gaz ajoute à son look moderne.";"Dimensions : Width : 19'' – Depth : 18'' – Height : 29''";"Dimensions : Larg 50 cm – Prof. 45 cm – Haut. 75 cm";78;;"PROD029-1.jpg";"MAGIS";"black";"Stools" +"PROD030";"Ron";"Get a look at the futur";"Une incursion dans le futur";"Get a look at the future — retro style — with our ''Ron'' bar stool! The contemporary design of the seating with a cut-out oval in the back for distinctive character, while the lively range of colours and high gloss make a big style statement. A chrome-finished base, oval footrest and adjustable, gas-lift mechanism add to the fresh look. Eye-catching and fun, the ''ron'' stool is a must-have for today's hottest dining area and bars. ";"Revisitez le futur avec une note retro grâce au tabouret de bar ''Ron''! Le design contemporain de ce siège grâce à l'ouverture ovale dans son dossier et une large gamme de couleurs vives. Son rendu glossy lui donne un style tout particulier. Une base chromée, un repose-pieds oval ajustable et un mécanisme à gaz ajoute à son look moderne. Surprenant et joyeux, le tabouret ''Ron'' est un incontournable des coin repas et des bars les plus branchés";"Dimensions : Width : 19'' – Depth : 18'' – Height : 29''";"Dimensions : Larg 50 cm – Prof. 45 cm – Haut. 75 cm";96;;"PROD030-1.jpg;PROD030-2.jpg;PROD030-3.jpg;PROD030-4.jpg;";"OFFUS";"blue;yellow;orange;purple";"Stools" diff --git a/install/insert.sql b/install/insert.sql index c7287089f..ec4e1b02b 100755 --- a/install/insert.sql +++ b/install/insert.sql @@ -19,20 +19,23 @@ INSERT INTO `config` (`name`, `value`, `secured`, `hidden`, `created_at`, `updat ('image_cache_dir_from_web_root', 'cache/images', 0, 0, NOW(), NOW()), ('document_cache_dir_from_web_root', 'cache/documents', 0, 0, NOW(), NOW()), ('currency_rate_update_url', 'http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml', 0, 0, NOW(), NOW()), -('page_not_found_view', '404.html', 0, 0, NOW(), NOW()), +('page_not_found_view', '404', 0, 0, NOW(), NOW()), +('passed_url_view', 'passed-url', 0, 0, NOW(), NOW()), ('use_tax_free_amounts', 0, 0, 0, NOW(), NOW()), ('process_assets', '1', 0, 0, NOW(), NOW()), ('thelia_admin_remember_me_cookie_name', 'tarmcn', 0, 0, NOW(), NOW()), ('thelia_admin_remember_me_cookie_expiration', 2592000, 0, 0, NOW(), NOW()), ('thelia_customer_remember_me_cookie_name', 'tcrmcn', 0, 0, NOW(), NOW()), ('thelia_customer_remember_me_cookie_expiration', 31536000, 0, 0, NOW(), NOW()), -('session_config.handlers', 'Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeFileSessionHandler', 0, 0, NOW(), NOW()) +('session_config.handlers', 'Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeFileSessionHandler', 0, 0, NOW(), NOW()) ; INSERT INTO `module` (`id`, `code`, `type`, `activate`, `position`, `full_namespace`, `created_at`, `updated_at`) VALUES -(1, 'DebugBar', 1, 1, 1, 'DebugBar\\DebugBar', NOW(), NOW()), -(2, 'Colissimo', 2, 1, 1, 'Colissimo\\Colissimo', NOW(), NOW()); +(1, 'TheliaDebugBar', 1, 1, 1, 'TheliaDebugBar\\TheliaDebugBar', NOW(), NOW()), +(2, 'Colissimo', 2, 0, 1, 'Colissimo\\Colissimo', NOW(), NOW()), +(3, 'Cheque', 3, 0, 1, 'Cheque\\Cheque', NOW(), NOW()), +(4, 'FakeCB', 3, 0, 2, 'FakeCB\\FakeCB', NOW(), NOW()); INSERT INTO `module_i18n` (`id`, `locale`, `title`, `description`, `chapo`, `postscriptum`) VALUES ('2', 'en_US', '72h delivery', NULL, NULL, NULL), @@ -67,6 +70,21 @@ VALUES (3, 'fr_FR', 'Livre anglaise'), (3, 'en_US', 'UK Pound'); +INSERT INTO `area` (`id`, `name`, `postage`, `created_at`, `updated_at`) VALUES +(1, 'France', NULL, NOW(), NOW()), +(2, 'Area 1', NULL, NOW(), NOW()), +(3, 'Area 2', NULL, NOW(), NOW()), +(4, 'Area 3', NULL, NOW(), NOW()), +(5, 'Area 4', NULL, NOW(), NOW()), +(6, 'Area 5', NULL, NOW(), NOW()), +(7, 'Area 6', NULL, NOW(), NOW()), +(8, 'Area 7', NULL, NOW(), NOW()), +(9, 'Area 8', NULL, NOW(), NOW()), +(10, 'DOM', NULL, NOW(), NOW()), +(11, 'TOM', NULL, NOW(), NOW()); + +INSERT INTO `area_delivery_module` (`id`, `area_id`, `delivery_module_id`, `created_at`, `updated_at`) VALUES +(1, 1, 2, NOW(), NOW()); INSERT INTO `country` (`id`, `area_id`, `isocode`, `isoalpha2`, `isoalpha3`, `by_default`, `created_at`, `updated_at`) VALUES (1, NULL, '4', 'AF', 'AFG', 0, NOW(), NOW()), @@ -130,7 +148,7 @@ INSERT INTO `country` (`id`, `area_id`, `isocode`, `isoalpha2`, `isoalpha3`, `by (61, NULL, '231', 'ET', 'ETH', 0, NOW(), NOW()), (62, NULL, '242', 'FJ', 'FJI', 0, NOW(), NOW()), (63, NULL, '246', 'FI', 'FIN', 0, NOW(), NOW()), -(64, NULL, '250', 'FR', 'FRA', 1, NOW(), NOW()), +(64, 1, '250', 'FR', 'FRA', 1, NOW(), NOW()), (65, NULL, '266', 'GA', 'GAB', 0, NOW(), NOW()), (66, NULL, '270', 'GM', 'GMB', 0, NOW(), NOW()), (67, NULL, '268', 'GE', 'GEO', 0, NOW(), NOW()), @@ -1135,17 +1153,36 @@ INSERT INTO `tax` (`id`, `type`, `serialized_requirements`, `created_at`, `upda INSERT INTO `tax_i18n` (`id`, `locale`, `title`) VALUES (1, 'fr_FR', 'TVA française à 19.6%'), - (1, 'en_UK', 'french 19.6% tax'); + (1, 'en_US', 'French 19.6% VAT'); -INSERT INTO `tax_rule` (`id`, `created_at`, `updated_at`) +INSERT INTO `tax_rule` (`id`, `is_default`, `created_at`, `updated_at`) VALUES - (1, NOW(), NOW()); + (1, 1, NOW(), NOW()); INSERT INTO `tax_rule_i18n` (`id`, `locale`, `title`) VALUES (1, 'fr_FR', 'TVA française à 19.6%'), - (1, 'en_UK', 'french 19.6% tax'); + (1, 'en_US', 'French 19.6% VAT'); INSERT INTO `tax_rule_country` (`tax_rule_id`, `country_id`, `tax_id`, `position`, `created_at`, `updated_at`) VALUES (1, 64, 1, 1, NOW(), NOW()); + +INSERT INTO `order_status`(`id`, `code`, `created_at`, `updated_at`) VALUES +(1, 'not_paid', NOW(), NOW()), +(2, 'paid', NOW(), NOW()), +(3, 'processing', NOW(), NOW()), +(4, 'sent', NOW(), NOW()), +(5, 'canceled', NOW(), NOW()); + +INSERT INTO `order_status_i18n` (`id`, `locale`, `title`, `description`, `chapo`, `postscriptum`) VALUES +(1, 'en_US', 'Not paid', '', '', ''), +(1, 'fr_FR', 'Non payée', '', '', ''), +(2, 'en_US', 'Paid', '', '', ''), +(2, 'fr_FR', 'Payée', '', '', ''), +(3, 'en_US', 'Processing', '', '', ''), +(3, 'fr_FR', 'Traitement', '', '', ''), +(4, 'en_US', 'Sent', '', '', ''), +(4, 'fr_FR', 'Envoyée', '', '', ''), +(5, 'en_US', 'Canceled', '', '', ''), +(5, 'fr_FR', 'Annulée', '', '', ''); diff --git a/install/thelia.sql b/install/thelia.sql index 3dc5d0454..6dbdd459f 100755 --- a/install/thelia.sql +++ b/install/thelia.sql @@ -36,7 +36,7 @@ CREATE TABLE `product` `ref` VARCHAR(255) NOT NULL, `visible` TINYINT DEFAULT 0 NOT NULL, `position` INTEGER NOT NULL, - `template_id` INTEGER NOT NULL, + `template_id` INTEGER, `created_at` DATETIME, `updated_at` DATETIME, `version` INTEGER DEFAULT 0, @@ -51,7 +51,7 @@ CREATE TABLE `product` REFERENCES `tax_rule` (`id`) ON UPDATE RESTRICT ON DELETE SET NULL, - CONSTRAINT `fk_product_template1` + CONSTRAINT `fk_product_template` FOREIGN KEY (`template_id`) REFERENCES `template` (`id`) ) ENGINE=InnoDB; @@ -135,6 +135,7 @@ DROP TABLE IF EXISTS `tax_rule`; CREATE TABLE `tax_rule` ( `id` INTEGER NOT NULL AUTO_INCREMENT, + `is_default` TINYINT(1) DEFAULT 0 NOT NULL, `created_at` DATETIME, `updated_at` DATETIME, PRIMARY KEY (`id`) @@ -185,7 +186,7 @@ CREATE TABLE `feature` ( `id` INTEGER NOT NULL AUTO_INCREMENT, `visible` INTEGER DEFAULT 0, - `position` INTEGER NOT NULL, + `position` INTEGER, `created_at` DATETIME, `updated_at` DATETIME, PRIMARY KEY (`id`) @@ -225,7 +226,7 @@ CREATE TABLE `feature_product` `product_id` INTEGER NOT NULL, `feature_id` INTEGER NOT NULL, `feature_av_id` INTEGER, - `by_default` VARCHAR(255), + `free_text_value` TEXT, `position` INTEGER, `created_at` DATETIME, `updated_at` DATETIME, @@ -261,6 +262,7 @@ CREATE TABLE `feature_template` `id` INTEGER NOT NULL AUTO_INCREMENT, `feature_id` INTEGER NOT NULL, `template_id` INTEGER NOT NULL, + `position` INTEGER, `created_at` DATETIME, `updated_at` DATETIME, PRIMARY KEY (`id`), @@ -357,11 +359,12 @@ CREATE TABLE `product_sale_elements` ( `id` INTEGER NOT NULL AUTO_INCREMENT, `product_id` INTEGER NOT NULL, - `ref` VARCHAR(45) NOT NULL, + `ref` VARCHAR(255) NOT NULL, `quantity` FLOAT NOT NULL, `promo` TINYINT DEFAULT 0, `newness` TINYINT DEFAULT 0, - `weight` FLOAT, + `weight` FLOAT DEFAULT 0, + `is_default` TINYINT(1) DEFAULT 0, `created_at` DATETIME, `updated_at` DATETIME, PRIMARY KEY (`id`), @@ -385,6 +388,8 @@ CREATE TABLE `attribute_template` `id` INTEGER NOT NULL AUTO_INCREMENT, `attribute_id` INTEGER NOT NULL, `template_id` INTEGER NOT NULL, + `position` INTEGER, + `attribute_templatecol` VARCHAR(45), `created_at` DATETIME, `updated_at` DATETIME, PRIMARY KEY (`id`), @@ -640,7 +645,7 @@ CREATE TABLE `order` `customer_id` INTEGER NOT NULL, `invoice_order_address_id` INTEGER NOT NULL, `delivery_order_address_id` INTEGER NOT NULL, - `invoice_date` DATE NOT NULL, + `invoice_date` DATE, `currency_id` INTEGER NOT NULL, `currency_rate` FLOAT NOT NULL, `transaction_ref` VARCHAR(100) COMMENT 'transaction reference - usually use to identify a transaction with banking modules', @@ -759,14 +764,21 @@ CREATE TABLE `order_product` ( `id` INTEGER NOT NULL AUTO_INCREMENT, `order_id` INTEGER NOT NULL, - `product_ref` VARCHAR(255), + `product_ref` VARCHAR(255) NOT NULL, + `product_sale_elements_ref` VARCHAR(255) NOT NULL, `title` VARCHAR(255), - `description` TEXT, `chapo` TEXT, + `description` LONGTEXT, + `postscriptum` TEXT, `quantity` FLOAT NOT NULL, `price` FLOAT NOT NULL, - `tax` FLOAT, - `parent` INTEGER, + `promo_price` VARCHAR(45), + `was_new` TINYINT NOT NULL, + `was_in_promo` TINYINT NOT NULL, + `weight` VARCHAR(45), + `tax_rule_title` VARCHAR(255), + `tax_rule_description` LONGTEXT, + `parent` INTEGER COMMENT 'not managed yet', `created_at` DATETIME, `updated_at` DATETIME, PRIMARY KEY (`id`), @@ -787,29 +799,36 @@ DROP TABLE IF EXISTS `order_status`; CREATE TABLE `order_status` ( `id` INTEGER NOT NULL AUTO_INCREMENT, - `code` VARCHAR(45), - `created_at` DATETIME, - `updated_at` DATETIME, - PRIMARY KEY (`id`) -) ENGINE=InnoDB; - --- --------------------------------------------------------------------- --- order_feature --- --------------------------------------------------------------------- - -DROP TABLE IF EXISTS `order_feature`; - -CREATE TABLE `order_feature` -( - `id` INTEGER NOT NULL AUTO_INCREMENT, - `order_product_id` INTEGER NOT NULL, - `feature_desc` VARCHAR(255), - `feature_av_desc` VARCHAR(255), + `code` VARCHAR(45) NOT NULL, `created_at` DATETIME, `updated_at` DATETIME, PRIMARY KEY (`id`), - INDEX `idx_order_feature_order_product_id` (`order_product_id`), - CONSTRAINT `fk_order_feature_order_product_id` + UNIQUE INDEX `code_UNIQUE` (`code`) +) ENGINE=InnoDB; + +-- --------------------------------------------------------------------- +-- order_product_attribute_combination +-- --------------------------------------------------------------------- + +DROP TABLE IF EXISTS `order_product_attribute_combination`; + +CREATE TABLE `order_product_attribute_combination` +( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `order_product_id` INTEGER NOT NULL, + `attribute_title` VARCHAR(255) NOT NULL, + `attribute_chapo` TEXT, + `attribute_description` LONGTEXT, + `attribute_postscriptumn` TEXT, + `attribute_av_title` VARCHAR(255) NOT NULL, + `attribute_av_chapo` TEXT, + `attribute_av_description` LONGTEXT, + `attribute_av_postscriptum` TEXT, + `created_at` DATETIME, + `updated_at` DATETIME, + PRIMARY KEY (`id`), + INDEX `idx_order_product_attribute_combination_order_product_id` (`order_product_id`), + CONSTRAINT `fk_order_product_attribute_combination_order_product_id` FOREIGN KEY (`order_product_id`) REFERENCES `order_product` (`id`) ON UPDATE RESTRICT @@ -895,6 +914,7 @@ CREATE TABLE `area_delivery_module` `created_at` DATETIME, `updated_at` DATETIME, PRIMARY KEY (`id`), + UNIQUE INDEX `area_id_delivery_module_id_UNIQUE` (`area_id`, `delivery_module_id`), INDEX `idx_area_delivery_module_area_id` (`area_id`), INDEX `idx_area_delivery_module_delivery_module_id_idx` (`delivery_module_id`), CONSTRAINT `fk_area_delivery_module_area_id` @@ -1534,6 +1554,53 @@ CREATE TABLE `template` PRIMARY KEY (`id`) ) ENGINE=InnoDB; +-- --------------------------------------------------------------------- +-- module_image +-- --------------------------------------------------------------------- + +DROP TABLE IF EXISTS `module_image`; + +CREATE TABLE `module_image` +( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `module_id` INTEGER NOT NULL, + `file` VARCHAR(255) NOT NULL, + `position` INTEGER, + `created_at` DATETIME, + `updated_at` DATETIME, + PRIMARY KEY (`id`), + INDEX `idx_module_image_module_id` (`module_id`), + CONSTRAINT `fk_module_image_module_id` + FOREIGN KEY (`module_id`) + REFERENCES `module` (`id`) + ON UPDATE RESTRICT + ON DELETE CASCADE +) ENGINE=InnoDB; + +-- --------------------------------------------------------------------- +-- order_product_tax +-- --------------------------------------------------------------------- + +DROP TABLE IF EXISTS `order_product_tax`; + +CREATE TABLE `order_product_tax` +( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `order_product_id` INTEGER NOT NULL, + `title` VARCHAR(255) NOT NULL, + `description` LONGTEXT, + `amount` FLOAT NOT NULL, + `created_at` DATETIME, + `updated_at` DATETIME, + PRIMARY KEY (`id`), + INDEX `idx_ order_product_tax_order_product_id` (`order_product_id`), + CONSTRAINT `fk_ order_product_tax_order_product_id0` + FOREIGN KEY (`order_product_id`) + REFERENCES `order_product` (`id`) + ON UPDATE RESTRICT + ON DELETE CASCADE +) ENGINE=InnoDB; + -- --------------------------------------------------------------------- -- category_i18n -- --------------------------------------------------------------------- @@ -1608,7 +1675,7 @@ CREATE TABLE `tax_i18n` `id` INTEGER NOT NULL, `locale` VARCHAR(5) DEFAULT 'en_US' NOT NULL, `title` VARCHAR(255), - `description` TEXT, + `description` LONGTEXT, PRIMARY KEY (`id`,`locale`), CONSTRAINT `tax_i18n_FK_1` FOREIGN KEY (`id`) @@ -1627,7 +1694,7 @@ CREATE TABLE `tax_rule_i18n` `id` INTEGER NOT NULL, `locale` VARCHAR(5) DEFAULT 'en_US' NOT NULL, `title` VARCHAR(255), - `description` TEXT, + `description` LONGTEXT, PRIMARY KEY (`id`,`locale`), CONSTRAINT `tax_rule_i18n_FK_1` FOREIGN KEY (`id`) @@ -2130,6 +2197,27 @@ CREATE TABLE `template_i18n` ON DELETE CASCADE ) ENGINE=InnoDB; +-- --------------------------------------------------------------------- +-- module_image_i18n +-- --------------------------------------------------------------------- + +DROP TABLE IF EXISTS `module_image_i18n`; + +CREATE TABLE `module_image_i18n` +( + `id` INTEGER NOT NULL, + `locale` VARCHAR(5) DEFAULT 'en_US' NOT NULL, + `title` VARCHAR(255), + `description` LONGTEXT, + `chapo` TEXT, + `postscriptum` TEXT, + PRIMARY KEY (`id`,`locale`), + CONSTRAINT `module_image_i18n_FK_1` + FOREIGN KEY (`id`) + REFERENCES `module_image` (`id`) + ON DELETE CASCADE +) ENGINE=InnoDB; + -- --------------------------------------------------------------------- -- category_version -- --------------------------------------------------------------------- @@ -2167,7 +2255,7 @@ CREATE TABLE `product_version` `ref` VARCHAR(255) NOT NULL, `visible` TINYINT DEFAULT 0 NOT NULL, `position` INTEGER NOT NULL, - `template_id` INTEGER NOT NULL, + `template_id` INTEGER, `created_at` DATETIME, `updated_at` DATETIME, `version` INTEGER DEFAULT 0 NOT NULL, diff --git a/local/config/schema.xml b/local/config/schema.xml index a43cfda56..610fb647a 100755 --- a/local/config/schema.xml +++ b/local/config/schema.xml @@ -28,11 +28,11 @@ - + - + @@ -55,7 +55,7 @@ - + @@ -101,7 +101,7 @@ - + @@ -110,7 +110,8 @@
- + + @@ -144,11 +145,11 @@
- + @@ -178,7 +179,7 @@ - + @@ -204,6 +205,7 @@ + @@ -220,11 +222,11 @@
- + @@ -276,11 +278,12 @@
- + - + + @@ -296,6 +299,8 @@ + + @@ -499,7 +504,7 @@ - + @@ -594,14 +599,21 @@
- + + - + + - - + + + + + + + @@ -612,25 +624,34 @@
- + + + +
- +
- - - + + + + + + + + + - + @@ -695,6 +716,10 @@ + + + +
@@ -1196,4 +1221,38 @@
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + +
diff --git a/local/modules/Cheque/Cheque.php b/local/modules/Cheque/Cheque.php new file mode 100755 index 000000000..4516c84f3 --- /dev/null +++ b/local/modules/Cheque/Cheque.php @@ -0,0 +1,95 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Cheque; + +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\HttpFoundation\Request; +use Thelia\Model\ModuleImageQuery; +use Thelia\Module\BaseModule; +use Thelia\Module\PaymentModuleInterface; + +class Cheque extends BaseModule implements PaymentModuleInterface +{ + protected $request; + protected $dispatcher; + + public function setRequest(Request $request) + { + $this->request = $request; + } + + public function getRequest() + { + return $this->request; + } + + public function setDispatcher(EventDispatcherInterface $dispatcher) + { + $this->dispatcher = $dispatcher; + } + + public function getDispatcher() + { + return $this->dispatcher; + } + + public function pay() + { + // no special process, waiting for the cheque. + } + + public function install() + { + + } + + public function afterActivation() + { + /* insert the images from image folder if first module activation */ + $module = $this->getModuleModel(); + if(ModuleImageQuery::create()->filterByModule($module)->count() == 0) { + $this->deployImageFolder($module, sprintf('%s/images', __DIR__)); + } + + /* set module title */ + $this->setTitle( + $module, + array( + "en_US" => "Cheque", + "fr_FR" => "Cheque", + ) + ); + } + + public function destroy() + { + // TODO: Implement destroy() method. + } + + public function getCode() + { + return 'Cheque'; + } + +} diff --git a/local/modules/Cheque/Config/config.xml b/local/modules/Cheque/Config/config.xml new file mode 100755 index 000000000..2430f5027 --- /dev/null +++ b/local/modules/Cheque/Config/config.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/local/modules/DebugBar/Config/plugin.xml b/local/modules/Cheque/Config/plugin.xml similarity index 100% rename from local/modules/DebugBar/Config/plugin.xml rename to local/modules/Cheque/Config/plugin.xml diff --git a/local/modules/Cheque/images/cheque.png b/local/modules/Cheque/images/cheque.png new file mode 100755 index 000000000..16d83ba11 Binary files /dev/null and b/local/modules/Cheque/images/cheque.png differ diff --git a/local/modules/Colissimo/Colissimo.php b/local/modules/Colissimo/Colissimo.php index 2fe9cd0b9..7ff972feb 100755 --- a/local/modules/Colissimo/Colissimo.php +++ b/local/modules/Colissimo/Colissimo.php @@ -61,12 +61,17 @@ class Colissimo extends BaseModule implements DeliveryModuleInterface * @param Country $country * @return mixed */ - public function calculate(Country $country) + public function getPostage(Country $country) { - // TODO: Implement calculate() method. + // TODO: Implement getPostage() method. return 2; } + public function afterActivation() + { + + } + /** * YOU HAVE TO IMPLEMENT HERE ABSTRACT METHODD FROM BaseModule Class * Like install and destroy @@ -81,4 +86,9 @@ class Colissimo extends BaseModule implements DeliveryModuleInterface // TODO: Implement destroy() method. } + public function getCode() + { + return 'Colissimo'; + } + } diff --git a/local/modules/Colissimo/Config/schema.xml b/local/modules/Colissimo/Config/schema.xml deleted file mode 100755 index a4e2315b0..000000000 --- a/local/modules/Colissimo/Config/schema.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/local/modules/DebugBar/Config/schema.xml b/local/modules/DebugBar/Config/schema.xml deleted file mode 100755 index 86ccca913..000000000 --- a/local/modules/DebugBar/Config/schema.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/local/modules/FakeCB/Config/config.xml b/local/modules/FakeCB/Config/config.xml new file mode 100755 index 000000000..2430f5027 --- /dev/null +++ b/local/modules/FakeCB/Config/config.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/templates/admin/default/product-attributes-edit.html b/local/modules/FakeCB/Config/plugin.xml old mode 100644 new mode 100755 similarity index 100% rename from templates/admin/default/product-attributes-edit.html rename to local/modules/FakeCB/Config/plugin.xml diff --git a/local/modules/FakeCB/FakeCB.php b/local/modules/FakeCB/FakeCB.php new file mode 100755 index 000000000..ca682fab3 --- /dev/null +++ b/local/modules/FakeCB/FakeCB.php @@ -0,0 +1,95 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace FakeCB; + +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\HttpFoundation\Request; +use Thelia\Model\Base\ModuleImageQuery; +use Thelia\Module\BaseModule; +use Thelia\Module\PaymentModuleInterface; + +class FakeCB extends BaseModule implements PaymentModuleInterface +{ + protected $request; + protected $dispatcher; + + public function setRequest(Request $request) + { + $this->request = $request; + } + + public function getRequest() + { + return $this->request; + } + + public function setDispatcher(EventDispatcherInterface $dispatcher) + { + $this->dispatcher = $dispatcher; + } + + public function getDispatcher() + { + return $this->dispatcher; + } + + public function pay() + { + // TODO: Implement pay() method. + } + + public function install() + { + + } + + public function afterActivation() + { + /* insert the images from image folder if first module activation */ + $module = $this->getModuleModel(); + if(ModuleImageQuery::create()->filterByModule($module)->count() == 0) { + $this->deployImageFolder($module, sprintf('%s/images', __DIR__)); + } + + /* set module title */ + $this->setTitle( + $module, + array( + "en_US" => "Credit Card", + "fr_FR" => "Carte de crédit", + ) + ); + } + + public function destroy() + { + // TODO: Implement destroy() method. + } + + public function getCode() + { + return 'FakeCB'; + } + +} diff --git a/local/modules/FakeCB/Tests/FakeCBTest.php b/local/modules/FakeCB/Tests/FakeCBTest.php new file mode 100755 index 000000000..20a68fc1d --- /dev/null +++ b/local/modules/FakeCB/Tests/FakeCBTest.php @@ -0,0 +1,52 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace FakeCB\Tests; + +use FakeCB\FakeCB; +use Thelia\Tests\Module\BaseModuleTestor; + +/** + * + * @author Etienne Roudeix + * + */ +class FakeCBTest extends BaseModuleTestor +{ + public function getTestedClassName() + { + return 'FakeCB\FakeCB'; + } + + public function getTestedInstance() + { + return new FakeCB(); + } + + public function testInstall() + { + //$fakeCB = new FakeCB(); + + //$fakeCB->install(); + } +} diff --git a/local/modules/FakeCB/images/mastercard.png b/local/modules/FakeCB/images/mastercard.png new file mode 100755 index 000000000..28701c3dd Binary files /dev/null and b/local/modules/FakeCB/images/mastercard.png differ diff --git a/local/modules/FakeCB/images/visa.png b/local/modules/FakeCB/images/visa.png new file mode 100755 index 000000000..ef0447105 Binary files /dev/null and b/local/modules/FakeCB/images/visa.png differ diff --git a/local/modules/DebugBar/Config/config.xml b/local/modules/TheliaDebugBar/Config/config.xml similarity index 87% rename from local/modules/DebugBar/Config/config.xml rename to local/modules/TheliaDebugBar/Config/config.xml index 12c5ccd24..564c17e66 100755 --- a/local/modules/DebugBar/Config/config.xml +++ b/local/modules/TheliaDebugBar/Config/config.xml @@ -32,13 +32,13 @@ - + %kernel.debug% - + diff --git a/local/modules/TheliaDebugBar/Config/plugin.xml b/local/modules/TheliaDebugBar/Config/plugin.xml new file mode 100755 index 000000000..e69de29bb diff --git a/local/modules/TheliaDebugBar/Config/schema.xml b/local/modules/TheliaDebugBar/Config/schema.xml new file mode 100755 index 000000000..9056a554b --- /dev/null +++ b/local/modules/TheliaDebugBar/Config/schema.xml @@ -0,0 +1,6 @@ + + + + diff --git a/local/modules/DebugBar/DataCollector/PropelCollector.php b/local/modules/TheliaDebugBar/DataCollector/PropelCollector.php similarity index 98% rename from local/modules/DebugBar/DataCollector/PropelCollector.php rename to local/modules/TheliaDebugBar/DataCollector/PropelCollector.php index c0ce87746..2605e07dd 100755 --- a/local/modules/DebugBar/DataCollector/PropelCollector.php +++ b/local/modules/TheliaDebugBar/DataCollector/PropelCollector.php @@ -21,14 +21,17 @@ /* */ /*************************************************************************************/ -namespace DebugBar\DataCollector; +namespace TheliaDebugBar\DataCollector; + +use DebugBar\DataCollector\DataCollector; +use DebugBar\DataCollector\Renderable; use Propel\Runtime\Propel; use Psr\Log\LoggerInterface; /** * Class PropelCollector - * @package DebugBar\DataCollector + * @package TheliaDebugBar\DataCollector * @author Manuel Raynaud */ class PropelCollector extends DataCollector implements Renderable, LoggerInterface diff --git a/local/modules/DebugBar/Listeners/DebugBarListeners.php b/local/modules/TheliaDebugBar/Listeners/DebugBarListeners.php similarity index 96% rename from local/modules/DebugBar/Listeners/DebugBarListeners.php rename to local/modules/TheliaDebugBar/Listeners/DebugBarListeners.php index edcd5cb21..c7b9d015c 100755 --- a/local/modules/DebugBar/Listeners/DebugBarListeners.php +++ b/local/modules/TheliaDebugBar/Listeners/DebugBarListeners.php @@ -21,11 +21,12 @@ /* */ /*************************************************************************************/ -namespace DebugBar\Listeners; +namespace TheliaDebugBar\Listeners; + use DebugBar\DataCollector\MemoryCollector; use DebugBar\DataCollector\MessagesCollector; use DebugBar\DataCollector\PhpInfoCollector; -use DebugBar\DataCollector\PropelCollector; +use TheliaDebugBar\DataCollector\PropelCollector; use DebugBar\DataCollector\TimeDataCollector; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\KernelEvents; @@ -35,7 +36,7 @@ use Thelia\Core\Event\TheliaEvents; /** * Class DebugBarListeners - * @package DebugBar\Listeners + * @package TheliaDebugBar\Listeners * @author Manuel Raynaud */ class DebugBarListeners extends BaseAction implements EventSubscriberInterface { diff --git a/local/modules/DebugBar/Smarty/Plugin/DebugBar.php b/local/modules/TheliaDebugBar/Smarty/Plugin/DebugBar.php similarity index 91% rename from local/modules/DebugBar/Smarty/Plugin/DebugBar.php rename to local/modules/TheliaDebugBar/Smarty/Plugin/DebugBar.php index 0cd1abee9..e03b7797c 100755 --- a/local/modules/DebugBar/Smarty/Plugin/DebugBar.php +++ b/local/modules/TheliaDebugBar/Smarty/Plugin/DebugBar.php @@ -21,7 +21,7 @@ /* */ /*************************************************************************************/ -namespace DebugBar\Smarty\Plugin; +namespace TheliaDebugBar\Smarty\Plugin; use Thelia\Core\Template\Smarty\AbstractSmartyPlugin; use Thelia\Core\Template\Smarty\an; use Thelia\Core\Template\Smarty\SmartyPluginDescriptor; @@ -71,7 +71,11 @@ class DebugBar extends AbstractSmartyPlugin } } - file_put_contents($cssFile, $assetCss->dump()); + if(!file_exists(THELIA_WEB_DIR . "/cache")) { + @mkdir(THELIA_WEB_DIR . "/cache"); + } + + @file_put_contents($cssFile, $assetCss->dump()); } $render = sprintf('', URL::getInstance()->absoluteUrl($webFile, array(), URL::PATH_TO_FILE)); } @@ -96,7 +100,11 @@ class DebugBar extends AbstractSmartyPlugin } } - file_put_contents($cacheFile, $assetJs->dump()); + if(!file_exists(THELIA_WEB_DIR . "/cache")) { + @mkdir(THELIA_WEB_DIR . "/cache"); + } + + @file_put_contents($cacheFile, $assetJs->dump()); } $render = sprintf('', URL::getInstance()->absoluteUrl($webFile, array(), URL::PATH_TO_FILE)); diff --git a/local/modules/DebugBar/DebugBar.php b/local/modules/TheliaDebugBar/TheliaDebugBar.php similarity index 91% rename from local/modules/DebugBar/DebugBar.php rename to local/modules/TheliaDebugBar/TheliaDebugBar.php index 7dde5fa8d..da9fddf12 100755 --- a/local/modules/DebugBar/DebugBar.php +++ b/local/modules/TheliaDebugBar/TheliaDebugBar.php @@ -21,17 +21,22 @@ /* */ /*************************************************************************************/ -namespace DebugBar; +namespace TheliaDebugBar; use Thelia\Module\BaseModule; -class DebugBar extends BaseModule +class TheliaDebugBar extends BaseModule { /** * YOU HAVE TO IMPLEMENT HERE ABSTRACT METHODD FROM BaseModule Class * Like install and destroy */ + public function afterActivation() + { + + } + public function install() { // TODO: Implement install() method. @@ -41,4 +46,9 @@ class DebugBar extends BaseModule { // TODO: Implement destroy() method. } + + public function getCode() + { + return 'TheliaDebugBar'; + } } diff --git a/phpunit.xml b/phpunit.xml index 1cad09b60..a45fc5bb3 100755 --- a/phpunit.xml +++ b/phpunit.xml @@ -12,6 +12,7 @@ core/lib/Thelia/Tests + local/modules/*/Tests diff --git a/reset_install.sh b/reset_install.sh index 348927a54..8280173d9 100755 --- a/reset_install.sh +++ b/reset_install.sh @@ -2,34 +2,43 @@ # @author Guillaume MOREL # v0.2 -echo -e "\033[47m\033[1;31m\n[WARN] This script will reset this Thelia2 install\n\033[0m" +echo -e "\033[47m\033[1;31m\n[WARNING] This script will reset this Thelia2 install\nPress ENTER to continue or ^C to cancel\033[0m" -echo -e "\n\e[01;34m[INFO] Clearing caches\e[00m\n" +read test + +echo -e "\n\033[01;34m[INFO] Clearing caches\033[00m\n" php Thelia cache:clear -echo -e "\n\e[01;34m[INFO] Downloading vendors\e[00m\n" +echo -e "\n\033[01;34m[INFO] Downloading vendors\033[00m\n" composer install --prefer-dist --optimize-autoloader cd local/config/ -echo -e "\n\e[01;34m[INFO] Building Models file\e[00m\n" +echo -e "\n\033[01;34m[INFO] Building Models file\033[00m\n" ../../bin/propel build -v --output-dir=../../core/lib/ -echo -e "\n\e[01;34m[INFO] Building SQL CREATE file\e[00m\n" +echo -e "\n\033[01;34m[INFO] Building SQL CREATE file\033[00m\n" ../../bin/propel sql:build -v --output-dir=../../install/ -echo -e "\n\e[01;34m[INFO] Reloading Thelia2 database\e[00m\n" +echo -e "\n\033[01;34m[INFO] Reloading Thelia2 database\033[00m\n" cd ../.. rm install/sqldb.map php Thelia thelia:dev:reloadDB -echo -e "\n\e[01;34m[INFO] Installing fixtures\e[00m\n" +echo -e "\n\033[01;34m[INFO] Installing fixtures\033[00m\n" php install/faker.php -echo -e "\n\e[01;34m[INFO] Adding admin\e[00m\n" +echo -e "\n\033[01;34m[INFO] Adding admin\033[00m\n" php Thelia thelia:create-admin --login_name thelia2 --password thelia2 --last_name thelia2 --first_name thelia2 -echo -e "\n\e[01;34m[INFO] Clearing caches\e[00m\n" +echo -e "\n\033[01;34m[INFO] Clearing caches\033[00m\n" php Thelia cache:clear -echo -e "\n\e[00;32m[SUCCESS] Reset done\e[00m\n" \ No newline at end of file +echo -e "\n\033[01;34m[INFO] Activating Delivery Module(s)\033[00m\n" +php Thelia module:activate Colissimo + +echo -e "\n\033[01;34m[INFO] Activating Payment Module(s)\033[00m\n" +php Thelia module:activate Cheque +php Thelia module:activate FakeCB + +echo -e "\n\033[00;32m[SUCCESS] Reset done\033[00m\n" \ No newline at end of file diff --git a/templates/admin/default/admin-layout.tpl b/templates/admin/default/admin-layout.tpl index 4cad798fb..6fe492f30 100644 --- a/templates/admin/default/admin-layout.tpl +++ b/templates/admin/default/admin-layout.tpl @@ -51,27 +51,27 @@
-
-
{intl l='Version %ver' ver="{$THELIA_VERSION}"}
+
+
{intl l='Version %ver' ver="{$THELIA_VERSION}"}
+ + +
{module_include location='inside_topbar'} - -
- -
- {intl l="View shop"} - - - -
- -
+
@@ -86,96 +86,98 @@
@@ -219,8 +221,16 @@ {* -- Javascript section ------------------------------------------------ *} {block name="before-javascript-include"}{/block} + + + - {debugbar_renderjs} {debugbar_renderresult} diff --git a/templates/admin/default/ajax/product-attributes-tab.html b/templates/admin/default/ajax/product-attributes-tab.html new file mode 100644 index 000000000..2a62da2e3 --- /dev/null +++ b/templates/admin/default/ajax/product-attributes-tab.html @@ -0,0 +1,248 @@ +{loop name="product_edit" type="product" visible="*" id=$product_id backend_context="1" lang=$edit_language_id} +
+ +
+
+

{* <---- FIXME Lame ! *} +
+ + + + +
+
+
+

{intl + l="To use features or attributes on this product, please select a product template. You can define product templates in the configuration section of the administration." + tpl_mgmt_url={url path='/admin/configuration/templates'} + } +

+ + + +
+ + + + + +
+
+
+
+
+
+
+ + {* Check if a product template is defined *} + +
+
+ +
+ + + + + {include + file = "includes/inner-form-toolbar.html" + hide_submit_buttons = false + + page_url = "{url path='/admin/products/update' product_id=$ID}" + close_url = "{url path='/admin/categories' category_id=$DEFAULT_CATEGORY}" + } + + {* -- Begin attributes management ------------------------------- *} + +
+
+
+
+

{intl l='Product Attributes'}

+ +

+ {if $TEMPLATE} + {intl + l="You can change template attributes and their positions in the template configuration page." + tpl_mgmt_url={url path='/admin/configuration/templates/update' template_id=$TEMPLATE} + } + {else} + {intl + l="You can change attributes and their positions in the attributes configuration page." + tpl_mgmt_url={url path='/admin/configuration/attributes'} + } + {/if} +

+ +
+ + + + + + + {module_include location='product_attributes_table_header'} + + + + + {loop name="product-attributes" type="attribute" order="manual" product=$product_id backend_context="1" lang="$edit_language_id"} + + + + + + {module_include location='product_features_table_row'} + + {/loop} + + {elseloop rel="product-attributes"} + + + + {/elseloop} + +
{intl l='ID'}{intl l='Attribute Name'}
{$ID}{$TITLE}
+
+ {intl l="This product template does not contains any features"} +
+
+
+
+
+
+
+ + {* -- Begin features management ---------------------------------- *} + +
+
+
+
+

{intl l='Product Features'}

+ +

+ {if $TEMPLATE} + {intl + l="You can change templates features and their positions in the template configuration page." + tpl_mgmt_url={url path='/admin/configuration/templates/update' template_id=$TEMPLATE} + } + {else} + {intl + l="You can change feature and their positions in the features configuration page." + tpl_mgmt_url={url path='/admin/configuration/features'} + } + {/if} +

+ +
+ + + + + + + + {module_include location='product_features_table_header'} + + + + + + {loop name="product-features" type="feature" order="manual" product=$product_id backend_context="1" lang="$edit_language_id"} + + + + + + + + {module_include location='product_features_table_row'} + + + {/loop} + + {elseloop rel="product-features"} + + + + {/elseloop} + +
{intl l='ID'}{intl l='Feature Name'}{intl l='Feature value for this product'}
{$ID}{$TITLE} + {* Multiple values *} + + {ifloop rel="product-features-av"} + + {* load all selected values in an array to speed up things a little *} + + {$selected = array()} + + {loop name="free-text-value" exclude_free_text="true" type="feature_value" product=$product_id feature=$ID backend_context="1" lang="$edit_language_id"} + {$selected[] = $FEATURE_AV_ID} + {/loop} + + {capture "select_options"} + {loop name="product-features-av" type="feature-availability" feature=$ID order="manual" backend_context="1" lang="$edit_language_id"} + + + {$options_count = $LOOP_COUNT} {* LOOP_COUNT is only available inside the loop ! *} + {/loop} + {/capture} + +
+ +
+ + + {intl l='Use Ctrl+click to select more than one value. You can also clear selected values.' id=$ID} + + {/ifloop} + + {* Free text *} + + {elseloop rel="product-features-av"} + {* Get the free text value *} + + {loop name="free-text-value" exclude_feature_availability="1" type="feature_value" product=$product_id feature=$ID backend_context="1" lang="$edit_language_id"} + {$feature_value=$FREE_TEXT_VALUE} + {/loop} + + + {/elseloop} +
+
+ {intl l="This product template does not contains any features"} +
+
+
+
+
+
+
+
+
+
+ +
+{/loop} + + diff --git a/templates/admin/default/ajax/product-related-tab.html b/templates/admin/default/ajax/product-related-tab.html new file mode 100644 index 000000000..3c909b390 --- /dev/null +++ b/templates/admin/default/ajax/product-related-tab.html @@ -0,0 +1,576 @@ +{loop name="product_edit" type="product" visible="*" id=$product_id backend_context="1" lang=$edit_language_id} +
+ + {include + file = "includes/inner-form-toolbar.html" + hide_submit_buttons = true + + page_url = "{url path='/admin/products/update' product_id=$ID}" + close_url = "{url path='/admin/categories' category_id=$DEFAULT_CATEGORY}" + } + +
+ + {* -- Begin related content management ------------------------------ *} + +
+
+
+ +
+ +
+ + + + + + + + + + {module_include location='product_contents_table_header'} + + + + + + + {loop name="assigned_contents" type="associated_content" product="$product_id" backend_context="1" lang="$edit_language_id"} + + + + + + + + {module_include location='product_contents_table_row'} + + + + {/loop} + + {elseloop rel="assigned_contents"} + + + + {/elseloop} + +
{intl l='ID'}{intl l='Content title'}{intl l='Position'}{intl l="Actions"}
{$ID} + {$TITLE} + + {admin_position_block + permission="admin.products.edit" + path={url path='/admin/product/update-content-position' product_id=$product_id current_tab="related"} + url_parameter="content_id" + in_place_edit_class="contentPositionChange" + position=$POSITION + id=$ID + } + +
+ {loop type="auth" name="can_create" roles="ADMIN" permissions="admin.product.content.delete"} + + + + {/loop} +
+
+
+ {intl l="This product contains no contents"} +
+
+
+
+
+ + {* -- End related content management -------------------------------- *} + + {* -- Begin accessories management ---------------------------------- *} + +
+
+
+
+ +

{intl l='Product accessories'}

+

{intl l='Define here this product\'s accessories'}

+ + + + + {ifloop rel="categories"} +
+ + + {intl l='Select a category to get its products'} +
+ +
+
+ + + + +
+ + {intl l='Select a product and click (+) to add it as an accessory'} +
+ +
+
+ {intl l="No available product in this category"} +
+
+ + {/ifloop} + + {elseloop rel="categories"} +
{intl l="No categories found"}
+ {/elseloop} + +
+
+ +
+ + + + + + + + + + {module_include location='product_accessories_table_header'} + + + + + + + {loop name="assigned_accessories" order="accessory" type="accessory" product="$product_id" backend_context="1" lang="$edit_language_id"} + + + + + + + + {module_include location='product_accessories_table_row'} + + + + {/loop} + + {elseloop rel="assigned_accessories"} + + + + {/elseloop} + +
{intl l='ID'}{intl l='Accessory title'}{intl l='Position'}{intl l="Actions"}
{$ID} + {$TITLE} + + {admin_position_block + permission="admin.products.edit" + path={url path='/admin/product/update-accessory-position' product_id=$product_id current_tab="related"} + url_parameter="accessory_id" + in_place_edit_class="accessoryPositionChange" + position=$POSITION + id=$ID + } + +
+ {loop type="auth" name="can_create" roles="ADMIN" permissions="admin.product.accessory.delete"} + + + + {/loop} +
+
+
+ {intl l="This product contains no accessories"} +
+
+
+
+
+ + {* -- End accessories management ------------------------------------ *} + +
+ +
+ + {* -- Begin categories management ----------------------------------- *} + +
+
+
+ +
+ +
+ + + + + + + + {module_include location='product_categories_table_header'} + + + + + + + {loop name="additional_categories" type="category" product=$product_id exclude=$DEFAULT_CATEGORY backend_context="1" lang="$edit_language_id"} + + + + + + {module_include location='product_categories_table_row'} + + + + {/loop} + + {elseloop rel="additional_categories"} + + + + {/elseloop} + +
{intl l='ID'}{intl l='Category title'}{intl l="Actions"}
{$ID} + {$TITLE} + +
+ {loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.product.category.delete"} + + + + {/loop} +
+
+
+ {intl l="This product doesn't belong to any additional category."} +
+
+
+
+
+ {* -- End categories management ------------------------------------- *} +
+ +
+ +{* Delete related content confirmation dialog *} + +{capture "delete_content_dialog"} + + + + + +{/capture} + +{include + file = "includes/generic-confirm-dialog.html" + + dialog_id = "delete_content_dialog" + dialog_title = {intl l="Remove related content"} + dialog_message = {intl l="Do you really want to remove this related content from the product ?"} + + form_action = {url path='/admin/products/content/delete'} + form_content = {$smarty.capture.delete_content_dialog nofilter} +} + +{* Delete accessory confirmation dialog *} + +{capture "delete_accessory_dialog"} + + + + + +{/capture} + +{include + file = "includes/generic-confirm-dialog.html" + + dialog_id = "delete_accessory_dialog" + dialog_title = {intl l="Remove an accessory"} + dialog_message = {intl l="Do you really want to remove this accessory from the product ?"} + + form_action = {url path='/admin/products/accessory/delete'} + form_content = {$smarty.capture.delete_accessory_dialog nofilter} +} + +{* Delete category confirmation dialog *} + +{capture "delete_category_dialog"} + + + + +{/capture} + +{include + file = "includes/generic-confirm-dialog.html" + + dialog_id = "delete_category_dialog" + dialog_title = {intl l="Remove from category"} + dialog_message = {intl l="Do you really want to remove the product from this category ?"} + + form_action = {url path='/admin/products/category/delete'} + form_content = {$smarty.capture.delete_category_dialog nofilter} +} + + +{/loop} \ No newline at end of file diff --git a/templates/admin/default/ajax/template-attribute-list.html b/templates/admin/default/ajax/template-attribute-list.html index 772ed5883..7c0c2fdb9 100644 --- a/templates/admin/default/ajax/template-attribute-list.html +++ b/templates/admin/default/ajax/template-attribute-list.html @@ -1,12 +1,12 @@
{ifloop rel="free_attributes"} -
+
' : ''; + var drop = + "
" + + "" + + "" + + "
"; + + return $(drop); + }, + + createView: function() { + var $drop = this.createDropdown(); + var $li = this.createLi(); + $drop.find('ul').append($li); + return $drop; + }, + + reloadLi: function() { + //Remove all children. + this.destroyLi(); + //Re build + var $li = this.createLi(); + this.$menu.find('ul').append( $li ); + }, + + destroyLi: function() { + this.$menu.find('li').remove(); + }, + + createLi: function() { + var that = this, + _liA = [], + _liHtml = ''; + + this.$element.find('option').each(function(index) { + var $this = $(this); + + //Get the class and text for the option + var optionClass = $this.attr("class") || ''; + var inline = $this.attr("style") || ''; + var text = $this.data('content') ? $this.data('content') : $this.html(); + var subtext = $this.data('subtext') !== undefined ? '' + $this.data('subtext') + '' : ''; + var icon = $this.data('icon') !== undefined ? ' ' : ''; + if (icon !== '' && ($this.is(':disabled') || $this.parent().is(':disabled'))) { + icon = ''+icon+''; + } + + if (!$this.data('content')) { + //Prepend any icon and append any subtext to the main text. + text = icon + '' + text + subtext + ''; + } + + if (that.options.hideDisabled && ($this.is(':disabled') || $this.parent().is(':disabled'))) { + _liA.push(''); + } else if ($this.parent().is('optgroup') && $this.data('divider') != true) { + if ($this.index() == 0) { + //Get the opt group label + var label = $this.parent().attr('label'); + var labelSubtext = $this.parent().data('subtext') !== undefined ? ''+$this.parent().data('subtext')+'' : ''; + var labelIcon = $this.parent().data('icon') ? ' ' : ''; + label = labelIcon + '' + label + labelSubtext + ''; + + if ($this[0].index != 0) { + _liA.push( + '
'+ + '
'+label+'
'+ + that.createA(text, "opt " + optionClass, inline ) + ); + } else { + _liA.push( + '
'+label+'
'+ + that.createA(text, "opt " + optionClass, inline )); + } + } else { + _liA.push(that.createA(text, "opt " + optionClass, inline )); + } + } else if ($this.data('divider') == true) { + _liA.push('
'); + } else if ($(this).data('hidden') == true) { + _liA.push(''); + } else { + _liA.push(that.createA(text, optionClass, inline )); + } + }); + + $.each(_liA, function(i, item) { + _liHtml += "
  • " + item + "
  • "; + }); + + //If we are not multiple, and we dont have a selected item, and we dont have a title, select the first element so something is set in the button + if (!this.multiple && this.$element.find('option:selected').length==0 && !this.options.title) { + this.$element.find('option').eq(0).prop('selected', true).attr('selected', 'selected'); + } + + return $(_liHtml); + }, + + createA: function(text, classes, inline) { + return '' + + text + + '' + + ''; + }, + + render: function() { + var that = this; + + //Update the LI to match the SELECT + this.$element.find('option').each(function(index) { + that.setDisabled(index, $(this).is(':disabled') || $(this).parent().is(':disabled') ); + that.setSelected(index, $(this).is(':selected') ); + }); + + var selectedItems = this.$element.find('option:selected').map(function(index,value) { + var $this = $(this); + var icon = $this.data('icon') && that.options.showIcon ? ' ' : ''; + var subtext; + if (that.options.showSubtext && $this.attr('data-subtext') && !that.multiple) { + subtext = ' '+$this.data('subtext') +''; + } else { + subtext = ''; + } + if ($this.data('content') && that.options.showContent) { + return $this.data('content'); + } else if ($this.attr('title') != undefined) { + return $this.attr('title'); + } else { + return icon + $this.html() + subtext; + } + }).toArray(); + + //Fixes issue in IE10 occurring when no default option is selected and at least one option is disabled + //Convert all the values into a comma delimited string + var title = !this.multiple ? selectedItems[0] : selectedItems.join(", "); + + //If this is multi select, and the selectText type is count, the show 1 of 2 selected etc.. + if (this.multiple && this.options.selectedTextFormat.indexOf('count') > -1) { + var max = this.options.selectedTextFormat.split(">"); + var notDisabled = this.options.hideDisabled ? ':not([disabled])' : ''; + if ( (max.length>1 && selectedItems.length > max[1]) || (max.length==1 && selectedItems.length>=2)) { + title = this.options.countSelectedText.replace('{0}', selectedItems.length).replace('{1}', this.$element.find('option:not([data-divider="true"]):not([data-hidden="true"])'+notDisabled).length); + } + } + + //If we dont have a title, then use the default, or if nothing is set at all, use the not selected text + if (!title) { + title = this.options.title != undefined ? this.options.title : this.options.noneSelectedText; + } + + this.$newElement.find('.filter-option').html(title); + }, + + setStyle: function(style, status) { + if (this.$element.attr('class')) { + this.$newElement.addClass(this.$element.attr('class').replace(/selectpicker|mobile-device/gi, '')); + } + + var buttonClass = style ? style : this.options.style; + + if (status == 'add') { + this.$button.addClass(buttonClass); + } else if (status == 'remove') { + this.$button.removeClass(buttonClass); + } else { + this.$button.removeClass(this.options.style); + this.$button.addClass(buttonClass); + } + }, + + liHeight: function() { + var selectClone = this.$newElement.clone(); + selectClone.appendTo('body'); + var $menuClone = selectClone.addClass('open').find('> .dropdown-menu'); + var liHeight = $menuClone.find('li > a').outerHeight(); + var headerHeight = this.options.header ? $menuClone.find('.popover-title').outerHeight() : 0; + selectClone.remove(); + this.$newElement.data('liHeight', liHeight).data('headerHeight', headerHeight); + }, + + setSize: function() { + var that = this, + menu = this.$menu, + menuInner = menu.find('.inner'), + menuA = menuInner.find('li > a'), + selectHeight = this.$newElement.outerHeight(), + liHeight = this.$newElement.data('liHeight'), + headerHeight = this.$newElement.data('headerHeight'), + divHeight = menu.find('li .divider').outerHeight(true), + menuPadding = parseInt(menu.css('padding-top')) + + parseInt(menu.css('padding-bottom')) + + parseInt(menu.css('border-top-width')) + + parseInt(menu.css('border-bottom-width')), + notDisabled = this.options.hideDisabled ? ':not(.disabled)' : '', + $window = $(window), + menuExtras = menuPadding + parseInt(menu.css('margin-top')) + parseInt(menu.css('margin-bottom')) + 2, + menuHeight, + selectOffsetTop, + selectOffsetBot, + posVert = function() { + selectOffsetTop = that.$newElement.offset().top - $window.scrollTop(); + selectOffsetBot = $window.height() - selectOffsetTop - selectHeight; + }; + posVert(); + if (this.options.header) menu.css('padding-top', 0); + + if (this.options.size == 'auto') { + var getSize = function() { + var minHeight; + posVert(); + menuHeight = selectOffsetBot - menuExtras; + that.$newElement.toggleClass('dropup', (selectOffsetTop > selectOffsetBot) && (menuHeight - menuExtras) < menu.height() && that.options.dropupAuto); + if (that.$newElement.hasClass('dropup')) { + menuHeight = selectOffsetTop - menuExtras; + } + if ((menu.find('li').length + menu.find('dt').length) > 3) { + minHeight = liHeight*3 + menuExtras - 2; + } else { + minHeight = 0; + } + menu.css({'max-height' : menuHeight + 'px', 'overflow' : 'hidden', 'min-height' : minHeight + 'px'}); + menuInner.css({'max-height' : menuHeight - headerHeight- menuPadding + 'px', 'overflow-y' : 'auto', 'min-height' : minHeight - menuPadding + 'px'}); + } + getSize(); + $(window).resize(getSize); + $(window).scroll(getSize); + } else if (this.options.size && this.options.size != 'auto' && menu.find('li'+notDisabled).length > this.options.size) { + var optIndex = menu.find("li"+notDisabled+" > *").filter(':not(.div-contain)').slice(0,this.options.size).last().parent().index(); + var divLength = menu.find("li").slice(0,optIndex + 1).find('.div-contain').length; + menuHeight = liHeight*this.options.size + divLength*divHeight + menuPadding; + this.$newElement.toggleClass('dropup', (selectOffsetTop > selectOffsetBot) && menuHeight < menu.height() && this.options.dropupAuto); + menu.css({'max-height' : menuHeight + headerHeight + 'px', 'overflow' : 'hidden'}); + menuInner.css({'max-height' : menuHeight - menuPadding + 'px', 'overflow-y' : 'auto'}); + } + }, + + setWidth: function() { + if (this.options.width == 'auto') { + this.$menu.css('min-width', '0'); + + // Get correct width if element hidden + var selectClone = this.$newElement.clone().appendTo('body'); + var ulWidth = selectClone.find('> .dropdown-menu').css('width'); + selectClone.remove(); + + this.$newElement.css('width', ulWidth); + } else if (this.options.width == 'fit') { + // Remove inline min-width so width can be changed from 'auto' + this.$menu.css('min-width', ''); + this.$newElement.css('width', '').addClass('fit-width'); + } else if (this.options.width) { + // Remove inline min-width so width can be changed from 'auto' + this.$menu.css('min-width', ''); + this.$newElement.css('width', this.options.width); + } else { + // Remove inline min-width/width so width can be changed + this.$menu.css('min-width', ''); + this.$newElement.css('width', ''); + } + // Remove fit-width class if width is changed programmatically + if (this.$newElement.hasClass('fit-width') && this.options.width !== 'fit') { + this.$newElement.removeClass('fit-width'); + } + }, + + selectPosition: function() { + var that = this, + drop = "
    ", + $drop = $(drop), + pos, + actualHeight, + getPlacement = function($element) { + $drop.addClass($element.attr('class')).toggleClass('dropup', $element.hasClass('dropup')); + pos = $element.offset(); + actualHeight = $element.hasClass('dropup') ? 0 : $element[0].offsetHeight; + $drop.css({'top' : pos.top + actualHeight, 'left' : pos.left, 'width' : $element[0].offsetWidth, 'position' : 'absolute'}); + }; + this.$newElement.on('click', function(e) { + getPlacement($(this)); + $drop.appendTo(that.options.container); + $drop.toggleClass('open', !$(this).hasClass('open')); + $drop.append(that.$menu); + }); + $(window).resize(function() { + getPlacement(that.$newElement); + }); + $(window).on('scroll', function(e) { + getPlacement(that.$newElement); + }); + $('html').on('click', function(e) { + if ($(e.target).closest(that.$newElement).length < 1) { + $drop.removeClass('open'); + } + }); + }, + + mobile: function() { + this.$element.addClass('mobile-device').appendTo(this.$newElement); + if (this.options.container) this.$menu.hide(); + }, + + refresh: function() { + this.reloadLi(); + this.render(); + this.setWidth(); + this.setStyle(); + this.checkDisabled(); + this.liHeight(); + }, + + setSelected: function(index, selected) { + this.$menu.find('li').eq(index).toggleClass('selected', selected); + }, + + setDisabled: function(index, disabled) { + if (disabled) { + this.$menu.find('li').eq(index).addClass('disabled').find('a').attr('href','#').attr('tabindex',-1); + } else { + this.$menu.find('li').eq(index).removeClass('disabled').find('a').removeAttr('href').attr('tabindex',0); + } + }, + + isDisabled: function() { + return this.$element.is(':disabled'); + }, + + checkDisabled: function() { + var that = this; + if (this.isDisabled()) { + this.$button.addClass('disabled'); + this.$button.attr('tabindex','-1'); + } else if (this.$button.hasClass('disabled')) { + this.$button.removeClass('disabled'); + this.$button.removeAttr('tabindex'); + } + this.$button.click(function() { + return !that.isDisabled(); + }); + }, + + checkTabIndex: function() { + if (this.$element.is('[tabindex]')) { + var tabindex = this.$element.attr("tabindex"); + this.$button.attr('tabindex', tabindex); + } + }, + + clickListener: function() { + var that = this; + + $('body').on('touchstart.dropdown', '.dropdown-menu', function(e) { + e.stopPropagation(); + }); + + this.$newElement.on('click', function() { + that.setSize(); + }); + + this.$menu.on('click', 'li a', function(e) { + var clickedIndex = $(this).parent().index(), + $this = $(this).parent(), + prevValue = that.$element.val(); + + //Dont close on multi choice menu + if (that.multiple) { + e.stopPropagation(); + } + + e.preventDefault(); + + //Dont run if we have been disabled + if (!that.isDisabled() && !$(this).parent().hasClass('disabled')) { + var $options = that.$element.find('option'); + var $option = $options.eq(clickedIndex); + + //Deselect all others if not multi select box + if (!that.multiple) { + $options.prop('selected', false); + $option.prop('selected', true); + } + //Else toggle the one we have chosen if we are multi select. + else { + var state = $option.prop('selected'); + + $option.prop('selected', !state); + } + + that.$button.focus(); + + // Trigger select 'change' + if (prevValue != that.$element.val()) { + that.$element.change(); + } + } + }); + + this.$menu.on('click', 'li.disabled a, li dt, li .div-contain, h3.popover-title', function(e) { + if (e.target == this) { + e.preventDefault(); + e.stopPropagation(); + that.$button.focus(); + } + }); + + this.$searchbox.on('click', function(e) { + e.stopPropagation(); + }); + + this.$element.change(function() { + that.render() + }); + }, + + liveSearchListener: function() { + var that = this; + + this.$newElement.on('click.dropdown.data-api', function(e){ + if(that.options.liveSearch) { + setTimeout(function() { + that.$searchbox.focus(); + }, 10); + } + }); + + this.$searchbox.on('input', function() { + that.$newElement.find('li').show().not(':icontains(' + that.$searchbox.val() + ')').hide(); + }); + }, + + val: function(value) { + + if (value != undefined) { + this.$element.val( value ); + + this.$element.change(); + return this.$element; + } else { + return this.$element.val(); + } + }, + + selectAll: function() { + this.$element.find('option').prop('selected', true).attr('selected', 'selected'); + this.render(); + }, + + deselectAll: function() { + this.$element.find('option').prop('selected', false).removeAttr('selected'); + this.render(); + }, + + keydown: function(e) { + var $this, + $items, + $parent, + index, + next, + first, + last, + prev, + nextPrev, + that; + + $this = $(this); + + $parent = $this.parent(); + + that = $parent.data('this'); + + if (that.options.container) $parent = that.$menu; + + $items = $('[role=menu] li:not(.divider):visible a', $parent); + + if (!$items.length) return; + + if (/(38|40)/.test(e.keyCode)) { + + index = $items.index($items.filter(':focus')); + first = $items.parent(':not(.disabled)').first().index(); + last = $items.parent(':not(.disabled)').last().index(); + next = $items.eq(index).parent().nextAll(':not(.disabled)').eq(0).index(); + prev = $items.eq(index).parent().prevAll(':not(.disabled)').eq(0).index(); + nextPrev = $items.eq(next).parent().prevAll(':not(.disabled)').eq(0).index(); + + if (e.keyCode == 38) { + if (index != nextPrev && index > prev) index = prev; + if (index < first) index = first; + } + + if (e.keyCode == 40) { + if (index != nextPrev && index < next) index = next; + if (index > last) index = last; + if (index == -1) index = 0; + } + + $items.eq(index).focus(); + } else { + var keyCodeMap = { + 48:"0", 49:"1", 50:"2", 51:"3", 52:"4", 53:"5", 54:"6", 55:"7", 56:"8", 57:"9", 59:";", + 65:"a", 66:"b", 67:"c", 68:"d", 69:"e", 70:"f", 71:"g", 72:"h", 73:"i", 74:"j", 75:"k", 76:"l", + 77:"m", 78:"n", 79:"o", 80:"p", 81:"q", 82:"r", 83:"s", 84:"t", 85:"u", 86:"v", 87:"w", 88:"x", 89:"y", 90:"z", + 96:"0", 97:"1", 98:"2", 99:"3", 100:"4", 101:"5", 102:"6", 103:"7", 104:"8", 105:"9" + } + + var keyIndex = []; + + $items.each(function() { + if ($(this).parent().is(':not(.disabled)')) { + if ($.trim($(this).text().toLowerCase()).substring(0,1) == keyCodeMap[e.keyCode]) { + keyIndex.push($(this).parent().index()); + } + } + }); + + var count = $(document).data('keycount'); + count++; + $(document).data('keycount',count); + + var prevKey = $.trim($(':focus').text().toLowerCase()).substring(0,1); + + if (prevKey != keyCodeMap[e.keyCode]) { + count = 1; + $(document).data('keycount',count); + } else if (count >= keyIndex.length) { + $(document).data('keycount',0); + } + + $items.eq(keyIndex[count - 1]).focus(); + } + + // select focused option if "Enter" or "Spacebar" are pressed + if (/(13|32)/.test(e.keyCode)) { + e.preventDefault(); + $(':focus').click(); + $(document).data('keycount',0); + } + }, + + hide: function() { + this.$newElement.hide(); + }, + + show: function() { + this.$newElement.show(); + }, + + destroy: function() { + this.$newElement.remove(); + this.$element.remove(); + } + }; + + $.fn.selectpicker = function(option, event) { + //get the args of the outer function.. + var args = arguments; + var value; + var chain = this.each(function() { + if ($(this).is('select')) { + var $this = $(this), + data = $this.data('selectpicker'), + options = typeof option == 'object' && option; + + if (!data) { + $this.data('selectpicker', (data = new Selectpicker(this, options, event))); + } else if (options) { + for(var i in options) { + data.options[i] = options[i]; + } + } + + if (typeof option == 'string') { + //Copy the value of option, as once we shift the arguments + //it also shifts the value of option. + var property = option; + if (data[property] instanceof Function) { + [].shift.apply(args); + value = data[property].apply(data, args); + } else { + value = data.options[property]; + } + } + } + }); + + if (value != undefined) { + return value; + } else { + return chain; + } + }; + + $.fn.selectpicker.defaults = { + style: 'btn-default', + size: 'auto', + title: null, + selectedTextFormat : 'values', + noneSelectedText : 'Nothing selected', + countSelectedText: '{0} of {1} selected', + width: false, + container: false, + hideDisabled: false, + showSubtext: false, + showIcon: true, + showContent: true, + dropupAuto: true, + header: false, + liveSearch: false + } + + $(document) + .data('keycount', 0) + .on('keydown', '[data-toggle=dropdown], [role=menu]' , Selectpicker.prototype.keydown) + +}(window.jQuery); diff --git a/templates/admin/default/assets/js/coupon.js b/templates/admin/default/assets/js/coupon.js index 41e0c1430..5ed22f9df 100644 --- a/templates/admin/default/assets/js/coupon.js +++ b/templates/admin/default/assets/js/coupon.js @@ -85,7 +85,7 @@ $(function($){ couponManager.createOrUpdateRuleAjax(); } } - + return false; }); }; couponManager.onClickSaveRule(); @@ -96,6 +96,7 @@ $(function($){ e.preventDefault(); var $this = $(this); couponManager.removeRuleAjax($this.attr('data-int')); + return false; }); }; couponManager.onClickDeleteRule(); @@ -109,6 +110,7 @@ $(function($){ // Hide row being updated $this.parent().parent().remove(); + return false; }); }; couponManager.onClickUpdateRule(); diff --git a/templates/admin/default/assets/js/document-upload.js b/templates/admin/default/assets/js/document-upload.js new file mode 100644 index 000000000..dc35ea943 --- /dev/null +++ b/templates/admin/default/assets/js/document-upload.js @@ -0,0 +1,100 @@ +$(function($){ + // Manage document upload + $.documentUploadManager = {}; + + Dropzone.autoDiscover = false; + + + + // Remove image on click + $.documentUploadManager.initDocumentDropZone = function() { + $.documentUploadManager.onClickDeleteDocument(); + + var documentDropzone = new Dropzone("#documents-dropzone", { + dictDefaultMessage : $('.btn-browse').html(), + uploadMultiple: false, + maxFilesize: 8 + }); + + var totalFiles = 0, + completedFiles = 0; + + documentDropzone.on("addedfile", function(file){ + totalFiles += 1; + + if(totalFiles == 1){ + $('.dz-message').hide(); + } + }); + + documentDropzone.on("complete", function(file){ + completedFiles += 1; + + if (completedFiles === totalFiles){ + $('.dz-message').slideDown(); + } + }); + + documentDropzone.on("success", function(file) { + documentDropzone.removeFile(file); + $.documentUploadManager.updateDocumentListAjax(); + $.documentUploadManager.onClickDeleteDocument(); + }); + + + + }; + + // Update picture list via AJAX call + $.documentUploadManager.updateDocumentListAjax = function() { + var $documentListArea = $(".document-manager .existing-document"); + $documentListArea.html('
    '); + $.ajax({ + type: "POST", + url: documentListUrl, + statusCode: { + 404: function() { + $documentListArea.html( + documentListErrorMessage + ); + } + } + }).done(function(data) { + $documentListArea.html( + data + ); + $.documentUploadManager.onClickDeleteDocument(); + }); + }; + + // Remove image on click + $.documentUploadManager.onClickDeleteDocument = function() { + $('.document-manager .document-delete-btn').on('click', function (e) { + e.preventDefault(); + var $this = $(this); + var $parent = $this.parent(); + $parent.find('a').remove(); + $parent.append('
    '); + var $url = $this.attr("href"); + var errorMessage = $this.attr("data-error-message"); + $.ajax({ + type: "POST", + url: $url, + statusCode: { + 404: function() { + $(".document-manager .message").html( + errorMessage + ); + } + } + }).done(function(data) { + $parent.parents('tr').remove(); + + $(".document-manager .message").html( + data + ); + }); + return false; + }); + }; +}); diff --git a/templates/admin/default/assets/js/dropzone.js b/templates/admin/default/assets/js/dropzone.js new file mode 100644 index 000000000..3e68289ad --- /dev/null +++ b/templates/admin/default/assets/js/dropzone.js @@ -0,0 +1,1758 @@ +;(function(){ + + /** + * Require the given path. + * + * @param {String} path + * @return {Object} exports + * @api public + */ + + function require(path, parent, orig) { + var resolved = require.resolve(path); + + // lookup failed + if (null == resolved) { + orig = orig || path; + parent = parent || 'root'; + var err = new Error('Failed to require "' + orig + '" from "' + parent + '"'); + err.path = orig; + err.parent = parent; + err.require = true; + throw err; + } + + var module = require.modules[resolved]; + + // perform real require() + // by invoking the module's + // registered function + if (!module.exports) { + module.exports = {}; + module.client = module.component = true; + module.call(this, module.exports, require.relative(resolved), module); + } + + return module.exports; + } + + /** + * Registered modules. + */ + + require.modules = {}; + + /** + * Registered aliases. + */ + + require.aliases = {}; + + /** + * Resolve `path`. + * + * Lookup: + * + * - PATH/index.js + * - PATH.js + * - PATH + * + * @param {String} path + * @return {String} path or null + * @api private + */ + + require.resolve = function(path) { + if (path.charAt(0) === '/') path = path.slice(1); + + var paths = [ + path, + path + '.js', + path + '.json', + path + '/index.js', + path + '/index.json' + ]; + + for (var i = 0; i < paths.length; i++) { + var path = paths[i]; + if (require.modules.hasOwnProperty(path)) return path; + if (require.aliases.hasOwnProperty(path)) return require.aliases[path]; + } + }; + + /** + * Normalize `path` relative to the current path. + * + * @param {String} curr + * @param {String} path + * @return {String} + * @api private + */ + + require.normalize = function(curr, path) { + var segs = []; + + if ('.' != path.charAt(0)) return path; + + curr = curr.split('/'); + path = path.split('/'); + + for (var i = 0; i < path.length; ++i) { + if ('..' == path[i]) { + curr.pop(); + } else if ('.' != path[i] && '' != path[i]) { + segs.push(path[i]); + } + } + + return curr.concat(segs).join('/'); + }; + + /** + * Register module at `path` with callback `definition`. + * + * @param {String} path + * @param {Function} definition + * @api private + */ + + require.register = function(path, definition) { + require.modules[path] = definition; + }; + + /** + * Alias a module definition. + * + * @param {String} from + * @param {String} to + * @api private + */ + + require.alias = function(from, to) { + if (!require.modules.hasOwnProperty(from)) { + throw new Error('Failed to alias "' + from + '", it does not exist'); + } + require.aliases[to] = from; + }; + + /** + * Return a require function relative to the `parent` path. + * + * @param {String} parent + * @return {Function} + * @api private + */ + + require.relative = function(parent) { + var p = require.normalize(parent, '..'); + + /** + * lastIndexOf helper. + */ + + function lastIndexOf(arr, obj) { + var i = arr.length; + while (i--) { + if (arr[i] === obj) return i; + } + return -1; + } + + /** + * The relative require() itself. + */ + + function localRequire(path) { + var resolved = localRequire.resolve(path); + return require(resolved, parent, path); + } + + /** + * Resolve relative to the parent. + */ + + localRequire.resolve = function(path) { + var c = path.charAt(0); + if ('/' == c) return path.slice(1); + if ('.' == c) return require.normalize(p, path); + + // resolve deps by returning + // the dep in the nearest "deps" + // directory + var segs = parent.split('/'); + var i = lastIndexOf(segs, 'deps') + 1; + if (!i) i = 0; + path = segs.slice(0, i + 1).join('/') + '/deps/' + path; + return path; + }; + + /** + * Check if module is defined at `path`. + */ + + localRequire.exists = function(path) { + return require.modules.hasOwnProperty(localRequire.resolve(path)); + }; + + return localRequire; + }; + require.register("component-emitter/index.js", function(exports, require, module){ + + /** + * Expose `Emitter`. + */ + + module.exports = Emitter; + + /** + * Initialize a new `Emitter`. + * + * @api public + */ + + function Emitter(obj) { + if (obj) return mixin(obj); + }; + + /** + * Mixin the emitter properties. + * + * @param {Object} obj + * @return {Object} + * @api private + */ + + function mixin(obj) { + for (var key in Emitter.prototype) { + obj[key] = Emitter.prototype[key]; + } + return obj; + } + + /** + * Listen on the given `event` with `fn`. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + + Emitter.prototype.on = function(event, fn){ + this._callbacks = this._callbacks || {}; + (this._callbacks[event] = this._callbacks[event] || []) + .push(fn); + return this; + }; + + /** + * Adds an `event` listener that will be invoked a single + * time then automatically removed. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + + Emitter.prototype.once = function(event, fn){ + var self = this; + this._callbacks = this._callbacks || {}; + + function on() { + self.off(event, on); + fn.apply(this, arguments); + } + + fn._off = on; + this.on(event, on); + return this; + }; + + /** + * Remove the given callback for `event` or all + * registered callbacks. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + + Emitter.prototype.off = + Emitter.prototype.removeListener = + Emitter.prototype.removeAllListeners = function(event, fn){ + this._callbacks = this._callbacks || {}; + var callbacks = this._callbacks[event]; + if (!callbacks) return this; + + // remove all handlers + if (1 == arguments.length) { + delete this._callbacks[event]; + return this; + } + + // remove specific handler + var i = callbacks.indexOf(fn._off || fn); + if (~i) callbacks.splice(i, 1); + return this; + }; + + /** + * Emit `event` with the given args. + * + * @param {String} event + * @param {Mixed} ... + * @return {Emitter} + */ + + Emitter.prototype.emit = function(event){ + this._callbacks = this._callbacks || {}; + var args = [].slice.call(arguments, 1) + , callbacks = this._callbacks[event]; + + if (callbacks) { + callbacks = callbacks.slice(0); + for (var i = 0, len = callbacks.length; i < len; ++i) { + callbacks[i].apply(this, args); + } + } + + return this; + }; + + /** + * Return array of callbacks for `event`. + * + * @param {String} event + * @return {Array} + * @api public + */ + + Emitter.prototype.listeners = function(event){ + this._callbacks = this._callbacks || {}; + return this._callbacks[event] || []; + }; + + /** + * Check if this emitter has `event` handlers. + * + * @param {String} event + * @return {Boolean} + * @api public + */ + + Emitter.prototype.hasListeners = function(event){ + return !! this.listeners(event).length; + }; + + }); + require.register("dropzone/index.js", function(exports, require, module){ + + + /** + * Exposing dropzone + */ + module.exports = require("./lib/dropzone.js"); + + }); + require.register("dropzone/lib/dropzone.js", function(exports, require, module){ + /* + # + # More info at [www.dropzonejs.com](http://www.dropzonejs.com) + # + # Copyright (c) 2012, Matias Meno + # + # Permission is hereby granted, free of charge, to any person obtaining a copy + # of this software and associated documentation files (the "Software"), to deal + # in the Software without restriction, including without limitation the rights + # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + # copies of the Software, and to permit persons to whom the Software is + # furnished to do so, subject to the following conditions: + # + # The above copyright notice and this permission notice shall be included in + # all copies or substantial portions of the Software. + # + # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + # THE SOFTWARE. + # + */ + + + (function() { + var Dropzone, Em, camelize, contentLoaded, noop, without, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __slice = [].slice; + + Em = typeof Emitter !== "undefined" && Emitter !== null ? Emitter : require("emitter"); + + noop = function() {}; + + Dropzone = (function(_super) { + var extend; + + __extends(Dropzone, _super); + + /* + This is a list of all available events you can register on a dropzone object. + + You can register an event handler like this: + + dropzone.on("dragEnter", function() { }); + */ + + + Dropzone.prototype.events = ["drop", "dragstart", "dragend", "dragenter", "dragover", "dragleave", "selectedfiles", "addedfile", "removedfile", "thumbnail", "error", "errormultiple", "processing", "processingmultiple", "uploadprogress", "totaluploadprogress", "sending", "sendingmultiple", "success", "successmultiple", "canceled", "canceledmultiple", "complete", "completemultiple", "reset", "maxfilesexceeded"]; + + Dropzone.prototype.defaultOptions = { + url: null, + method: "post", + withCredentials: false, + parallelUploads: 2, + uploadMultiple: false, + maxFilesize: 256, + paramName: "file", + createImageThumbnails: true, + maxThumbnailFilesize: 10, + thumbnailWidth: 100, + thumbnailHeight: 100, + maxFiles: null, + params: {}, + clickable: true, + ignoreHiddenFiles: true, + acceptedFiles: null, + acceptedMimeTypes: null, + autoProcessQueue: true, + addRemoveLinks: false, + previewsContainer: null, + dictDefaultMessage: "Drop files here to upload", + dictFallbackMessage: "Your browser does not support drag'n'drop file uploads.", + dictFallbackText: "Please use the fallback form below to upload your files like in the olden days.", + dictFileTooBig: "File is too big ({{filesize}}MB). Max filesize: {{maxFilesize}}MB.", + dictInvalidFileType: "You can't upload files of this type.", + dictResponseError: "Server responded with {{statusCode}} code.", + dictCancelUpload: "Cancel upload", + dictCancelUploadConfirmation: "Are you sure you want to cancel this upload?", + dictRemoveFile: "Remove file", + dictRemoveFileConfirmation: null, + dictMaxFilesExceeded: "You can only upload {{maxFiles}} files.", + accept: function(file, done) { + return done(); + }, + init: function() { + return noop; + }, + forceFallback: false, + fallback: function() { + var child, messageElement, span, _i, _len, _ref; + this.element.className = "" + this.element.className + " dz-browser-not-supported"; + _ref = this.element.getElementsByTagName("div"); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + child = _ref[_i]; + if (/(^| )dz-message($| )/.test(child.className)) { + messageElement = child; + child.className = "dz-message"; + continue; + } + } + if (!messageElement) { + messageElement = Dropzone.createElement("
    "); + this.element.appendChild(messageElement); + } + span = messageElement.getElementsByTagName("span")[0]; + if (span) { + span.textContent = this.options.dictFallbackMessage; + } + return this.element.appendChild(this.getFallbackForm()); + }, + resize: function(file) { + var info, srcRatio, trgRatio; + info = { + srcX: 0, + srcY: 0, + srcWidth: file.width, + srcHeight: file.height + }; + srcRatio = file.width / file.height; + trgRatio = this.options.thumbnailWidth / this.options.thumbnailHeight; + if (file.height < this.options.thumbnailHeight || file.width < this.options.thumbnailWidth) { + info.trgHeight = info.srcHeight; + info.trgWidth = info.srcWidth; + } else { + if (srcRatio > trgRatio) { + info.srcHeight = file.height; + info.srcWidth = info.srcHeight * trgRatio; + } else { + info.srcWidth = file.width; + info.srcHeight = info.srcWidth / trgRatio; + } + } + info.srcX = (file.width - info.srcWidth) / 2; + info.srcY = (file.height - info.srcHeight) / 2; + return info; + }, + /* + Those functions register themselves to the events on init and handle all + the user interface specific stuff. Overwriting them won't break the upload + but can break the way it's displayed. + You can overwrite them if you don't like the default behavior. If you just + want to add an additional event handler, register it on the dropzone object + and don't overwrite those options. + */ + + drop: function(e) { + return this.element.classList.remove("dz-drag-hover"); + }, + dragstart: noop, + dragend: function(e) { + return this.element.classList.remove("dz-drag-hover"); + }, + dragenter: function(e) { + return this.element.classList.add("dz-drag-hover"); + }, + dragover: function(e) { + return this.element.classList.add("dz-drag-hover"); + }, + dragleave: function(e) { + return this.element.classList.remove("dz-drag-hover"); + }, + selectedfiles: function(files) { + if (this.element === this.previewsContainer) { + return this.element.classList.add("dz-started"); + } + }, + reset: function() { + return this.element.classList.remove("dz-started"); + }, + addedfile: function(file) { + var _this = this; + file.previewElement = Dropzone.createElement(this.options.previewTemplate); + file.previewTemplate = file.previewElement; + this.previewsContainer.appendChild(file.previewElement); + file.previewElement.querySelector("[data-dz-name]").textContent = file.name; + file.previewElement.querySelector("[data-dz-size]").innerHTML = this.filesize(file.size); + if (this.options.addRemoveLinks) { + file._removeLink = Dropzone.createElement("" + this.options.dictRemoveFile + ""); + file._removeLink.addEventListener("click", function(e) { + e.preventDefault(); + e.stopPropagation(); + if (file.status === Dropzone.UPLOADING) { + return Dropzone.confirm(_this.options.dictCancelUploadConfirmation, function() { + return _this.removeFile(file); + }); + } else { + if (_this.options.dictRemoveFileConfirmation) { + return Dropzone.confirm(_this.options.dictRemoveFileConfirmation, function() { + return _this.removeFile(file); + }); + } else { + return _this.removeFile(file); + } + } + }); + file.previewElement.appendChild(file._removeLink); + } + return this._updateMaxFilesReachedClass(); + }, + removedfile: function(file) { + var _ref; + if ((_ref = file.previewElement) != null) { + _ref.parentNode.removeChild(file.previewElement); + } + return this._updateMaxFilesReachedClass(); + }, + thumbnail: function(file, dataUrl) { + var thumbnailElement; + file.previewElement.classList.remove("dz-file-preview"); + file.previewElement.classList.add("dz-image-preview"); + thumbnailElement = file.previewElement.querySelector("[data-dz-thumbnail]"); + thumbnailElement.alt = file.name; + return thumbnailElement.src = dataUrl; + }, + error: function(file, message) { + file.previewElement.classList.add("dz-error"); + return file.previewElement.querySelector("[data-dz-errormessage]").textContent = message; + }, + errormultiple: noop, + processing: function(file) { + file.previewElement.classList.add("dz-processing"); + if (file._removeLink) { + return file._removeLink.textContent = this.options.dictCancelUpload; + } + }, + processingmultiple: noop, + uploadprogress: function(file, progress, bytesSent) { + return file.previewElement.querySelector("[data-dz-uploadprogress]").style.width = "" + progress + "%"; + }, + totaluploadprogress: noop, + sending: noop, + sendingmultiple: noop, + success: function(file) { + return file.previewElement.classList.add("dz-success"); + }, + successmultiple: noop, + canceled: function(file) { + return this.emit("error", file, "Upload canceled."); + }, + canceledmultiple: noop, + complete: function(file) { + if (file._removeLink) { + return file._removeLink.textContent = this.options.dictRemoveFile; + } + }, + completemultiple: noop, + maxfilesexceeded: noop, + previewTemplate: "
    \n
    \n
    \n
    \n \n
    \n
    \n
    \n
    \n
    \n
    " + }; + + extend = function() { + var key, object, objects, target, val, _i, _len; + target = arguments[0], objects = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + for (_i = 0, _len = objects.length; _i < _len; _i++) { + object = objects[_i]; + for (key in object) { + val = object[key]; + target[key] = val; + } + } + return target; + }; + + function Dropzone(element, options) { + var elementOptions, fallback, _ref; + this.element = element; + this.version = Dropzone.version; + this.defaultOptions.previewTemplate = this.defaultOptions.previewTemplate.replace(/\n*/g, ""); + this.clickableElements = []; + this.listeners = []; + this.files = []; + if (typeof this.element === "string") { + this.element = document.querySelector(this.element); + } + if (!(this.element && (this.element.nodeType != null))) { + throw new Error("Invalid dropzone element."); + } + if (this.element.dropzone) { + throw new Error("Dropzone already attached."); + } + Dropzone.instances.push(this); + element.dropzone = this; + elementOptions = (_ref = Dropzone.optionsForElement(this.element)) != null ? _ref : {}; + this.options = extend({}, this.defaultOptions, elementOptions, options != null ? options : {}); + if (this.options.forceFallback || !Dropzone.isBrowserSupported()) { + return this.options.fallback.call(this); + } + if (this.options.url == null) { + this.options.url = this.element.getAttribute("action"); + } + if (!this.options.url) { + throw new Error("No URL provided."); + } + if (this.options.acceptedFiles && this.options.acceptedMimeTypes) { + throw new Error("You can't provide both 'acceptedFiles' and 'acceptedMimeTypes'. 'acceptedMimeTypes' is deprecated."); + } + if (this.options.acceptedMimeTypes) { + this.options.acceptedFiles = this.options.acceptedMimeTypes; + delete this.options.acceptedMimeTypes; + } + this.options.method = this.options.method.toUpperCase(); + if ((fallback = this.getExistingFallback()) && fallback.parentNode) { + fallback.parentNode.removeChild(fallback); + } + if (this.options.previewsContainer) { + this.previewsContainer = Dropzone.getElement(this.options.previewsContainer, "previewsContainer"); + } else { + this.previewsContainer = this.element; + } + if (this.options.clickable) { + if (this.options.clickable === true) { + this.clickableElements = [this.element]; + } else { + this.clickableElements = Dropzone.getElements(this.options.clickable, "clickable"); + } + } + this.init(); + } + + Dropzone.prototype.getAcceptedFiles = function() { + var file, _i, _len, _ref, _results; + _ref = this.files; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + file = _ref[_i]; + if (file.accepted) { + _results.push(file); + } + } + return _results; + }; + + Dropzone.prototype.getRejectedFiles = function() { + var file, _i, _len, _ref, _results; + _ref = this.files; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + file = _ref[_i]; + if (!file.accepted) { + _results.push(file); + } + } + return _results; + }; + + Dropzone.prototype.getQueuedFiles = function() { + var file, _i, _len, _ref, _results; + _ref = this.files; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + file = _ref[_i]; + if (file.status === Dropzone.QUEUED) { + _results.push(file); + } + } + return _results; + }; + + Dropzone.prototype.getUploadingFiles = function() { + var file, _i, _len, _ref, _results; + _ref = this.files; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + file = _ref[_i]; + if (file.status === Dropzone.UPLOADING) { + _results.push(file); + } + } + return _results; + }; + + Dropzone.prototype.init = function() { + var eventName, noPropagation, setupHiddenFileInput, _i, _len, _ref, _ref1, + _this = this; + if (this.element.tagName === "form") { + this.element.setAttribute("enctype", "multipart/form-data"); + } + if (this.element.classList.contains("dropzone") && !this.element.querySelector(".dz-message")) { + this.element.appendChild(Dropzone.createElement("
    " + this.options.dictDefaultMessage + "
    ")); + } + if (this.clickableElements.length) { + setupHiddenFileInput = function() { + if (_this.hiddenFileInput) { + document.body.removeChild(_this.hiddenFileInput); + } + _this.hiddenFileInput = document.createElement("input"); + _this.hiddenFileInput.setAttribute("type", "file"); + _this.hiddenFileInput.setAttribute("multiple", "multiple"); + if (_this.options.acceptedFiles != null) { + _this.hiddenFileInput.setAttribute("accept", _this.options.acceptedFiles); + } + _this.hiddenFileInput.style.visibility = "hidden"; + _this.hiddenFileInput.style.position = "absolute"; + _this.hiddenFileInput.style.top = "0"; + _this.hiddenFileInput.style.left = "0"; + _this.hiddenFileInput.style.height = "0"; + _this.hiddenFileInput.style.width = "0"; + document.body.appendChild(_this.hiddenFileInput); + return _this.hiddenFileInput.addEventListener("change", function() { + var files; + files = _this.hiddenFileInput.files; + if (files.length) { + _this.emit("selectedfiles", files); + _this.handleFiles(files); + } + return setupHiddenFileInput(); + }); + }; + setupHiddenFileInput(); + } + this.URL = (_ref = window.URL) != null ? _ref : window.webkitURL; + _ref1 = this.events; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + eventName = _ref1[_i]; + this.on(eventName, this.options[eventName]); + } + this.on("uploadprogress", function() { + return _this.updateTotalUploadProgress(); + }); + this.on("removedfile", function() { + return _this.updateTotalUploadProgress(); + }); + this.on("canceled", function(file) { + return _this.emit("complete", file); + }); + noPropagation = function(e) { + e.stopPropagation(); + if (e.preventDefault) { + return e.preventDefault(); + } else { + return e.returnValue = false; + } + }; + this.listeners = [ + { + element: this.element, + events: { + "dragstart": function(e) { + return _this.emit("dragstart", e); + }, + "dragenter": function(e) { + noPropagation(e); + return _this.emit("dragenter", e); + }, + "dragover": function(e) { + noPropagation(e); + return _this.emit("dragover", e); + }, + "dragleave": function(e) { + return _this.emit("dragleave", e); + }, + "drop": function(e) { + noPropagation(e); + return _this.drop(e); + }, + "dragend": function(e) { + return _this.emit("dragend", e); + } + } + } + ]; + this.clickableElements.forEach(function(clickableElement) { + return _this.listeners.push({ + element: clickableElement, + events: { + "click": function(evt) { + if ((clickableElement !== _this.element) || (evt.target === _this.element || Dropzone.elementInside(evt.target, _this.element.querySelector(".dz-message")))) { + return _this.hiddenFileInput.click(); + } + } + } + }); + }); + this.enable(); + return this.options.init.call(this); + }; + + Dropzone.prototype.destroy = function() { + var _ref; + this.disable(); + this.removeAllFiles(true); + if ((_ref = this.hiddenFileInput) != null ? _ref.parentNode : void 0) { + this.hiddenFileInput.parentNode.removeChild(this.hiddenFileInput); + this.hiddenFileInput = null; + } + return delete this.element.dropzone; + }; + + Dropzone.prototype.updateTotalUploadProgress = function() { + var acceptedFiles, file, totalBytes, totalBytesSent, totalUploadProgress, _i, _len, _ref; + totalBytesSent = 0; + totalBytes = 0; + acceptedFiles = this.getAcceptedFiles(); + if (acceptedFiles.length) { + _ref = this.getAcceptedFiles(); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + file = _ref[_i]; + totalBytesSent += file.upload.bytesSent; + totalBytes += file.upload.total; + } + totalUploadProgress = 100 * totalBytesSent / totalBytes; + } else { + totalUploadProgress = 100; + } + return this.emit("totaluploadprogress", totalUploadProgress, totalBytes, totalBytesSent); + }; + + Dropzone.prototype.getFallbackForm = function() { + var existingFallback, fields, fieldsString, form; + if (existingFallback = this.getExistingFallback()) { + return existingFallback; + } + fieldsString = "
    "; + if (this.options.dictFallbackText) { + fieldsString += "

    " + this.options.dictFallbackText + "

    "; + } + fieldsString += "
    "; + fields = Dropzone.createElement(fieldsString); + if (this.element.tagName !== "FORM") { + form = Dropzone.createElement(""); + form.appendChild(fields); + } else { + this.element.setAttribute("enctype", "multipart/form-data"); + this.element.setAttribute("method", this.options.method); + } + return form != null ? form : fields; + }; + + Dropzone.prototype.getExistingFallback = function() { + var fallback, getFallback, tagName, _i, _len, _ref; + getFallback = function(elements) { + var el, _i, _len; + for (_i = 0, _len = elements.length; _i < _len; _i++) { + el = elements[_i]; + if (/(^| )fallback($| )/.test(el.className)) { + return el; + } + } + }; + _ref = ["div", "form"]; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + tagName = _ref[_i]; + if (fallback = getFallback(this.element.getElementsByTagName(tagName))) { + return fallback; + } + } + }; + + Dropzone.prototype.setupEventListeners = function() { + var elementListeners, event, listener, _i, _len, _ref, _results; + _ref = this.listeners; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + elementListeners = _ref[_i]; + _results.push((function() { + var _ref1, _results1; + _ref1 = elementListeners.events; + _results1 = []; + for (event in _ref1) { + listener = _ref1[event]; + _results1.push(elementListeners.element.addEventListener(event, listener, false)); + } + return _results1; + })()); + } + return _results; + }; + + Dropzone.prototype.removeEventListeners = function() { + var elementListeners, event, listener, _i, _len, _ref, _results; + _ref = this.listeners; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + elementListeners = _ref[_i]; + _results.push((function() { + var _ref1, _results1; + _ref1 = elementListeners.events; + _results1 = []; + for (event in _ref1) { + listener = _ref1[event]; + _results1.push(elementListeners.element.removeEventListener(event, listener, false)); + } + return _results1; + })()); + } + return _results; + }; + + Dropzone.prototype.disable = function() { + var file, _i, _len, _ref, _results; + this.clickableElements.forEach(function(element) { + return element.classList.remove("dz-clickable"); + }); + this.removeEventListeners(); + _ref = this.files; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + file = _ref[_i]; + _results.push(this.cancelUpload(file)); + } + return _results; + }; + + Dropzone.prototype.enable = function() { + this.clickableElements.forEach(function(element) { + return element.classList.add("dz-clickable"); + }); + return this.setupEventListeners(); + }; + + Dropzone.prototype.filesize = function(size) { + var string; + if (size >= 100000000000) { + size = size / 100000000000; + string = "TB"; + } else if (size >= 100000000) { + size = size / 100000000; + string = "GB"; + } else if (size >= 100000) { + size = size / 100000; + string = "MB"; + } else if (size >= 100) { + size = size / 100; + string = "KB"; + } else { + size = size * 10; + string = "b"; + } + return "" + (Math.round(size) / 10) + " " + string; + }; + + Dropzone.prototype._updateMaxFilesReachedClass = function() { + if (this.options.maxFiles && this.getAcceptedFiles().length >= this.options.maxFiles) { + return this.element.classList.add("dz-max-files-reached"); + } else { + return this.element.classList.remove("dz-max-files-reached"); + } + }; + + Dropzone.prototype.drop = function(e) { + var files, items; + if (!e.dataTransfer) { + return; + } + this.emit("drop", e); + files = e.dataTransfer.files; + this.emit("selectedfiles", files); + if (files.length) { + items = e.dataTransfer.items; + if (items && items.length && ((items[0].webkitGetAsEntry != null) || (items[0].getAsEntry != null))) { + this.handleItems(items); + } else { + this.handleFiles(files); + } + } + }; + + Dropzone.prototype.handleFiles = function(files) { + var file, _i, _len, _results; + _results = []; + for (_i = 0, _len = files.length; _i < _len; _i++) { + file = files[_i]; + _results.push(this.addFile(file)); + } + return _results; + }; + + Dropzone.prototype.handleItems = function(items) { + var entry, item, _i, _len; + for (_i = 0, _len = items.length; _i < _len; _i++) { + item = items[_i]; + if (item.webkitGetAsEntry != null) { + entry = item.webkitGetAsEntry(); + if (entry.isFile) { + this.addFile(item.getAsFile()); + } else if (entry.isDirectory) { + this.addDirectory(entry, entry.name); + } + } else { + this.addFile(item.getAsFile()); + } + } + }; + + Dropzone.prototype.accept = function(file, done) { + if (file.size > this.options.maxFilesize * 1024 * 1024) { + return done(this.options.dictFileTooBig.replace("{{filesize}}", Math.round(file.size / 1024 / 10.24) / 100).replace("{{maxFilesize}}", this.options.maxFilesize)); + } else if (!Dropzone.isValidFile(file, this.options.acceptedFiles)) { + return done(this.options.dictInvalidFileType); + } else if (this.options.maxFiles && this.getAcceptedFiles().length >= this.options.maxFiles) { + done(this.options.dictMaxFilesExceeded.replace("{{maxFiles}}", this.options.maxFiles)); + return this.emit("maxfilesexceeded", file); + } else { + return this.options.accept.call(this, file, done); + } + }; + + Dropzone.prototype.addFile = function(file) { + var _this = this; + file.upload = { + progress: 0, + total: file.size, + bytesSent: 0 + }; + this.files.push(file); + file.status = Dropzone.ADDED; + this.emit("addedfile", file); + if (this.options.createImageThumbnails && file.type.match(/image.*/) && file.size <= this.options.maxThumbnailFilesize * 1024 * 1024) { + this.createThumbnail(file); + } + return this.accept(file, function(error) { + if (error) { + file.accepted = false; + return _this._errorProcessing([file], error); + } else { + return _this.enqueueFile(file); + } + }); + }; + + Dropzone.prototype.enqueueFiles = function(files) { + var file, _i, _len; + for (_i = 0, _len = files.length; _i < _len; _i++) { + file = files[_i]; + this.enqueueFile(file); + } + return null; + }; + + Dropzone.prototype.enqueueFile = function(file) { + var _this = this; + file.accepted = true; + if (file.status === Dropzone.ADDED) { + file.status = Dropzone.QUEUED; + if (this.options.autoProcessQueue) { + return setTimeout((function() { + return _this.processQueue(); + }), 1); + } + } else { + throw new Error("This file can't be queued because it has already been processed or was rejected."); + } + }; + + Dropzone.prototype.addDirectory = function(entry, path) { + var dirReader, entriesReader, + _this = this; + dirReader = entry.createReader(); + entriesReader = function(entries) { + var _i, _len; + for (_i = 0, _len = entries.length; _i < _len; _i++) { + entry = entries[_i]; + if (entry.isFile) { + entry.file(function(file) { + if (_this.options.ignoreHiddenFiles && file.name.substring(0, 1) === '.') { + return; + } + file.fullPath = "" + path + "/" + file.name; + return _this.addFile(file); + }); + } else if (entry.isDirectory) { + _this.addDirectory(entry, "" + path + "/" + entry.name); + } + } + }; + return dirReader.readEntries(entriesReader, function(error) { + return typeof console !== "undefined" && console !== null ? typeof console.log === "function" ? console.log(error) : void 0 : void 0; + }); + }; + + Dropzone.prototype.removeFile = function(file) { + if (file.status === Dropzone.UPLOADING) { + this.cancelUpload(file); + } + this.files = without(this.files, file); + this.emit("removedfile", file); + if (this.files.length === 0) { + return this.emit("reset"); + } + }; + + Dropzone.prototype.removeAllFiles = function(cancelIfNecessary) { + var file, _i, _len, _ref; + if (cancelIfNecessary == null) { + cancelIfNecessary = false; + } + _ref = this.files.slice(); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + file = _ref[_i]; + if (file.status !== Dropzone.UPLOADING || cancelIfNecessary) { + this.removeFile(file); + } + } + return null; + }; + + Dropzone.prototype.createThumbnail = function(file) { + var fileReader, + _this = this; + fileReader = new FileReader; + fileReader.onload = function() { + var img; + img = new Image; + img.onload = function() { + var canvas, ctx, resizeInfo, thumbnail, _ref, _ref1, _ref2, _ref3; + file.width = img.width; + file.height = img.height; + resizeInfo = _this.options.resize.call(_this, file); + if (resizeInfo.trgWidth == null) { + resizeInfo.trgWidth = _this.options.thumbnailWidth; + } + if (resizeInfo.trgHeight == null) { + resizeInfo.trgHeight = _this.options.thumbnailHeight; + } + canvas = document.createElement("canvas"); + ctx = canvas.getContext("2d"); + canvas.width = resizeInfo.trgWidth; + canvas.height = resizeInfo.trgHeight; + ctx.drawImage(img, (_ref = resizeInfo.srcX) != null ? _ref : 0, (_ref1 = resizeInfo.srcY) != null ? _ref1 : 0, resizeInfo.srcWidth, resizeInfo.srcHeight, (_ref2 = resizeInfo.trgX) != null ? _ref2 : 0, (_ref3 = resizeInfo.trgY) != null ? _ref3 : 0, resizeInfo.trgWidth, resizeInfo.trgHeight); + thumbnail = canvas.toDataURL("image/png"); + return _this.emit("thumbnail", file, thumbnail); + }; + return img.src = fileReader.result; + }; + return fileReader.readAsDataURL(file); + }; + + Dropzone.prototype.processQueue = function() { + var i, parallelUploads, processingLength, queuedFiles; + parallelUploads = this.options.parallelUploads; + processingLength = this.getUploadingFiles().length; + i = processingLength; + if (processingLength >= parallelUploads) { + return; + } + queuedFiles = this.getQueuedFiles(); + if (!(queuedFiles.length > 0)) { + return; + } + if (this.options.uploadMultiple) { + return this.processFiles(queuedFiles.slice(0, parallelUploads - processingLength)); + } else { + while (i < parallelUploads) { + if (!queuedFiles.length) { + return; + } + this.processFile(queuedFiles.shift()); + i++; + } + } + }; + + Dropzone.prototype.processFile = function(file) { + return this.processFiles([file]); + }; + + Dropzone.prototype.processFiles = function(files) { + var file, _i, _len; + for (_i = 0, _len = files.length; _i < _len; _i++) { + file = files[_i]; + file.processing = true; + file.status = Dropzone.UPLOADING; + this.emit("processing", file); + } + if (this.options.uploadMultiple) { + this.emit("processingmultiple", files); + } + return this.uploadFiles(files); + }; + + Dropzone.prototype._getFilesWithXhr = function(xhr) { + var file, files; + return files = (function() { + var _i, _len, _ref, _results; + _ref = this.files; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + file = _ref[_i]; + if (file.xhr === xhr) { + _results.push(file); + } + } + return _results; + }).call(this); + }; + + Dropzone.prototype.cancelUpload = function(file) { + var groupedFile, groupedFiles, _i, _j, _len, _len1, _ref; + if (file.status === Dropzone.UPLOADING) { + groupedFiles = this._getFilesWithXhr(file.xhr); + for (_i = 0, _len = groupedFiles.length; _i < _len; _i++) { + groupedFile = groupedFiles[_i]; + groupedFile.status = Dropzone.CANCELED; + } + file.xhr.abort(); + for (_j = 0, _len1 = groupedFiles.length; _j < _len1; _j++) { + groupedFile = groupedFiles[_j]; + this.emit("canceled", groupedFile); + } + if (this.options.uploadMultiple) { + this.emit("canceledmultiple", groupedFiles); + } + } else if ((_ref = file.status) === Dropzone.ADDED || _ref === Dropzone.QUEUED) { + file.status = Dropzone.CANCELED; + this.emit("canceled", file); + if (this.options.uploadMultiple) { + this.emit("canceledmultiple", [file]); + } + } + if (this.options.autoProcessQueue) { + return this.processQueue(); + } + }; + + Dropzone.prototype.uploadFile = function(file) { + return this.uploadFiles([file]); + }; + + Dropzone.prototype.uploadFiles = function(files) { + var file, formData, handleError, headerName, headerValue, headers, input, inputName, inputType, key, progressObj, response, updateProgress, value, xhr, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1, _ref2, _ref3, + _this = this; + xhr = new XMLHttpRequest(); + for (_i = 0, _len = files.length; _i < _len; _i++) { + file = files[_i]; + file.xhr = xhr; + } + xhr.open(this.options.method, this.options.url, true); + xhr.withCredentials = !!this.options.withCredentials; + response = null; + handleError = function() { + var _j, _len1, _results; + _results = []; + for (_j = 0, _len1 = files.length; _j < _len1; _j++) { + file = files[_j]; + _results.push(_this._errorProcessing(files, response || _this.options.dictResponseError.replace("{{statusCode}}", xhr.status), xhr)); + } + return _results; + }; + updateProgress = function(e) { + var allFilesFinished, progress, _j, _k, _l, _len1, _len2, _len3, _results; + if (e != null) { + progress = 100 * e.loaded / e.total; + for (_j = 0, _len1 = files.length; _j < _len1; _j++) { + file = files[_j]; + file.upload = { + progress: progress, + total: e.total, + bytesSent: e.loaded + }; + } + } else { + allFilesFinished = true; + progress = 100; + for (_k = 0, _len2 = files.length; _k < _len2; _k++) { + file = files[_k]; + if (!(file.upload.progress === 100 && file.upload.bytesSent === file.upload.total)) { + allFilesFinished = false; + } + file.upload.progress = progress; + file.upload.bytesSent = file.upload.total; + } + if (allFilesFinished) { + return; + } + } + _results = []; + for (_l = 0, _len3 = files.length; _l < _len3; _l++) { + file = files[_l]; + _results.push(_this.emit("uploadprogress", file, progress, file.upload.bytesSent)); + } + return _results; + }; + xhr.onload = function(e) { + var _ref; + if (files[0].status === Dropzone.CANCELED) { + return; + } + if (xhr.readyState !== 4) { + return; + } + response = xhr.responseText; + if (xhr.getResponseHeader("content-type") && ~xhr.getResponseHeader("content-type").indexOf("application/json")) { + try { + response = JSON.parse(response); + } catch (_error) { + e = _error; + response = "Invalid JSON response from server."; + } + } + updateProgress(); + if (!((200 <= (_ref = xhr.status) && _ref < 300))) { + return handleError(); + } else { + return _this._finished(files, response, e); + } + }; + xhr.onerror = function() { + if (files[0].status === Dropzone.CANCELED) { + return; + } + return handleError(); + }; + progressObj = (_ref = xhr.upload) != null ? _ref : xhr; + progressObj.onprogress = updateProgress; + headers = { + "Accept": "application/json", + "Cache-Control": "no-cache", + "X-Requested-With": "XMLHttpRequest" + }; + if (this.options.headers) { + extend(headers, this.options.headers); + } + for (headerName in headers) { + headerValue = headers[headerName]; + xhr.setRequestHeader(headerName, headerValue); + } + formData = new FormData(); + if (this.options.params) { + _ref1 = this.options.params; + for (key in _ref1) { + value = _ref1[key]; + formData.append(key, value); + } + } + for (_j = 0, _len1 = files.length; _j < _len1; _j++) { + file = files[_j]; + this.emit("sending", file, xhr, formData); + } + if (this.options.uploadMultiple) { + this.emit("sendingmultiple", files, xhr, formData); + } + if (this.element.tagName === "FORM") { + _ref2 = this.element.querySelectorAll("input, textarea, select, button"); + for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { + input = _ref2[_k]; + inputName = input.getAttribute("name"); + inputType = input.getAttribute("type"); + if (!inputType || ((_ref3 = inputType.toLowerCase()) !== "checkbox" && _ref3 !== "radio") || input.checked) { + formData.append(inputName, input.value); + } + } + } + for (_l = 0, _len3 = files.length; _l < _len3; _l++) { + file = files[_l]; + formData.append("" + this.options.paramName + (this.options.uploadMultiple ? "[]" : ""), file, file.name); + } + return xhr.send(formData); + }; + + Dropzone.prototype._finished = function(files, responseText, e) { + var file, _i, _len; + for (_i = 0, _len = files.length; _i < _len; _i++) { + file = files[_i]; + file.status = Dropzone.SUCCESS; + this.emit("success", file, responseText, e); + this.emit("complete", file); + } + if (this.options.uploadMultiple) { + this.emit("successmultiple", files, responseText, e); + this.emit("completemultiple", files); + } + if (this.options.autoProcessQueue) { + return this.processQueue(); + } + }; + + Dropzone.prototype._errorProcessing = function(files, message, xhr) { + var file, _i, _len; + for (_i = 0, _len = files.length; _i < _len; _i++) { + file = files[_i]; + file.status = Dropzone.ERROR; + this.emit("error", file, message, xhr); + this.emit("complete", file); + } + if (this.options.uploadMultiple) { + this.emit("errormultiple", files, message, xhr); + this.emit("completemultiple", files); + } + if (this.options.autoProcessQueue) { + return this.processQueue(); + } + }; + + return Dropzone; + + })(Em); + + Dropzone.version = "3.7.1"; + + Dropzone.options = {}; + + Dropzone.optionsForElement = function(element) { + if (element.id) { + return Dropzone.options[camelize(element.id)]; + } else { + return void 0; + } + }; + + Dropzone.instances = []; + + Dropzone.forElement = function(element) { + if (typeof element === "string") { + element = document.querySelector(element); + } + if ((element != null ? element.dropzone : void 0) == null) { + throw new Error("No Dropzone found for given element. This is probably because you're trying to access it before Dropzone had the time to initialize. Use the `init` option to setup any additional observers on your Dropzone."); + } + return element.dropzone; + }; + + Dropzone.autoDiscover = true; + + Dropzone.discover = function() { + var checkElements, dropzone, dropzones, _i, _len, _results; + if (document.querySelectorAll) { + dropzones = document.querySelectorAll(".dropzone"); + } else { + dropzones = []; + checkElements = function(elements) { + var el, _i, _len, _results; + _results = []; + for (_i = 0, _len = elements.length; _i < _len; _i++) { + el = elements[_i]; + if (/(^| )dropzone($| )/.test(el.className)) { + _results.push(dropzones.push(el)); + } else { + _results.push(void 0); + } + } + return _results; + }; + checkElements(document.getElementsByTagName("div")); + checkElements(document.getElementsByTagName("form")); + } + _results = []; + for (_i = 0, _len = dropzones.length; _i < _len; _i++) { + dropzone = dropzones[_i]; + if (Dropzone.optionsForElement(dropzone) !== false) { + _results.push(new Dropzone(dropzone)); + } else { + _results.push(void 0); + } + } + return _results; + }; + + Dropzone.blacklistedBrowsers = [/opera.*Macintosh.*version\/12/i]; + + Dropzone.isBrowserSupported = function() { + var capableBrowser, regex, _i, _len, _ref; + capableBrowser = true; + if (window.File && window.FileReader && window.FileList && window.Blob && window.FormData && document.querySelector) { + if (!("classList" in document.createElement("a"))) { + capableBrowser = false; + } else { + _ref = Dropzone.blacklistedBrowsers; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + regex = _ref[_i]; + if (regex.test(navigator.userAgent)) { + capableBrowser = false; + continue; + } + } + } + } else { + capableBrowser = false; + } + return capableBrowser; + }; + + without = function(list, rejectedItem) { + var item, _i, _len, _results; + _results = []; + for (_i = 0, _len = list.length; _i < _len; _i++) { + item = list[_i]; + if (item !== rejectedItem) { + _results.push(item); + } + } + return _results; + }; + + camelize = function(str) { + return str.replace(/[\-_](\w)/g, function(match) { + return match[1].toUpperCase(); + }); + }; + + Dropzone.createElement = function(string) { + var div; + div = document.createElement("div"); + div.innerHTML = string; + return div.childNodes[0]; + }; + + Dropzone.elementInside = function(element, container) { + if (element === container) { + return true; + } + while (element = element.parentNode) { + if (element === container) { + return true; + } + } + return false; + }; + + Dropzone.getElement = function(el, name) { + var element; + if (typeof el === "string") { + element = document.querySelector(el); + } else if (el.nodeType != null) { + element = el; + } + if (element == null) { + throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector or a plain HTML element."); + } + return element; + }; + + Dropzone.getElements = function(els, name) { + var e, el, elements, _i, _j, _len, _len1, _ref; + if (els instanceof Array) { + elements = []; + try { + for (_i = 0, _len = els.length; _i < _len; _i++) { + el = els[_i]; + elements.push(this.getElement(el, name)); + } + } catch (_error) { + e = _error; + elements = null; + } + } else if (typeof els === "string") { + elements = []; + _ref = document.querySelectorAll(els); + for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) { + el = _ref[_j]; + elements.push(el); + } + } else if (els.nodeType != null) { + elements = [els]; + } + if (!((elements != null) && elements.length)) { + throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector, a plain HTML element or a list of those."); + } + return elements; + }; + + Dropzone.confirm = function(question, accepted, rejected) { + if (window.confirm(question)) { + return accepted(); + } else if (rejected != null) { + return rejected(); + } + }; + + Dropzone.isValidFile = function(file, acceptedFiles) { + var baseMimeType, mimeType, validType, _i, _len; + if (!acceptedFiles) { + return true; + } + acceptedFiles = acceptedFiles.split(","); + mimeType = file.type; + baseMimeType = mimeType.replace(/\/.*$/, ""); + for (_i = 0, _len = acceptedFiles.length; _i < _len; _i++) { + validType = acceptedFiles[_i]; + validType = validType.trim(); + if (validType.charAt(0) === ".") { + if (file.name.indexOf(validType, file.name.length - validType.length) !== -1) { + return true; + } + } else if (/\/\*$/.test(validType)) { + if (baseMimeType === validType.replace(/\/.*$/, "")) { + return true; + } + } else { + if (mimeType === validType) { + return true; + } + } + } + return false; + }; + + if (typeof jQuery !== "undefined" && jQuery !== null) { + jQuery.fn.dropzone = function(options) { + return this.each(function() { + return new Dropzone(this, options); + }); + }; + } + + if (typeof module !== "undefined" && module !== null) { + module.exports = Dropzone; + } else { + window.Dropzone = Dropzone; + } + + Dropzone.ADDED = "added"; + + Dropzone.QUEUED = "queued"; + + Dropzone.ACCEPTED = Dropzone.QUEUED; + + Dropzone.UPLOADING = "uploading"; + + Dropzone.PROCESSING = Dropzone.UPLOADING; + + Dropzone.CANCELED = "canceled"; + + Dropzone.ERROR = "error"; + + Dropzone.SUCCESS = "success"; + + /* + # contentloaded.js + # + # Author: Diego Perini (diego.perini at gmail.com) + # Summary: cross-browser wrapper for DOMContentLoaded + # Updated: 20101020 + # License: MIT + # Version: 1.2 + # + # URL: + # http://javascript.nwbox.com/ContentLoaded/ + # http://javascript.nwbox.com/ContentLoaded/MIT-LICENSE + */ + + + contentLoaded = function(win, fn) { + var add, doc, done, init, poll, pre, rem, root, top; + done = false; + top = true; + doc = win.document; + root = doc.documentElement; + add = (doc.addEventListener ? "addEventListener" : "attachEvent"); + rem = (doc.addEventListener ? "removeEventListener" : "detachEvent"); + pre = (doc.addEventListener ? "" : "on"); + init = function(e) { + if (e.type === "readystatechange" && doc.readyState !== "complete") { + return; + } + (e.type === "load" ? win : doc)[rem](pre + e.type, init, false); + if (!done && (done = true)) { + return fn.call(win, e.type || e); + } + }; + poll = function() { + var e; + try { + root.doScroll("left"); + } catch (_error) { + e = _error; + setTimeout(poll, 50); + return; + } + return init("poll"); + }; + if (doc.readyState !== "complete") { + if (doc.createEventObject && root.doScroll) { + try { + top = !win.frameElement; + } catch (_error) {} + if (top) { + poll(); + } + } + doc[add](pre + "DOMContentLoaded", init, false); + doc[add](pre + "readystatechange", init, false); + return win[add](pre + "load", init, false); + } + }; + + Dropzone._autoDiscoverFunction = function() { + if (Dropzone.autoDiscover) { + return Dropzone.discover(); + } + }; + + contentLoaded(window, Dropzone._autoDiscoverFunction); + + }).call(this); + + }); + require.alias("component-emitter/index.js", "dropzone/deps/emitter/index.js"); + require.alias("component-emitter/index.js", "emitter/index.js"); + if (typeof exports == "object") { + module.exports = require("dropzone"); + } else if (typeof define == "function" && define.amd) { + define(function(){ return require("dropzone"); }); + } else { + this["Dropzone"] = require("dropzone"); + }})(); \ No newline at end of file diff --git a/templates/admin/default/assets/js/image-upload.js b/templates/admin/default/assets/js/image-upload.js new file mode 100644 index 000000000..c1414c73b --- /dev/null +++ b/templates/admin/default/assets/js/image-upload.js @@ -0,0 +1,102 @@ +$(function($){ + // Manage picture upload + $.imageUploadManager = {}; + + Dropzone.autoDiscover = false; + + + + // Remove image on click + $.imageUploadManager.initImageDropZone = function() { + $.imageUploadManager.onClickDeleteImage(); + + var imageDropzone = new Dropzone("#images-dropzone", { + dictDefaultMessage : $('.btn-browse').html(), + uploadMultiple: false, + maxFilesize: 8, + acceptedFiles: 'image/png, image/gif, image/jpeg' + }); + + var totalFiles = 0, + completedFiles = 0; + + imageDropzone.on("addedfile", function(file){ + totalFiles += 1; + + if(totalFiles == 1){ + $('.dz-message').hide(); + } + }); + + imageDropzone.on("complete", function(file){ + completedFiles += 1; + + if (completedFiles === totalFiles){ + $('.dz-message').slideDown(); + } + }); + + imageDropzone.on("success", function(file) { + imageDropzone.removeFile(file); + $.imageUploadManager.updateImageListAjax(); + $.imageUploadManager.onClickDeleteImage(); + }); + + + + }; + + // Update picture list via AJAX call + $.imageUploadManager.updateImageListAjax = function() { + var $imageListArea = $(".image-manager .existing-image"); + $imageListArea.html('
    '); + $.ajax({ + type: "POST", + url: imageListUrl, + statusCode: { + 404: function() { + $imageListArea.html( + imageListErrorMessage + ); + } + } + }).done(function(data) { + $imageListArea.html( + data + ); + $.imageUploadManager.onClickDeleteImage(); + }); + }; + + // Remove image on click + $.imageUploadManager.onClickDeleteImage = function() { + $('.image-manager .image-delete-btn').on('click', function (e) { + e.preventDefault(); + var $this = $(this); + var $parent = $this.parent(); + var $greatParent = $parent.parent(); + + $greatParent.append('
    '); + $greatParent.find('.btn-group').remove(); + var $url = $this.attr("href"); + var errorMessage = $this.attr("data-error-message"); + $.ajax({ + type: "POST", + url: $url, + statusCode: { + 404: function() { + $(".image-manager .message").html( + errorMessage + ); + } + } + }).done(function(data) { + $greatParent.remove(); + $(".image-manager .message").html( + data + ); + }); + return false; + }); + }; +}); diff --git a/templates/admin/default/assets/js/jqplot/jquery.jqplot.min.js b/templates/admin/default/assets/js/jqplot/jquery.jqplot.min.js new file mode 100644 index 000000000..f25712c36 --- /dev/null +++ b/templates/admin/default/assets/js/jqplot/jquery.jqplot.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(L){var u;L.fn.emptyForce=function(){for(var ah=0,ai;(ai=L(this)[ah])!=null;ah++){if(ai.nodeType===1){L.cleanData(ai.getElementsByTagName("*"))}if(L.jqplot.use_excanvas){ai.outerHTML=""}else{while(ai.firstChild){ai.removeChild(ai.firstChild)}}ai=null}return L(this)};L.fn.removeChildForce=function(ah){while(ah.firstChild){this.removeChildForce(ah.firstChild);ah.removeChild(ah.firstChild)}};L.fn.jqplot=function(){var ah=[];var aj=[];for(var ak=0,ai=arguments.length;ak'+ao+"
    ");L("#"+an).addClass("jqplot-error");document.getElementById(an).style.background=L.jqplot.config.errorBackground;document.getElementById(an).style.border=L.jqplot.config.errorBorder;document.getElementById(an).style.fontFamily=L.jqplot.config.errorFontFamily;document.getElementById(an).style.fontSize=L.jqplot.config.errorFontSize;document.getElementById(an).style.fontStyle=L.jqplot.config.errorFontStyle;document.getElementById(an).style.fontWeight=L.jqplot.config.errorFontWeight}}else{am.init(an,aj,ah);am.draw();am.themeEngine.init.call(am);return am}};L.jqplot.version="1.0.8";L.jqplot.revision="1250";L.jqplot.targetCounter=1;L.jqplot.CanvasManager=function(){if(typeof L.jqplot.CanvasManager.canvases=="undefined"){L.jqplot.CanvasManager.canvases=[];L.jqplot.CanvasManager.free=[]}var ah=[];this.getCanvas=function(){var ak;var aj=true;if(!L.jqplot.use_excanvas){for(var al=0,ai=L.jqplot.CanvasManager.canvases.length;al887){L.jqplot.support_canvas_text.result=true}else{L.jqplot.support_canvas_text.result=!!(document.createElement("canvas").getContext&&typeof document.createElement("canvas").getContext("2d").fillText=="function")}}return L.jqplot.support_canvas_text.result};L.jqplot.use_excanvas=((!L.support.boxModel||!L.support.objectAll||!$support.leadingWhitespace)&&!L.jqplot.support_canvas())?true:false;L.jqplot.preInitHooks=[];L.jqplot.postInitHooks=[];L.jqplot.preParseOptionsHooks=[];L.jqplot.postParseOptionsHooks=[];L.jqplot.preDrawHooks=[];L.jqplot.postDrawHooks=[];L.jqplot.preDrawSeriesHooks=[];L.jqplot.postDrawSeriesHooks=[];L.jqplot.preDrawLegendHooks=[];L.jqplot.addLegendRowHooks=[];L.jqplot.preSeriesInitHooks=[];L.jqplot.postSeriesInitHooks=[];L.jqplot.preParseSeriesOptionsHooks=[];L.jqplot.postParseSeriesOptionsHooks=[];L.jqplot.eventListenerHooks=[];L.jqplot.preDrawSeriesShadowHooks=[];L.jqplot.postDrawSeriesShadowHooks=[];L.jqplot.ElemContainer=function(){this._elem;this._plotWidth;this._plotHeight;this._plotDimensions={height:null,width:null}};L.jqplot.ElemContainer.prototype.createElement=function(ak,am,ai,aj,an){this._offsets=am;var ah=ai||"jqplot";var al=document.createElement(ak);this._elem=L(al);this._elem.addClass(ah);this._elem.css(aj);this._elem.attr(an);al=null;return this._elem};L.jqplot.ElemContainer.prototype.getWidth=function(){if(this._elem){return this._elem.outerWidth(true)}else{return null}};L.jqplot.ElemContainer.prototype.getHeight=function(){if(this._elem){return this._elem.outerHeight(true)}else{return null}};L.jqplot.ElemContainer.prototype.getPosition=function(){if(this._elem){return this._elem.position()}else{return{top:null,left:null,bottom:null,right:null}}};L.jqplot.ElemContainer.prototype.getTop=function(){return this.getPosition().top};L.jqplot.ElemContainer.prototype.getLeft=function(){return this.getPosition().left};L.jqplot.ElemContainer.prototype.getBottom=function(){return this._elem.css("bottom")};L.jqplot.ElemContainer.prototype.getRight=function(){return this._elem.css("right")};function w(ah){L.jqplot.ElemContainer.call(this);this.name=ah;this._series=[];this.show=false;this.tickRenderer=L.jqplot.AxisTickRenderer;this.tickOptions={};this.labelRenderer=L.jqplot.AxisLabelRenderer;this.labelOptions={};this.label=null;this.showLabel=true;this.min=null;this.max=null;this.autoscale=false;this.pad=1.2;this.padMax=null;this.padMin=null;this.ticks=[];this.numberTicks;this.tickInterval;this.renderer=L.jqplot.LinearAxisRenderer;this.rendererOptions={};this.showTicks=true;this.showTickMarks=true;this.showMinorTicks=true;this.drawMajorGridlines=true;this.drawMinorGridlines=false;this.drawMajorTickMarks=true;this.drawMinorTickMarks=true;this.useSeriesColor=false;this.borderWidth=null;this.borderColor=null;this.scaleToHiddenSeries=false;this._dataBounds={min:null,max:null};this._intervalStats=[];this._offsets={min:null,max:null};this._ticks=[];this._label=null;this.syncTicks=null;this.tickSpacing=75;this._min=null;this._max=null;this._tickInterval=null;this._numberTicks=null;this.__ticks=null;this._options={}}w.prototype=new L.jqplot.ElemContainer();w.prototype.constructor=w;w.prototype.init=function(){if(L.isFunction(this.renderer)){this.renderer=new this.renderer()}this.tickOptions.axis=this.name;if(this.tickOptions.showMark==null){this.tickOptions.showMark=this.showTicks}if(this.tickOptions.showMark==null){this.tickOptions.showMark=this.showTickMarks}if(this.tickOptions.showLabel==null){this.tickOptions.showLabel=this.showTicks}if(this.label==null||this.label==""){this.showLabel=false}else{this.labelOptions.label=this.label}if(this.showLabel==false){this.labelOptions.show=false}if(this.pad==0){this.pad=1}if(this.padMax==0){this.padMax=1}if(this.padMin==0){this.padMin=1}if(this.padMax==null){this.padMax=(this.pad-1)/2+1}if(this.padMin==null){this.padMin=(this.pad-1)/2+1}this.pad=this.padMax+this.padMin-1;if(this.min!=null||this.max!=null){this.autoscale=false}if(this.syncTicks==null&&this.name.indexOf("y")>-1){this.syncTicks=true}else{if(this.syncTicks==null){this.syncTicks=false}}this.renderer.init.call(this,this.rendererOptions)};w.prototype.draw=function(ah,ai){if(this.__ticks){this.__ticks=null}return this.renderer.draw.call(this,ah,ai)};w.prototype.set=function(){this.renderer.set.call(this)};w.prototype.pack=function(ai,ah){if(this.show){this.renderer.pack.call(this,ai,ah)}if(this._min==null){this._min=this.min;this._max=this.max;this._tickInterval=this.tickInterval;this._numberTicks=this.numberTicks;this.__ticks=this._ticks}};w.prototype.reset=function(){this.renderer.reset.call(this)};w.prototype.resetScale=function(ah){L.extend(true,this,{min:null,max:null,numberTicks:null,tickInterval:null,_ticks:[],ticks:[]},ah);this.resetDataBounds()};w.prototype.resetDataBounds=function(){var ao=this._dataBounds;ao.min=null;ao.max=null;var ai,ap,am;var aj=(this.show)?true:false;for(var al=0;alao.max)||ao.max==null){ao.max=am[ak][0]}}else{if((am[ak][ah]!=null&&am[ak][ah]ao.max)||ao.max==null){ao.max=am[ak][an]}}}if(aj&&ap.renderer.constructor!==L.jqplot.BarRenderer){aj=false}else{if(aj&&this._options.hasOwnProperty("forceTickAt0")&&this._options.forceTickAt0==false){aj=false}else{if(aj&&ap.renderer.constructor===L.jqplot.BarRenderer){if(ap.barDirection=="vertical"&&this.name!="xaxis"&&this.name!="x2axis"){if(this._options.pad!=null||this._options.padMin!=null){aj=false}}else{if(ap.barDirection=="horizontal"&&(this.name=="xaxis"||this.name=="x2axis")){if(this._options.pad!=null||this._options.padMin!=null){aj=false}}}}}}}}if(aj&&this.renderer.constructor===L.jqplot.LinearAxisRenderer&&ao.min>=0){this.padMin=1;this.forceTickAt0=true}};function q(ah){L.jqplot.ElemContainer.call(this);this.show=false;this.location="ne";this.labels=[];this.showLabels=true;this.showSwatches=true;this.placement="insideGrid";this.xoffset=0;this.yoffset=0;this.border;this.background;this.textColor;this.fontFamily;this.fontSize;this.rowSpacing="0.5em";this.renderer=L.jqplot.TableLegendRenderer;this.rendererOptions={};this.preDraw=false;this.marginTop=null;this.marginRight=null;this.marginBottom=null;this.marginLeft=null;this.escapeHtml=false;this._series=[];L.extend(true,this,ah)}q.prototype=new L.jqplot.ElemContainer();q.prototype.constructor=q;q.prototype.setOptions=function(ah){L.extend(true,this,ah);if(this.placement=="inside"){this.placement="insideGrid"}if(this.xoffset>0){if(this.placement=="insideGrid"){switch(this.location){case"nw":case"w":case"sw":if(this.marginLeft==null){this.marginLeft=this.xoffset+"px"}this.marginRight="0px";break;case"ne":case"e":case"se":default:if(this.marginRight==null){this.marginRight=this.xoffset+"px"}this.marginLeft="0px";break}}else{if(this.placement=="outside"){switch(this.location){case"nw":case"w":case"sw":if(this.marginRight==null){this.marginRight=this.xoffset+"px"}this.marginLeft="0px";break;case"ne":case"e":case"se":default:if(this.marginLeft==null){this.marginLeft=this.xoffset+"px"}this.marginRight="0px";break}}}this.xoffset=0}if(this.yoffset>0){if(this.placement=="outside"){switch(this.location){case"sw":case"s":case"se":if(this.marginTop==null){this.marginTop=this.yoffset+"px"}this.marginBottom="0px";break;case"ne":case"n":case"nw":default:if(this.marginBottom==null){this.marginBottom=this.yoffset+"px"}this.marginTop="0px";break}}else{if(this.placement=="insideGrid"){switch(this.location){case"sw":case"s":case"se":if(this.marginBottom==null){this.marginBottom=this.yoffset+"px"}this.marginTop="0px";break;case"ne":case"n":case"nw":default:if(this.marginTop==null){this.marginTop=this.yoffset+"px"}this.marginBottom="0px";break}}}this.yoffset=0}};q.prototype.init=function(){if(L.isFunction(this.renderer)){this.renderer=new this.renderer()}this.renderer.init.call(this,this.rendererOptions)};q.prototype.draw=function(ai,aj){for(var ah=0;ah
    ');this.target.append(az);az.height(aD);az.width(aA);az.css("top",this.eventCanvas._offsets.top);az.css("left",this.eventCanvas._offsets.left);var aC=L('
    ');az.append(aC);aC.html(this.noDataIndicator.indicator);var aB=aC.height();var ax=aC.width();aC.height(aB);aC.width(ax);aC.css("top",(aD-aB)/2+"px")})}}this.data=L.extend(true,[],ar);this.parseOptions(ay);if(this.textColor){this.target.css("color",this.textColor)}if(this.fontFamily){this.target.css("font-family",this.fontFamily)}if(this.fontSize){this.target.css("font-size",this.fontSize)}this.title.init();this.legend.init();this._sumy=0;this._sumx=0;this.computePlotData();for(var at=0;at0){for(var aq=au;aq--;){var an=this._plotData[aq][ap][av];if(aw*an>=0){this._plotData[au][ap][av]+=an;this._stackData[au][ap][av]+=an;break}}}}}else{for(var ar=0;ar0){at._prevPlotData=this.series[au-1]._plotData}at._sumy=0;at._sumx=0;for(ar=at.data.length-1;ar>-1;ar--){at._sumy+=at.data[ar][1];at._sumx+=at.data[ar][0]}}};this.populatePlotData=function(au,av){this._plotData=[];this._stackData=[];au._stackData=[];au._plotData=[];var ay={x:[],y:[]};if(this.stackSeries&&!au.disableStack){au._stack=true;var ax=(au._stackAxis==="x")?0:1;var az=L.extend(true,[],au.data);var aA=L.extend(true,[],au.data);var an,am,ao,aw,al;for(var ar=0;ar=0){aA[aq][ax]+=aw}}}for(var at=0;at0){au._prevPlotData=this.series[av-1]._plotData}au._sumy=0;au._sumx=0;for(at=au.data.length-1;at>-1;at--){au._sumy+=au.data[at][1];au._sumx+=au.data[at][0]}};this.getNextSeriesColor=(function(am){var al=0;var an=am.seriesColors;return function(){if(al=0&&an>=0){al.top+=aK;al.bottom+=aK;al.left+=an;al.right+=an}}var am=["top","bottom","left","right"];for(var aB in am){if(this._gridPadding[am[aB]]==null&&al[am[aB]]>0){this._gridPadding[am[aB]]=al[am[aB]]}else{if(this._gridPadding[am[aB]]==null){this._gridPadding[am[aB]]=this._defaultGridPadding[am[aB]]}}}var aA=this._gridPadding;if(this.legend.placement==="outsideGrid"){aA={top:this.title.getHeight(),left:0,right:0,bottom:0};if(this.legend.location==="s"){aA.left=this._gridPadding.left;aA.right=this._gridPadding.right}}ar.xaxis.pack({position:"absolute",bottom:this._gridPadding.bottom-ar.xaxis.getHeight(),left:0,width:this._width},{min:this._gridPadding.left,max:this._width-this._gridPadding.right});ar.yaxis.pack({position:"absolute",top:0,left:this._gridPadding.left-ar.yaxis.getWidth(),height:this._height},{min:this._height-this._gridPadding.bottom,max:this._gridPadding.top});ar.x2axis.pack({position:"absolute",top:this._gridPadding.top-ar.x2axis.getHeight(),left:0,width:this._width},{min:this._gridPadding.left,max:this._width-this._gridPadding.right});for(aH=8;aH>0;aH--){ar[aG[aH-1]].pack({position:"absolute",top:0,right:this._gridPadding.right-az[aH-1]},{min:this._height-this._gridPadding.bottom,max:this._gridPadding.top})}var au=(this._width-this._gridPadding.left-this._gridPadding.right)/2+this._gridPadding.left-ar.yMidAxis.getWidth()/2;ar.yMidAxis.pack({position:"absolute",top:0,left:au,zIndex:9,textAlign:"center"},{min:this._height-this._gridPadding.bottom,max:this._gridPadding.top});this.target.append(this.grid.createElement(this._gridPadding,this));this.grid.draw();var aq=this.series;var aJ=aq.length;for(aH=0,aE=aJ;aHax)?av:ax;var ar=this.series[aw];var aq=this.series[au];if(aq.renderer.smooth){var ap=aq.renderer._smoothedData.slice(0).reverse()}else{var ap=aq.gridData.slice(0).reverse()}if(ar.renderer.smooth){var at=ar.renderer._smoothedData.concat(ap)}else{var at=ar.gridData.concat(ap)}var ao=(an.color!==null)?an.color:this.series[ax].fillColor;var ay=(an.baseSeries!==null)?an.baseSeries:aw;var am=this.series[ay].renderer.shapeRenderer;var al={fillStyle:ao,fill:true,closePath:true};am.draw(ar.shadowCanvas._ctx,at,al)};this.bindCustomEvents=function(){this.eventCanvas._elem.bind("click",{plot:this},this.onClick);this.eventCanvas._elem.bind("dblclick",{plot:this},this.onDblClick);this.eventCanvas._elem.bind("mousedown",{plot:this},this.onMouseDown);this.eventCanvas._elem.bind("mousemove",{plot:this},this.onMouseMove);this.eventCanvas._elem.bind("mouseenter",{plot:this},this.onMouseEnter);this.eventCanvas._elem.bind("mouseleave",{plot:this},this.onMouseLeave);if(this.captureRightClick){this.eventCanvas._elem.bind("mouseup",{plot:this},this.onRightClick);this.eventCanvas._elem.get(0).oncontextmenu=function(){return false}}else{this.eventCanvas._elem.bind("mouseup",{plot:this},this.onMouseUp)}};function ai(av){var au=av.data.plot;var ap=au.eventCanvas._elem.offset();var at={x:av.pageX-ap.left,y:av.pageY-ap.top};var aq={xaxis:null,yaxis:null,x2axis:null,y2axis:null,y3axis:null,y4axis:null,y5axis:null,y6axis:null,y7axis:null,y8axis:null,y9axis:null,yMidAxis:null};var ar=["xaxis","yaxis","x2axis","y2axis","y3axis","y4axis","y5axis","y6axis","y7axis","y8axis","y9axis","yMidAxis"];var al=au.axes;var am,ao;for(am=11;am>0;am--){ao=ar[am-1];if(al[ao].show){aq[ao]=al[ao].series_p2u(at[ao.charAt(0)])}}return{offsets:ap,gridPos:at,dataPos:aq}}function ak(al,am){var aq=am.series;var aW,aU,aT,aO,aP,aJ,aI,aw,au,az,aA,aK;var aS,aX,aQ,ar,aH,aM,aV;var an,aN;for(aT=am.seriesStack.length-1;aT>=0;aT--){aW=am.seriesStack[aT];aO=aq[aW];aV=aO._highlightThreshold;switch(aO.renderer.constructor){case L.jqplot.BarRenderer:aJ=al.x;aI=al.y;for(aU=0;aUaH[0][0]&&aJaH[2][1]&&aIaH[0][0]+aV[0][0]&&aJaH[2][1]&&aI0&&-aI>=0){aw=2*Math.PI-Math.atan(-aI/aJ)}else{if(aJ>0&&-aI<0){aw=-Math.atan(-aI/aJ)}else{if(aJ<0){aw=Math.PI-Math.atan(-aI/aJ)}else{if(aJ==0&&-aI>0){aw=3*Math.PI/2}else{if(aJ==0&&-aI<0){aw=Math.PI/2}else{if(aJ==0&&aI==0){aw=0}}}}}}if(az){aw-=az;if(aw<0){aw+=2*Math.PI}else{if(aw>2*Math.PI){aw-=2*Math.PI}}}au=aO.sliceMargin/180*Math.PI;if(aPaO._innerRadius){for(aU=0;aU0)?aO.gridData[aU-1][1]+au:au;aK=aO.gridData[aU][1];if(aw>aA&&aw0&&-aI>=0){aw=2*Math.PI-Math.atan(-aI/aJ)}else{if(aJ>0&&-aI<0){aw=-Math.atan(-aI/aJ)}else{if(aJ<0){aw=Math.PI-Math.atan(-aI/aJ)}else{if(aJ==0&&-aI>0){aw=3*Math.PI/2}else{if(aJ==0&&-aI<0){aw=Math.PI/2}else{if(aJ==0&&aI==0){aw=0}}}}}}if(az){aw-=az;if(aw<0){aw+=2*Math.PI}else{if(aw>2*Math.PI){aw-=2*Math.PI}}}au=aO.sliceMargin/180*Math.PI;if(aP0)?aO.gridData[aU-1][1]+au:au;aK=aO.gridData[aU][1];if(aw>aA&&aw=ay[0][1]&&aI<=ay[3][1]&&aJ>=at[0]&&aJ<=aE[0]){return{seriesIndex:aO.index,pointIndex:aU,gridData:null,data:aO.data[aU]}}}break;case L.jqplot.LineRenderer:aJ=al.x;aI=al.y;aP=aO.renderer;if(aO.show){if((aO.fill||(aO.renderer.bands.show&&aO.renderer.bands.fill))&&(!am.plugins.highlighter||!am.plugins.highlighter.show)){var ax=false;if(aJ>aO._boundingBox[0][0]&&aJaO._boundingBox[1][1]&&aI=aI||aB[1]=aI){if(aC[0]+(aI-aC[1])/(aB[1]-aC[1])*(aB[0]-aC[0])0)?aN:0;for(var aU=0;aU=aQ[0]-aP._bodyWidth/2&&aJ<=aQ[0]+aP._bodyWidth/2&&aI>=av(aO.data[aU][2])&&aI<=av(aO.data[aU][3])){return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}else{if(!aP.hlc){var av=aO._yaxis.series_u2p;if(aJ>=aQ[0]-aP._tickLength&&aJ<=aQ[0]+aP._tickLength&&aI>=av(aO.data[aU][2])&&aI<=av(aO.data[aU][3])){return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}else{var av=aO._yaxis.series_u2p;if(aJ>=aQ[0]-aP._tickLength&&aJ<=aQ[0]+aP._tickLength&&aI>=av(aO.data[aU][1])&&aI<=av(aO.data[aU][2])){return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}}}else{if(aQ[0]!=null&&aQ[1]!=null){aX=Math.sqrt((aJ-aQ[0])*(aJ-aQ[0])+(aI-aQ[1])*(aI-aQ[1]));if(aX<=an&&(aX<=aS||aS==null)){aS=aX;return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}}}}}break;default:aJ=al.x;aI=al.y;aP=aO.renderer;if(aO.show){aN=aO.markerRenderer.size/2+aO.neighborThreshold;an=(aN>0)?aN:0;for(var aU=0;aU=aQ[0]-aP._bodyWidth/2&&aJ<=aQ[0]+aP._bodyWidth/2&&aI>=av(aO.data[aU][2])&&aI<=av(aO.data[aU][3])){return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}else{if(!aP.hlc){var av=aO._yaxis.series_u2p;if(aJ>=aQ[0]-aP._tickLength&&aJ<=aQ[0]+aP._tickLength&&aI>=av(aO.data[aU][2])&&aI<=av(aO.data[aU][3])){return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}else{var av=aO._yaxis.series_u2p;if(aJ>=aQ[0]-aP._tickLength&&aJ<=aQ[0]+aP._tickLength&&aI>=av(aO.data[aU][1])&&aI<=av(aO.data[aU][2])){return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}}}else{aX=Math.sqrt((aJ-aQ[0])*(aJ-aQ[0])+(aI-aQ[1])*(aI-aQ[1]));if(aX<=an&&(aX<=aS||aS==null)){aS=aX;return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}}}break}}return null}this.onClick=function(an){var am=ai(an);var ap=an.data.plot;var ao=ak(am.gridPos,ap);var al=L.Event("jqplotClick");al.pageX=an.pageX;al.pageY=an.pageY;L(this).trigger(al,[am.gridPos,am.dataPos,ao,ap])};this.onDblClick=function(an){var am=ai(an);var ap=an.data.plot;var ao=ak(am.gridPos,ap);var al=L.Event("jqplotDblClick");al.pageX=an.pageX;al.pageY=an.pageY;L(this).trigger(al,[am.gridPos,am.dataPos,ao,ap])};this.onMouseDown=function(an){var am=ai(an);var ap=an.data.plot;var ao=ak(am.gridPos,ap);var al=L.Event("jqplotMouseDown");al.pageX=an.pageX;al.pageY=an.pageY;L(this).trigger(al,[am.gridPos,am.dataPos,ao,ap])};this.onMouseUp=function(an){var am=ai(an);var al=L.Event("jqplotMouseUp");al.pageX=an.pageX;al.pageY=an.pageY;L(this).trigger(al,[am.gridPos,am.dataPos,null,an.data.plot])};this.onRightClick=function(an){var am=ai(an);var ap=an.data.plot;var ao=ak(am.gridPos,ap);if(ap.captureRightClick){if(an.which==3){var al=L.Event("jqplotRightClick");al.pageX=an.pageX;al.pageY=an.pageY;L(this).trigger(al,[am.gridPos,am.dataPos,ao,ap])}else{var al=L.Event("jqplotMouseUp");al.pageX=an.pageX;al.pageY=an.pageY;L(this).trigger(al,[am.gridPos,am.dataPos,ao,ap])}}};this.onMouseMove=function(an){var am=ai(an);var ap=an.data.plot;var ao=ak(am.gridPos,ap);var al=L.Event("jqplotMouseMove");al.pageX=an.pageX;al.pageY=an.pageY;L(this).trigger(al,[am.gridPos,am.dataPos,ao,ap])};this.onMouseEnter=function(an){var am=ai(an);var ao=an.data.plot;var al=L.Event("jqplotMouseEnter");al.pageX=an.pageX;al.pageY=an.pageY;al.relatedTarget=an.relatedTarget;L(this).trigger(al,[am.gridPos,am.dataPos,null,ao])};this.onMouseLeave=function(an){var am=ai(an);var ao=an.data.plot;var al=L.Event("jqplotMouseLeave");al.pageX=an.pageX;al.pageY=an.pageY;al.relatedTarget=an.relatedTarget;L(this).trigger(al,[am.gridPos,am.dataPos,null,ao])};this.drawSeries=function(an,al){var ap,ao,am;al=(typeof(an)==="number"&&al==null)?an:al;an=(typeof(an)==="object")?an:{};if(al!=u){ao=this.series[al];am=ao.shadowCanvas._ctx;am.clearRect(0,0,am.canvas.width,am.canvas.height);ao.drawShadow(am,an,this);am=ao.canvas._ctx;am.clearRect(0,0,am.canvas.width,am.canvas.height);ao.draw(am,an,this);if(ao.renderer.constructor==L.jqplot.BezierCurveRenderer){if(al660)?ah[aj]*0.85:0.73*ah[aj]+90;ah[aj]=parseInt(ah[aj],10);(ah[aj]>255)?255:ah[aj]}ah[3]=0.3+0.35*al[3];ak.push("rgba("+ah[0]+","+ah[1]+","+ah[2]+","+ah[3]+")")}}else{var al=L.jqplot.getColorComponents(ai);var ah=[al[0],al[1],al[2]];var an=ah[0]+ah[1]+ah[2];for(var aj=0;aj<3;aj++){ah[aj]=(an>660)?ah[aj]*0.85:0.73*ah[aj]+90;ah[aj]=parseInt(ah[aj],10);(ah[aj]>255)?255:ah[aj]}ah[3]=0.3+0.35*al[3];ak="rgba("+ah[0]+","+ah[1]+","+ah[2]+","+ah[3]+")"}return ak};L.jqplot.ColorGenerator=function(ai){ai=ai||L.jqplot.config.defaultColors;var ah=0;this.next=function(){if(ah0){return ai[ah--]}else{ah=ai.length-1;return ai[ah]}};this.get=function(ak){var aj=ak-ai.length*Math.floor(ak/ai.length);return ai[aj]};this.setColors=function(aj){ai=aj};this.reset=function(){ah=0};this.getIndex=function(){return ah};this.setIndex=function(aj){ah=aj}};L.jqplot.hex2rgb=function(aj,ah){aj=aj.replace("#","");if(aj.length==3){aj=aj.charAt(0)+aj.charAt(0)+aj.charAt(1)+aj.charAt(1)+aj.charAt(2)+aj.charAt(2)}var ai;ai="rgba("+parseInt(aj.slice(0,2),16)+", "+parseInt(aj.slice(2,4),16)+", "+parseInt(aj.slice(4,6),16);if(ah){ai+=", "+ah}ai+=")";return ai};L.jqplot.rgb2hex=function(am){var aj=/rgba?\( *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *(?:, *[0-9.]*)?\)/;var ah=am.match(aj);var al="#";for(var ak=1;ak<4;ak++){var ai;if(ah[ak].search(/%/)!=-1){ai=parseInt(255*ah[ak]/100,10).toString(16);if(ai.length==1){ai="0"+ai}}else{ai=parseInt(ah[ak],10).toString(16);if(ai.length==1){ai="0"+ai}}al+=ai}return al};L.jqplot.normalize2rgb=function(ai,ah){if(ai.search(/^ *rgba?\(/)!=-1){return ai}else{if(ai.search(/^ *#?[0-9a-fA-F]?[0-9a-fA-F]/)!=-1){return L.jqplot.hex2rgb(ai,ah)}else{throw new Error("Invalid color spec")}}};L.jqplot.getColorComponents=function(am){am=L.jqplot.colorKeywordMap[am]||am;var ak=L.jqplot.normalize2rgb(am);var aj=/rgba?\( *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *,? *([0-9.]* *)?\)/;var ah=ak.match(aj);var ai=[];for(var al=1;al<4;al++){if(ah[al].search(/%/)!=-1){ai[al-1]=parseInt(255*ah[al]/100,10)}else{ai[al-1]=parseInt(ah[al],10)}}ai[3]=parseFloat(ah[4])?parseFloat(ah[4]):1;return ai};L.jqplot.colorKeywordMap={aliceblue:"rgb(240, 248, 255)",antiquewhite:"rgb(250, 235, 215)",aqua:"rgb( 0, 255, 255)",aquamarine:"rgb(127, 255, 212)",azure:"rgb(240, 255, 255)",beige:"rgb(245, 245, 220)",bisque:"rgb(255, 228, 196)",black:"rgb( 0, 0, 0)",blanchedalmond:"rgb(255, 235, 205)",blue:"rgb( 0, 0, 255)",blueviolet:"rgb(138, 43, 226)",brown:"rgb(165, 42, 42)",burlywood:"rgb(222, 184, 135)",cadetblue:"rgb( 95, 158, 160)",chartreuse:"rgb(127, 255, 0)",chocolate:"rgb(210, 105, 30)",coral:"rgb(255, 127, 80)",cornflowerblue:"rgb(100, 149, 237)",cornsilk:"rgb(255, 248, 220)",crimson:"rgb(220, 20, 60)",cyan:"rgb( 0, 255, 255)",darkblue:"rgb( 0, 0, 139)",darkcyan:"rgb( 0, 139, 139)",darkgoldenrod:"rgb(184, 134, 11)",darkgray:"rgb(169, 169, 169)",darkgreen:"rgb( 0, 100, 0)",darkgrey:"rgb(169, 169, 169)",darkkhaki:"rgb(189, 183, 107)",darkmagenta:"rgb(139, 0, 139)",darkolivegreen:"rgb( 85, 107, 47)",darkorange:"rgb(255, 140, 0)",darkorchid:"rgb(153, 50, 204)",darkred:"rgb(139, 0, 0)",darksalmon:"rgb(233, 150, 122)",darkseagreen:"rgb(143, 188, 143)",darkslateblue:"rgb( 72, 61, 139)",darkslategray:"rgb( 47, 79, 79)",darkslategrey:"rgb( 47, 79, 79)",darkturquoise:"rgb( 0, 206, 209)",darkviolet:"rgb(148, 0, 211)",deeppink:"rgb(255, 20, 147)",deepskyblue:"rgb( 0, 191, 255)",dimgray:"rgb(105, 105, 105)",dimgrey:"rgb(105, 105, 105)",dodgerblue:"rgb( 30, 144, 255)",firebrick:"rgb(178, 34, 34)",floralwhite:"rgb(255, 250, 240)",forestgreen:"rgb( 34, 139, 34)",fuchsia:"rgb(255, 0, 255)",gainsboro:"rgb(220, 220, 220)",ghostwhite:"rgb(248, 248, 255)",gold:"rgb(255, 215, 0)",goldenrod:"rgb(218, 165, 32)",gray:"rgb(128, 128, 128)",grey:"rgb(128, 128, 128)",green:"rgb( 0, 128, 0)",greenyellow:"rgb(173, 255, 47)",honeydew:"rgb(240, 255, 240)",hotpink:"rgb(255, 105, 180)",indianred:"rgb(205, 92, 92)",indigo:"rgb( 75, 0, 130)",ivory:"rgb(255, 255, 240)",khaki:"rgb(240, 230, 140)",lavender:"rgb(230, 230, 250)",lavenderblush:"rgb(255, 240, 245)",lawngreen:"rgb(124, 252, 0)",lemonchiffon:"rgb(255, 250, 205)",lightblue:"rgb(173, 216, 230)",lightcoral:"rgb(240, 128, 128)",lightcyan:"rgb(224, 255, 255)",lightgoldenrodyellow:"rgb(250, 250, 210)",lightgray:"rgb(211, 211, 211)",lightgreen:"rgb(144, 238, 144)",lightgrey:"rgb(211, 211, 211)",lightpink:"rgb(255, 182, 193)",lightsalmon:"rgb(255, 160, 122)",lightseagreen:"rgb( 32, 178, 170)",lightskyblue:"rgb(135, 206, 250)",lightslategray:"rgb(119, 136, 153)",lightslategrey:"rgb(119, 136, 153)",lightsteelblue:"rgb(176, 196, 222)",lightyellow:"rgb(255, 255, 224)",lime:"rgb( 0, 255, 0)",limegreen:"rgb( 50, 205, 50)",linen:"rgb(250, 240, 230)",magenta:"rgb(255, 0, 255)",maroon:"rgb(128, 0, 0)",mediumaquamarine:"rgb(102, 205, 170)",mediumblue:"rgb( 0, 0, 205)",mediumorchid:"rgb(186, 85, 211)",mediumpurple:"rgb(147, 112, 219)",mediumseagreen:"rgb( 60, 179, 113)",mediumslateblue:"rgb(123, 104, 238)",mediumspringgreen:"rgb( 0, 250, 154)",mediumturquoise:"rgb( 72, 209, 204)",mediumvioletred:"rgb(199, 21, 133)",midnightblue:"rgb( 25, 25, 112)",mintcream:"rgb(245, 255, 250)",mistyrose:"rgb(255, 228, 225)",moccasin:"rgb(255, 228, 181)",navajowhite:"rgb(255, 222, 173)",navy:"rgb( 0, 0, 128)",oldlace:"rgb(253, 245, 230)",olive:"rgb(128, 128, 0)",olivedrab:"rgb(107, 142, 35)",orange:"rgb(255, 165, 0)",orangered:"rgb(255, 69, 0)",orchid:"rgb(218, 112, 214)",palegoldenrod:"rgb(238, 232, 170)",palegreen:"rgb(152, 251, 152)",paleturquoise:"rgb(175, 238, 238)",palevioletred:"rgb(219, 112, 147)",papayawhip:"rgb(255, 239, 213)",peachpuff:"rgb(255, 218, 185)",peru:"rgb(205, 133, 63)",pink:"rgb(255, 192, 203)",plum:"rgb(221, 160, 221)",powderblue:"rgb(176, 224, 230)",purple:"rgb(128, 0, 128)",red:"rgb(255, 0, 0)",rosybrown:"rgb(188, 143, 143)",royalblue:"rgb( 65, 105, 225)",saddlebrown:"rgb(139, 69, 19)",salmon:"rgb(250, 128, 114)",sandybrown:"rgb(244, 164, 96)",seagreen:"rgb( 46, 139, 87)",seashell:"rgb(255, 245, 238)",sienna:"rgb(160, 82, 45)",silver:"rgb(192, 192, 192)",skyblue:"rgb(135, 206, 235)",slateblue:"rgb(106, 90, 205)",slategray:"rgb(112, 128, 144)",slategrey:"rgb(112, 128, 144)",snow:"rgb(255, 250, 250)",springgreen:"rgb( 0, 255, 127)",steelblue:"rgb( 70, 130, 180)",tan:"rgb(210, 180, 140)",teal:"rgb( 0, 128, 128)",thistle:"rgb(216, 191, 216)",tomato:"rgb(255, 99, 71)",turquoise:"rgb( 64, 224, 208)",violet:"rgb(238, 130, 238)",wheat:"rgb(245, 222, 179)",white:"rgb(255, 255, 255)",whitesmoke:"rgb(245, 245, 245)",yellow:"rgb(255, 255, 0)",yellowgreen:"rgb(154, 205, 50)"};L.jqplot.AxisLabelRenderer=function(ah){L.jqplot.ElemContainer.call(this);this.axis;this.show=true;this.label="";this.fontFamily=null;this.fontSize=null;this.textColor=null;this._elem;this.escapeHTML=false;L.extend(true,this,ah)};L.jqplot.AxisLabelRenderer.prototype=new L.jqplot.ElemContainer();L.jqplot.AxisLabelRenderer.prototype.constructor=L.jqplot.AxisLabelRenderer;L.jqplot.AxisLabelRenderer.prototype.init=function(ah){L.extend(true,this,ah)};L.jqplot.AxisLabelRenderer.prototype.draw=function(ah,ai){if(this._elem){this._elem.emptyForce();this._elem=null}this._elem=L('
    ');if(Number(this.label)){this._elem.css("white-space","nowrap")}if(!this.escapeHTML){this._elem.html(this.label)}else{this._elem.text(this.label)}if(this.fontFamily){this._elem.css("font-family",this.fontFamily)}if(this.fontSize){this._elem.css("font-size",this.fontSize)}if(this.textColor){this._elem.css("color",this.textColor)}return this._elem};L.jqplot.AxisLabelRenderer.prototype.pack=function(){};L.jqplot.AxisTickRenderer=function(ah){L.jqplot.ElemContainer.call(this);this.mark="outside";this.axis;this.showMark=true;this.showGridline=true;this.isMinorTick=false;this.size=4;this.markSize=6;this.show=true;this.showLabel=true;this.label=null;this.value=null;this._styles={};this.formatter=L.jqplot.DefaultTickFormatter;this.prefix="";this.suffix="";this.formatString="";this.fontFamily;this.fontSize;this.textColor;this.escapeHTML=false;this._elem;this._breakTick=false;L.extend(true,this,ah)};L.jqplot.AxisTickRenderer.prototype.init=function(ah){L.extend(true,this,ah)};L.jqplot.AxisTickRenderer.prototype=new L.jqplot.ElemContainer();L.jqplot.AxisTickRenderer.prototype.constructor=L.jqplot.AxisTickRenderer;L.jqplot.AxisTickRenderer.prototype.setTick=function(ah,aj,ai){this.value=ah;this.axis=aj;if(ai){this.isMinorTick=true}return this};L.jqplot.AxisTickRenderer.prototype.draw=function(){if(this.label===null){this.label=this.prefix+this.formatter(this.formatString,this.value)+this.suffix}var ai={position:"absolute"};if(Number(this.label)){ai.whitSpace="nowrap"}if(this._elem){this._elem.emptyForce();this._elem=null}this._elem=L(document.createElement("div"));this._elem.addClass("jqplot-"+this.axis+"-tick");if(!this.escapeHTML){this._elem.html(this.label)}else{this._elem.text(this.label)}this._elem.css(ai);for(var ah in this._styles){this._elem.css(ah,this._styles[ah])}if(this.fontFamily){this._elem.css("font-family",this.fontFamily)}if(this.fontSize){this._elem.css("font-size",this.fontSize)}if(this.textColor){this._elem.css("color",this.textColor)}if(this._breakTick){this._elem.addClass("jqplot-breakTick")}return this._elem};L.jqplot.DefaultTickFormatter=function(ah,ai){if(typeof ai=="number"){if(!ah){ah=L.jqplot.config.defaultTickFormatString}return L.jqplot.sprintf(ah,ai)}else{return String(ai)}};L.jqplot.PercentTickFormatter=function(ah,ai){if(typeof ai=="number"){ai=100*ai;if(!ah){ah=L.jqplot.config.defaultTickFormatString}return L.jqplot.sprintf(ah,ai)}else{return String(ai)}};L.jqplot.AxisTickRenderer.prototype.pack=function(){};L.jqplot.CanvasGridRenderer=function(){this.shadowRenderer=new L.jqplot.ShadowRenderer()};L.jqplot.CanvasGridRenderer.prototype.init=function(ai){this._ctx;L.extend(true,this,ai);var ah={lineJoin:"miter",lineCap:"round",fill:false,isarc:false,angle:this.shadowAngle,offset:this.shadowOffset,alpha:this.shadowAlpha,depth:this.shadowDepth,lineWidth:this.shadowWidth,closePath:false,strokeStyle:this.shadowColor};this.renderer.shadowRenderer.init(ah)};L.jqplot.CanvasGridRenderer.prototype.createElement=function(ak){var aj;if(this._elem){if(L.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==u){aj=this._elem.get(0);window.G_vmlCanvasManager.uninitElement(aj);aj=null}this._elem.emptyForce();this._elem=null}aj=ak.canvasManager.getCanvas();var ah=this._plotDimensions.width;var ai=this._plotDimensions.height;aj.width=ah;aj.height=ai;this._elem=L(aj);this._elem.addClass("jqplot-grid-canvas");this._elem.css({position:"absolute",left:0,top:0});aj=ak.canvasManager.initCanvas(aj);this._top=this._offsets.top;this._bottom=ai-this._offsets.bottom;this._left=this._offsets.left;this._right=ah-this._offsets.right;this._width=this._right-this._left;this._height=this._bottom-this._top;aj=null;return this._elem};L.jqplot.CanvasGridRenderer.prototype.draw=function(){this._ctx=this._elem.get(0).getContext("2d");var at=this._ctx;var aw=this._axes;at.save();at.clearRect(0,0,this._plotDimensions.width,this._plotDimensions.height);at.fillStyle=this.backgroundColor||this.background;at.fillRect(this._left,this._top,this._width,this._height);at.save();at.lineJoin="miter";at.lineCap="butt";at.lineWidth=this.gridLineWidth;at.strokeStyle=this.gridLineColor;var aA,az,ap,aq;var am=["xaxis","yaxis","x2axis","y2axis"];for(var ay=4;ay>0;ay--){var aD=am[ay-1];var ah=aw[aD];var aB=ah._ticks;var ar=aB.length;if(ah.show){if(ah.drawBaseline){var aC={};if(ah.baselineWidth!==null){aC.lineWidth=ah.baselineWidth}if(ah.baselineColor!==null){aC.strokeStyle=ah.baselineColor}switch(aD){case"xaxis":ao(this._left,this._bottom,this._right,this._bottom,aC);break;case"yaxis":ao(this._left,this._bottom,this._left,this._top,aC);break;case"x2axis":ao(this._left,this._bottom,this._right,this._bottom,aC);break;case"y2axis":ao(this._right,this._bottom,this._right,this._top,aC);break}}for(var au=ar;au>0;au--){var an=aB[au-1];if(an.show){var ak=Math.round(ah.u2p(an.value))+0.5;switch(aD){case"xaxis":if(an.showGridline&&this.drawGridlines&&((!an.isMinorTick&&ah.drawMajorGridlines)||(an.isMinorTick&&ah.drawMinorGridlines))){ao(ak,this._top,ak,this._bottom)}if(an.showMark&&an.mark&&((!an.isMinorTick&&ah.drawMajorTickMarks)||(an.isMinorTick&&ah.drawMinorTickMarks))){ap=an.markSize;aq=an.mark;var ak=Math.round(ah.u2p(an.value))+0.5;switch(aq){case"outside":aA=this._bottom;az=this._bottom+ap;break;case"inside":aA=this._bottom-ap;az=this._bottom;break;case"cross":aA=this._bottom-ap;az=this._bottom+ap;break;default:aA=this._bottom;az=this._bottom+ap;break}if(this.shadow){this.renderer.shadowRenderer.draw(at,[[ak,aA],[ak,az]],{lineCap:"butt",lineWidth:this.gridLineWidth,offset:this.gridLineWidth*0.75,depth:2,fill:false,closePath:false})}ao(ak,aA,ak,az)}break;case"yaxis":if(an.showGridline&&this.drawGridlines&&((!an.isMinorTick&&ah.drawMajorGridlines)||(an.isMinorTick&&ah.drawMinorGridlines))){ao(this._right,ak,this._left,ak)}if(an.showMark&&an.mark&&((!an.isMinorTick&&ah.drawMajorTickMarks)||(an.isMinorTick&&ah.drawMinorTickMarks))){ap=an.markSize;aq=an.mark;var ak=Math.round(ah.u2p(an.value))+0.5;switch(aq){case"outside":aA=this._left-ap;az=this._left;break;case"inside":aA=this._left;az=this._left+ap;break;case"cross":aA=this._left-ap;az=this._left+ap;break;default:aA=this._left-ap;az=this._left;break}if(this.shadow){this.renderer.shadowRenderer.draw(at,[[aA,ak],[az,ak]],{lineCap:"butt",lineWidth:this.gridLineWidth*1.5,offset:this.gridLineWidth*0.75,fill:false,closePath:false})}ao(aA,ak,az,ak,{strokeStyle:ah.borderColor})}break;case"x2axis":if(an.showGridline&&this.drawGridlines&&((!an.isMinorTick&&ah.drawMajorGridlines)||(an.isMinorTick&&ah.drawMinorGridlines))){ao(ak,this._bottom,ak,this._top)}if(an.showMark&&an.mark&&((!an.isMinorTick&&ah.drawMajorTickMarks)||(an.isMinorTick&&ah.drawMinorTickMarks))){ap=an.markSize;aq=an.mark;var ak=Math.round(ah.u2p(an.value))+0.5;switch(aq){case"outside":aA=this._top-ap;az=this._top;break;case"inside":aA=this._top;az=this._top+ap;break;case"cross":aA=this._top-ap;az=this._top+ap;break;default:aA=this._top-ap;az=this._top;break}if(this.shadow){this.renderer.shadowRenderer.draw(at,[[ak,aA],[ak,az]],{lineCap:"butt",lineWidth:this.gridLineWidth,offset:this.gridLineWidth*0.75,depth:2,fill:false,closePath:false})}ao(ak,aA,ak,az)}break;case"y2axis":if(an.showGridline&&this.drawGridlines&&((!an.isMinorTick&&ah.drawMajorGridlines)||(an.isMinorTick&&ah.drawMinorGridlines))){ao(this._left,ak,this._right,ak)}if(an.showMark&&an.mark&&((!an.isMinorTick&&ah.drawMajorTickMarks)||(an.isMinorTick&&ah.drawMinorTickMarks))){ap=an.markSize;aq=an.mark;var ak=Math.round(ah.u2p(an.value))+0.5;switch(aq){case"outside":aA=this._right;az=this._right+ap;break;case"inside":aA=this._right-ap;az=this._right;break;case"cross":aA=this._right-ap;az=this._right+ap;break;default:aA=this._right;az=this._right+ap;break}if(this.shadow){this.renderer.shadowRenderer.draw(at,[[aA,ak],[az,ak]],{lineCap:"butt",lineWidth:this.gridLineWidth*1.5,offset:this.gridLineWidth*0.75,fill:false,closePath:false})}ao(aA,ak,az,ak,{strokeStyle:ah.borderColor})}break;default:break}}}an=null}ah=null;aB=null}am=["y3axis","y4axis","y5axis","y6axis","y7axis","y8axis","y9axis","yMidAxis"];for(var ay=7;ay>0;ay--){var ah=aw[am[ay-1]];var aB=ah._ticks;if(ah.show){var ai=aB[ah.numberTicks-1];var al=aB[0];var aj=ah.getLeft();var av=[[aj,ai.getTop()+ai.getHeight()/2],[aj,al.getTop()+al.getHeight()/2+1]];if(this.shadow){this.renderer.shadowRenderer.draw(at,av,{lineCap:"butt",fill:false,closePath:false})}ao(av[0][0],av[0][1],av[1][0],av[1][1],{lineCap:"butt",strokeStyle:ah.borderColor,lineWidth:ah.borderWidth});for(var au=aB.length;au>0;au--){var an=aB[au-1];ap=an.markSize;aq=an.mark;var ak=Math.round(ah.u2p(an.value))+0.5;if(an.showMark&&an.mark){switch(aq){case"outside":aA=aj;az=aj+ap;break;case"inside":aA=aj-ap;az=aj;break;case"cross":aA=aj-ap;az=aj+ap;break;default:aA=aj;az=aj+ap;break}av=[[aA,ak],[az,ak]];if(this.shadow){this.renderer.shadowRenderer.draw(at,av,{lineCap:"butt",lineWidth:this.gridLineWidth*1.5,offset:this.gridLineWidth*0.75,fill:false,closePath:false})}ao(aA,ak,az,ak,{strokeStyle:ah.borderColor})}an=null}al=null}ah=null;aB=null}at.restore();function ao(aH,aG,aE,ax,aF){at.save();aF=aF||{};if(aF.lineWidth==null||aF.lineWidth!=0){L.extend(true,at,aF);at.beginPath();at.moveTo(aH,aG);at.lineTo(aE,ax);at.stroke();at.restore()}}if(this.shadow){var av=[[this._left,this._bottom],[this._right,this._bottom],[this._right,this._top]];this.renderer.shadowRenderer.draw(at,av)}if(this.borderWidth!=0&&this.drawBorder){ao(this._left,this._top,this._right,this._top,{lineCap:"round",strokeStyle:aw.x2axis.borderColor,lineWidth:aw.x2axis.borderWidth});ao(this._right,this._top,this._right,this._bottom,{lineCap:"round",strokeStyle:aw.y2axis.borderColor,lineWidth:aw.y2axis.borderWidth});ao(this._right,this._bottom,this._left,this._bottom,{lineCap:"round",strokeStyle:aw.xaxis.borderColor,lineWidth:aw.xaxis.borderWidth});ao(this._left,this._bottom,this._left,this._top,{lineCap:"round",strokeStyle:aw.yaxis.borderColor,lineWidth:aw.yaxis.borderWidth})}at.restore();at=null;aw=null};L.jqplot.DivTitleRenderer=function(){};L.jqplot.DivTitleRenderer.prototype.init=function(ah){L.extend(true,this,ah)};L.jqplot.DivTitleRenderer.prototype.draw=function(){if(this._elem){this._elem.emptyForce();this._elem=null}var ak=this.renderer;var aj=document.createElement("div");this._elem=L(aj);this._elem.addClass("jqplot-title");if(!this.text){this.show=false;this._elem.height(0);this._elem.width(0)}else{if(this.text){var ah;if(this.color){ah=this.color}else{if(this.textColor){ah=this.textColor}}var ai={position:"absolute",top:"0px",left:"0px"};if(this._plotWidth){ai.width=this._plotWidth+"px"}if(this.fontSize){ai.fontSize=this.fontSize}if(typeof this.textAlign==="string"){ai.textAlign=this.textAlign}else{ai.textAlign="center"}if(ah){ai.color=ah}if(this.paddingBottom){ai.paddingBottom=this.paddingBottom}if(this.fontFamily){ai.fontFamily=this.fontFamily}this._elem.css(ai);if(this.escapeHtml){this._elem.text(this.text)}else{this._elem.html(this.text)}}}aj=null;return this._elem};L.jqplot.DivTitleRenderer.prototype.pack=function(){};var r=0.1;L.jqplot.LinePattern=function(aw,aq){var ap={dotted:[r,L.jqplot.config.dotGapLength],dashed:[L.jqplot.config.dashLength,L.jqplot.config.gapLength],solid:null};if(typeof aq==="string"){if(aq[0]==="."||aq[0]==="-"){var ax=aq;aq=[];for(var ao=0,al=ax.length;ao0)&&(aC>0)){aA/=aB;az/=aB;while(true){var aD=aC*ar;if(aD=aq.length){ak=0}ar=aq[ak]}else{au=ay;at=aE;if((ak&1)==0){aw.lineTo(au,at)}else{aw.moveTo(au,at)}ar-=aB/aC;break}}}};var ai=function(){aw.beginPath()};var am=function(){aj(an,ah)};return{moveTo:av,lineTo:aj,beginPath:ai,closePath:am}};L.jqplot.LineRenderer=function(){this.shapeRenderer=new L.jqplot.ShapeRenderer();this.shadowRenderer=new L.jqplot.ShadowRenderer()};L.jqplot.LineRenderer.prototype.init=function(ai,an){ai=ai||{};this._type="line";this.renderer.animation={show:false,direction:"left",speed:2500,_supported:true};this.renderer.smooth=false;this.renderer.tension=null;this.renderer.constrainSmoothing=true;this.renderer._smoothedData=[];this.renderer._smoothedPlotData=[];this.renderer._hiBandGridData=[];this.renderer._lowBandGridData=[];this.renderer._hiBandSmoothedData=[];this.renderer._lowBandSmoothedData=[];this.renderer.bandData=[];this.renderer.bands={show:false,hiData:[],lowData:[],color:this.color,showLines:false,fill:true,fillColor:null,_min:null,_max:null,interval:"3%"};var al={highlightMouseOver:ai.highlightMouseOver,highlightMouseDown:ai.highlightMouseDown,highlightColor:ai.highlightColor};delete (ai.highlightMouseOver);delete (ai.highlightMouseDown);delete (ai.highlightColor);L.extend(true,this.renderer,ai);this.renderer.options=ai;if(this.renderer.bandData.length>1&&(!ai.bands||ai.bands.show==null)){this.renderer.bands.show=true}else{if(ai.bands&&ai.bands.show==null&&ai.bands.interval!=null){this.renderer.bands.show=true}}if(this.fill){this.renderer.bands.show=false}if(this.renderer.bands.show){this.renderer.initBands.call(this,this.renderer.options,an)}if(this._stack){this.renderer.smooth=false}var am={lineJoin:this.lineJoin,lineCap:this.lineCap,fill:this.fill,isarc:false,strokeStyle:this.color,fillStyle:this.fillColor,lineWidth:this.lineWidth,linePattern:this.linePattern,closePath:this.fill};this.renderer.shapeRenderer.init(am);var aj=ai.shadowOffset;if(aj==null){if(this.lineWidth>2.5){aj=1.25*(1+(Math.atan((this.lineWidth/2.5))/0.785398163-1)*0.6)}else{aj=1.25*Math.atan((this.lineWidth/2.5))/0.785398163}}var ah={lineJoin:this.lineJoin,lineCap:this.lineCap,fill:this.fill,isarc:false,angle:this.shadowAngle,offset:aj,alpha:this.shadowAlpha,depth:this.shadowDepth,lineWidth:this.lineWidth,linePattern:this.linePattern,closePath:this.fill};this.renderer.shadowRenderer.init(ah);this._areaPoints=[];this._boundingBox=[[],[]];if(!this.isTrendline&&this.fill||this.renderer.bands.show){this.highlightMouseOver=true;this.highlightMouseDown=false;this.highlightColor=null;if(al.highlightMouseDown&&al.highlightMouseOver==null){al.highlightMouseOver=false}L.extend(true,this,{highlightMouseOver:al.highlightMouseOver,highlightMouseDown:al.highlightMouseDown,highlightColor:al.highlightColor});if(!this.highlightColor){var ak=(this.renderer.bands.show)?this.renderer.bands.fillColor:this.fillColor;this.highlightColor=L.jqplot.computeHighlightColors(ak)}if(this.highlighter){this.highlighter.show=false}}if(!this.isTrendline&&an){an.plugins.lineRenderer={};an.postInitHooks.addOnce(z);an.postDrawHooks.addOnce(af);an.eventListenerHooks.addOnce("jqplotMouseMove",h);an.eventListenerHooks.addOnce("jqplotMouseDown",e);an.eventListenerHooks.addOnce("jqplotMouseUp",ad);an.eventListenerHooks.addOnce("jqplotClick",g);an.eventListenerHooks.addOnce("jqplotRightClick",s)}};L.jqplot.LineRenderer.prototype.initBands=function(ak,av){var al=ak.bandData||[];var an=this.renderer.bands;an.hiData=[];an.lowData=[];var aB=this.data;an._max=null;an._min=null;if(al.length==2){if(L.isArray(al[0][0])){var ao;var ah=0,ar=0;for(var aw=0,at=al[0].length;awan._max)||an._max==null){an._max=ao[1]}if((ao[1]!=null&&ao[1]an._max)||an._max==null){an._max=ao[1];ar=1}if((ao[1]!=null&&ao[1]al[1][0])?0:1;var aC=(aj)?0:1;for(var aw=0,at=aB.length;aw2&&!L.isArray(al[0][0])){var aj=(al[0][0]>al[0][1])?0:1;var aC=(aj)?0:1;for(var aw=0,at=al.length;awan._max)||an._max==null){an._max=am[aw][1]}}for(var aw=0,at=ap.length;aw0){aR=Math.abs((ap[aQ][1]-ap[aQ-1][1])/(ap[aQ][0]-ap[aQ-1][0]))}am=aR/aG+aE;aM=aF*A(am)-aF*A(aE)+aS;aT=(aO+aM)/2}else{aT=aU}for(aK=0;aK2){var ao;if(this.renderer.constrainSmoothing){ao=J.call(this,this.gridData);this.renderer._smoothedData=ao[0];this.renderer._smoothedPlotData=ao[1];if(ak.show){ao=J.call(this,this.renderer._hiBandGridData);this.renderer._hiBandSmoothedData=ao[0];ao=J.call(this,this.renderer._lowBandGridData);this.renderer._lowBandSmoothedData=ao[0]}ao=null}else{ao=F.call(this,this.gridData);this.renderer._smoothedData=ao[0];this.renderer._smoothedPlotData=ao[1];if(ak.show){ao=F.call(this,this.renderer._hiBandGridData);this.renderer._hiBandSmoothedData=ao[0];ao=F.call(this,this.renderer._lowBandGridData);this.renderer._lowBandSmoothedData=ao[0]}ao=null}}};L.jqplot.LineRenderer.prototype.makeGridData=function(ao,aq){var am=this._xaxis.series_u2p;var ah=this._yaxis.series_u2p;var ar=[];var aj=[];this.renderer._smoothedData=[];this.renderer._smoothedPlotData=[];this.renderer._hiBandGridData=[];this.renderer._lowBandGridData=[];this.renderer._hiBandSmoothedData=[];this.renderer._lowBandSmoothedData=[];var al=this.renderer.bands;var ai=false;for(var an=0;an2){var ap;if(this.renderer.constrainSmoothing){ap=J.call(this,ar);this.renderer._smoothedData=ap[0];this.renderer._smoothedPlotData=ap[1];if(al.show){ap=J.call(this,this.renderer._hiBandGridData);this.renderer._hiBandSmoothedData=ap[0];ap=J.call(this,this.renderer._lowBandGridData);this.renderer._lowBandSmoothedData=ap[0]}ap=null}else{ap=F.call(this,ar);this.renderer._smoothedData=ap[0];this.renderer._smoothedPlotData=ap[1];if(al.show){ap=F.call(this,this.renderer._hiBandGridData);this.renderer._hiBandSmoothedData=ap[0];ap=F.call(this,this.renderer._lowBandGridData);this.renderer._lowBandSmoothedData=ap[0]}ap=null}}return ar};L.jqplot.LineRenderer.prototype.draw=function(ax,aI,ai,aB){var aC;var aq=L.extend(true,{},ai);var ak=(aq.shadow!=u)?aq.shadow:this.shadow;var aJ=(aq.showLine!=u)?aq.showLine:this.showLine;var aA=(aq.fill!=u)?aq.fill:this.fill;var ah=(aq.fillAndStroke!=u)?aq.fillAndStroke:this.fillAndStroke;var ar,ay,av,aE;ax.save();if(aI.length){if(aJ){if(aA){if(this.fillToZero){var aF=this.negativeColor;if(!this.useNegativeColors){aF=aq.fillStyle}var ao=false;var ap=aq.fillStyle;if(ah){var aH=aI.slice(0)}if(this.index==0||!this._stack){var aw=[];var aL=(this.renderer.smooth)?this.renderer._smoothedPlotData:this._plotData;this._areaPoints=[];var aG=this._yaxis.series_u2p(this.fillToValue);var aj=this._xaxis.series_u2p(this.fillToValue);aq.closePath=true;if(this.fillAxis=="y"){aw.push([aI[0][0],aG]);this._areaPoints.push([aI[0][0],aG]);for(var aC=0;aC0;aC--){aI.push(au[aC-1])}if(ak){this.renderer.shadowRenderer.draw(ax,aI,aq)}this._areaPoints=aI;this.renderer.shapeRenderer.draw(ax,aI,aq)}}else{if(ah){var aH=aI.slice(0)}if(this.index==0||!this._stack){var al=ax.canvas.height;aI.unshift([aI[0][0],al]);var aD=aI.length;aI.push([aI[aD-1][0],al])}else{var au=this._prevGridData;for(var aC=au.length;aC>0;aC--){aI.push(au[aC-1])}}this._areaPoints=aI;if(ak){this.renderer.shadowRenderer.draw(ax,aI,aq)}this.renderer.shapeRenderer.draw(ax,aI,aq)}if(ah){var az=L.extend(true,{},aq,{fill:false,closePath:false});this.renderer.shapeRenderer.draw(ax,aH,az);if(this.markerRenderer.show){if(this.renderer.smooth){aH=this.gridData}for(aC=0;aCat[0]||ar==null){ar=at[0]}if(aEat[1]||ay==null){ay=at[1]}}if(this.type==="line"&&this.renderer.bands.show){aE=this._yaxis.series_u2p(this.renderer.bands._min);ay=this._yaxis.series_u2p(this.renderer.bands._max)}this._boundingBox=[[ar,aE],[av,ay]];if(this.markerRenderer.show&&!aA){if(this.renderer.smooth){aI=this.gridData}for(aC=0;aCao){ao=aj}}}al=null;am=null;if(ah){ai=this._label._elem.outerWidth(true);an=this._label._elem.outerHeight(true)}if(this.name=="xaxis"){ao=ao+an;this._elem.css({height:ao+"px",left:"0px",bottom:"0px"})}else{if(this.name=="x2axis"){ao=ao+an;this._elem.css({height:ao+"px",left:"0px",top:"0px"})}else{if(this.name=="yaxis"){ao=ao+ai;this._elem.css({width:ao+"px",left:"0px",top:"0px"});if(ah&&this._label.constructor==L.jqplot.AxisLabelRenderer){this._label._elem.css("width",ai+"px")}}else{ao=ao+ai;this._elem.css({width:ao+"px",right:"0px",top:"0px"});if(ah&&this._label.constructor==L.jqplot.AxisLabelRenderer){this._label._elem.css("width",ai+"px")}}}}}};L.jqplot.LinearAxisRenderer.prototype.createTicks=function(aj){var aT=this._ticks;var aK=this.ticks;var az=this.name;var aB=this._dataBounds;var ah=(this.name.charAt(0)==="x")?this._plotDimensions.width:this._plotDimensions.height;var an;var a6,aI;var ap,ao;var a4,a0;var aH=this.min;var a5=this.max;var aW=this.numberTicks;var ba=this.tickInterval;var am=30;this._scalefact=(Math.max(ah,am+1)-am)/300;if(aK.length){for(a0=0;a0this.breakPoints[0]&&aO[0]<=this.breakPoints[1]){aU.show=false;aU.showGridline=false;aU.label=aO[1]}else{aU.label=aO[1]}}}else{aU.label=aO[1]}aU.setTick(aO[0],this.name);this._ticks.push(aU)}else{if(L.isPlainObject(aO)){L.extend(true,aU,aO);aU.axis=this.name;this._ticks.push(aU)}else{aU.value=aO;if(this.breakPoints){if(aO==this.breakPoints[0]){aU.label=this.breakTickLabel;aU._breakTick=true;aU.showGridline=false;aU.showMark=false}else{if(aO>this.breakPoints[0]&&aO<=this.breakPoints[1]){aU.show=false;aU.showGridline=false}}}aU.setTick(aO,this.name);this._ticks.push(aU)}}}this.numberTicks=aK.length;this.min=this._ticks[0].value;this.max=this._ticks[this.numberTicks-1].value;this.tickInterval=(this.max-this.min)/(this.numberTicks-1)}else{if(az=="xaxis"||az=="x2axis"){ah=this._plotDimensions.width}else{ah=this._plotDimensions.height}var ax=this.numberTicks;if(this.alignTicks){if(this.name==="x2axis"&&aj.axes.xaxis.show){ax=aj.axes.xaxis.numberTicks}else{if(this.name.charAt(0)==="y"&&this.name!=="yaxis"&&this.name!=="yMidAxis"&&aj.axes.yaxis.show){ax=aj.axes.yaxis.numberTicks}}}a6=((this.min!=null)?this.min:aB.min);aI=((this.max!=null)?this.max:aB.max);var av=aI-a6;var aS,ay;var at;if(this.tickOptions==null||!this.tickOptions.formatString){this._overrideFormatString=true}if(this.min==null||this.max==null&&this.tickInterval==null&&!this.autoscale){if(this.forceTickAt0){if(a6>0){a6=0}if(aI<0){aI=0}}if(this.forceTickAt100){if(a6>100){a6=100}if(aI<100){aI=100}}var aE=false,a1=false;if(this.min!=null){aE=true}else{if(this.max!=null){a1=true}}var aP=L.jqplot.LinearTickGenerator(a6,aI,this._scalefact,ax,aE,a1);var aw=(this.min!=null)?a6:a6+av*(this.padMin-1);var aQ=(this.max!=null)?aI:aI-av*(this.padMax-1);if(a6aQ){aw=(this.min!=null)?a6:a6-av*(this.padMin-1);aQ=(this.max!=null)?aI:aI+av*(this.padMax-1);aP=L.jqplot.LinearTickGenerator(aw,aQ,this._scalefact,ax,aE,a1)}this.min=aP[0];this.max=aP[1];this.numberTicks=aP[2];this._autoFormatString=aP[3];this.tickInterval=aP[4]}else{if(a6==aI){var ai=0.05;if(a6>0){ai=Math.max(Math.log(a6)/Math.LN10,0.05)}a6-=ai;aI+=ai}if(this.autoscale&&this.min==null&&this.max==null){var ak,al,ar;var aC=false;var aN=false;var aA={min:null,max:null,average:null,stddev:null};for(var a0=0;a0a2){a2=aR[aZ]}}}var au=(a2-aG)/a2;if(aV.renderer.constructor==L.jqplot.BarRenderer){if(aG>=0&&(aV.fillToZero||au>0.1)){aC=true}else{aC=false;if(aV.fill&&aV.fillToZero&&aG<0&&a2>0){aN=true}else{aN=false}}}else{if(aV.fill){if(aG>=0&&(aV.fillToZero||au>0.1)){aC=true}else{if(aG<0&&a2>0&&aV.fillToZero){aC=false;aN=true}else{aC=false;aN=false}}}else{if(aG<0){aC=false}}}}}if(aC){this.numberTicks=2+Math.ceil((ah-(this.tickSpacing-1))/this.tickSpacing);this.min=0;aH=0;al=aI/(this.numberTicks-1);at=Math.pow(10,Math.abs(Math.floor(Math.log(al)/Math.LN10)));if(al/at==parseInt(al/at,10)){al+=at}this.tickInterval=Math.ceil(al/at)*at;this.max=this.tickInterval*(this.numberTicks-1)}else{if(aN){this.numberTicks=2+Math.ceil((ah-(this.tickSpacing-1))/this.tickSpacing);var aJ=Math.ceil(Math.abs(a6)/av*(this.numberTicks-1));var a9=this.numberTicks-1-aJ;al=Math.max(Math.abs(a6/aJ),Math.abs(aI/a9));at=Math.pow(10,Math.abs(Math.floor(Math.log(al)/Math.LN10)));this.tickInterval=Math.ceil(al/at)*at;this.max=this.tickInterval*a9;this.min=-this.tickInterval*aJ}else{if(this.numberTicks==null){if(this.tickInterval){this.numberTicks=3+Math.ceil(av/this.tickInterval)}else{this.numberTicks=2+Math.ceil((ah-(this.tickSpacing-1))/this.tickSpacing)}}if(this.tickInterval==null){al=av/(this.numberTicks-1);if(al<1){at=Math.pow(10,Math.abs(Math.floor(Math.log(al)/Math.LN10)))}else{at=1}this.tickInterval=Math.ceil(al*at*this.pad)/at}else{at=1/this.tickInterval}ak=this.tickInterval*(this.numberTicks-1);ar=(ak-av)/2;if(this.min==null){this.min=Math.floor(at*(a6-ar))/at}if(this.max==null){this.max=this.min+ak}}}var aF=L.jqplot.getSignificantFigures(this.tickInterval);var aM;if(aF.digitsLeft>=aF.significantDigits){aM="%d"}else{var at=Math.max(0,5-aF.digitsLeft);at=Math.min(at,aF.digitsRight);aM="%."+at+"f"}this._autoFormatString=aM}else{aS=(this.min!=null)?this.min:a6-av*(this.padMin-1);ay=(this.max!=null)?this.max:aI+av*(this.padMax-1);av=ay-aS;if(this.numberTicks==null){if(this.tickInterval!=null){this.numberTicks=Math.ceil((ay-aS)/this.tickInterval)+1}else{if(ah>100){this.numberTicks=parseInt(3+(ah-100)/75,10)}else{this.numberTicks=2}}}if(this.tickInterval==null){this.tickInterval=av/(this.numberTicks-1)}if(this.max==null){ay=aS+this.tickInterval*(this.numberTicks-1)}if(this.min==null){aS=ay-this.tickInterval*(this.numberTicks-1)}var aF=L.jqplot.getSignificantFigures(this.tickInterval);var aM;if(aF.digitsLeft>=aF.significantDigits){aM="%d"}else{var at=Math.max(0,5-aF.digitsLeft);at=Math.min(at,aF.digitsRight);aM="%."+at+"f"}this._autoFormatString=aM;this.min=aS;this.max=ay}if(this.renderer.constructor==L.jqplot.LinearAxisRenderer&&this._autoFormatString==""){av=this.max-this.min;var a7=new this.tickRenderer(this.tickOptions);var aL=a7.formatString||L.jqplot.config.defaultTickFormatString;var aL=aL.match(L.jqplot.sprintf.regex)[0];var a3=0;if(aL){if(aL.search(/[fFeEgGpP]/)>-1){var aY=aL.match(/\%\.(\d{0,})?[eEfFgGpP]/);if(aY){a3=parseInt(aY[1],10)}else{a3=6}}else{if(aL.search(/[di]/)>-1){a3=0}}var aq=Math.pow(10,-a3);if(this.tickIntervalthis.breakPoints[0]&&aAthis.breakPoints[0]&&aAthis.breakPoints[0]&&aA=this.breakPoints[1]){return(aA-au)*ak/al}else{return(aA+this.breakPoints[1]-this.breakPoints[0]-au)*ak/al}};this.series_p2u=function(aA){return aA*al/ak+au}}}else{this.p2u=function(aA){return(aA-am)*al/ak+at};this.u2p=function(aA){return(aA-at)*ak/al+am};if(this.name=="xaxis"||this.name=="x2axis"){this.series_u2p=function(aA){return(aA-at)*ak/al};this.series_p2u=function(aA){return aA*al/ak+at}}else{this.series_u2p=function(aA){return(aA-au)*ak/al};this.series_p2u=function(aA){return aA*al/ak+au}}}if(this.show){if(this.name=="xaxis"||this.name=="x2axis"){for(var av=0;av0){ah=-ap._textRenderer.height*Math.cos(-ap._textRenderer.angle)/2}else{ah=-ap.getHeight()+ap._textRenderer.height*Math.cos(ap._textRenderer.angle)/2}break;case"middle":ah=-ap.getHeight()/2;break;default:ah=-ap.getHeight()/2;break}}else{ah=-ap.getHeight()/2}var az=this.u2p(ap.value)+ah+"px";ap._elem.css("top",az);ap.pack()}}if(aq){var aw=this._label._elem.outerHeight(true);this._label._elem.css("top",ao-ak/2-aw/2+"px");if(this.name=="yaxis"){this._label._elem.css("left","0px")}else{this._label._elem.css("right","0px")}this._label.pack()}}}ay=null};function i(ai){var ah;ai=Math.abs(ai);if(ai>=10){ah="%d"}else{if(ai>1){if(ai===parseInt(ai,10)){ah="%d"}else{ah="%.1f"}}else{var aj=-Math.floor(Math.log(ai)/Math.LN10);ah="%."+aj+"f"}}return ah}var b=[0.1,0.2,0.3,0.4,0.5,0.8,1,2,3,4,5];var c=function(ai){var ah=b.indexOf(ai);if(ah>0){return b[ah-1]}else{return b[b.length-1]/100}};var k=function(ai){var ah=b.indexOf(ai);if(ah5){ah=10*aj}else{if(am>2){ah=5*aj}else{if(am>1){ah=2*aj}else{ah=aj}}}}else{if(am>5){ah=10*aj}else{if(am>4){ah=5*aj}else{if(am>3){ah=4*aj}else{if(am>2){ah=3*aj}else{if(am>1){ah=2*aj}else{ah=aj}}}}}}return ah}function Q(ai,ah){ah=ah||1;var ak=Math.floor(Math.log(ai)/Math.LN10);var am=Math.pow(10,ak);var al=ai/am;var aj;al=al/ah;if(al<=0.38){aj=0.1}else{if(al<=1.6){aj=0.2}else{if(al<=4){aj=0.5}else{if(al<=8){aj=1}else{if(al<=16){aj=2}else{aj=5}}}}}return aj*am}function x(aj,ai){var al=Math.floor(Math.log(aj)/Math.LN10);var an=Math.pow(10,al);var am=aj/an;var ah;var ak;am=am/ai;if(am<=0.38){ak=0.1}else{if(am<=1.6){ak=0.2}else{if(am<=4){ak=0.5}else{if(am<=8){ak=1}else{if(am<=16){ak=2}else{ak=5}}}}}ah=ak*an;return[ah,ak,an]}L.jqplot.LinearTickGenerator=function(an,aq,aj,ak,ao,ar){ao=(ao===null)?false:ao;ar=(ar===null||ao)?false:ar;if(an===aq){aq=(aq)?0:1}aj=aj||1;if(aqat){at=aB}if(ai>aA){aA=ai}})}an.width=at+Number(av);an.height=aA+Number(ax);var ak=an.getContext("2d");ak.save();ak.fillStyle=al;ak.fillRect(0,0,an.width,an.height);ak.restore();ak.translate(au,ar);ak.textAlign="left";ak.textBaseline="top";function aC(aE){var aF=parseInt(L(aE).css("line-height"),10);if(isNaN(aF)){aF=parseInt(L(aE).css("font-size"),10)*1.2}return aF}function aD(aF,aE,aS,aG,aO,aH){var aQ=aC(aF);var aK=L(aF).innerWidth();var aL=L(aF).innerHeight();var aN=aS.split(/\s+/);var aR=aN.length;var aP="";var aM=[];var aU=aO;var aT=aG;for(var aJ=0;aJaK){aM.push(aJ);aP="";aJ--}}if(aM.length===0){if(L(aF).css("textAlign")==="center"){aT=aG+(aH-aE.measureText(aP).width)/2-au}aE.fillText(aS,aT,aO)}else{aP=aN.slice(0,aM[0]).join(" ");if(L(aF).css("textAlign")==="center"){aT=aG+(aH-aE.measureText(aP).width)/2-au}aE.fillText(aP,aT,aU);aU+=aQ;for(var aJ=1,aI=aM.length;aJ0){ak.strokeRect(aI,aL,L(aG).innerWidth(),L(aG).innerHeight())}L(aG).find("div.jqplot-table-legend-swatch-outline").each(function(){var aU=L(this);ak.strokeStyle=aU.css("border-top-color");var aQ=aI+aU.position().left;var aR=aL+aU.position().top;ak.strokeRect(aQ,aR,aU.innerWidth(),aU.innerHeight());aQ+=parseInt(aU.css("padding-left"),10);aR+=parseInt(aU.css("padding-top"),10);var aT=aU.innerHeight()-2*parseInt(aU.css("padding-top"),10);var aP=aU.innerWidth()-2*parseInt(aU.css("padding-left"),10);var aS=aU.children("div.jqplot-table-legend-swatch");ak.fillStyle=aS.css("background-color");ak.fillRect(aQ,aR,aP,aT)});L(aG).find("td.jqplot-table-legend-label").each(function(){var aR=L(this);var aP=aI+aR.position().left;var aQ=aL+aR.position().top+parseInt(aR.css("padding-top"),10);ak.font=aR.jqplotGetComputedFontStyle();ak.fillStyle=aR.css("color");aD(aR,ak,aR.text(),aP,aQ,aM)});var aH=null}else{if(aN=="canvas"){ak.drawImage(aG,aI,aL)}}}}L(this).children().each(function(){aw(this,av,ax)});return an};L.fn.jqplotToImageStr=function(ai){var ah=L(this).jqplotToImageCanvas(ai);if(ah){return ah.toDataURL("image/png")}else{return null}};L.fn.jqplotToImageElem=function(ah){var ai=document.createElement("img");var aj=L(this).jqplotToImageStr(ah);ai.src=aj;return ai};L.fn.jqplotToImageElemStr=function(ah){var ai="";return ai};L.fn.jqplotSaveImage=function(){var ah=L(this).jqplotToImageStr({});if(ah){window.location.href=ah.replace("image/png","image/octet-stream")}};L.fn.jqplotViewImage=function(){var ai=L(this).jqplotToImageElemStr({});var aj=L(this).jqplotToImageStr({});if(ai){var ah=window.open("");ah.document.open("image/png");ah.document.write(ai);ah.document.close();ah=null}};var ag=function(){this.syntax=ag.config.syntax;this._type="jsDate";this.proxy=new Date();this.options={};this.locale=ag.regional.getLocale();this.formatString="";this.defaultCentury=ag.config.defaultCentury;switch(arguments.length){case 0:break;case 1:if(l(arguments[0])=="[object Object]"&&arguments[0]._type!="jsDate"){var aj=this.options=arguments[0];this.syntax=aj.syntax||this.syntax;this.defaultCentury=aj.defaultCentury||this.defaultCentury;this.proxy=ag.createDate(aj.date)}else{this.proxy=ag.createDate(arguments[0])}break;default:var ah=[];for(var ai=0;ai0?"floor":"ceil"](ak))};ag.prototype.getAbbrDayName=function(){return ag.regional[this.locale]["dayNamesShort"][this.proxy.getDay()]};ag.prototype.getAbbrMonthName=function(){return ag.regional[this.locale]["monthNamesShort"][this.proxy.getMonth()]};ag.prototype.getAMPM=function(){return this.proxy.getHours()>=12?"PM":"AM"};ag.prototype.getAmPm=function(){return this.proxy.getHours()>=12?"pm":"am"};ag.prototype.getCentury=function(){return parseInt(this.proxy.getFullYear()/100,10)};ag.prototype.getDate=function(){return this.proxy.getDate()};ag.prototype.getDay=function(){return this.proxy.getDay()};ag.prototype.getDayOfWeek=function(){var ah=this.proxy.getDay();return ah===0?7:ah};ag.prototype.getDayOfYear=function(){var ai=this.proxy;var ah=ai-new Date(""+ai.getFullYear()+"/1/1 GMT");ah+=ai.getTimezoneOffset()*60000;ai=null;return parseInt(ah/60000/60/24,10)+1};ag.prototype.getDayName=function(){return ag.regional[this.locale]["dayNames"][this.proxy.getDay()]};ag.prototype.getFullWeekOfYear=function(){var ak=this.proxy;var ah=this.getDayOfYear();var aj=6-ak.getDay();var ai=parseInt((ah+aj)/7,10);return ai};ag.prototype.getFullYear=function(){return this.proxy.getFullYear()};ag.prototype.getGmtOffset=function(){var ah=this.proxy.getTimezoneOffset()/60;var ai=ah<0?"+":"-";ah=Math.abs(ah);return ai+N(Math.floor(ah),2)+":"+N((ah%1)*60,2)};ag.prototype.getHours=function(){return this.proxy.getHours()};ag.prototype.getHours12=function(){var ah=this.proxy.getHours();return ah>12?ah-12:(ah==0?12:ah)};ag.prototype.getIsoWeek=function(){var ak=this.proxy;var aj=this.getWeekOfYear();var ah=(new Date(""+ak.getFullYear()+"/1/1")).getDay();var ai=aj+(ah>4||ah<=1?0:1);if(ai==53&&(new Date(""+ak.getFullYear()+"/12/31")).getDay()<4){ai=1}else{if(ai===0){ak=new ag(new Date(""+(ak.getFullYear()-1)+"/12/31"));ai=ak.getIsoWeek()}}ak=null;return ai};ag.prototype.getMilliseconds=function(){return this.proxy.getMilliseconds()};ag.prototype.getMinutes=function(){return this.proxy.getMinutes()};ag.prototype.getMonth=function(){return this.proxy.getMonth()};ag.prototype.getMonthName=function(){return ag.regional[this.locale]["monthNames"][this.proxy.getMonth()]};ag.prototype.getMonthNumber=function(){return this.proxy.getMonth()+1};ag.prototype.getSeconds=function(){return this.proxy.getSeconds()};ag.prototype.getShortYear=function(){return this.proxy.getYear()%100};ag.prototype.getTime=function(){return this.proxy.getTime()};ag.prototype.getTimezoneAbbr=function(){return this.proxy.toString().replace(/^.*\(([^)]+)\)$/,"$1")};ag.prototype.getTimezoneName=function(){var ah=/(?:\((.+)\)$| ([A-Z]{3}) )/.exec(this.toString());return ah[1]||ah[2]||"GMT"+this.getGmtOffset()};ag.prototype.getTimezoneOffset=function(){return this.proxy.getTimezoneOffset()};ag.prototype.getWeekOfYear=function(){var ah=this.getDayOfYear();var aj=7-this.getDayOfWeek();var ai=parseInt((ah+aj)/7,10);return ai};ag.prototype.getUnix=function(){return Math.round(this.proxy.getTime()/1000,0)};ag.prototype.getYear=function(){return this.proxy.getYear()};ag.prototype.next=function(ah){ah=ah||"day";return this.clone().add(1,ah)};ag.prototype.set=function(){switch(arguments.length){case 0:this.proxy=new Date();break;case 1:if(l(arguments[0])=="[object Object]"&&arguments[0]._type!="jsDate"){var aj=this.options=arguments[0];this.syntax=aj.syntax||this.syntax;this.defaultCentury=aj.defaultCentury||this.defaultCentury;this.proxy=ag.createDate(aj.date)}else{this.proxy=ag.createDate(arguments[0])}break;default:var ah=[];for(var ai=0;ai0?"floor":"ceil"](ah/12));var ai=aj.getMonth()+(ah%12);if(ai==12){ai=0;aj.setYear(aj.getFullYear()+1)}else{if(ai==-1){ai=11;aj.setYear(aj.getFullYear()-1)}}aj.setMonth(ai)},diff:function(al,aj){var ah=al.getFullYear()-aj.getFullYear();var ai=al.getMonth()-aj.getMonth()+(ah*12);var ak=al.getDate()-aj.getDate();return ai+(ak/30)}},year:{add:function(ai,ah){ai.setYear(ai.getFullYear()+Math[ah>0?"floor":"ceil"](ah))},diff:function(ai,ah){return E.month.diff(ai,ah)/12}}};for(var Y in E){if(Y.substring(Y.length-1)!="s"){E[Y+"s"]=E[Y]}}var H=function(al,ak,ai){if(ag.formats[ai]["shortcuts"][ak]){return ag.strftime(al,ag.formats[ai]["shortcuts"][ak],ai)}else{var ah=(ag.formats[ai]["codes"][ak]||"").split(".");var aj=al["get"+ah[0]]?al["get"+ah[0]]():"";if(ah[1]){aj=N(aj,ah[1])}return aj}};ag.strftime=function(an,ak,aj,ao){var ai="perl";var am=ag.regional.getLocale();if(aj&&ag.formats.hasOwnProperty(aj)){ai=aj}else{if(aj&&ag.regional.hasOwnProperty(aj)){am=aj}}if(ao&&ag.formats.hasOwnProperty(ao)){ai=ao}else{if(ao&&ag.regional.hasOwnProperty(ao)){am=ao}}if(l(an)!="[object Object]"||an._type!="jsDate"){an=new ag(an);an.locale=am}if(!ak){ak=an.formatString||ag.regional[am]["formatString"]}var ah=ak||"%Y-%m-%d",ap="",al;while(ah.length>0){if(al=ah.match(ag.formats[ai].codes.matcher)){ap+=ah.slice(0,al.index);ap+=(al[1]||"")+H(an,al[2],ai);ah=ah.slice(al.index+al[0].length)}else{ap+=ah;ah=""}}return ap};ag.formats={ISO:"%Y-%m-%dT%H:%M:%S.%N%G",SQL:"%Y-%m-%d %H:%M:%S"};ag.formats.perl={codes:{matcher:/()%(#?(%|[a-z]))/i,Y:"FullYear",y:"ShortYear.2",m:"MonthNumber.2","#m":"MonthNumber",B:"MonthName",b:"AbbrMonthName",d:"Date.2","#d":"Date",e:"Date",A:"DayName",a:"AbbrDayName",w:"Day",H:"Hours.2","#H":"Hours",I:"Hours12.2","#I":"Hours12",p:"AMPM",M:"Minutes.2","#M":"Minutes",S:"Seconds.2","#S":"Seconds",s:"Unix",N:"Milliseconds.3","#N":"Milliseconds",O:"TimezoneOffset",Z:"TimezoneName",G:"GmtOffset"},shortcuts:{F:"%Y-%m-%d",T:"%H:%M:%S",X:"%H:%M:%S",x:"%m/%d/%y",D:"%m/%d/%y","#c":"%a %b %e %H:%M:%S %Y",v:"%e-%b-%Y",R:"%H:%M",r:"%I:%M:%S %p",t:"\t",n:"\n","%":"%"}};ag.formats.php={codes:{matcher:/()%((%|[a-z]))/i,a:"AbbrDayName",A:"DayName",d:"Date.2",e:"Date",j:"DayOfYear.3",u:"DayOfWeek",w:"Day",U:"FullWeekOfYear.2",V:"IsoWeek.2",W:"WeekOfYear.2",b:"AbbrMonthName",B:"MonthName",m:"MonthNumber.2",h:"AbbrMonthName",C:"Century.2",y:"ShortYear.2",Y:"FullYear",H:"Hours.2",I:"Hours12.2",l:"Hours12",p:"AMPM",P:"AmPm",M:"Minutes.2",S:"Seconds.2",s:"Unix",O:"TimezoneOffset",z:"GmtOffset",Z:"TimezoneAbbr"},shortcuts:{D:"%m/%d/%y",F:"%Y-%m-%d",T:"%H:%M:%S",X:"%H:%M:%S",x:"%m/%d/%y",R:"%H:%M",r:"%I:%M:%S %p",t:"\t",n:"\n","%":"%"}};ag.createDate=function(aj){if(aj==null){return new Date()}if(aj instanceof Date){return aj}if(typeof aj=="number"){return new Date(aj)}var ao=String(aj).replace(/^\s*(.+)\s*$/g,"$1");ao=ao.replace(/^([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,4})/,"$1/$2/$3");ao=ao.replace(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{4})/i,"$1 $2 $3");var an=ao.match(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{2})\D*/i);if(an&&an.length>3){var at=parseFloat(an[3]);var am=ag.config.defaultCentury+at;am=String(am);ao=ao.replace(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{2})\D*/i,an[1]+" "+an[2]+" "+am)}an=ao.match(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})[^0-9]/);function ar(ax,aw){var aC=parseFloat(aw[1]);var aB=parseFloat(aw[2]);var aA=parseFloat(aw[3]);var az=ag.config.defaultCentury;var av,au,aD,ay;if(aC>31){au=aA;aD=aB;av=az+aC}else{au=aB;aD=aC;av=az+aA}ay=aD+"/"+au+"/"+av;return ax.replace(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})/,ay)}if(an&&an.length>3){ao=ar(ao,an)}var an=ao.match(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})$/);if(an&&an.length>3){ao=ar(ao,an)}var al=0;var ai=ag.matchers.length;var aq,ah,ap=ao,ak;while(al31){ah=an;ai=am+ao}else{ah=ao;ai=am+an}var ap=ab(aj[2],ag.regional[ag.regional.getLocale()]["monthNamesShort"]);if(ap==-1){ap=ab(aj[2],ag.regional[ag.regional.getLocale()]["monthNames"])}ak.setFullYear(ai,ap,ah);ak.setHours(0,0,0,0);return ak}else{return al}}];function ab(aj,ak){if(ak.indexOf){return ak.indexOf(aj)}for(var ah=0,ai=ak.length;ah=ap)?"":Array(1+ap-au.length>>>0).join(aq);return at?au+ar:ar+au}function ak(ar){var aq=new String(ar);for(var ap=10;ap>0;ap--){if(aq==(aq=aq.replace(/^(\d+)(\d{3})/,"$1"+L.jqplot.sprintf.thousandsSeparator+"$2"))){break}}return aq}function aj(av,au,ax,ar,at,aq){var aw=ar-av.length;if(aw>0){var ap=" ";if(aq){ap=" "}if(ax||!at){av=an(av,ar,ap,ax)}else{av=av.slice(0,au.length)+an("",aw,"0",true)+av.slice(au.length)}}return av}function ao(ay,aq,aw,ar,ap,av,ax,au){var at=ay>>>0;aw=aw&&at&&{"2":"0b","8":"0","16":"0x"}[aq]||"";ay=aw+an(at.toString(aq),av||0,"0",false);return aj(ay,aw,ar,ap,ax,au)}function ah(au,av,ar,ap,at,aq){if(ap!=null){au=au.slice(0,ap)}return aj(au,"",av,ar,at,aq)}var ai=arguments,al=0,am=ai[al++];return am.replace(L.jqplot.sprintf.regex,function(aM,ax,ay,aB,aO,aJ,av){if(aM=="%%"){return"%"}var aD=false,az="",aA=false,aL=false,aw=false,au=false;for(var aI=0;ay&&aI-1?6:(av=="d")?0:void (0)}else{if(aJ=="*"){aJ=+ai[al++]}else{if(aJ.charAt(0)=="*"){aJ=+ai[aJ.slice(1,-1)]}else{aJ=+aJ}}}var aF=ax?ai[ax.slice(0,-1)]:ai[al++];switch(av){case"s":if(aF==null){return""}return ah(String(aF),aD,aB,aJ,aA,aw);case"c":return ah(String.fromCharCode(+aF),aD,aB,aJ,aA,aw);case"b":return ao(aF,2,aL,aD,aB,aJ,aA,aw);case"o":return ao(aF,8,aL,aD,aB,aJ,aA,aw);case"x":return ao(aF,16,aL,aD,aB,aJ,aA,aw);case"X":return ao(aF,16,aL,aD,aB,aJ,aA,aw).toUpperCase();case"u":return ao(aF,10,aL,aD,aB,aJ,aA,aw);case"i":var ar=parseInt(+aF,10);if(isNaN(ar)){return""}var aH=ar<0?"-":az;var aK=au?ak(String(Math.abs(ar))):String(Math.abs(ar));aF=aH+an(aK,aJ,"0",false);return aj(aF,aH,aD,aB,aA,aw);case"d":var ar=Math.round(+aF);if(isNaN(ar)){return""}var aH=ar<0?"-":az;var aK=au?ak(String(Math.abs(ar))):String(Math.abs(ar));aF=aH+an(aK,aJ,"0",false);return aj(aF,aH,aD,aB,aA,aw);case"e":case"E":case"f":case"F":case"g":case"G":var ar=+aF;if(isNaN(ar)){return""}var aH=ar<0?"-":az;var at=["toExponential","toFixed","toPrecision"]["efg".indexOf(av.toLowerCase())];var aN=["toString","toUpperCase"]["eEfFgG".indexOf(av)%2];var aK=Math.abs(ar)[at](aJ);var aE=aK.toString().split(".");aE[0]=au?ak(aE[0]):aE[0];aK=aE.join(L.jqplot.sprintf.decimalMark);aF=aH+aK;var aC=aj(aF,aH,aD,aB,aA,aw)[aN]();return aC;case"p":case"P":var ar=+aF;if(isNaN(ar)){return""}var aH=ar<0?"-":az;var aE=String(Number(Math.abs(ar)).toExponential()).split(/e|E/);var aq=(aE[0].indexOf(".")!=-1)?aE[0].length-1:String(ar).length;var aG=(aE[1]<0)?-aE[1]-1:0;if(Math.abs(ar)<1){if(aq+aG<=aJ){aF=aH+Math.abs(ar).toPrecision(aq)}else{if(aq<=aJ-1){aF=aH+Math.abs(ar).toExponential(aq-1)}else{aF=aH+Math.abs(ar).toExponential(aJ-1)}}}else{var ap=(aq<=aJ)?aq:aJ;aF=aH+Math.abs(ar).toPrecision(ap)}var aN=["toString","toUpperCase"]["pP".indexOf(av)%2];return aj(aF,aH,aD,aB,aA,aw)[aN]();case"n":return"";default:return aM}})};L.jqplot.sprintf.thousandsSeparator=",";L.jqplot.sprintf.decimalMark=".";L.jqplot.sprintf.regex=/%%|%(\d+\$)?([-+#0&\' ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([nAscboxXuidfegpEGP])/g;L.jqplot.getSignificantFigures=function(al){var an=String(Number(Math.abs(al)).toExponential()).split(/e|E/);var am=(an[0].indexOf(".")!=-1)?an[0].length-1:an[0].length;var ai=(an[1]<0)?-an[1]-1:0;var ah=parseInt(an[1],10);var aj=(ah+1>0)?ah+1:0;var ak=(am<=aj)?0:am-ah-1;return{significantDigits:am,digitsLeft:aj,digitsRight:ak,zeros:ai,exponent:ah}};L.jqplot.getPrecision=function(ah){return L.jqplot.getSignificantFigures(ah).digitsRight};var X=L.uiBackCompat!==false;L.jqplot.effects={effect:{}};var m="jqplot.storage.";L.extend(L.jqplot.effects,{version:"1.9pre",save:function(ai,aj){for(var ah=0;ah
    ").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),ah={width:ai.width(),height:ai.height()},ak=document.activeElement;ai.wrap(al);if(ai[0]===ak||L.contains(ai[0],ak)){L(ak).focus()}al=ai.parent();if(ai.css("position")==="static"){al.css({position:"relative"});ai.css({position:"relative"})}else{L.extend(aj,{position:ai.css("position"),zIndex:ai.css("z-index")});L.each(["top","left","bottom","right"],function(am,an){aj[an]=ai.css(an);if(isNaN(parseInt(aj[an],10))){aj[an]="auto"}});ai.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})}ai.css(ah);return al.css(aj).show()},removeWrapper:function(ah){var ai=document.activeElement;if(ah.parent().is(".ui-effects-wrapper")){ah.parent().replaceWith(ah);if(ah[0]===ai||L.contains(ah[0],ai)){L(ai).focus()}}return ah}});function j(ai,ah,aj,ak){if(L.isPlainObject(ai)){return ai}ai={effect:ai};if(ah===u){ah={}}if(L.isFunction(ah)){ak=ah;aj=null;ah={}}if(L.type(ah)==="number"||L.fx.speeds[ah]){ak=aj;aj=ah;ah={}}if(L.isFunction(aj)){ak=aj;aj=null}if(ah){L.extend(ai,ah)}aj=aj||ah.duration;ai.duration=L.fx.off?0:typeof aj==="number"?aj:aj in L.fx.speeds?L.fx.speeds[aj]:L.fx.speeds._default;ai.complete=ak||ah.complete;return ai}function ae(ah){if(!ah||typeof ah==="number"||L.fx.speeds[ah]){return true}if(typeof ah==="string"&&!L.jqplot.effects.effect[ah]){if(X&&L.jqplot.effects[ah]){return false}return true}return false}L.fn.extend({jqplotEffect:function(ap,aq,ai,ao){var an=j.apply(this,arguments),ak=an.mode,al=an.queue,am=L.jqplot.effects.effect[an.effect],ah=!am&&X&&L.jqplot.effects[an.effect];if(L.fx.off||!(am||ah)){if(ak){return this[ak](an.duration,an.complete)}else{return this.each(function(){if(an.complete){an.complete.call(this)}})}}function aj(au){var av=L(this),at=an.complete,aw=an.mode;function ar(){if(L.isFunction(at)){at.call(av[0])}if(L.isFunction(au)){au()}}if(av.is(":hidden")?aw==="hide":aw==="show"){ar()}else{am.call(av[0],an,ar)}}if(am){return al===false?this.each(aj):this.queue(al||"fx",aj)}else{return ah.call(this,{options:an,duration:an.duration,callback:an.complete,mode:an.mode})}}});var a=/up|down|vertical/,v=/up|left|vertical|horizontal/;L.jqplot.effects.effect.blind=function(aj,ao){var ak=L(this),ar=["position","top","bottom","left","right","height","width"],ap=L.jqplot.effects.setMode(ak,aj.mode||"hide"),au=aj.direction||"up",am=a.test(au),al=am?"height":"width",aq=am?"top":"left",aw=v.test(au),an={},av=ap==="show",ai,ah,at;if(ak.parent().is(".ui-effects-wrapper")){L.jqplot.effects.save(ak.parent(),ar)}else{L.jqplot.effects.save(ak,ar)}ak.show();at=parseInt(ak.css("top"),10);ai=L.jqplot.effects.createWrapper(ak).css({overflow:"hidden"});ah=am?ai[al]()+at:ai[al]();an[al]=av?String(ah):"0";if(!aw){ak.css(am?"bottom":"right",0).css(am?"top":"left","").css({position:"absolute"});an[aq]=av?"0":String(ah)}if(av){ai.css(al,0);if(!aw){ai.css(aq,ah)}}ai.animate(an,{duration:aj.duration,easing:aj.easing,queue:false,complete:function(){if(ap==="hide"){ak.hide()}L.jqplot.effects.restore(ak,ar);L.jqplot.effects.removeWrapper(ak);ao()}})}})(jQuery); \ No newline at end of file diff --git a/templates/admin/default/assets/js/jqplot/plugins/jqplot.BezierCurveRenderer.min.js b/templates/admin/default/assets/js/jqplot/plugins/jqplot.BezierCurveRenderer.min.js new file mode 100644 index 000000000..94c6fc5e7 --- /dev/null +++ b/templates/admin/default/assets/js/jqplot/plugins/jqplot.BezierCurveRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(b){b.jqplot.BezierCurveRenderer=function(){b.jqplot.LineRenderer.call(this)};b.jqplot.BezierCurveRenderer.prototype=new b.jqplot.LineRenderer();b.jqplot.BezierCurveRenderer.prototype.constructor=b.jqplot.BezierCurveRenderer;b.jqplot.BezierCurveRenderer.prototype.setGridData=function(h){var e=this._xaxis.series_u2p;var g=this._yaxis.series_u2p;var f=this.data;this.gridData=[];this._prevGridData=[];var d=this.index;if(f.length==2){if(d==0){this.gridData=[[e.call(this._xaxis,f[0][0]),g.call(this._yaxis,f[0][1])],[e.call(this._xaxis,f[1][0]),g.call(this._yaxis,f[1][1]),e.call(this._xaxis,f[1][2]),g.call(this._yaxis,f[1][3]),e.call(this._xaxis,f[1][4]),g.call(this._yaxis,f[1][5])],[e.call(this._xaxis,f[1][4]),g.call(this._yaxis,this._yaxis.min)],[e.call(this._xaxis,f[0][0]),g.call(this._yaxis,this._yaxis.min)]]}else{var c=h.series[d-1].data;this.gridData=[[e.call(this._xaxis,f[0][0]),g.call(this._yaxis,f[0][1])],[e.call(this._xaxis,f[1][0]),g.call(this._yaxis,f[1][1]),e.call(this._xaxis,f[1][2]),g.call(this._yaxis,f[1][3]),e.call(this._xaxis,f[1][4]),g.call(this._yaxis,f[1][5])],[e.call(this._xaxis,c[1][4]),g.call(this._yaxis,c[1][5])],[e.call(this._xaxis,c[1][2]),g.call(this._yaxis,c[1][3]),e.call(this._xaxis,c[1][0]),g.call(this._yaxis,c[1][1]),e.call(this._xaxis,c[0][0]),g.call(this._yaxis,c[0][1])]]}}else{if(d==0){this.gridData=[[e.call(this._xaxis,f[0][0]),g.call(this._yaxis,f[0][1])],[e.call(this._xaxis,f[1][0]),g.call(this._yaxis,f[1][1]),e.call(this._xaxis,f[2][0]),g.call(this._yaxis,f[2][1]),e.call(this._xaxis,f[3][0]),g.call(this._yaxis,f[3][1])],[e.call(this._xaxis,f[3][1]),g.call(this._yaxis,this._yaxis.min)],[e.call(this._xaxis,f[0][0]),g.call(this._yaxis,this._yaxis.min)]]}else{var c=h.series[d-1].data;this.gridData=[[e.call(this._xaxis,f[0][0]),g.call(this._yaxis,f[0][1])],[e.call(this._xaxis,f[1][0]),g.call(this._yaxis,f[1][1]),e.call(this._xaxis,f[2][0]),g.call(this._yaxis,f[2][1]),e.call(this._xaxis,f[3][0]),g.call(this._yaxis,f[3][1])],[e.call(this._xaxis,c[3][0]),g.call(this._yaxis,c[3][1])],[e.call(this._xaxis,c[2][0]),g.call(this._yaxis,c[2][1]),e.call(this._xaxis,c[1][0]),g.call(this._yaxis,c[1][1]),e.call(this._xaxis,c[0][0]),g.call(this._yaxis,c[0][1])]]}}};b.jqplot.BezierCurveRenderer.prototype.makeGridData=function(g,i){var f=this._xaxis.series_u2p;var h=this._yaxis.series_u2p;var e=[];var j=[];var d=this.index;if(g.length==2){if(d==0){e=[[f.call(this._xaxis,g[0][0]),h.call(this._yaxis,g[0][1])],[f.call(this._xaxis,g[1][0]),h.call(this._yaxis,g[1][1]),f.call(this._xaxis,g[1][2]),h.call(this._yaxis,g[1][3]),f.call(this._xaxis,g[1][4]),h.call(this._yaxis,g[1][5])],[f.call(this._xaxis,g[1][4]),h.call(this._yaxis,this._yaxis.min)],[f.call(this._xaxis,g[0][0]),h.call(this._yaxis,this._yaxis.min)]]}else{var c=i.series[d-1].data;e=[[f.call(this._xaxis,g[0][0]),h.call(this._yaxis,g[0][1])],[f.call(this._xaxis,g[1][0]),h.call(this._yaxis,g[1][1]),f.call(this._xaxis,g[1][2]),h.call(this._yaxis,g[1][3]),f.call(this._xaxis,g[1][4]),h.call(this._yaxis,g[1][5])],[f.call(this._xaxis,c[1][4]),h.call(this._yaxis,c[1][5])],[f.call(this._xaxis,c[1][2]),h.call(this._yaxis,c[1][3]),f.call(this._xaxis,c[1][0]),h.call(this._yaxis,c[1][1]),f.call(this._xaxis,c[0][0]),h.call(this._yaxis,c[0][1])]]}}else{if(d==0){e=[[f.call(this._xaxis,g[0][0]),h.call(this._yaxis,g[0][1])],[f.call(this._xaxis,g[1][0]),h.call(this._yaxis,g[1][1]),f.call(this._xaxis,g[2][0]),h.call(this._yaxis,g[2][1]),f.call(this._xaxis,g[3][0]),h.call(this._yaxis,g[3][1])],[f.call(this._xaxis,g[3][1]),h.call(this._yaxis,this._yaxis.min)],[f.call(this._xaxis,g[0][0]),h.call(this._yaxis,this._yaxis.min)]]}else{var c=i.series[d-1].data;e=[[f.call(this._xaxis,g[0][0]),h.call(this._yaxis,g[0][1])],[f.call(this._xaxis,g[1][0]),h.call(this._yaxis,g[1][1]),f.call(this._xaxis,g[2][0]),h.call(this._yaxis,g[2][1]),f.call(this._xaxis,g[3][0]),h.call(this._yaxis,g[3][1])],[f.call(this._xaxis,c[3][0]),h.call(this._yaxis,c[3][1])],[f.call(this._xaxis,c[2][0]),h.call(this._yaxis,c[2][1]),f.call(this._xaxis,c[1][0]),h.call(this._yaxis,c[1][1]),f.call(this._xaxis,c[0][0]),h.call(this._yaxis,c[0][1])]]}}return e};b.jqplot.BezierCurveRenderer.prototype.draw=function(c,g,d){var e;c.save();if(g.length){if(this.showLine){c.save();var f=(d!=null)?d:{};c.fillStyle=f.fillStyle||this.color;c.beginPath();c.moveTo(g[0][0],g[0][1]);c.bezierCurveTo(g[1][0],g[1][1],g[1][2],g[1][3],g[1][4],g[1][5]);c.lineTo(g[2][0],g[2][1]);if(g[3].length==2){c.lineTo(g[3][0],g[3][1])}else{c.bezierCurveTo(g[3][0],g[3][1],g[3][2],g[3][3],g[3][4],g[3][5])}c.closePath();c.fill();c.restore()}}c.restore()};b.jqplot.BezierCurveRenderer.prototype.drawShadow=function(c,e,d){};b.jqplot.BezierAxisRenderer=function(){b.jqplot.LinearAxisRenderer.call(this)};b.jqplot.BezierAxisRenderer.prototype=new b.jqplot.LinearAxisRenderer();b.jqplot.BezierAxisRenderer.prototype.constructor=b.jqplot.BezierAxisRenderer;b.jqplot.BezierAxisRenderer.prototype.init=function(f){b.extend(true,this,f);var c=this._dataBounds;for(var g=0;gc.max||c.max==null){c.max=k[e][0]}}else{if(k[e][1]c.max||c.max==null){c.max=k[e][1]}}}}else{if(this.name=="xaxis"||this.name=="x2axis"){if(k[0][0]c.max||c.max==null){c.max=k[0][0]}for(var e=0;e<5;e+=2){if(k[1][e]c.max||c.max==null){c.max=k[1][e]}}}else{if(k[0][1]c.max||c.max==null){c.max=k[0][1]}for(var e=1;e<6;e+=2){if(k[1][e]c.max||c.max==null){c.max=k[1][e]}}}}}};function a(g,f,d){d=d||{};d.axesDefaults=b.extend(true,{pad:0},d.axesDefaults);d.seriesDefaults=d.seriesDefaults||{};d.legend=b.extend(true,{placement:"outside"},d.legend);var c=false;if(d.seriesDefaults.renderer==b.jqplot.BezierCurveRenderer){c=true}else{if(d.series){for(var e=0;e0){this.data[q][u]+=this.data[q-1][u]}}this.data[this.data.length]=(u==1)?[this.data.length+1,s]:[s,this.data.length+1];this._data[this._data.length]=(u==1)?[this._data.length+1,s]:[s,this._data.length+1]}if(this.rendererOptions.groups>1){this.breakOnNull=true;var n=this.data.length;var v=parseInt(n/this.rendererOptions.groups,10);var r=0;for(var q=v;q570)?n[p]*0.8:n[p]+0.3*(255-n[p]);n[p]=parseInt(n[p],10)}q.push("rgb("+n[0]+","+n[1]+","+n[2]+")")}return q}function i(v,u,s,t,o){var q=v,w=v-1,n,p,r=(o==="x")?0:1;if(q>0){p=t.series[w]._plotData[u][r];if((s*p)<0){n=i(w,u,s,t,o)}else{n=t.series[w].gridData[u][r]}}else{n=(r===0)?t.series[q]._xaxis.series_u2p(0):t.series[q]._yaxis.series_u2p(0)}return n}d.jqplot.BarRenderer.prototype.draw=function(E,L,q,G){var I;var A=d.extend({},q);var w=(A.shadow!=undefined)?A.shadow:this.shadow;var O=(A.showLine!=undefined)?A.showLine:this.showLine;var F=(A.fill!=undefined)?A.fill:this.fill;var p=this.xaxis;var J=this.yaxis;var y=this._xaxis.series_u2p;var K=this._yaxis.series_u2p;var D,C;this._dataColors=[];this._barPoints=[];if(this.barWidth==null){this.renderer.setBarWidth.call(this)}var N=this._plotSeriesInfo=this.renderer.calcSeriesNumbers.call(this);var x=N[0];var v=N[1];var s=N[2];var H=[];if(this._stack){this._barNudge=0}else{this._barNudge=(-Math.abs(v/2-0.5)+s)*(this.barWidth+this.barPadding)}if(O){var u=new d.jqplot.ColorGenerator(this.negativeSeriesColors);var B=new d.jqplot.ColorGenerator(this.seriesColors);var M=u.get(this.index);if(!this.useNegativeColors){M=A.fillStyle}var t=A.fillStyle;var r;var P;var o;if(this.barDirection=="vertical"){for(var I=0;I0&&I=0){o=this._yaxis.series_u2p(0)}else{if(this._yaxis.min>0){o=E.canvas.height}else{o=0}}}else{if(this.waterfall&&I==this.gridData.length-1){if(this._yaxis.min<=0&&this._yaxis.max>=0){o=this._yaxis.series_u2p(0)}else{if(this._yaxis.min>0){o=E.canvas.height}else{o=0}}}else{o=E.canvas.height}}}}}if((this.fillToZero&&this._plotData[I][1]<0)||(this.waterfall&&this._data[I][1]<0)){if(this.varyBarColor&&!this._stack){if(this.useNegativeColors){A.fillStyle=u.next()}else{A.fillStyle=B.next()}}else{A.fillStyle=M}}else{if(this.varyBarColor&&!this._stack){A.fillStyle=B.next()}else{A.fillStyle=t}}if(!this.fillToZero||this._plotData[I][1]>=0){H.push([r-this.barWidth/2,o]);H.push([r-this.barWidth/2,L[I][1]]);H.push([r+this.barWidth/2,L[I][1]]);H.push([r+this.barWidth/2,o])}else{H.push([r-this.barWidth/2,L[I][1]]);H.push([r-this.barWidth/2,o]);H.push([r+this.barWidth/2,o]);H.push([r+this.barWidth/2,L[I][1]])}this._barPoints.push(H);if(w&&!this._stack){var z=d.extend(true,{},A);delete z.fillStyle;this.renderer.shadowRenderer.draw(E,H,z)}var n=A.fillStyle||this.color;this._dataColors.push(n);this.renderer.shapeRenderer.draw(E,H,A)}}else{if(this.barDirection=="horizontal"){for(var I=0;I0&&I=0){P=this._xaxis.series_u2p(0)}else{if(this._xaxis.min>0){P=0}else{P=0}}}else{if(this.waterfall&&I==this.gridData.length-1){if(this._xaxis.min<=0&&this._xaxis.max>=0){P=this._xaxis.series_u2p(0)}else{if(this._xaxis.min>0){P=0}else{P=E.canvas.width}}}else{P=0}}}}}if((this.fillToZero&&this._plotData[I][0]<0)||(this.waterfall&&this._data[I][0]<0)){if(this.varyBarColor&&!this._stack){if(this.useNegativeColors){A.fillStyle=u.next()}else{A.fillStyle=B.next()}}else{A.fillStyle=M}}else{if(this.varyBarColor&&!this._stack){A.fillStyle=B.next()}else{A.fillStyle=t}}if(!this.fillToZero||this._plotData[I][0]>=0){H.push([P,r+this.barWidth/2]);H.push([P,r-this.barWidth/2]);H.push([L[I][0],r-this.barWidth/2]);H.push([L[I][0],r+this.barWidth/2])}else{H.push([L[I][0],r+this.barWidth/2]);H.push([L[I][0],r-this.barWidth/2]);H.push([P,r-this.barWidth/2]);H.push([P,r+this.barWidth/2])}this._barPoints.push(H);if(w&&!this._stack){var z=d.extend(true,{},A);delete z.fillStyle;this.renderer.shadowRenderer.draw(E,H,z)}var n=A.fillStyle||this.color;this._dataColors.push(n);this.renderer.shapeRenderer.draw(E,H,A)}}}}if(this.highlightColors.length==0){this.highlightColors=d.jqplot.computeHighlightColors(this._dataColors)}else{if(typeof(this.highlightColors)=="string"){var N=this.highlightColors;this.highlightColors=[];for(var I=0;I")}k=a.extend(true,{},this.css,k);c=a('
    ');this.canvas._elem.append(c);this.escapeHtml?c.text(p):c.html(p);delete k.position;delete k.marginRight;delete k.marginLeft;if(!k.background&&!k.backgroundColor&&!k.backgroundImage){k.background=j.next()}c.css(k);n=c.outerWidth();g=c.outerHeight();e=o[0]-n/2+"px";m=o[1]-g/2+"px";c.css({left:e,top:m});c=null}};a.jqplot.BlockCanvas=function(){a.jqplot.ElemContainer.call(this);this._ctx};a.jqplot.BlockCanvas.prototype=new a.jqplot.ElemContainer();a.jqplot.BlockCanvas.prototype.constructor=a.jqplot.BlockCanvas;a.jqplot.BlockCanvas.prototype.createElement=function(i,e,c){this._offsets=i;var b="jqplot-blockCanvas";if(e!=undefined){b=e}var g;if(this._elem){g=this._elem.get(0)}else{g=document.createElement("div")}if(c!=undefined){this._plotDimensions=c}var d=this._plotDimensions.width-this._offsets.left-this._offsets.right+"px";var f=this._plotDimensions.height-this._offsets.top-this._offsets.bottom+"px";this._elem=a(g);this._elem.css({position:"absolute",width:d,height:f,left:this._offsets.left,top:this._offsets.top});this._elem.addClass(b);return this._elem};a.jqplot.BlockCanvas.prototype.setContext=function(){this._ctx={canvas:{width:0,height:0},clearRect:function(){return null}};return this._ctx}})(jQuery); \ No newline at end of file diff --git a/templates/admin/default/assets/js/jqplot/plugins/jqplot.bubbleRenderer.min.js b/templates/admin/default/assets/js/jqplot/plugins/jqplot.bubbleRenderer.min.js new file mode 100644 index 000000000..dc0c1ef01 --- /dev/null +++ b/templates/admin/default/assets/js/jqplot/plugins/jqplot.bubbleRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(f){var d=function(m){return Math.max.apply(Math,m)};var j=function(m){return Math.min.apply(Math,m)};f.jqplot.BubbleRenderer=function(){f.jqplot.LineRenderer.call(this)};f.jqplot.BubbleRenderer.prototype=new f.jqplot.LineRenderer();f.jqplot.BubbleRenderer.prototype.constructor=f.jqplot.BubbleRenderer;f.jqplot.BubbleRenderer.prototype.init=function(w,t){this.varyBubbleColors=true;this.autoscaleBubbles=true;this.autoscaleMultiplier=1;this.autoscalePointsFactor=-0.07;this.escapeHtml=true;this.highlightMouseOver=true;this.highlightMouseDown=false;this.highlightColors=[];this.bubbleAlpha=1;this.highlightAlpha=null;this.bubbleGradients=false;this.showLabels=true;this.radii=[];this.maxRadius=0;this._highlightedPoint=null;this.labels=[];this.bubbleCanvases=[];this._type="bubble";if(w.highlightMouseDown&&w.highlightMouseOver==null){w.highlightMouseOver=false}f.extend(true,this,w);if(this.highlightAlpha==null){this.highlightAlpha=this.bubbleAlpha;if(this.bubbleGradients){this.highlightAlpha=0.35}}this.autoscaleMultiplier=this.autoscaleMultiplier*Math.pow(this.data.length,this.autoscalePointsFactor);this._highlightedPoint=null;var n;for(var r=0;r570)?u[q]*0.8:u[q]+0.3*(255-u[q]);u[q]=parseInt(u[q],10)}this.highlightColors.push("rgba("+u[0]+","+u[1]+","+u[2]+", "+this.highlightAlpha+")")}}this.highlightColorGenerator=new f.jqplot.ColorGenerator(this.highlightColors);var m={fill:true,isarc:true,angle:this.shadowAngle,alpha:this.shadowAlpha,closePath:true};this.renderer.shadowRenderer.init(m);this.canvas=new f.jqplot.DivCanvas();this.canvas._plotDimensions=this._plotDimensions;t.eventListenerHooks.addOnce("jqplotMouseMove",a);t.eventListenerHooks.addOnce("jqplotMouseDown",b);t.eventListenerHooks.addOnce("jqplotMouseUp",k);t.eventListenerHooks.addOnce("jqplotClick",g);t.eventListenerHooks.addOnce("jqplotRightClick",l);t.postDrawHooks.addOnce(h)};f.jqplot.BubbleRenderer.prototype.setGridData=function(w){var q=this._xaxis.series_u2p;var m=this._yaxis.series_u2p;var t=this._plotData;this.gridData=[];var s=[];this.radii=[];var v=Math.min(w._height,w._width);for(var u=0;u');if(this.escapeHtml){p.text(z)}else{p.html(z)}this.canvas._elem.append(p);var H=f(p).outerHeight();var v=f(p).outerWidth();var B=J[1]-0.5*H;var o=J[0]-0.5*v;p.css({top:B,left:o});this.labels[C]=f(p)}}};f.jqplot.DivCanvas=function(){f.jqplot.ElemContainer.call(this);this._ctx};f.jqplot.DivCanvas.prototype=new f.jqplot.ElemContainer();f.jqplot.DivCanvas.prototype.constructor=f.jqplot.DivCanvas;f.jqplot.DivCanvas.prototype.createElement=function(s,p,n){this._offsets=s;var m="jqplot-DivCanvas";if(p!=undefined){m=p}var r;if(this._elem){r=this._elem.get(0)}else{r=document.createElement("div")}if(n!=undefined){this._plotDimensions=n}var o=this._plotDimensions.width-this._offsets.left-this._offsets.right+"px";var q=this._plotDimensions.height-this._offsets.top-this._offsets.bottom+"px";this._elem=f(r);this._elem.css({position:"absolute",width:o,height:q,left:this._offsets.left,top:this._offsets.top});this._elem.addClass(m);return this._elem};f.jqplot.DivCanvas.prototype.setContext=function(){this._ctx={canvas:{width:0,height:0},clearRect:function(){return null}};return this._ctx};f.jqplot.BubbleCanvas=function(){f.jqplot.ElemContainer.call(this);this._ctx};f.jqplot.BubbleCanvas.prototype=new f.jqplot.ElemContainer();f.jqplot.BubbleCanvas.prototype.constructor=f.jqplot.BubbleCanvas;f.jqplot.BubbleCanvas.prototype.createElement=function(n,u,s){var m="jqplot-bubble-point";var q;if(this._elem){q=this._elem.get(0)}else{q=document.createElement("canvas")}q.width=(s!=null)?2*s:q.width;q.height=(s!=null)?2*s:q.height;this._elem=f(q);var o=(n!=null&&s!=null)?n-s:this._elem.css("left");var p=(u!=null&&s!=null)?u-s:this._elem.css("top");this._elem.css({position:"absolute",left:o,top:p});this._elem.addClass(m);if(f.jqplot.use_excanvas){window.G_vmlCanvasManager.init_(document);q=window.G_vmlCanvasManager.initElement(q)}return this._elem};f.jqplot.BubbleCanvas.prototype.draw=function(m,s,v,p){var D=this._ctx;var B=D.canvas.width/2;var z=D.canvas.height/2;D.save();if(v&&!f.jqplot.use_excanvas){m=m*1.04;var o=f.jqplot.getColorComponents(s);var u="rgba("+Math.round(o[0]+0.8*(255-o[0]))+", "+Math.round(o[1]+0.8*(255-o[1]))+", "+Math.round(o[2]+0.8*(255-o[2]))+", "+o[3]+")";var t="rgba("+o[0]+", "+o[1]+", "+o[2]+", 0)";var C=0.35*m;var A=B-Math.cos(p)*0.33*m;var n=z-Math.sin(p)*0.33*m;var w=D.createRadialGradient(A,n,C,B,z,m);w.addColorStop(0,u);w.addColorStop(0.93,s);w.addColorStop(0.96,t);w.addColorStop(1,t);D.fillStyle=w;D.fillRect(0,0,D.canvas.width,D.canvas.height)}else{D.fillStyle=s;D.strokeStyle=s;D.lineWidth=1;D.beginPath();var q=2*Math.PI;D.arc(B,z,m,0,q,0);D.closePath();D.fill()}D.restore()};f.jqplot.BubbleCanvas.prototype.setContext=function(){this._ctx=this._elem.get(0).getContext("2d");return this._ctx};f.jqplot.BubbleAxisRenderer=function(){f.jqplot.LinearAxisRenderer.call(this)};f.jqplot.BubbleAxisRenderer.prototype=new f.jqplot.LinearAxisRenderer();f.jqplot.BubbleAxisRenderer.prototype.constructor=f.jqplot.BubbleAxisRenderer;f.jqplot.BubbleAxisRenderer.prototype.init=function(n){f.extend(true,this,n);var I=this._dataBounds;var H=0,v=0,m=0,y=0,q=0,r=0,D=0,t=0,F=0,z=0;for(var E=0;EI.max||I.max==null){I.max=G[B][0];m=E;y=B;q=G[B][2];t=x.maxRadius;F=x.autoscaleMultiplier}}else{if(G[B][1]I.max||I.max==null){I.max=G[B][1];m=E;y=B;q=G[B][2];t=x.maxRadius;F=x.autoscaleMultiplier}}}}var o=r/D;var w=q/t;var C=I.max-I.min;var A=Math.min(this._plotDimensions.width,this._plotDimensions.height);var p=o*z/3*C;var u=w*F/3*C;I.max+=u;I.min-=p};function e(p,v,q){p.plugins.bubbleRenderer.highlightLabelCanvas.empty();var z=p.series[v];var n=p.plugins.bubbleRenderer.highlightCanvas;var w=n._ctx;w.clearRect(0,0,w.canvas.width,w.canvas.height);z._highlightedPoint=q;p.plugins.bubbleRenderer.highlightedSeriesIndex=v;var o=z.highlightColorGenerator.get(q);var u=z.gridData[q][0],t=z.gridData[q][1],m=z.gridData[q][2];w.save();w.fillStyle=o;w.strokeStyle=o;w.lineWidth=1;w.beginPath();w.arc(u,t,m,0,2*Math.PI,0);w.closePath();w.fill();w.restore();if(z.labels[q]){p.plugins.bubbleRenderer.highlightLabel=z.labels[q].clone();p.plugins.bubbleRenderer.highlightLabel.appendTo(p.plugins.bubbleRenderer.highlightLabelCanvas);p.plugins.bubbleRenderer.highlightLabel.addClass("jqplot-bubble-label-highlight")}}function i(p){var m=p.plugins.bubbleRenderer.highlightCanvas;var o=p.plugins.bubbleRenderer.highlightedSeriesIndex;p.plugins.bubbleRenderer.highlightLabelCanvas.empty();m._ctx.clearRect(0,0,m._ctx.canvas.width,m._ctx.canvas.height);for(var n=0;n');var q=this._gridPadding.top;var p=this._gridPadding.left;var n=this._plotDimensions.width-this._gridPadding.left-this._gridPadding.right;var m=this._plotDimensions.height-this._gridPadding.top-this._gridPadding.bottom;this.plugins.bubbleRenderer.highlightLabelCanvas.css({top:q,left:p,width:n+"px",height:m+"px"});this.eventCanvas._elem.before(this.plugins.bubbleRenderer.highlightCanvas.createElement(this._gridPadding,"jqplot-bubbleRenderer-highlight-canvas",this._plotDimensions,this));this.eventCanvas._elem.before(this.plugins.bubbleRenderer.highlightLabelCanvas);var o=this.plugins.bubbleRenderer.highlightCanvas.setContext()}function c(q,p,n){n=n||{};n.axesDefaults=n.axesDefaults||{};n.seriesDefaults=n.seriesDefaults||{};var m=false;if(n.seriesDefaults.renderer==f.jqplot.BubbleRenderer){m=true}else{if(n.series){for(var o=0;ot){y=w;w=t;t=y}if(v>s){y=v;v=s;s=y}var u=(o>=w&&o<=t&&n>=v&&n<=s);return u}function a(z,w,r,A,x){var y=x.plugins.canvasOverlay;var v=y.objects;var s=v.length;var u,o=false;var q;for(var t=0;t-1){return c/this.pt2px}else{if(b.indexOf("pt")>-1){return c}else{if(b.indexOf("em")>-1){return c*12}else{if(b.indexOf("%")>-1){return c*12/100}else{return c/this.pt2px}}}}};a.jqplot.CanvasTextRenderer.prototype.fontWeight2Float=function(b){if(Number(b)){return b/400}else{switch(b){case"normal":return 1;break;case"bold":return 1.75;break;case"bolder":return 2.25;break;case"lighter":return 0.75;break;default:return 1;break}}};a.jqplot.CanvasTextRenderer.prototype.getText=function(){return this.text};a.jqplot.CanvasTextRenderer.prototype.setText=function(c,b){this.text=c;this.setWidth(b);return this};a.jqplot.CanvasTextRenderer.prototype.getWidth=function(b){return this.width};a.jqplot.CanvasTextRenderer.prototype.setWidth=function(c,b){if(!b){this.width=this.measure(c,this.text)}else{this.width=b}return this};a.jqplot.CanvasTextRenderer.prototype.getHeight=function(b){return this.height};a.jqplot.CanvasTextRenderer.prototype.setHeight=function(b){if(!b){this.height=this.normalizedFontSize*this.pt2px}else{this.height=b}return this};a.jqplot.CanvasTextRenderer.prototype.letter=function(b){return this.letters[b]};a.jqplot.CanvasTextRenderer.prototype.ascent=function(){return this.normalizedFontSize};a.jqplot.CanvasTextRenderer.prototype.descent=function(){return 7*this.normalizedFontSize/25};a.jqplot.CanvasTextRenderer.prototype.measure=function(d,g){var f=0;var b=g.length;for(var e=0;e30)?2:2+(30-this.normalizedFontSize)/20;s.lineWidth=t*k*this.fontWeight2Float(this.fontWeight);for(var g=0;g":{width:24,points:[[4,18],[20,9],[4,0]]},"?":{width:18,points:[[3,16],[3,17],[4,19],[5,20],[7,21],[11,21],[13,20],[14,19],[15,17],[15,15],[14,13],[13,12],[9,10],[9,7],[-1,-1],[9,2],[8,1],[9,0],[10,1],[9,2]]},"@":{width:27,points:[[18,13],[17,15],[15,16],[12,16],[10,15],[9,14],[8,11],[8,8],[9,6],[11,5],[14,5],[16,6],[17,8],[-1,-1],[12,16],[10,14],[9,11],[9,8],[10,6],[11,5],[-1,-1],[18,16],[17,8],[17,6],[19,5],[21,5],[23,7],[24,10],[24,12],[23,15],[22,17],[20,19],[18,20],[15,21],[12,21],[9,20],[7,19],[5,17],[4,15],[3,12],[3,9],[4,6],[5,4],[7,2],[9,1],[12,0],[15,0],[18,1],[20,2],[21,3],[-1,-1],[19,16],[18,8],[18,6],[19,5]]},A:{width:18,points:[[9,21],[1,0],[-1,-1],[9,21],[17,0],[-1,-1],[4,7],[14,7]]},B:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[-1,-1],[4,11],[13,11],[16,10],[17,9],[18,7],[18,4],[17,2],[16,1],[13,0],[4,0]]},C:{width:21,points:[[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5]]},D:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[11,21],[14,20],[16,18],[17,16],[18,13],[18,8],[17,5],[16,3],[14,1],[11,0],[4,0]]},E:{width:19,points:[[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11],[-1,-1],[4,0],[17,0]]},F:{width:18,points:[[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11]]},G:{width:21,points:[[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[18,8],[-1,-1],[13,8],[18,8]]},H:{width:22,points:[[4,21],[4,0],[-1,-1],[18,21],[18,0],[-1,-1],[4,11],[18,11]]},I:{width:8,points:[[4,21],[4,0]]},J:{width:16,points:[[12,21],[12,5],[11,2],[10,1],[8,0],[6,0],[4,1],[3,2],[2,5],[2,7]]},K:{width:21,points:[[4,21],[4,0],[-1,-1],[18,21],[4,7],[-1,-1],[9,12],[18,0]]},L:{width:17,points:[[4,21],[4,0],[-1,-1],[4,0],[16,0]]},M:{width:24,points:[[4,21],[4,0],[-1,-1],[4,21],[12,0],[-1,-1],[20,21],[12,0],[-1,-1],[20,21],[20,0]]},N:{width:22,points:[[4,21],[4,0],[-1,-1],[4,21],[18,0],[-1,-1],[18,21],[18,0]]},O:{width:22,points:[[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21]]},P:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,14],[17,12],[16,11],[13,10],[4,10]]},Q:{width:22,points:[[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21],[-1,-1],[12,4],[18,-2]]},R:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[4,11],[-1,-1],[11,11],[18,0]]},S:{width:20,points:[[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]]},T:{width:16,points:[[8,21],[8,0],[-1,-1],[1,21],[15,21]]},U:{width:22,points:[[4,21],[4,6],[5,3],[7,1],[10,0],[12,0],[15,1],[17,3],[18,6],[18,21]]},V:{width:18,points:[[1,21],[9,0],[-1,-1],[17,21],[9,0]]},W:{width:24,points:[[2,21],[7,0],[-1,-1],[12,21],[7,0],[-1,-1],[12,21],[17,0],[-1,-1],[22,21],[17,0]]},X:{width:20,points:[[3,21],[17,0],[-1,-1],[17,21],[3,0]]},Y:{width:18,points:[[1,21],[9,11],[9,0],[-1,-1],[17,21],[9,11]]},Z:{width:20,points:[[17,21],[3,0],[-1,-1],[3,21],[17,21],[-1,-1],[3,0],[17,0]]},"[":{width:14,points:[[4,25],[4,-7],[-1,-1],[5,25],[5,-7],[-1,-1],[4,25],[11,25],[-1,-1],[4,-7],[11,-7]]},"\\":{width:14,points:[[0,21],[14,-3]]},"]":{width:14,points:[[9,25],[9,-7],[-1,-1],[10,25],[10,-7],[-1,-1],[3,25],[10,25],[-1,-1],[3,-7],[10,-7]]},"^":{width:16,points:[[6,15],[8,18],[10,15],[-1,-1],[3,12],[8,17],[13,12],[-1,-1],[8,17],[8,0]]},_:{width:16,points:[[0,-2],[16,-2]]},"`":{width:10,points:[[6,21],[5,20],[4,18],[4,16],[5,15],[6,16],[5,17]]},a:{width:19,points:[[15,14],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},b:{width:19,points:[[4,21],[4,0],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]]},c:{width:18,points:[[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},d:{width:19,points:[[15,21],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},e:{width:18,points:[[3,8],[15,8],[15,10],[14,12],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},f:{width:12,points:[[10,21],[8,21],[6,20],[5,17],[5,0],[-1,-1],[2,14],[9,14]]},g:{width:19,points:[[15,14],[15,-2],[14,-5],[13,-6],[11,-7],[8,-7],[6,-6],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},h:{width:19,points:[[4,21],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]]},i:{width:8,points:[[3,21],[4,20],[5,21],[4,22],[3,21],[-1,-1],[4,14],[4,0]]},j:{width:10,points:[[5,21],[6,20],[7,21],[6,22],[5,21],[-1,-1],[6,14],[6,-3],[5,-6],[3,-7],[1,-7]]},k:{width:17,points:[[4,21],[4,0],[-1,-1],[14,14],[4,4],[-1,-1],[8,8],[15,0]]},l:{width:8,points:[[4,21],[4,0]]},m:{width:30,points:[[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0],[-1,-1],[15,10],[18,13],[20,14],[23,14],[25,13],[26,10],[26,0]]},n:{width:19,points:[[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]]},o:{width:19,points:[[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3],[16,6],[16,8],[15,11],[13,13],[11,14],[8,14]]},p:{width:19,points:[[4,14],[4,-7],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]]},q:{width:19,points:[[15,14],[15,-7],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},r:{width:13,points:[[4,14],[4,0],[-1,-1],[4,8],[5,11],[7,13],[9,14],[12,14]]},s:{width:17,points:[[14,11],[13,13],[10,14],[7,14],[4,13],[3,11],[4,9],[6,8],[11,7],[13,6],[14,4],[14,3],[13,1],[10,0],[7,0],[4,1],[3,3]]},t:{width:12,points:[[5,21],[5,4],[6,1],[8,0],[10,0],[-1,-1],[2,14],[9,14]]},u:{width:19,points:[[4,14],[4,4],[5,1],[7,0],[10,0],[12,1],[15,4],[-1,-1],[15,14],[15,0]]},v:{width:16,points:[[2,14],[8,0],[-1,-1],[14,14],[8,0]]},w:{width:22,points:[[3,14],[7,0],[-1,-1],[11,14],[7,0],[-1,-1],[11,14],[15,0],[-1,-1],[19,14],[15,0]]},x:{width:17,points:[[3,14],[14,0],[-1,-1],[14,14],[3,0]]},y:{width:16,points:[[2,14],[8,0],[-1,-1],[14,14],[8,0],[6,-4],[4,-6],[2,-7],[1,-7]]},z:{width:17,points:[[14,14],[3,0],[-1,-1],[3,14],[14,14],[-1,-1],[3,0],[14,0]]},"{":{width:14,points:[[9,25],[7,24],[6,23],[5,21],[5,19],[6,17],[7,16],[8,14],[8,12],[6,10],[-1,-1],[7,24],[6,22],[6,20],[7,18],[8,17],[9,15],[9,13],[8,11],[4,9],[8,7],[9,5],[9,3],[8,1],[7,0],[6,-2],[6,-4],[7,-6],[-1,-1],[6,8],[8,6],[8,4],[7,2],[6,1],[5,-1],[5,-3],[6,-5],[7,-6],[9,-7]]},"|":{width:8,points:[[4,25],[4,-7]]},"}":{width:14,points:[[5,25],[7,24],[8,23],[9,21],[9,19],[8,17],[7,16],[6,14],[6,12],[8,10],[-1,-1],[7,24],[8,22],[8,20],[7,18],[6,17],[5,15],[5,13],[6,11],[10,9],[6,7],[5,5],[5,3],[6,1],[7,0],[8,-2],[8,-4],[7,-6],[-1,-1],[8,8],[6,6],[6,4],[7,2],[8,1],[9,-1],[9,-3],[8,-5],[7,-6],[5,-7]]},"~":{width:24,points:[[3,6],[3,8],[4,11],[6,12],[8,12],[10,11],[14,8],[16,7],[18,7],[20,8],[21,10],[-1,-1],[3,8],[4,10],[6,11],[8,11],[10,10],[14,7],[16,6],[18,6],[20,7],[21,10],[21,12]]}};a.jqplot.CanvasFontRenderer=function(b){b=b||{};if(!b.pt2px){b.pt2px=1.5}a.jqplot.CanvasTextRenderer.call(this,b)};a.jqplot.CanvasFontRenderer.prototype=new a.jqplot.CanvasTextRenderer({});a.jqplot.CanvasFontRenderer.prototype.constructor=a.jqplot.CanvasFontRenderer;a.jqplot.CanvasFontRenderer.prototype.measure=function(c,e){var d=this.fontSize+" "+this.fontFamily;c.save();c.font=d;var b=c.measureText(e).width;c.restore();return b};a.jqplot.CanvasFontRenderer.prototype.draw=function(e,g){var c=0;var h=this.height*0.72;e.save();var d,b;if((-Math.PI/2<=this.angle&&this.angle<=0)||(Math.PI*3/2<=this.angle&&this.angle<=Math.PI*2)){d=0;b=-Math.sin(this.angle)*this.width}else{if((0b.max||b.max==null){b.max=h[c][0]}}else{if(h[c][1]b.max||b.max==null){b.max=h[c][1]}}}}if(this.groupLabels.length){this.groups=this.groupLabels.length}};a.jqplot.CategoryAxisRenderer.prototype.createTicks=function(){var D=this._ticks;var z=this.ticks;var F=this.name;var C=this._dataBounds;var v,A;var q,w;var d,c;var b,x;if(z.length){if(this.groups>1&&!this._grouped){var r=z.length;var p=parseInt(r/this.groups,10);var e=0;for(var x=p;x1&&!this._grouped){var r=y.length;var p=parseInt(r/this.groups,10);var e=0;for(var x=p;x0&&o');if(this.name=="xaxis"||this.name=="x2axis"){this._elem.width(this._plotDimensions.width)}else{this._elem.height(this._plotDimensions.height)}this.labelOptions.axis=this.name;this._label=new this.labelRenderer(this.labelOptions);if(this._label.show){var g=this._label.draw(b,j);g.appendTo(this._elem)}var f=this._ticks;for(var e=0;e');g.html(this.groupLabels[e]);this._groupLabels.push(g);g.appendTo(this._elem)}}return this._elem};a.jqplot.CategoryAxisRenderer.prototype.set=function(){var e=0;var m;var k=0;var f=0;var d=(this._label==null)?false:this._label.show;if(this.show){var n=this._ticks;for(var c=0;ce){e=m}}}var j=0;for(var c=0;cj){j=m}}if(d){k=this._label._elem.outerWidth(true);f=this._label._elem.outerHeight(true)}if(this.name=="xaxis"){e+=j+f;this._elem.css({height:e+"px",left:"0px",bottom:"0px"})}else{if(this.name=="x2axis"){e+=j+f;this._elem.css({height:e+"px",left:"0px",top:"0px"})}else{if(this.name=="yaxis"){e+=j+k;this._elem.css({width:e+"px",left:"0px",top:"0px"});if(d&&this._label.constructor==a.jqplot.AxisLabelRenderer){this._label._elem.css("width",k+"px")}}else{e+=j+k;this._elem.css({width:e+"px",right:"0px",top:"0px"});if(d&&this._label.constructor==a.jqplot.AxisLabelRenderer){this._label._elem.css("width",k+"px")}}}}}};a.jqplot.CategoryAxisRenderer.prototype.pack=function(e,c){var C=this._ticks;var v=this.max;var s=this.min;var n=c.max;var l=c.min;var q=(this._label==null)?false:this._label.show;var x;for(var r in e){this._elem.css(r,e[r])}this._offsets=c;var g=n-l;var k=v-s;if(!this.reverse){this.u2p=function(h){return(h-s)*g/k+l};this.p2u=function(h){return(h-l)*k/g+s};if(this.name=="xaxis"||this.name=="x2axis"){this.series_u2p=function(h){return(h-s)*g/k};this.series_p2u=function(h){return h*k/g+s}}else{this.series_u2p=function(h){return(h-v)*g/k};this.series_p2u=function(h){return h*k/g+v}}}else{this.u2p=function(h){return l+(v-h)*g/k};this.p2u=function(h){return s+(h-l)*k/g};if(this.name=="xaxis"||this.name=="x2axis"){this.series_u2p=function(h){return(v-h)*g/k};this.series_p2u=function(h){return h*k/g+v}}else{this.series_u2p=function(h){return(s-h)*g/k};this.series_p2u=function(h){return h*k/g+s}}}if(this.show){if(this.name=="xaxis"||this.name=="x2axis"){for(x=0;x=this._ticks.length-1){continue}if(this._ticks[u]._elem&&this._ticks[u].label!=" "){var o=this._ticks[u]._elem;var r=o.position();B+=r.left+o.outerWidth(true)/2;f++}}B=B/f;this._groupLabels[x].css({left:(B-this._groupLabels[x].outerWidth(true)/2)});this._groupLabels[x].css(z[0],z[1])}}else{for(x=0;x0){b=-o._textRenderer.height*Math.cos(-o._textRenderer.angle)/2}else{b=-o.getHeight()+o._textRenderer.height*Math.cos(o._textRenderer.angle)/2}break;case"middle":b=-o.getHeight()/2;break;default:b=-o.getHeight()/2;break}}else{b=-o.getHeight()/2}var D=this.u2p(o.value)+b+"px";o._elem.css("top",D);o.pack()}}var z=["left",0];if(q){var y=this._label._elem.outerHeight(true);this._label._elem.css("top",n-g/2-y/2+"px");if(this.name=="yaxis"){this._label._elem.css("left","0px");z=["left",this._label._elem.outerWidth(true)]}else{this._label._elem.css("right","0px");z=["right",this._label._elem.outerWidth(true)]}this._label.pack()}var d=parseInt(this._ticks.length/this.groups,10)+1;for(x=0;x=this._ticks.length-1){continue}if(this._ticks[u]._elem&&this._ticks[u].label!=" "){var o=this._ticks[u]._elem;var r=o.position();B+=r.top+o.outerHeight()/2;f++}}B=B/f;this._groupLabels[x].css({top:B-this._groupLabels[x].outerHeight()/2});this._groupLabels[x].css(z[0],z[1])}}}}})(jQuery); \ No newline at end of file diff --git a/templates/admin/default/assets/js/jqplot/plugins/jqplot.ciParser.min.js b/templates/admin/default/assets/js/jqplot/plugins/jqplot.ciParser.min.js new file mode 100644 index 000000000..08f46c851 --- /dev/null +++ b/templates/admin/default/assets/js/jqplot/plugins/jqplot.ciParser.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(a){a.jqplot.ciParser=function(g,l){var m=[],o,n,h,f,e,c;if(typeof(g)=="string"){g=a.jqplot.JSON.parse(g,d)}else{if(typeof(g)=="object"){for(e in g){for(h=0;h=0){i=/^\/Date\((-?[0-9]+)\)\/$/.exec(k);if(i){return parseInt(i[1],10)}}return k}}for(var b in g){o=[];n=g[b];switch(b){case"PriceTicks":for(h=0;h6&&Math.abs(G.y-I._zoom.start[1])>6)||(I.constrainZoomTo=="x"&&Math.abs(G.x-I._zoom.start[0])>6)||(I.constrainZoomTo=="y"&&Math.abs(G.y-I._zoom.start[1])>6)){if(!C.plugins.cursor.zoomProxy){for(var y in t){if(I._zoom.axes[y]==undefined){I._zoom.axes[y]={};I._zoom.axes[y].numberTicks=F[y].numberTicks;I._zoom.axes[y].tickInterval=F[y].tickInterval;I._zoom.axes[y].daTickInterval=F[y].daTickInterval;I._zoom.axes[y].min=F[y].min;I._zoom.axes[y].max=F[y].max;I._zoom.axes[y].tickFormatString=(F[y].tickOptions!=null)?F[y].tickOptions.formatString:""}if((I.constrainZoomTo=="none")||(I.constrainZoomTo=="x"&&y.charAt(0)=="x")||(I.constrainZoomTo=="y"&&y.charAt(0)=="y")){z=t[y];if(z!=null){if(z>w[y]){v=w[y];x=z}else{D=w[y]-z;v=z;x=w[y]}q=F[y];H=null;if(q.alignTicks){if(q.name==="x2axis"&&C.axes.xaxis.show){H=C.axes.xaxis.numberTicks}else{if(q.name.charAt(0)==="y"&&q.name!=="yaxis"&&q.name!=="yMidAxis"&&C.axes.yaxis.show){H=C.axes.yaxis.numberTicks}}}if(this.looseZoom&&(F[y].renderer.constructor===j.jqplot.LinearAxisRenderer||F[y].renderer.constructor===j.jqplot.LogAxisRenderer)){J=j.jqplot.LinearTickGenerator(v,x,q._scalefact,H);if(F[y].tickInset&&J[0]F[y].max-F[y].tickInset*F[y].tickInterval){J[1]-=J[4];J[2]-=1}if(F[y].renderer.constructor===j.jqplot.LogAxisRenderer&&J[0]"}if(J.useAxesFormatters){for(var D=0;D"}w+=j.jqplot.sprintf(J.tooltipFormatString,t,z,x);N=true}}}}J._tooltipElem.html(w)}function g(C,A){var E=A.plugins.cursor;var z=E.cursorCanvas._ctx;z.clearRect(0,0,z.canvas.width,z.canvas.height);if(E.showVerticalLine){E.shapeRenderer.draw(z,[[C.x,0],[C.x,z.canvas.height]])}if(E.showHorizontalLine){E.shapeRenderer.draw(z,[[0,C.y],[z.canvas.width,C.y]])}var G=d(A,C.x,C.y);if(E.showCursorLegend){var r=j(A.targetId+" td.jqplot-cursor-legend-label");for(var B=0;B0;r--){s=v[r-1];if(q[s].show){u[s]=q[s].series_p2u(w[s.charAt(0)])}}return{offsets:t,gridPos:w,dataPos:u}}function h(z){var x=z.data.plot;var y=x.plugins.cursor;if(y.show&&y.zoom&&y._zoom.started&&!y.zoomTarget){z.preventDefault();var B=y.zoomCanvas._ctx;var v=o(z);var w=v.gridPos;var t=v.dataPos;y._zoom.gridpos=w;y._zoom.datapos=t;y._zoom.zooming=true;var u=w.x;var s=w.y;var A=B.canvas.height;var q=B.canvas.width;if(y.showTooltip&&!y.onGrid&&y.showTooltipOutsideZoom){e(w,t,x);if(y.followMouse){n(w,x)}}if(y.constrainZoomTo=="x"){y._zoom.end=[u,A]}else{if(y.constrainZoomTo=="y"){y._zoom.end=[q,s]}else{y._zoom.end=[u,s]}}var r=window.getSelection;if(document.selection&&document.selection.empty){document.selection.empty()}else{if(r&&!r().isCollapsed){r().collapse()}}l.call(y);B=null}}function a(w,s,r,x,t){var v=t.plugins.cursor;if(t.plugins.mobile){j(document).one("vmouseup.jqplot_cursor",{plot:t},p)}else{j(document).one("mouseup.jqplot_cursor",{plot:t},p)}var u=t.axes;if(document.onselectstart!=undefined){v._oldHandlers.onselectstart=document.onselectstart;document.onselectstart=function(){return false}}if(document.ondrag!=undefined){v._oldHandlers.ondrag=document.ondrag;document.ondrag=function(){return false}}if(document.onmousedown!=undefined){v._oldHandlers.onmousedown=document.onmousedown;document.onmousedown=function(){return false}}if(v.zoom){if(!v.zoomProxy){var y=v.zoomCanvas._ctx;y.clearRect(0,0,y.canvas.width,y.canvas.height);y=null}if(v.constrainZoomTo=="x"){v._zoom.start=[s.x,0]}else{if(v.constrainZoomTo=="y"){v._zoom.start=[0,s.y]}else{v._zoom.start=[s.x,s.y]}}v._zoom.started=true;for(var q in r){v._zoom.axes.start[q]=r[q]}if(t.plugins.mobile){j(document).bind("vmousemove.jqplotCursor",{plot:t},h)}else{j(document).bind("mousemove.jqplotCursor",{plot:t},h)}}}function p(y){var v=y.data.plot;var x=v.plugins.cursor;if(x.zoom&&x._zoom.zooming&&!x.zoomTarget){var u=x._zoom.gridpos.x;var r=x._zoom.gridpos.y;var t=x._zoom.datapos;var z=x.zoomCanvas._ctx.canvas.height;var q=x.zoomCanvas._ctx.canvas.width;var w=v.axes;if(x.constrainOutsideZoom&&!x.onGrid){if(u<0){u=0}else{if(u>q){u=q}}if(r<0){r=0}else{if(r>z){r=z}}for(var s in t){if(t[s]){if(s.charAt(0)=="x"){t[s]=w[s].series_p2u(u)}else{t[s]=w[s].series_p2u(r)}}}}if(x.constrainZoomTo=="x"){r=z}else{if(x.constrainZoomTo=="y"){u=q}}x._zoom.end=[u,r];x._zoom.gridpos={x:u,y:r};x.doZoom(x._zoom.gridpos,t,v,x)}x._zoom.started=false;x._zoom.zooming=false;j(document).unbind("mousemove.jqplotCursor",h);if(document.onselectstart!=undefined&&x._oldHandlers.onselectstart!=null){document.onselectstart=x._oldHandlers.onselectstart;x._oldHandlers.onselectstart=null}if(document.ondrag!=undefined&&x._oldHandlers.ondrag!=null){document.ondrag=x._oldHandlers.ondrag;x._oldHandlers.ondrag=null}if(document.onmousedown!=undefined&&x._oldHandlers.onmousedown!=null){document.onmousedown=x._oldHandlers.onmousedown;x._oldHandlers.onmousedown=null}}function l(){var y=this._zoom.start;var u=this._zoom.end;var s=this.zoomCanvas._ctx;var r,v,x,q;if(u[0]>y[0]){r=y[0];q=u[0]-y[0]}else{r=u[0];q=y[0]-u[0]}if(u[1]>y[1]){v=y[1];x=u[1]-y[1]}else{v=u[1];x=y[1]-u[1]}s.fillStyle="rgba(0,0,0,0.2)";s.strokeStyle="#999999";s.lineWidth=1;s.clearRect(0,0,s.canvas.width,s.canvas.height);s.fillRect(0,0,s.canvas.width,s.canvas.height);s.clearRect(r,v,q,x);s.strokeRect(r,v,q,x);s=null}j.jqplot.CursorLegendRenderer=function(q){j.jqplot.TableLegendRenderer.call(this,q);this.formatString="%s"};j.jqplot.CursorLegendRenderer.prototype=new j.jqplot.TableLegendRenderer();j.jqplot.CursorLegendRenderer.prototype.constructor=j.jqplot.CursorLegendRenderer;j.jqplot.CursorLegendRenderer.prototype.draw=function(){if(this._elem){this._elem.emptyForce();this._elem=null}if(this.show){var w=this._series,A;var r=document.createElement("table");this._elem=j(r);r=null;this._elem.addClass("jqplot-legend jqplot-cursor-legend");this._elem.css("position","absolute");var q=false;for(var x=0;x').appendTo(this._elem);E.data("seriesIndex",s);j('
    ').appendTo(E);var G=j('');G.appendTo(E);G.data("seriesIndex",s);if(this.escapeHtml){G.text(D)}else{G.html(D)}E=null;G=null}return this._elem}})(jQuery); \ No newline at end of file diff --git a/templates/admin/default/assets/js/jqplot/plugins/jqplot.dateAxisRenderer.min.js b/templates/admin/default/assets/js/jqplot/plugins/jqplot.dateAxisRenderer.min.js new file mode 100644 index 000000000..741780150 --- /dev/null +++ b/templates/admin/default/assets/js/jqplot/plugins/jqplot.dateAxisRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(h){h.jqplot.DateAxisRenderer=function(){h.jqplot.LinearAxisRenderer.call(this);this.date=new h.jsDate()};var c=1000;var e=60*c;var f=60*e;var l=24*f;var b=7*l;var j=30.4368499*l;var k=365.242199*l;var g=[31,28,31,30,31,30,31,30,31,30,31,30];var i=["%M:%S.%#N","%M:%S.%#N","%M:%S.%#N","%M:%S","%M:%S","%M:%S","%M:%S","%H:%M:%S","%H:%M:%S","%H:%M","%H:%M","%H:%M","%H:%M","%H:%M","%H:%M","%a %H:%M","%a %H:%M","%b %e %H:%M","%b %e %H:%M","%b %e %H:%M","%b %e %H:%M","%v","%v","%v","%v","%v","%v","%v"];var m=[0.1*c,0.2*c,0.5*c,c,2*c,5*c,10*c,15*c,30*c,e,2*e,5*e,10*e,15*e,30*e,f,2*f,4*f,6*f,8*f,12*f,l,2*l,3*l,4*l,5*l,b,2*b];var d=[];function a(p,s,t){var o=Number.MAX_VALUE;var u,r,v;for(var q=0,n=m.length;qC.max)||C.max==null){C.max=y[r][0]}if(r>0){o=Math.abs(y[r][0]-y[r-1][0]);u.intervals.push(o);if(u.frequencies.hasOwnProperty(o)){u.frequencies[o]+=1}else{u.frequencies[o]=1}}x+=o}else{y[r][1]=new h.jsDate(y[r][1]).getTime();A[r][1]=new h.jsDate(y[r][1]).getTime();z[r][1]=new h.jsDate(y[r][1]).getTime();if((y[r][1]!=null&&y[r][1]C.max)||C.max==null){C.max=y[r][1]}if(r>0){o=Math.abs(y[r][1]-y[r-1][1]);u.intervals.push(o);if(u.frequencies.hasOwnProperty(o)){u.frequencies[o]+=1}else{u.frequencies[o]=1}}}x+=o}if(D.renderer.bands){if(D.renderer.bands.hiData.length){var w=D.renderer.bands.hiData;for(var r=0,q=w.length;rC.max)||C.max==null){C.max=w[r][0]}}else{w[r][1]=new h.jsDate(w[r][1]).getTime();if((w[r][1]!=null&&w[r][1]>C.max)||C.max==null){C.max=w[r][1]}}}}if(D.renderer.bands.lowData.length){var w=D.renderer.bands.lowData;for(var r=0,q=w.length;r6){D=6}}var V=new h.jsDate(ae).setDate(1).setHours(0,0,0,0);var q=new h.jsDate(J);var z=new h.jsDate(J).setDate(1).setHours(0,0,0,0);if(q.getTime()!==z.getTime()){z=z.add(1,"month")}var S=z.diff(V,"month");ab=Math.ceil(S/D)+1;this.min=V.getTime();this.max=V.clone().add((ab-1)*D,"month").getTime();this.numberTicks=ab;for(var aa=0;aa200){this.numberTicks=parseInt(3+(n-200)/100,10)}else{this.numberTicks=2}}}O=B/(this.numberTicks-1)/1000;if(this.daTickInterval==null){this.daTickInterval=[O,"seconds"]}for(var aa=0;aa570)?n[o]*0.8:n[o]+0.3*(255-n[o]);n[o]=parseInt(n[o],10)}this.highlightColors.push("rgb("+n[0]+","+n[1]+","+n[2]+")")}}t.postParseOptionsHooks.addOnce(l);t.postInitHooks.addOnce(g);t.eventListenerHooks.addOnce("jqplotMouseMove",b);t.eventListenerHooks.addOnce("jqplotMouseDown",a);t.eventListenerHooks.addOnce("jqplotMouseUp",j);t.eventListenerHooks.addOnce("jqplotClick",f);t.eventListenerHooks.addOnce("jqplotRightClick",m);t.postDrawHooks.addOnce(h)};e.jqplot.DonutRenderer.prototype.setGridData=function(s){var o=[];var t=[];var n=this.startAngle/180*Math.PI;var r=0;this._drawData=false;for(var q=0;q0){o[q]+=o[q-1]}r+=this.data[q][1]}var p=Math.PI*2/o[o.length-1];for(var q=0;q0){o[q]+=o[q-1]}r+=s[q][1]}var p=Math.PI*2/o[o.length-1];for(var q=0;q6.282+this.startAngle){t=6.282+this.startAngle;if(u>t){u=6.281+this.startAngle}}if(u>=t){return}x.beginPath();x.fillStyle=p;x.strokeStyle=p;x.arc(0,0,n,u,t,false);x.lineTo(v*Math.cos(t),v*Math.sin(t));x.arc(0,0,v,t,u,true);x.closePath();if(w){x.fill()}else{x.stroke()}}if(s){for(var q=0;q1&&this.index>0)?this._previousSeries[0]._diameter:this._diameter;this._thickness=this.thickness||(M-this.innerDiameter-2*X*this._numberSeries)/this._numberSeries/2}else{this._thickness=this.thickness||v/2/(this._numberSeries+1)*0.85}var K=this._radius=this._diameter/2;this._innerRadius=this._radius-this._thickness;var o=this.startAngle/180*Math.PI;this._center=[(s-u*q)/2+u*q,(H-u*p)/2+u*p];if(this.shadow){var L="rgba(0,0,0,"+this.shadowAlpha+")";for(var Q=0;Q=this.dataLabelThreshold){var S,U=(A+z)/2,C;if(this.dataLabels=="label"){S=this.dataLabelFormatString||"%s";C=e.jqplot.sprintf(S,V[Q][0])}else{if(this.dataLabels=="value"){S=this.dataLabelFormatString||"%d";C=e.jqplot.sprintf(S,this.data[Q][1])}else{if(this.dataLabels=="percent"){S=this.dataLabelFormatString||"%d%%";C=e.jqplot.sprintf(S,V[Q][2]*100)}else{if(this.dataLabels.constructor==Array){S=this.dataLabelFormatString||"%s";C=e.jqplot.sprintf(S,this.dataLabels[Q])}}}}var n=this._innerRadius+this._thickness*this.dataLabelPositionFactor+this.sliceMargin+this.dataLabelNudge;var F=this._center[0]+Math.cos(U)*n+this.canvas._offsets.left;var E=this._center[1]+Math.sin(U)*n+this.canvas._offsets.top;var D=e(''+C+"").insertBefore(P.eventCanvas._elem);F-=D.width()/2;E-=D.height()/2;F=Math.round(F);E=Math.round(E);D.css({left:F,top:E})}}};e.jqplot.DonutAxisRenderer=function(){e.jqplot.LinearAxisRenderer.call(this)};e.jqplot.DonutAxisRenderer.prototype=new e.jqplot.LinearAxisRenderer();e.jqplot.DonutAxisRenderer.prototype.constructor=e.jqplot.DonutAxisRenderer;e.jqplot.DonutAxisRenderer.prototype.init=function(n){this.tickRenderer=e.jqplot.DonutTickRenderer;e.extend(true,this,n);this._dataBounds={min:0,max:100};this.min=0;this.max=100;this.showTicks=false;this.ticks=[];this.showMark=false;this.show=false};e.jqplot.DonutLegendRenderer=function(){e.jqplot.TableLegendRenderer.call(this)};e.jqplot.DonutLegendRenderer.prototype=new e.jqplot.TableLegendRenderer();e.jqplot.DonutLegendRenderer.prototype.constructor=e.jqplot.DonutLegendRenderer;e.jqplot.DonutLegendRenderer.prototype.init=function(n){this.numberRows=null;this.numberColumns=null;e.extend(true,this,n)};e.jqplot.DonutLegendRenderer.prototype.draw=function(){var q=this;if(this.show){var y=this._series;var B="position:absolute;";B+=(this.background)?"background:"+this.background+";":"";B+=(this.border)?"border:"+this.border+";":"";B+=(this.fontSize)?"font-size:"+this.fontSize+";":"";B+=(this.fontFamily)?"font-family:"+this.fontFamily+";":"";B+=(this.textColor)?"color:"+this.textColor+";":"";B+=(this.marginTop!=null)?"margin-top:"+this.marginTop+";":"";B+=(this.marginBottom!=null)?"margin-bottom:"+this.marginBottom+";":"";B+=(this.marginLeft!=null)?"margin-left:"+this.marginLeft+";":"";B+=(this.marginRight!=null)?"margin-right:"+this.marginRight+";":"";this._elem=e('
    ');var F=false,x=false,n,v;var z=y[0];var o=new e.jqplot.ColorGenerator(z.seriesColors);if(z.show){var G=z.data;if(this.numberRows){n=this.numberRows;if(!this.numberColumns){v=Math.ceil(G.length/n)}else{v=this.numberColumns}}else{if(this.numberColumns){v=this.numberColumns;n=Math.ceil(G.length/this.numberColumns)}else{n=G.length;v=1}}var E,D,p,t,r,u,w,C;var A=0;for(E=0;E').prependTo(this._elem)}else{p=e('').appendTo(this._elem)}for(D=0;D0){F=true}else{F=false}}else{if(E==n-1){F=false}else{F=true}}w=(F)?this.rowSpacing:"0";t=e('
    ');r=e('');if(this.escapeHtml){r.text(u)}else{r.html(u)}if(x){r.prependTo(p);t.prependTo(p)}else{t.appendTo(p);r.appendTo(p)}F=true}A++}}}}return this._elem};function c(r,q,o){o=o||{};o.axesDefaults=o.axesDefaults||{};o.legend=o.legend||{};o.seriesDefaults=o.seriesDefaults||{};var n=false;if(o.seriesDefaults.renderer==e.jqplot.DonutRenderer){n=true}else{if(o.series){for(var p=0;p=0.6)?l[3]*0.6:l[3]*(2-l[3]);m.color="rgba("+o[0]+","+o[1]+","+o[2]+","+k+")"}i.color=m.color;i.init();var g=(p.pointIndex>0)?p.pointIndex-1:0;var j=p.pointIndex+2;m._gridData=q.gridData.slice(g,j)}function e(o,l,h,t,m){if(m.plugins.dragable.dragCanvas.isDragging){var u=m.plugins.dragable.dragCanvas;var i=u._neighbor;var w=m.series[i.seriesIndex];var k=w.plugins.dragable;var r=w.gridData;var p=(k.constrainTo=="y")?i.gridData[0]:l.x;var n=(k.constrainTo=="x")?i.gridData[1]:l.y;var g=w._xaxis.series_p2u(p);var q=w._yaxis.series_p2u(n);var v=u._ctx;v.clearRect(0,0,v.canvas.width,v.canvas.height);if(i.pointIndex>0){k._gridData[1]=[p,n]}else{k._gridData[0]=[p,n]}m.series[i.seriesIndex].draw(u._ctx,{gridData:k._gridData,shadow:false,preventJqPlotSeriesDrawTrigger:true,color:k.color,markerOptions:{color:k.color,shadow:false},trendline:{show:false}});m.target.trigger("jqplotSeriesPointChange",[i.seriesIndex,i.pointIndex,[g,q],[p,n]])}else{if(t!=null){var j=m.series[t.seriesIndex];if(j.isDragable){var u=m.plugins.dragable.dragCanvas;if(!u.isOver){u._cursors.push(o.target.style.cursor);o.target.style.cursor="pointer"}u.isOver=true}}else{if(t==null){var u=m.plugins.dragable.dragCanvas;if(u.isOver){o.target.style.cursor=u._cursors.pop();u.isOver=false}}}}}function c(k,i,g,l,j){var m=j.plugins.dragable.dragCanvas;m._cursors.push(k.target.style.cursor);if(l!=null){var o=j.series[l.seriesIndex];var h=o.plugins.dragable;if(o.isDragable&&!m.isDragging){m._neighbor=l;m.isDragging=true;f(j,l);h.markerRenderer.draw(o.gridData[l.pointIndex][0],o.gridData[l.pointIndex][1],m._ctx);k.target.style.cursor="move";j.target.trigger("jqplotDragStart",[l.seriesIndex,l.pointIndex,i,g])}}else{var n=m._ctx;n.clearRect(0,0,n.canvas.width,n.canvas.height);m.isDragging=false}}function a(m,j,g,o,k){if(k.plugins.dragable.dragCanvas.isDragging){var p=k.plugins.dragable.dragCanvas;var q=p._ctx;q.clearRect(0,0,q.canvas.width,q.canvas.height);p.isDragging=false;var h=p._neighbor;var r=k.series[h.seriesIndex];var i=r.plugins.dragable;var n=(i.constrainTo=="y")?h.data[0]:g[r.xaxis];var l=(i.constrainTo=="x")?h.data[1]:g[r.yaxis];r.data[h.pointIndex][0]=n;r.data[h.pointIndex][1]=l;k.drawSeries({preventJqPlotSeriesDrawTrigger:true},h.seriesIndex);p._neighbor=null;m.target.style.cursor=p._cursors.pop();k.target.trigger("jqplotDragStop",[j,g])}}})(jQuery); \ No newline at end of file diff --git a/templates/admin/default/assets/js/jqplot/plugins/jqplot.enhancedLegendRenderer.min.js b/templates/admin/default/assets/js/jqplot/plugins/jqplot.enhancedLegendRenderer.min.js new file mode 100644 index 000000000..968e77cd0 --- /dev/null +++ b/templates/admin/default/assets/js/jqplot/plugins/jqplot.enhancedLegendRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(c){c.jqplot.EnhancedLegendRenderer=function(){c.jqplot.TableLegendRenderer.call(this)};c.jqplot.EnhancedLegendRenderer.prototype=new c.jqplot.TableLegendRenderer();c.jqplot.EnhancedLegendRenderer.prototype.constructor=c.jqplot.EnhancedLegendRenderer;c.jqplot.EnhancedLegendRenderer.prototype.init=function(d){this.numberRows=null;this.numberColumns=null;this.seriesToggle="normal";this.seriesToggleReplot=false;this.disableIEFading=true;c.extend(true,this,d);if(this.seriesToggle){c.jqplot.postDrawHooks.push(b)}};c.jqplot.EnhancedLegendRenderer.prototype.draw=function(m,y){var f=this;if(this.show){var r=this._series;var u;var w="position:absolute;";w+=(this.background)?"background:"+this.background+";":"";w+=(this.border)?"border:"+this.border+";":"";w+=(this.fontSize)?"font-size:"+this.fontSize+";":"";w+=(this.fontFamily)?"font-family:"+this.fontFamily+";":"";w+=(this.textColor)?"color:"+this.textColor+";":"";w+=(this.marginTop!=null)?"margin-top:"+this.marginTop+";":"";w+=(this.marginBottom!=null)?"margin-bottom:"+this.marginBottom+";":"";w+=(this.marginLeft!=null)?"margin-left:"+this.marginLeft+";":"";w+=(this.marginRight!=null)?"margin-right:"+this.marginRight+";":"";this._elem=c('
    ');if(this.seriesToggle){this._elem.css("z-index","3")}var C=false,q=false,d,o;if(this.numberRows){d=this.numberRows;if(!this.numberColumns){o=Math.ceil(r.length/d)}else{o=this.numberColumns}}else{if(this.numberColumns){o=this.numberColumns;d=Math.ceil(r.length/this.numberColumns)}else{d=r.length;o=1}}var B,z,e,l,k,n,p,t,h,g;var v=0;for(B=r.length-1;B>=0;B--){if(o==1&&r[B]._stack||r[B].renderer.constructor==c.jqplot.BezierCurveRenderer){q=true}}for(B=0;B0){C=true}else{C=false}}else{if(B==d-1){C=false}else{C=true}}p=(C)?this.rowSpacing:"0";l=c(document.createElement("td"));l.addClass("jqplot-table-legend jqplot-table-legend-swatch");l.css({textAlign:"center",paddingTop:p});h=c(document.createElement("div"));h.addClass("jqplot-table-legend-swatch-outline");g=c(document.createElement("div"));g.addClass("jqplot-table-legend-swatch");g.css({backgroundColor:x,borderColor:x});l.append(h.append(g));k=c(document.createElement("td"));k.addClass("jqplot-table-legend jqplot-table-legend-label");k.css("paddingTop",p);if(this.escapeHtml){k.text(n)}else{k.html(n)}if(q){if(this.showLabels){k.prependTo(e)}if(this.showSwatches){l.prependTo(e)}}else{if(this.showSwatches){l.appendTo(e)}if(this.showLabels){k.appendTo(e)}}if(this.seriesToggle){var A;if(typeof(this.seriesToggle)==="string"||typeof(this.seriesToggle)==="number"){if(!c.jqplot.use_excanvas||!this.disableIEFading){A=this.seriesToggle}}if(this.showSwatches){l.bind("click",{series:u,speed:A,plot:y,replot:this.seriesToggleReplot},a);l.addClass("jqplot-seriesToggle")}if(this.showLabels){k.bind("click",{series:u,speed:A,plot:y,replot:this.seriesToggleReplot},a);k.addClass("jqplot-seriesToggle")}if(!u.show&&u.showLabel){l.addClass("jqplot-series-hidden");k.addClass("jqplot-series-hidden")}}C=true}}v++}l=k=h=g=null}}return this._elem};var a=function(j){var i=j.data,m=i.series,k=i.replot,h=i.plot,f=i.speed,l=m.index,g=false;if(m.canvas._elem.is(":hidden")||!m.show){g=true}var e=function(){if(k){var n={};if(c.isPlainObject(k)){c.extend(true,n,k)}h.replot(n);if(g&&f){var d=h.series[l];if(d.shadowCanvas._elem){d.shadowCanvas._elem.hide().fadeIn(f)}d.canvas._elem.hide().fadeIn(f);d.canvas._elem.nextAll(".jqplot-point-label.jqplot-series-"+d.index).hide().fadeIn(f)}}else{var d=h.series[l];if(d.canvas._elem.is(":hidden")||!d.show){if(typeof h.options.legend.showSwatches==="undefined"||h.options.legend.showSwatches===true){h.legend._elem.find("td").eq(l*2).addClass("jqplot-series-hidden")}if(typeof h.options.legend.showLabels==="undefined"||h.options.legend.showLabels===true){h.legend._elem.find("td").eq((l*2)+1).addClass("jqplot-series-hidden")}}else{if(typeof h.options.legend.showSwatches==="undefined"||h.options.legend.showSwatches===true){h.legend._elem.find("td").eq(l*2).removeClass("jqplot-series-hidden")}if(typeof h.options.legend.showLabels==="undefined"||h.options.legend.showLabels===true){h.legend._elem.find("td").eq((l*2)+1).removeClass("jqplot-series-hidden")}}}};m.toggleDisplay(j,e)};var b=function(){if(this.legend.renderer.constructor==c.jqplot.EnhancedLegendRenderer&&this.legend.seriesToggle){var d=this.legend._elem.detach();this.eventCanvas._elem.after(d)}}})(jQuery); \ No newline at end of file diff --git a/templates/admin/default/assets/js/jqplot/plugins/jqplot.funnelRenderer.min.js b/templates/admin/default/assets/js/jqplot/plugins/jqplot.funnelRenderer.min.js new file mode 100644 index 000000000..af0dabac2 --- /dev/null +++ b/templates/admin/default/assets/js/jqplot/plugins/jqplot.funnelRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(e){e.jqplot.FunnelRenderer=function(){e.jqplot.LineRenderer.call(this)};e.jqplot.FunnelRenderer.prototype=new e.jqplot.LineRenderer();e.jqplot.FunnelRenderer.prototype.constructor=e.jqplot.FunnelRenderer;e.jqplot.FunnelRenderer.prototype.init=function(p,t){this.padding={top:20,right:20,bottom:20,left:20};this.sectionMargin=6;this.fill=true;this.shadowOffset=2;this.shadowAlpha=0.07;this.shadowDepth=5;this.highlightMouseOver=true;this.highlightMouseDown=false;this.highlightColors=[];this.widthRatio=0.2;this.lineWidth=2;this.dataLabels="percent";this.showDataLabels=false;this.dataLabelFormatString=null;this.dataLabelThreshold=3;this._type="funnel";this.tickRenderer=e.jqplot.FunnelTickRenderer;if(p.highlightMouseDown&&p.highlightMouseOver==null){p.highlightMouseOver=false}e.extend(true,this,p);this._highlightedPoint=null;this._bases=[];this._atot;this._areas=[];this._lengths=[];this._angle;this._dataIndices=[];this._unorderedData=e.extend(true,[],this.data);var o=e.extend(true,[],this.data);for(var r=0;r570)?m[n]*0.8:m[n]+0.4*(255-m[n]);m[n]=parseInt(m[n],10)}this.highlightColors.push("rgb("+m[0]+","+m[1]+","+m[2]+")")}}t.postParseOptionsHooks.addOnce(k);t.postInitHooks.addOnce(g);t.eventListenerHooks.addOnce("jqplotMouseMove",a);t.eventListenerHooks.addOnce("jqplotMouseDown",b);t.eventListenerHooks.addOnce("jqplotMouseUp",j);t.eventListenerHooks.addOnce("jqplotClick",f);t.eventListenerHooks.addOnce("jqplotRightClick",l);t.postDrawHooks.addOnce(h)};e.jqplot.FunnelRenderer.prototype.setGridData=function(o){var n=0;var p=[];for(var m=0;mthis._lengths[Y]*n&&W<100){this._lengths[Y]=this._areas[Y]/(this._bases[Y]-this._lengths[Y]*Math.tan(this._angle));aa=Math.abs(this._lengths[Y]-E);this._bases[Y+1]=this._bases[Y]-(2*this._lengths[Y]*Math.tan(this._angle));E=this._lengths[Y];W++}Q+=this._lengths[Y]}this._vertices=new Array(B.length);var ae=[t,F],ad=[t+this._bases[0],F],ac=[t+(this._bases[0]-this._bases[this._bases.length-1])/2,F+this._length],ab=[ac[0]+this._bases[this._bases.length-1],ac[1]];function V(ag){var x=(ae[1]-ac[1])/(ae[0]-ac[0]);var v=ae[1]-x*ae[0];var ah=ag+ae[1];return[(ah-v)/x,ah]}function D(ag){var x=(ad[1]-ab[1])/(ad[0]-ab[0]);var v=ad[1]-x*ad[0];var ah=ag+ad[1];return[(ah-v)/x,ah]}var T=w,S=u;var Z=0,m=0;for(Y=0;Y0&&Y0&&Y=this.dataLabelThreshold){var K,X;if(this.dataLabels=="label"){K=this.dataLabelFormatString||"%s";X=e.jqplot.sprintf(K,B[Y][0])}else{if(this.dataLabels=="value"){K=this.dataLabelFormatString||"%d";X=e.jqplot.sprintf(K,this.data[Y][1])}else{if(this.dataLabels=="percent"){K=this.dataLabelFormatString||"%d%%";X=e.jqplot.sprintf(K,B[Y][1]*100)}else{if(this.dataLabels.constructor==Array){K=this.dataLabelFormatString||"%s";X=e.jqplot.sprintf(K,this.dataLabels[this._dataIndices[Y]])}}}}var s=(this._radius)*this.dataLabelPositionFactor+this.sliceMargin+this.dataLabelNudge;var T=(U[0][0]+U[1][0])/2+this.canvas._offsets.left;var S=(U[1][1]+U[2][1])/2+this.canvas._offsets.top;var z=e(''+X+"").insertBefore(p.eventCanvas._elem);T-=z.width()/2;S-=z.height()/2;T=Math.round(T);S=Math.round(S);z.css({left:T,top:S})}}};e.jqplot.FunnelAxisRenderer=function(){e.jqplot.LinearAxisRenderer.call(this)};e.jqplot.FunnelAxisRenderer.prototype=new e.jqplot.LinearAxisRenderer();e.jqplot.FunnelAxisRenderer.prototype.constructor=e.jqplot.FunnelAxisRenderer;e.jqplot.FunnelAxisRenderer.prototype.init=function(m){this.tickRenderer=e.jqplot.FunnelTickRenderer;e.extend(true,this,m);this._dataBounds={min:0,max:100};this.min=0;this.max=100;this.showTicks=false;this.ticks=[];this.showMark=false;this.show=false};e.jqplot.FunnelLegendRenderer=function(){e.jqplot.TableLegendRenderer.call(this)};e.jqplot.FunnelLegendRenderer.prototype=new e.jqplot.TableLegendRenderer();e.jqplot.FunnelLegendRenderer.prototype.constructor=e.jqplot.FunnelLegendRenderer;e.jqplot.FunnelLegendRenderer.prototype.init=function(m){this.numberRows=null;this.numberColumns=null;e.extend(true,this,m)};e.jqplot.FunnelLegendRenderer.prototype.draw=function(){var p=this;if(this.show){var x=this._series;var A="position:absolute;";A+=(this.background)?"background:"+this.background+";":"";A+=(this.border)?"border:"+this.border+";":"";A+=(this.fontSize)?"font-size:"+this.fontSize+";":"";A+=(this.fontFamily)?"font-family:"+this.fontFamily+";":"";A+=(this.textColor)?"color:"+this.textColor+";":"";A+=(this.marginTop!=null)?"margin-top:"+this.marginTop+";":"";A+=(this.marginBottom!=null)?"margin-bottom:"+this.marginBottom+";":"";A+=(this.marginLeft!=null)?"margin-left:"+this.marginLeft+";":"";A+=(this.marginRight!=null)?"margin-right:"+this.marginRight+";":"";this._elem=e('
    ');var E=false,w=false,m,u;var y=x[0];var n=new e.jqplot.ColorGenerator(y.seriesColors);if(y.show){var F=y.data;if(this.numberRows){m=this.numberRows;if(!this.numberColumns){u=Math.ceil(F.length/m)}else{u=this.numberColumns}}else{if(this.numberColumns){u=this.numberColumns;m=Math.ceil(F.length/this.numberColumns)}else{m=F.length;u=1}}var D,C,o,r,q,t,v,B;var z=0;for(D=0;D').prependTo(this._elem)}else{o=e('').appendTo(this._elem)}for(C=0;C0){E=true}else{E=false}}else{if(D==m-1){E=false}else{E=true}}v=(E)?this.rowSpacing:"0";r=e('
    ');q=e('');if(this.escapeHtml){q.text(t)}else{q.html(t)}if(w){q.prependTo(o);r.prependTo(o)}else{r.appendTo(o);q.appendTo(o)}E=true}z++}}}}return this._elem};function c(q,p,n){n=n||{};n.axesDefaults=n.axesDefaults||{};n.legend=n.legend||{};n.seriesDefaults=n.seriesDefaults||{};var m=false;if(n.seriesDefaults.renderer==e.jqplot.FunnelRenderer){m=true}else{if(n.series){for(var o=0;o=0.6)?l[3]*0.6:l[3]*(2-l[3]);i.color="rgba("+n[0]+","+n[1]+","+n[2]+","+k+")";i.init();i.draw(p.gridData[o.pointIndex][0],p.gridData[o.pointIndex][1],j.highlightCanvas._ctx)}function g(A,q,m){var k=A.plugins.highlighter;var D=k._tooltipElem;var r=q.highlighter||{};var t=d.extend(true,{},k,r);if(t.useAxesFormatters){var w=q._xaxis._ticks[0].formatter;var h=q._yaxis._ticks[0].formatter;var E=q._xaxis._ticks[0].formatString;var s=q._yaxis._ticks[0].formatString;var z;var u=w(E,m.data[0]);var l=[];for(var B=1;B140){h=Math.round(Math.log(this.max/this.min)/Math.log(this.base)+1);if(h<2){h=2}if(C===0){var o=b/(h-1);if(o<100){C=0}else{if(o<190){C=1}else{if(o<250){C=3}else{if(o<600){C=4}else{C=9}}}}}}else{h=2;if(C===0){C=1}C=0}}else{h=this.numberTicks}if(E>=0&&C!==3){this._autoFormatString="%d"}else{if(E<=0&&C===3){var o=-(E-1);this._autoFormatString="%."+Math.abs(E-1)+"f"}else{if(E<0){var o=-E;this._autoFormatString="%."+Math.abs(E)+"f"}else{this._autoFormatString="%d"}}}var O,H,z,p,n,k;for(var K=0;K=0;J--){z=p-k*(J+1);H=new this.tickRenderer(this.tickOptions);if(this._overrideFormatString&&this._autoFormatString!=""){H.formatString=this._autoFormatString}if(!this.showTicks){H.showLabel=false;H.showMark=false}else{if(!this.showTickMarks){H.showMark=false}}H.setTick(z,this.name);this._ticks.push(H)}}}}else{if(this.min!=null&&this.max!=null){var y=a.extend(true,{},this.tickOptions,{name:this.name,value:null});var I,e;if(this.numberTicks==null&&this.tickInterval==null){var D=Math.max(b,g+1);var L=Math.ceil((D-g)/35+1);var B=a.jqplot.LinearTickGenerator.bestConstrainedInterval(this.min,this.max,L);this._autoFormatString=B[3];I=B[2];e=B[4];for(var K=0;K0){c=-n._textRenderer.height*Math.cos(-n._textRenderer.angle)/2}else{c=-n.getHeight()+n._textRenderer.height*Math.cos(n._textRenderer.angle)/2}break;case"middle":c=-n.getHeight()/2;break;default:c=-n.getHeight()/2;break}}else{c=-n.getHeight()/2}var z=this.u2p(n.value)+c+"px";n._elem.css("top",z);n.pack()}}if(o){var x=this._label._elem.outerHeight(true);this._label._elem.css("top",m-g/2-x/2+"px");if(this.name=="yaxis"){this._label._elem.css("left","0px")}else{this._label._elem.css("right","0px")}this._label.pack()}}}}})(jQuery); \ No newline at end of file diff --git a/templates/admin/default/assets/js/jqplot/plugins/jqplot.mekkoAxisRenderer.min.js b/templates/admin/default/assets/js/jqplot/plugins/jqplot.mekkoAxisRenderer.min.js new file mode 100644 index 000000000..7969de739 --- /dev/null +++ b/templates/admin/default/assets/js/jqplot/plugins/jqplot.mekkoAxisRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(a){a.jqplot.MekkoAxisRenderer=function(){};a.jqplot.MekkoAxisRenderer.prototype.init=function(c){this.tickMode;this.barLabelRenderer=a.jqplot.AxisLabelRenderer;this.barLabels=this.barLabels||[];this.barLabelOptions={};this.tickOptions=a.extend(true,{showGridline:false},this.tickOptions);this._barLabels=[];a.extend(true,this,c);if(this.name=="yaxis"){this.tickOptions.formatString=this.tickOptions.formatString||"%d%"}var b=this._dataBounds;b.min=0;if(this.name=="yaxis"||this.name=="y2axis"){b.max=100;this.tickMode="even"}else{if(this.name=="xaxis"){this.tickMode=(this.tickMode==null)?"bar":this.tickMode;for(var d=0;dk){k=d}}}if(b){c=this._label._elem.outerWidth(true);j=this._label._elem.outerHeight(true)}if(this.name=="xaxis"){k=k+j;this._elem.css({height:k+"px",left:"0px",bottom:"0px"})}else{if(this.name=="x2axis"){k=k+j;this._elem.css({height:k+"px",left:"0px",top:"0px"})}else{if(this.name=="yaxis"){k=k+c;this._elem.css({width:k+"px",left:"0px",top:"0px"});if(b&&this._label.constructor==a.jqplot.AxisLabelRenderer){this._label._elem.css("width",c+"px")}}else{k=k+c;this._elem.css({width:k+"px",right:"0px",top:"0px"});if(b&&this._label.constructor==a.jqplot.AxisLabelRenderer){this._label._elem.css("width",c+"px")}}}}}};a.jqplot.MekkoAxisRenderer.prototype.createTicks=function(){var z=this._ticks;var w=this.ticks;var B=this.name;var y=this._dataBounds;var p,x;var n,r;var d,c;var h,b,s,q;if(w.length){for(s=0;s0){g=Math.max(Math.log(n)/Math.LN10,0.05)}n-=g;r+=g}var k=r-n;var m,o;var v,l,u;var f=[3,5,6,11,21];if(this.name=="yaxis"||this.name=="y2axis"){this.min=0;this.max=100;if(!this.numberTicks){if(this.tickInterval){this.numberTicks=3+Math.ceil(k/this.tickInterval)}else{v=2+Math.ceil((p-(this.tickSpacing-1))/this.tickSpacing);for(s=0;s1){l=u;continue}else{if(u<1){if(Math.abs(l-1)v){h=new this.tickRenderer(this.tickOptions);if(!this.showTicks){h.showLabel=false;h.showMark=false}else{if(!this.showTickMarks){h.showMark=false}}h.setTick(this.max,this.name);this._ticks.push(h)}}else{if(this.tickMode=="even"){this.min=0;this.max=this.max||y.max;var A=2+Math.ceil((p-(this.tickSpacing-1))/this.tickSpacing);k=this.max-this.min;this.numberTicks=A;this.tickInterval=k/(this.numberTicks-1);for(s=0;s0){c=-n._textRenderer.height*Math.cos(-n._textRenderer.angle)/2}else{c=-n.getHeight()+n._textRenderer.height*Math.cos(n._textRenderer.angle)/2}break;case"middle":c=-n.getHeight()/2;break;default:c=-n.getHeight()/2;break}}else{c=-n.getHeight()/2}var D=this.u2p(n.value)+c+"px";n._elem.css("top",D);n.pack()}}if(o){var z=this._label._elem.outerHeight(true);this._label._elem.css("top",m-f/2-z/2+"px");if(this.name=="yaxis"){this._label._elem.css("left","0px")}else{this._label._elem.css("right","0px")}this._label.pack()}}}}})(jQuery); \ No newline at end of file diff --git a/templates/admin/default/assets/js/jqplot/plugins/jqplot.mekkoRenderer.min.js b/templates/admin/default/assets/js/jqplot/plugins/jqplot.mekkoRenderer.min.js new file mode 100644 index 000000000..18dc3a12b --- /dev/null +++ b/templates/admin/default/assets/js/jqplot/plugins/jqplot.mekkoRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(b){b.jqplot.MekkoRenderer=function(){this.shapeRenderer=new b.jqplot.ShapeRenderer();this.borderColor=null;this.showBorders=true};b.jqplot.MekkoRenderer.prototype.init=function(c,e){this.fill=false;this.fillRect=true;this.strokeRect=true;this.shadow=false;this._xwidth=0;this._xstart=0;b.extend(true,this.renderer,c);var d={lineJoin:"miter",lineCap:"butt",isarc:false,fillRect:this.fillRect,strokeRect:this.strokeRect};this.renderer.shapeRenderer.init(d);e.axes.x2axis._series.push(this);this._type="mekko"};b.jqplot.MekkoRenderer.prototype.setGridData=function(h){var e=this._xaxis.series_u2p;var c=this._yaxis.series_u2p;var g=this._plotData;this.gridData=[];this._xwidth=e(this._sumy)-e(0);if(this.index>0){this._xstart=h.series[this.index-1]._xstart+h.series[this.index-1]._xwidth}var l=this.canvas.getHeight();var d=0;var k;var j;for(var f=0;f');var w=false,n=true,c,l;var p=o[0];var d=new b.jqplot.ColorGenerator(p.seriesColors);if(p.show){var x=p.data;if(this.numberRows){c=this.numberRows;if(!this.numberColumns){l=Math.ceil(x.length/c)}else{l=this.numberColumns}}else{if(this.numberColumns){l=this.numberColumns;c=Math.ceil(x.length/this.numberColumns)}else{c=x.length;l=1}}var v,u,e,h,g,k,m,t;var q=0;for(v=0;v').prependTo(this._elem)}else{e=b('').appendTo(this._elem)}for(u=0;u0){w=true}else{w=false}}else{if(v==c-1){w=false}else{w=true}}m=(w)?this.rowSpacing:"0";h=b('
    ');g=b('');if(this.escapeHtml){g.text(k)}else{g.html(k)}if(n){g.prependTo(e);h.prependTo(e)}else{h.appendTo(e);g.appendTo(e)}w=true}q++}}e=null;h=null;g=null}}return this._elem};b.jqplot.MekkoLegendRenderer.prototype.pack=function(f){if(this.show){var e={_top:f.top,_left:f.left,_right:f.right,_bottom:this._plotDimensions.height-f.bottom};if(this.placement=="insideGrid"){switch(this.location){case"nw":var d=e._left+this.xoffset;var c=e._top+this.yoffset;this._elem.css("left",d);this._elem.css("top",c);break;case"n":var d=(f.left+(this._plotDimensions.width-f.right))/2-this.getWidth()/2;var c=e._top+this.yoffset;this._elem.css("left",d);this._elem.css("top",c);break;case"ne":var d=f.right+this.xoffset;var c=e._top+this.yoffset;this._elem.css({right:d,top:c});break;case"e":var d=f.right+this.xoffset;var c=(f.top+(this._plotDimensions.height-f.bottom))/2-this.getHeight()/2;this._elem.css({right:d,top:c});break;case"se":var d=f.right+this.xoffset;var c=f.bottom+this.yoffset;this._elem.css({right:d,bottom:c});break;case"s":var d=(f.left+(this._plotDimensions.width-f.right))/2-this.getWidth()/2;var c=f.bottom+this.yoffset;this._elem.css({left:d,bottom:c});break;case"sw":var d=e._left+this.xoffset;var c=f.bottom+this.yoffset;this._elem.css({left:d,bottom:c});break;case"w":var d=e._left+this.xoffset;var c=(f.top+(this._plotDimensions.height-f.bottom))/2-this.getHeight()/2;this._elem.css({left:d,top:c});break;default:var d=e._right-this.xoffset;var c=e._bottom+this.yoffset;this._elem.css({right:d,bottom:c});break}}else{switch(this.location){case"nw":var d=this._plotDimensions.width-e._left+this.xoffset;var c=e._top+this.yoffset;this._elem.css("right",d);this._elem.css("top",c);break;case"n":var d=(f.left+(this._plotDimensions.width-f.right))/2-this.getWidth()/2;var c=this._plotDimensions.height-e._top+this.yoffset;this._elem.css("left",d);this._elem.css("bottom",c);break;case"ne":var d=this._plotDimensions.width-f.right+this.xoffset;var c=e._top+this.yoffset;this._elem.css({left:d,top:c});break;case"e":var d=this._plotDimensions.width-f.right+this.xoffset;var c=(f.top+(this._plotDimensions.height-f.bottom))/2-this.getHeight()/2;this._elem.css({left:d,top:c});break;case"se":var d=this._plotDimensions.width-f.right+this.xoffset;var c=f.bottom+this.yoffset;this._elem.css({left:d,bottom:c});break;case"s":var d=(f.left+(this._plotDimensions.width-f.right))/2-this.getWidth()/2;var c=this._plotDimensions.height-f.bottom+this.yoffset;this._elem.css({left:d,top:c});break;case"sw":var d=this._plotDimensions.width-e._left+this.xoffset;var c=f.bottom+this.yoffset;this._elem.css({right:d,bottom:c});break;case"w":var d=this._plotDimensions.width-e._left+this.xoffset;var c=(f.top+(this._plotDimensions.height-f.bottom))/2-this.getHeight()/2;this._elem.css({right:d,top:c});break;default:var d=e._right-this.xoffset;var c=e._bottom+this.yoffset;this._elem.css({right:d,bottom:c});break}}}};function a(g,f,d){d=d||{};d.axesDefaults=d.axesDefaults||{};d.legend=d.legend||{};d.seriesDefaults=d.seriesDefaults||{};var c=false;if(d.seriesDefaults.renderer==b.jqplot.MekkoRenderer){c=true}else{if(d.series){for(var e=0;e=this.data[0][1]){this.max=this.intervals[this.intervals.length-1][0];this.setmax=false}}else{this.setmax=false}}else{this.min=(this.min==null)?0:this.min;this.setmin=false;if(this.max==null){this.max=this.data[0][1]*1.25;this.setmax=true}else{this.setmax=false}}}};c.jqplot.MeterGaugeRenderer.prototype.setGridData=function(j){var f=[];var k=[];var e=this.startAngle;for(var h=0;h0){f[h]+=f[h-1]}}var g=Math.PI*2/f[f.length-1];for(var h=0;h0){f[h]+=f[h-1]}}var g=Math.PI*2/f[f.length-1];for(var h=0;h=0;h--){e=f/(j[h]*Math.pow(10,g));if(e==4||e==5){return e-1}}return null}c.jqplot.MeterGaugeRenderer.prototype.draw=function(X,aC,ap){var aa;var aM=(ap!=undefined)?ap:{};var ai=0;var ah=0;var at=1;if(ap.legendInfo&&ap.legendInfo.placement=="inside"){var aI=ap.legendInfo;switch(aI.location){case"nw":ai=aI.width+aI.xoffset;break;case"w":ai=aI.width+aI.xoffset;break;case"sw":ai=aI.width+aI.xoffset;break;case"ne":ai=aI.width+aI.xoffset;at=-1;break;case"e":ai=aI.width+aI.xoffset;at=-1;break;case"se":ai=aI.width+aI.xoffset;at=-1;break;case"n":ah=aI.height+aI.yoffset;break;case"s":ah=aI.height+aI.yoffset;at=-1;break;default:break}}if(this.label){this._labelElem=c('
    '+this.label+"
    ");this.canvas._elem.after(this._labelElem)}var m=(aM.shadow!=undefined)?aM.shadow:this.shadow;var N=(aM.showLine!=undefined)?aM.showLine:this.showLine;var I=(aM.fill!=undefined)?aM.fill:this.fill;var K=X.canvas.width;var S=X.canvas.height;if(this.padding==null){this.padding=Math.round(Math.min(K,S)/30)}var Q=K-ai-2*this.padding;var ab=S-ah-2*this.padding;if(this.labelPosition=="bottom"&&this.label){ab-=this._labelElem.outerHeight(true)}var L=Math.min(Q,ab);var ad=L;if(!this.diameter){if(this.semiCircular){if(Q>=2*ab){if(!this.ringWidth){this.ringWidth=2*ab/35}this.needleThickness=this.needleThickness||2+Math.pow(this.ringWidth,0.8);this.innerPad=this.ringWidth/2+this.needleThickness/2+this.needlePad;this.diameter=2*(ab-2*this.innerPad)}else{if(!this.ringWidth){this.ringWidth=Q/35}this.needleThickness=this.needleThickness||2+Math.pow(this.ringWidth,0.8);this.innerPad=this.ringWidth/2+this.needleThickness/2+this.needlePad;this.diameter=Q-2*this.innerPad-this.ringWidth-this.padding}this._center=[(K-at*ai)/2+at*ai,(S+at*ah-this.padding-this.ringWidth-this.innerPad)]}else{if(!this.ringWidth){this.ringWidth=ad/35}this.needleThickness=this.needleThickness||2+Math.pow(this.ringWidth,0.8);this.innerPad=0;this.diameter=ad-this.ringWidth;this._center=[(K-at*ai)/2+at*ai,(S-at*ah)/2+at*ah]}if(this._labelElem&&this.labelPosition=="bottom"){this._center[1]-=this._labelElem.outerHeight(true)}}this._radius=this.diameter/2;this.tickSpacing=6000/this.diameter;if(!this.hubRadius){this.hubRadius=this.diameter/18}this.shadowOffset=0.5+this.ringWidth/9;this.shadowWidth=this.ringWidth*1;this.tickPadding=3+Math.pow(this.diameter/20,0.7);this.tickOuterRadius=this._radius-this.ringWidth/2-this.tickPadding;this.tickLength=(this.showTicks)?this._radius/13:0;if(this.ticks.length==0){var A=this.max,aL=this.min,q=this.setmax,aG=this.setmin,au=(A-aL)*this.tickSpacing/this.span;var aw=Math.floor(parseFloat((Math.log(au)/Math.log(10)).toFixed(11)));var an=(au/Math.pow(10,aw));(an>2&&an<=2.5)?an=2.5:an=Math.ceil(an);var T=this.tickPositions;var aA,ak;for(aa=0;aa0)?aL-aL%au:aL-aL%au-au;if(!this.forceZero){var D=Math.min(aL-aP,0.8*au);var o=Math.floor(D/T[aA]);if(o>1){aP=aP+T[aA]*(o-1);if(parseInt(aP,10)!=aP&&parseInt(aP-T[aA],10)==aP-T[aA]){aP=aP-T[aA]}}}if(aL==aP){aL-=au}else{if(aL-aP>0.23*au){aL=aP}else{aL=aP-au;ak+=1}}ak+=1;var E=aL+(ak-1)*au;if(A>=E){E+=au;ak+=1}if(E-A<0.23*au){E+=au;ak+=1}this.max=A=E;this.min=aL;this.tickInterval=au;this.numberTicks=ak;var O;for(aa=0;aa=E){A=E+au;ak+=1}else{A=E}this.tickInterval=this.tickInterval||au;this.numberTicks=this.numberTicks||ak;var O;for(aa=0;aa1){var aJ=String(P);if(aJ.search(/\./)==-1){var aF=aJ.search(/0+$/);av=(aF>0)?aJ.length-aF-1:0}}M=P/Math.pow(10,av);for(aa=0;aa'+this.ticks[aa][1]+"");this.canvas._elem.after(J);aO=J.outerWidth(true);g=J.outerHeight(true);W=this._tickPoints[aa][0]-aO*(this._tickPoints[aa][2]-Math.PI)/Math.PI-an*Math.cos(this._tickPoints[aa][2]);T=this._tickPoints[aa][1]-g/2+g/2*Math.pow(Math.abs((Math.sin(this._tickPoints[aa][2]))),0.5)+an/3*Math.pow(Math.abs((Math.sin(this._tickPoints[aa][2]))),0.5);J.css({left:W,top:T,color:this.tickColor});G=aO*Math.cos(this._tickPoints[aa][2])+g*Math.sin(Math.PI/2+this._tickPoints[aa][2]/2);n=(G>n)?G:n}}if(this.label&&this.labelPosition=="inside"){var W=this._center[0]+this.canvas._offsets.left;var an=this.tickPadding*(1-1/(this.diameter/80+1));var T=0.5*(this._center[1]+this.canvas._offsets.top-this.hubRadius)+0.5*(this._center[1]+this.canvas._offsets.top-this.tickOuterRadius+this.tickLength+an)+this.labelHeightAdjust;W-=this._labelElem.outerWidth(true)/2;T-=this._labelElem.outerHeight(true)/2;this._labelElem.css({left:W,top:T})}else{if(this.label&&this.labelPosition=="bottom"){var W=this._center[0]+this.canvas._offsets.left-this._labelElem.outerWidth(true)/2;var T=this._center[1]+this.canvas._offsets.top+this.innerPad+this.ringWidth+this.padding+this.labelHeightAdjust;this._labelElem.css({left:W,top:T})}}X.save();var ax=this.intervalInnerRadius||this.hubRadius*1.5;if(this.intervalOuterRadius==null){if(this.showTickLabels){var ag=(this.tickOuterRadius-this.tickLength-this.tickPadding-this.diameter/8)}else{var ag=(this.tickOuterRadius-this.tickLength-this.diameter/16)}}else{var ag=this.intervalOuterRadius}var P=this.max-this.min;var aD=this.intervals[this.intervals.length-1]-this.min;var y,Z,u=this.span*Math.PI/180;for(aa=0;aathis.max+R*3/this.span){ay=this.max+R*3/this.span}if(this.data[0][1]');var f=false,q=false,u,o;var w=p[0];if(w.show){var t=w.data;if(this.numberRows){u=this.numberRows;if(!this.numberColumns){o=Math.ceil(t.length/u)}else{o=this.numberColumns}}else{if(this.numberColumns){o=this.numberColumns;u=Math.ceil(t.length/this.numberColumns)}else{u=t.length;o=1}}var n,m,r,g,e,l,k,h;var v=0;for(n=0;n').prependTo(this._elem)}else{r=c('').appendTo(this._elem)}for(m=0;m0){f=true}else{f=false}}else{if(n==u-1){f=false}else{f=true}}k=(f)?this.rowSpacing:"0";g=c('
    ');e=c('');if(this.escapeHtml){e.text(l)}else{e.html(l)}if(q){e.prependTo(r);g.prependTo(r)}else{g.appendTo(r);e.appendTo(r)}f=true}v++}}}}return this._elem};function a(j,h,f){f=f||{};f.axesDefaults=f.axesDefaults||{};f.legend=f.legend||{};f.seriesDefaults=f.seriesDefaults||{};f.grid=f.grid||{};var e=false;if(f.seriesDefaults.renderer==c.jqplot.MeterGaugeRenderer){e=true}else{if(f.series){for(var g=0;gb.max||b.max==null){b.max=f[c][1]}}}else{for(var c=0;cb.max||b.max==null){b.max=f[c][2]}}}};a.jqplot.OHLCRenderer.prototype.draw=function(A,N,j){var J=this.data;var v=this._xaxis.min;var z=this._xaxis.max;var l=0;var K=J.length;var p=this._xaxis.series_u2p;var G=this._yaxis.series_u2p;var D,E,f,M,F,n,O,C;var y;var u=this.renderer;var s=(j!=undefined)?j:{};var k=(s.shadow!=undefined)?s.shadow:this.shadow;var B=(s.fill!=undefined)?s.fill:this.fill;var c=(s.fillAndStroke!=undefined)?s.fillAndStroke:this.fillAndStroke;u.bodyWidth=(s.bodyWidth!=undefined)?s.bodyWidth:u.bodyWidth;u.tickLength=(s.tickLength!=undefined)?s.tickLength:u.tickLength;A.save();if(this.show){var m,q,g,Q,t;for(var D=0;Dq){if(u.wickColor){y.color=u.wickColor}else{if(u.downBodyColor){y.color=u.downBodyColor}}f=a.extend(true,{},s,y);u.shapeRenderer.draw(A,[[m,g],[m,q]],f);u.shapeRenderer.draw(A,[[m,t],[m,Q]],f);y={};M=q;F=t-q;if(u.fillDownBody){y.fillRect=true}else{y.strokeRect=true;n=n-this.lineWidth;O=m-n/2}if(u.downBodyColor){y.color=u.downBodyColor;y.fillStyle=u.downBodyColor}C=[O,M,n,F]}else{if(u.wickColor){y.color=u.wickColor}f=a.extend(true,{},s,y);u.shapeRenderer.draw(A,[[m,g],[m,Q]],f);y={};y.fillRect=false;y.strokeRect=false;O=[m-n/2,q];M=[m+n/2,t];n=null;F=null;C=[O,M]}}f=a.extend(true,{},s,y);u.shapeRenderer.draw(A,C,f)}else{E=s.color;if(u.openColor){s.color=u.openColor}if(!u.hlc){u.shapeRenderer.draw(A,[[m-u._tickLength,q],[m,q]],s)}s.color=E;if(u.wickColor){s.color=u.wickColor}u.shapeRenderer.draw(A,[[m,g],[m,Q]],s);s.color=E;if(u.closeColor){s.color=u.closeColor}u.shapeRenderer.draw(A,[[m,t],[m+u._tickLength,t]],s);s.color=E}}}A.restore()};a.jqplot.OHLCRenderer.prototype.drawShadow=function(b,d,c){};a.jqplot.OHLCRenderer.checkOptions=function(d,c,b){if(!b.highlighter){b.highlighter={showMarker:false,tooltipAxes:"y",yvalues:4,formatString:'
    date:%s
    open:%s
    hi:%s
    low:%s
    close:%s
    '}}}})(jQuery); \ No newline at end of file diff --git a/templates/admin/default/assets/js/jqplot/plugins/jqplot.pieRenderer.min.js b/templates/admin/default/assets/js/jqplot/plugins/jqplot.pieRenderer.min.js new file mode 100644 index 000000000..a09f8f107 --- /dev/null +++ b/templates/admin/default/assets/js/jqplot/plugins/jqplot.pieRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(e){e.jqplot.PieRenderer=function(){e.jqplot.LineRenderer.call(this)};e.jqplot.PieRenderer.prototype=new e.jqplot.LineRenderer();e.jqplot.PieRenderer.prototype.constructor=e.jqplot.PieRenderer;e.jqplot.PieRenderer.prototype.init=function(q,u){this.diameter=null;this.padding=20;this.sliceMargin=0;this.fill=true;this.shadowOffset=2;this.shadowAlpha=0.07;this.shadowDepth=5;this.highlightMouseOver=true;this.highlightMouseDown=false;this.highlightColors=[];this.dataLabels="percent";this.showDataLabels=false;this.dataLabelFormatString=null;this.dataLabelThreshold=3;this.dataLabelPositionFactor=0.52;this.dataLabelNudge=2;this.dataLabelCenterOn=true;this.startAngle=0;this.tickRenderer=e.jqplot.PieTickRenderer;this._drawData=true;this._type="pie";if(q.highlightMouseDown&&q.highlightMouseOver==null){q.highlightMouseOver=false}e.extend(true,this,q);if(this.sliceMargin<0){this.sliceMargin=0}this._diameter=null;this._radius=null;this._sliceAngles=[];this._highlightedPoint=null;if(this.highlightColors.length==0){for(var s=0;s570)?o[p]*0.8:o[p]+0.3*(255-o[p]);o[p]=parseInt(o[p],10)}this.highlightColors.push("rgb("+o[0]+","+o[1]+","+o[2]+")")}}this.highlightColorGenerator=new e.jqplot.ColorGenerator(this.highlightColors);u.postParseOptionsHooks.addOnce(m);u.postInitHooks.addOnce(g);u.eventListenerHooks.addOnce("jqplotMouseMove",b);u.eventListenerHooks.addOnce("jqplotMouseDown",a);u.eventListenerHooks.addOnce("jqplotMouseUp",l);u.eventListenerHooks.addOnce("jqplotClick",f);u.eventListenerHooks.addOnce("jqplotRightClick",n);u.postDrawHooks.addOnce(i)};e.jqplot.PieRenderer.prototype.setGridData=function(t){var p=[];var u=[];var o=this.startAngle/180*Math.PI;var s=0;this._drawData=false;for(var r=0;r0){p[r]+=p[r-1]}s+=this.data[r][1]}var q=Math.PI*2/p[p.length-1];for(var r=0;r0){p[r]+=p[r-1]}s+=t[r][1]}var q=Math.PI*2/p[p.length-1];for(var r=0;r0&&s>0.01&&s<6.282){w=parseFloat(p)/2/h(q)}return w}e.jqplot.PieRenderer.prototype.drawSlice=function(B,z,y,u,w){if(this._drawData){var p=this._radius;var A=this.fill;var x=this.lineWidth;var s=this.sliceMargin;if(this.fill==false){s+=this.lineWidth}B.save();B.translate(this._center[0],this._center[1]);var D=j(z,y,this.sliceMargin,this.fill,this.lineWidth);var o=D*Math.cos((z+y)/2);var C=D*Math.sin((z+y)/2);if((y-z)<=Math.PI){p-=D}else{p+=D}B.translate(o,C);if(w){for(var v=0,t=this.shadowDepth;v6.282+this.startAngle){y=6.282+this.startAngle;if(z>y){z=6.281+this.startAngle}}if(z>=y){return}B.beginPath();B.fillStyle=u;B.strokeStyle=u;B.lineWidth=x;B.arc(0,0,r,z,y,false);B.lineTo(0,0);B.closePath();if(A){B.fill()}else{B.stroke()}}};e.jqplot.PieRenderer.prototype.draw=function(B,z,E,o){var W;var H=(E!=undefined)?E:{};var t=0;var s=0;var N=1;var L=new e.jqplot.ColorGenerator(this.seriesColors);if(E.legendInfo&&E.legendInfo.placement=="insideGrid"){var J=E.legendInfo;switch(J.location){case"nw":t=J.width+J.xoffset;break;case"w":t=J.width+J.xoffset;break;case"sw":t=J.width+J.xoffset;break;case"ne":t=J.width+J.xoffset;N=-1;break;case"e":t=J.width+J.xoffset;N=-1;break;case"se":t=J.width+J.xoffset;N=-1;break;case"n":s=J.height+J.yoffset;break;case"s":s=J.height+J.yoffset;N=-1;break;default:break}}var K=(H.shadow!=undefined)?H.shadow:this.shadow;var A=(H.fill!=undefined)?H.fill:this.fill;var C=B.canvas.width;var I=B.canvas.height;var Q=C-t-2*this.padding;var X=I-s-2*this.padding;var M=Math.min(Q,X);var Y=M;this._sliceAngles=[];var v=this.sliceMargin;if(this.fill==false){v+=this.lineWidth}var q;var G=0;var R,aa,Z,ab;var D=this.startAngle/180*Math.PI;for(var W=0,V=z.length;WMath.PI){G=Math.max(q,G)}}if(this.diameter!=null&&this.diameter>0){this._diameter=this.diameter-2*G}else{this._diameter=Y-2*G}if(this._diameter<6){e.jqplot.log("Diameter of pie too small, not rendering.");return}var S=this._radius=this._diameter/2;this._center=[(C-N*t)/2+N*t+G*Math.cos(D),(I-N*s)/2+N*s+G*Math.sin(D)];if(this.shadow){for(var W=0,V=z.length;W=this.dataLabelThreshold){var F,U=(this._sliceAngles[W][0]+this._sliceAngles[W][1])/2,T;if(this.dataLabels=="label"){F=this.dataLabelFormatString||"%s";T=e.jqplot.sprintf(F,z[W][0])}else{if(this.dataLabels=="value"){F=this.dataLabelFormatString||"%d";T=e.jqplot.sprintf(F,this.data[W][1])}else{if(this.dataLabels=="percent"){F=this.dataLabelFormatString||"%d%%";T=e.jqplot.sprintf(F,z[W][2]*100)}else{if(this.dataLabels.constructor==Array){F=this.dataLabelFormatString||"%s";T=e.jqplot.sprintf(F,this.dataLabels[W])}}}}var p=(this._radius)*this.dataLabelPositionFactor+this.sliceMargin+this.dataLabelNudge;var P=this._center[0]+Math.cos(U)*p+this.canvas._offsets.left;var O=this._center[1]+Math.sin(U)*p+this.canvas._offsets.top;var u=e('
    '+T+"
    ").insertBefore(o.eventCanvas._elem);if(this.dataLabelCenterOn){P-=u.width()/2;O-=u.height()/2}else{P-=u.width()*Math.sin(U/2);O-=u.height()/2}P=Math.round(P);O=Math.round(O);u.css({left:P,top:O})}}};e.jqplot.PieAxisRenderer=function(){e.jqplot.LinearAxisRenderer.call(this)};e.jqplot.PieAxisRenderer.prototype=new e.jqplot.LinearAxisRenderer();e.jqplot.PieAxisRenderer.prototype.constructor=e.jqplot.PieAxisRenderer;e.jqplot.PieAxisRenderer.prototype.init=function(o){this.tickRenderer=e.jqplot.PieTickRenderer;e.extend(true,this,o);this._dataBounds={min:0,max:100};this.min=0;this.max=100;this.showTicks=false;this.ticks=[];this.showMark=false;this.show=false};e.jqplot.PieLegendRenderer=function(){e.jqplot.TableLegendRenderer.call(this)};e.jqplot.PieLegendRenderer.prototype=new e.jqplot.TableLegendRenderer();e.jqplot.PieLegendRenderer.prototype.constructor=e.jqplot.PieLegendRenderer;e.jqplot.PieLegendRenderer.prototype.init=function(o){this.numberRows=null;this.numberColumns=null;e.extend(true,this,o)};e.jqplot.PieLegendRenderer.prototype.draw=function(){var r=this;if(this.show){var B=this._series;this._elem=e(document.createElement("table"));this._elem.addClass("jqplot-table-legend");var E={position:"absolute"};if(this.background){E.background=this.background}if(this.border){E.border=this.border}if(this.fontSize){E.fontSize=this.fontSize}if(this.fontFamily){E.fontFamily=this.fontFamily}if(this.textColor){E.textColor=this.textColor}if(this.marginTop!=null){E.marginTop=this.marginTop}if(this.marginBottom!=null){E.marginBottom=this.marginBottom}if(this.marginLeft!=null){E.marginLeft=this.marginLeft}if(this.marginRight!=null){E.marginRight=this.marginRight}this._elem.css(E);var I=false,A=false,o,y;var C=B[0];var p=new e.jqplot.ColorGenerator(C.seriesColors);if(C.show){var J=C.data;if(this.numberRows){o=this.numberRows;if(!this.numberColumns){y=Math.ceil(J.length/o)}else{y=this.numberColumns}}else{if(this.numberColumns){y=this.numberColumns;o=Math.ceil(J.length/this.numberColumns)}else{o=J.length;y=1}}var H,G;var q,w,v;var x,z,F;var D=0;var u,t;for(H=0;H0){I=true}else{I=false}}else{if(H==o-1){I=false}else{I=true}}z=(I)?this.rowSpacing:"0";w=e(document.createElement("td"));w.addClass("jqplot-table-legend jqplot-table-legend-swatch");w.css({textAlign:"center",paddingTop:z});u=e(document.createElement("div"));u.addClass("jqplot-table-legend-swatch-outline");t=e(document.createElement("div"));t.addClass("jqplot-table-legend-swatch");t.css({backgroundColor:F,borderColor:F});w.append(u.append(t));v=e(document.createElement("td"));v.addClass("jqplot-table-legend jqplot-table-legend-label");v.css("paddingTop",z);if(this.escapeHtml){v.text(x)}else{v.html(x)}if(A){v.prependTo(q);w.prependTo(q)}else{w.appendTo(q);v.appendTo(q)}I=true}D++}}}}return this._elem};e.jqplot.PieRenderer.prototype.handleMove=function(q,p,t,s,r){if(s){var o=[s.seriesIndex,s.pointIndex,s.data];r.target.trigger("jqplotDataMouseOver",o);if(r.series[o[0]].highlightMouseOver&&!(o[0]==r.plugins.pieRenderer.highlightedSeriesIndex&&o[1]==r.series[o[0]]._highlightedPoint)){r.target.trigger("jqplotDataHighlight",o);d(r,o[0],o[1])}}else{if(s==null){k(r)}}};function c(s,r,p){p=p||{};p.axesDefaults=p.axesDefaults||{};p.legend=p.legend||{};p.seriesDefaults=p.seriesDefaults||{};var o=false;if(p.seriesDefaults.renderer==e.jqplot.PieRenderer){o=true}else{if(p.series){for(var q=0;qB||s+C>m){z.remove()}z=null;f=null}}};c.jqplot.postSeriesInitHooks.push(c.jqplot.PointLabels.init);c.jqplot.postDrawSeriesHooks.push(c.jqplot.PointLabels.draw)})(jQuery); \ No newline at end of file diff --git a/templates/admin/default/assets/js/jqplot/plugins/jqplot.pyramidAxisRenderer.min.js b/templates/admin/default/assets/js/jqplot/plugins/jqplot.pyramidAxisRenderer.min.js new file mode 100644 index 000000000..7b5db948f --- /dev/null +++ b/templates/admin/default/assets/js/jqplot/plugins/jqplot.pyramidAxisRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(e){e.jqplot.PyramidAxisRenderer=function(){e.jqplot.LinearAxisRenderer.call(this)};e.jqplot.PyramidAxisRenderer.prototype=new e.jqplot.LinearAxisRenderer();e.jqplot.PyramidAxisRenderer.prototype.constructor=e.jqplot.PyramidAxisRenderer;e.jqplot.PyramidAxisRenderer.prototype.init=function(f){this.position=null;this.drawBaseline=true;this.baselineWidth=null;this.baselineColor=null;this.tickSpacingFactor=25;this._type="pyramid";this._splitAxis=false;this._splitLength=null;this.category=false;this._autoFormatString="";this._overrideFormatString=false;e.extend(true,this,f);this.renderer.options=f;this.resetDataBounds=this.renderer.resetDataBounds;this.resetDataBounds()};e.jqplot.PyramidAxisRenderer.prototype.resetDataBounds=function(){var h=this._dataBounds;h.min=null;h.max=null;var g;for(var m=0;mh.max)||h.max===null){h.max=g}}else{g=o[k][0];if((g!==null&&gh.max)||h.max===null){h.max=g}}}}};e.jqplot.PyramidAxisRenderer.prototype.draw=function(f,n){if(this.show){this.renderer.createTicks.call(this,n);var m=0;var g;if(this._elem){this._elem.emptyForce();this._elem=null}this._elem=e(document.createElement("div"));this._elem.addClass("jqplot-axis jqplot-"+this.name);this._elem.css("position","absolute");if(this.name=="xaxis"||this.name=="x2axis"){this._elem.width(this._plotDimensions.width)}else{this._elem.height(this._plotDimensions.height)}this.labelOptions.axis=this.name;this._label=new this.labelRenderer(this.labelOptions);if(this._label.show){var l=this._label.draw(f,n);l.appendTo(this._elem);l=null}var k=this._ticks;var j;for(var h=0;hr){I=this.numberTicks-1;for(H=2;H0;H--){v=new this.tickRenderer(this.tickOptions);v.value=this._ticks[H-1].value+this.tickInterval/2;v.label="";v.showLabel=false;v.axis=this.name;this._ticks[H].showGridline=false;this._ticks[H].showMark=false;this._ticks.splice(H,0,v)}v=new this.tickRenderer(this.tickOptions);v.value=this._ticks[0].value-this.tickInterval/2;v.label="";v.showLabel=false;v.axis=this.name;this._ticks.unshift(v);v=new this.tickRenderer(this.tickOptions);v.value=this._ticks[this._ticks.length-1].value+this.tickInterval/2;v.label="";v.showLabel=false;v.axis=this.name;this._ticks.push(v);this.tickInterval=this.tickInterval/2;this.numberTicks=this._ticks.length;this.min=this._ticks[0].value;this.max=this._ticks[this._ticks.length-1].value}}else{if(this.name.charAt(0)==="x"){E=this._plotDimensions.width;var w=Math.max(M.max,Math.abs(M.min));var u=Math.min(M.min,-w);B=u;G=w;y=G-B;if(this.tickOptions==null||!this.tickOptions.formatString){this._overrideFormatString=true}m=30;g=Math.max(E,m+1);j=(g-m)/300;O=e.jqplot.LinearTickGenerator(B,G,j);A=B+y*(this.padMin-1);F=G-y*(this.padMax-1);if(BF){A=B-y*(this.padMin-1);F=G+y*(this.padMax-1);O=e.jqplot.LinearTickGenerator(A,F,j)}this.min=O[0];this.max=O[1];this.numberTicks=O[2];this._autoFormatString=O[3];this.tickInterval=O[4]}else{E=this._plotDimensions.height;B=M.min;G=M.max;x=this._series[0];this._ticks=[];y=G-B;if(d[y]){y+=1;G+=1}this.max=G;this.min=B;r=Math.round(2+E/this.tickSpacingFactor);if(y+1<=r){this.numberTicks=y+1;this.tickInterval=1}else{for(var H=r;H>1;H--){if(y/(H-1)===Math.round(y/(H-1))){this.numberTicks=H;this.tickInterval=y/(H-1);break}}}}if(this._overrideFormatString&&this._autoFormatString!=""){this.tickOptions=this.tickOptions||{};this.tickOptions.formatString=this._autoFormatString}var f;for(H=0;Ho){o=j}}}if(this.name==="yMidAxis"){for(m=0;m0){f=-q._textRenderer.height*Math.cos(-q._textRenderer.angle)/2}else{f=-q.getHeight()+q._textRenderer.height*Math.cos(q._textRenderer.angle)/2}break;case"middle":f=-q.getHeight()/2;break;default:f=-q.getHeight()/2;break}}else{f=-q.getHeight()/2}var C=this.u2p(q.value)+f+"px";q._elem.css("top",C);q.pack()}}if(r){var y=this._label._elem.outerHeight(true);if(this.name!=="yMidAxis"){this._label._elem.css("top",o-k/2-y/2+"px")}if(this.name=="yaxis"){this._label._elem.css("left","0px")}else{if(this.name!=="yMidAxis"){this._label._elem.css("right","0px")}}this._label.pack()}}}B=null}})(jQuery); \ No newline at end of file diff --git a/templates/admin/default/assets/js/jqplot/plugins/jqplot.pyramidGridRenderer.min.js b/templates/admin/default/assets/js/jqplot/plugins/jqplot.pyramidGridRenderer.min.js new file mode 100644 index 000000000..25769919d --- /dev/null +++ b/templates/admin/default/assets/js/jqplot/plugins/jqplot.pyramidGridRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(a){a.jqplot.PyramidGridRenderer=function(){a.jqplot.CanvasGridRenderer.call(this)};a.jqplot.PyramidGridRenderer.prototype=new a.jqplot.CanvasGridRenderer();a.jqplot.PyramidGridRenderer.prototype.constructor=a.jqplot.PyramidGridRenderer;a.jqplot.CanvasGridRenderer.prototype.init=function(c){this._ctx;this.plotBands={show:false,color:"rgb(230, 219, 179)",axis:"y",start:null,interval:10};a.extend(true,this,c);var b={lineJoin:"miter",lineCap:"round",fill:false,isarc:false,angle:this.shadowAngle,offset:this.shadowOffset,alpha:this.shadowAlpha,depth:this.shadowDepth,lineWidth:this.shadowWidth,closePath:false,strokeStyle:this.shadowColor};this.renderer.shadowRenderer.init(b)};a.jqplot.PyramidGridRenderer.prototype.draw=function(){this._ctx=this._elem.get(0).getContext("2d");var D=this._ctx;var G=this._axes;var q=G.xaxis.u2p;var J=G.yMidAxis.u2p;var l=G.xaxis.max/1000;var u=q(0);var f=q(l);var r=["xaxis","yaxis","x2axis","y2axis","yMidAxis"];D.save();D.clearRect(0,0,this._plotDimensions.width,this._plotDimensions.height);D.fillStyle=this.backgroundColor||this.background;D.fillRect(this._left,this._top,this._width,this._height);if(this.plotBands.show){D.save();var c=this.plotBands;D.fillStyle=c.color;var d;var o,n,p,I;if(c.axis.charAt(0)==="x"){if(G.xaxis.show){d=G.xaxis}}else{if(c.axis.charAt(0)==="y"){if(G.yaxis.show){d=G.yaxis}else{if(G.y2axis.show){d=G.y2axis}else{if(G.yMidAxis.show){d=G.yMidAxis}}}}}if(d!==undefined){var g=c.start;if(g===null){g=d.min}for(var H=g;H0;H--){var O=r[H-1];var d=G[O];var M=d._ticks;var B=M.length;if(d.show){if(d.drawBaseline){var N={};if(d.baselineWidth!==null){N.lineWidth=d.baselineWidth}if(d.baselineColor!==null){N.strokeStyle=d.baselineColor}switch(O){case"xaxis":if(G.yMidAxis.show){z(this._left,this._bottom,u,this._bottom,N);z(f,this._bottom,this._right,this._bottom,N)}else{z(this._left,this._bottom,this._right,this._bottom,N)}break;case"yaxis":z(this._left,this._bottom,this._left,this._top,N);break;case"yMidAxis":z(u,this._bottom,u,this._top,N);z(f,this._bottom,f,this._top,N);break;case"x2axis":if(G.yMidAxis.show){z(this._left,this._top,u,this._top,N);z(f,this._top,this._right,this._top,N)}else{z(this._left,this._bottom,this._right,this._bottom,N)}break;case"y2axis":z(this._right,this._bottom,this._right,this._top,N);break}}for(var E=B;E>0;E--){var v=M[E-1];if(v.show){var k=Math.round(d.u2p(v.value))+0.5;switch(O){case"xaxis":if(v.showGridline&&this.drawGridlines&&(!v.isMinorTick||d.showMinorTicks)){z(k,this._top,k,this._bottom)}if(v.showMark&&v.mark&&(!v.isMinorTick||d.showMinorTicks)){A=v.markSize;C=v.mark;var k=Math.round(d.u2p(v.value))+0.5;switch(C){case"outside":L=this._bottom;K=this._bottom+A;break;case"inside":L=this._bottom-A;K=this._bottom;break;case"cross":L=this._bottom-A;K=this._bottom+A;break;default:L=this._bottom;K=this._bottom+A;break}if(this.shadow){this.renderer.shadowRenderer.draw(D,[[k,L],[k,K]],{lineCap:"butt",lineWidth:this.gridLineWidth,offset:this.gridLineWidth*0.75,depth:2,fill:false,closePath:false})}z(k,L,k,K)}break;case"yaxis":if(v.showGridline&&this.drawGridlines&&(!v.isMinorTick||d.showMinorTicks)){z(this._right,k,this._left,k)}if(v.showMark&&v.mark&&(!v.isMinorTick||d.showMinorTicks)){A=v.markSize;C=v.mark;var k=Math.round(d.u2p(v.value))+0.5;switch(C){case"outside":L=this._left-A;K=this._left;break;case"inside":L=this._left;K=this._left+A;break;case"cross":L=this._left-A;K=this._left+A;break;default:L=this._left-A;K=this._left;break}if(this.shadow){this.renderer.shadowRenderer.draw(D,[[L,k],[K,k]],{lineCap:"butt",lineWidth:this.gridLineWidth*1.5,offset:this.gridLineWidth*0.75,fill:false,closePath:false})}z(L,k,K,k,{strokeStyle:d.borderColor})}break;case"yMidAxis":if(v.showGridline&&this.drawGridlines&&(!v.isMinorTick||d.showMinorTicks)){z(this._left,k,u,k);z(f,k,this._right,k)}if(v.showMark&&v.mark&&(!v.isMinorTick||d.showMinorTicks)){A=v.markSize;C=v.mark;var k=Math.round(d.u2p(v.value))+0.5;L=u;K=u+A;if(this.shadow){this.renderer.shadowRenderer.draw(D,[[L,k],[K,k]],{lineCap:"butt",lineWidth:this.gridLineWidth*1.5,offset:this.gridLineWidth*0.75,fill:false,closePath:false})}z(L,k,K,k,{strokeStyle:d.borderColor});L=f-A;K=f;if(this.shadow){this.renderer.shadowRenderer.draw(D,[[L,k],[K,k]],{lineCap:"butt",lineWidth:this.gridLineWidth*1.5,offset:this.gridLineWidth*0.75,fill:false,closePath:false})}z(L,k,K,k,{strokeStyle:d.borderColor})}break;case"x2axis":if(v.showGridline&&this.drawGridlines&&(!v.isMinorTick||d.showMinorTicks)){z(k,this._bottom,k,this._top)}if(v.showMark&&v.mark&&(!v.isMinorTick||d.showMinorTicks)){A=v.markSize;C=v.mark;var k=Math.round(d.u2p(v.value))+0.5;switch(C){case"outside":L=this._top-A;K=this._top;break;case"inside":L=this._top;K=this._top+A;break;case"cross":L=this._top-A;K=this._top+A;break;default:L=this._top-A;K=this._top;break}if(this.shadow){this.renderer.shadowRenderer.draw(D,[[k,L],[k,K]],{lineCap:"butt",lineWidth:this.gridLineWidth,offset:this.gridLineWidth*0.75,depth:2,fill:false,closePath:false})}z(k,L,k,K)}break;case"y2axis":if(v.showGridline&&this.drawGridlines&&(!v.isMinorTick||d.showMinorTicks)){z(this._left,k,this._right,k)}if(v.showMark&&v.mark&&(!v.isMinorTick||d.showMinorTicks)){A=v.markSize;C=v.mark;var k=Math.round(d.u2p(v.value))+0.5;switch(C){case"outside":L=this._right;K=this._right+A;break;case"inside":L=this._right-A;K=this._right;break;case"cross":L=this._right-A;K=this._right+A;break;default:L=this._right;K=this._right+A;break}if(this.shadow){this.renderer.shadowRenderer.draw(D,[[L,k],[K,k]],{lineCap:"butt",lineWidth:this.gridLineWidth*1.5,offset:this.gridLineWidth*0.75,fill:false,closePath:false})}z(L,k,K,k,{strokeStyle:d.borderColor})}break;default:break}}}v=null}d=null;M=null}D.restore();function z(j,i,e,b,h){D.save();h=h||{};if(h.lineWidth==null||h.lineWidth!=0){a.extend(true,D,h);D.beginPath();D.moveTo(j,i);D.lineTo(e,b);D.stroke()}D.restore()}if(this.shadow){if(G.yMidAxis.show){var F=[[this._left,this._bottom],[u,this._bottom]];this.renderer.shadowRenderer.draw(D,F);var F=[[f,this._bottom],[this._right,this._bottom],[this._right,this._top]];this.renderer.shadowRenderer.draw(D,F);var F=[[u,this._bottom],[u,this._top]];this.renderer.shadowRenderer.draw(D,F)}else{var F=[[this._left,this._bottom],[this._right,this._bottom],[this._right,this._top]];this.renderer.shadowRenderer.draw(D,F)}}if(this.borderWidth!=0&&this.drawBorder){if(G.yMidAxis.show){z(this._left,this._top,u,this._top,{lineCap:"round",strokeStyle:G.x2axis.borderColor,lineWidth:G.x2axis.borderWidth});z(f,this._top,this._right,this._top,{lineCap:"round",strokeStyle:G.x2axis.borderColor,lineWidth:G.x2axis.borderWidth});z(this._right,this._top,this._right,this._bottom,{lineCap:"round",strokeStyle:G.y2axis.borderColor,lineWidth:G.y2axis.borderWidth});z(this._right,this._bottom,f,this._bottom,{lineCap:"round",strokeStyle:G.xaxis.borderColor,lineWidth:G.xaxis.borderWidth});z(u,this._bottom,this._left,this._bottom,{lineCap:"round",strokeStyle:G.xaxis.borderColor,lineWidth:G.xaxis.borderWidth});z(this._left,this._bottom,this._left,this._top,{lineCap:"round",strokeStyle:G.yaxis.borderColor,lineWidth:G.yaxis.borderWidth});z(u,this._bottom,u,this._top,{lineCap:"round",strokeStyle:G.yaxis.borderColor,lineWidth:G.yaxis.borderWidth});z(f,this._bottom,f,this._top,{lineCap:"round",strokeStyle:G.yaxis.borderColor,lineWidth:G.yaxis.borderWidth})}else{z(this._left,this._top,this._right,this._top,{lineCap:"round",strokeStyle:G.x2axis.borderColor,lineWidth:G.x2axis.borderWidth});z(this._right,this._top,this._right,this._bottom,{lineCap:"round",strokeStyle:G.y2axis.borderColor,lineWidth:G.y2axis.borderWidth});z(this._right,this._bottom,this._left,this._bottom,{lineCap:"round",strokeStyle:G.xaxis.borderColor,lineWidth:G.xaxis.borderWidth});z(this._left,this._bottom,this._left,this._top,{lineCap:"round",strokeStyle:G.yaxis.borderColor,lineWidth:G.yaxis.borderWidth})}}D.restore();D=null;G=null}})(jQuery); \ No newline at end of file diff --git a/templates/admin/default/assets/js/jqplot/plugins/jqplot.pyramidRenderer.min.js b/templates/admin/default/assets/js/jqplot/plugins/jqplot.pyramidRenderer.min.js new file mode 100644 index 000000000..9266e2273 --- /dev/null +++ b/templates/admin/default/assets/js/jqplot/plugins/jqplot.pyramidRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(c){if(c.jqplot.PyramidAxisRenderer===undefined){c.ajax({url:c.jqplot.pluginLocation+"jqplot.pyramidAxisRenderer.js",dataType:"script",async:false})}if(c.jqplot.PyramidGridRenderer===undefined){c.ajax({url:c.jqplot.pluginLocation+"jqplot.pyramidGridRenderer.js",dataType:"script",async:false})}c.jqplot.PyramidRenderer=function(){c.jqplot.LineRenderer.call(this)};c.jqplot.PyramidRenderer.prototype=new c.jqplot.LineRenderer();c.jqplot.PyramidRenderer.prototype.constructor=c.jqplot.PyramidRenderer;c.jqplot.PyramidRenderer.prototype.init=function(j,o){j=j||{};this._type="pyramid";this.barPadding=10;this.barWidth=null;this.fill=true;this.highlightMouseOver=true;this.highlightMouseDown=false;this.highlightColors=[];this.highlightThreshold=2;this.synchronizeHighlight=false;this.offsetBars=false;if(j.highlightMouseDown&&j.highlightMouseOver==null){j.highlightMouseOver=false}this.side="right";c.extend(true,this,j);if(this.side==="left"){this._highlightThreshold=[[-this.highlightThreshold,0],[-this.highlightThreshold,0],[0,0],[0,0]]}else{this._highlightThreshold=[[0,0],[0,0],[this.highlightThreshold,0],[this.highlightThreshold,0]]}this.renderer.options=j;this._highlightedPoint=null;this._dataColors=[];this._barPoints=[];this.fillAxis="y";this._primaryAxis="_yaxis";this._xnudge=0;var n={lineJoin:"miter",lineCap:"butt",fill:this.fill,fillRect:this.fill,isarc:false,strokeStyle:this.color,fillStyle:this.color,closePath:this.fill,lineWidth:this.lineWidth};this.renderer.shapeRenderer.init(n);var m=j.shadowOffset;if(m==null){if(this.lineWidth>2.5){m=1.25*(1+(Math.atan((this.lineWidth/2.5))/0.785398163-1)*0.6)}else{m=1.25*Math.atan((this.lineWidth/2.5))/0.785398163}}var h={lineJoin:"miter",lineCap:"butt",fill:this.fill,fillRect:this.fill,isarc:false,angle:this.shadowAngle,offset:m,alpha:this.shadowAlpha,depth:this.shadowDepth,closePath:this.fill,lineWidth:this.lineWidth};this.renderer.shadowRenderer.init(h);o.postDrawHooks.addOnce(f);o.eventListenerHooks.addOnce("jqplotMouseMove",e);if(this.side==="left"){for(var k=0,g=this.data.length;k=0){s=I[E][0]-L;F=this.barWidth;D=[L,n-y-r,s,F]}else{s=L-I[E][0];F=this.barWidth;D=[I[E][0],n-y-r,s,F]}this._barPoints.push([[D[0],D[1]+F],[D[0],D[1]],[D[0]+s,D[1]],[D[0]+s,D[1]+F]]);if(p){this.renderer.shadowRenderer.draw(B,D)}var g=u.fillStyle||this.color;this._dataColors.push(g);this.renderer.shapeRenderer.draw(B,D,u)}else{if(E===0){D=[[L,j],[I[E][0],j],[I[E][0],I[E][1]-y-r]]}else{if(E=h.synchronizeHighlight&&h.synchronizeHighlight!==l){h=m.series[h.synchronizeHighlight];k={fillStyle:h.highlightColors[j],fillRect:false};h.renderer.shapeRenderer.draw(g._ctx,h._barPoints[j],k)}g=null}function d(j){var g=j.plugins.pyramidRenderer.highlightCanvas;g._ctx.clearRect(0,0,g._ctx.canvas.width,g._ctx.canvas.height);for(var h=0;h)[^>]*|#([\w-]*))$/,k=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,E=/^[\],:{}\s]*$/,S=/(?:^|:|,)(?:\s*\[)+/g,A=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,j=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,D=/^-ms-/,L=/-([\da-z])/gi,H=function(e,t){return t.toUpperCase()},q=function(e){(a.addEventListener||"load"===e.type||"complete"===a.readyState)&&(_(),x.ready())},_=function(){a.addEventListener?(a.removeEventListener("DOMContentLoaded",q,!1),e.removeEventListener("load",q,!1)):(a.detachEvent("onreadystatechange",q),e.detachEvent("onload",q))};x.fn=x.prototype={jquery:f,constructor:x,init:function(e,n,r){var i,o;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof x?n[0]:n,x.merge(this,x.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:a,!0)),k.test(i[1])&&x.isPlainObject(n))for(i in n)x.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(o=a.getElementById(i[2]),o&&o.parentNode){if(o.id!==i[2])return r.find(e);this.length=1,this[0]=o}return this.context=a,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):x.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),x.makeArray(e,this))},selector:"",length:0,toArray:function(){return g.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=x.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return x.each(this,e,t)},ready:function(e){return x.ready.promise().done(e),this},slice:function(){return this.pushStack(g.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(x.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:h,sort:[].sort,splice:[].splice},x.fn.init.prototype=x.fn,x.extend=x.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},l=1,u=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},l=2),"object"==typeof s||x.isFunction(s)||(s={}),u===l&&(s=this,--l);u>l;l++)if(null!=(o=arguments[l]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(x.isPlainObject(r)||(n=x.isArray(r)))?(n?(n=!1,a=e&&x.isArray(e)?e:[]):a=e&&x.isPlainObject(e)?e:{},s[i]=x.extend(c,a,r)):r!==t&&(s[i]=r));return s},x.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),noConflict:function(t){return e.$===x&&(e.$=u),t&&e.jQuery===x&&(e.jQuery=l),x},isReady:!1,readyWait:1,holdReady:function(e){e?x.readyWait++:x.ready(!0)},ready:function(e){if(e===!0?!--x.readyWait:!x.isReady){if(!a.body)return setTimeout(x.ready);x.isReady=!0,e!==!0&&--x.readyWait>0||(n.resolveWith(a,[x]),x.fn.trigger&&x(a).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===x.type(e)},isArray:Array.isArray||function(e){return"array"===x.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?c[y.call(e)]||"object":typeof e},isPlainObject:function(e){var n;if(!e||"object"!==x.type(e)||e.nodeType||x.isWindow(e))return!1;try{if(e.constructor&&!v.call(e,"constructor")&&!v.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(r){return!1}if(x.support.ownLast)for(n in e)return v.call(e,n);for(n in e);return n===t||v.call(e,n)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||a;var r=k.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=x.buildFragment([e],t,i),i&&x(i).remove(),x.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=x.trim(n),n&&E.test(n.replace(A,"@").replace(j,"]").replace(S,"")))?Function("return "+n)():(x.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||x.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&x.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(D,"ms-").replace(L,H)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,a=M(e);if(n){if(a){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(a){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:b&&!b.call("\ufeff\u00a0")?function(e){return null==e?"":b.call(e)}:function(e){return null==e?"":(e+"").replace(C,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(M(Object(e))?x.merge(n,"string"==typeof e?[e]:e):h.call(n,e)),n},inArray:function(e,t,n){var r;if(t){if(m)return m.call(t,e,n);for(r=t.length,n=n?0>n?Math.max(0,r+n):n:0;r>n;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,o=0;if("number"==typeof r)for(;r>o;o++)e[i++]=n[o];else while(n[o]!==t)e[i++]=n[o++];return e.length=i,e},grep:function(e,t,n){var r,i=[],o=0,a=e.length;for(n=!!n;a>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,a=M(e),s=[];if(a)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(s[s.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(s[s.length]=r);return d.apply([],s)},guid:1,proxy:function(e,n){var r,i,o;return"string"==typeof n&&(o=e[n],n=e,e=o),x.isFunction(e)?(r=g.call(arguments,2),i=function(){return e.apply(n||this,r.concat(g.call(arguments)))},i.guid=e.guid=e.guid||x.guid++,i):t},access:function(e,n,r,i,o,a,s){var l=0,u=e.length,c=null==r;if("object"===x.type(r)){o=!0;for(l in r)x.access(e,n,l,r[l],!0,a,s)}else if(i!==t&&(o=!0,x.isFunction(i)||(s=!0),c&&(s?(n.call(e,i),n=null):(c=n,n=function(e,t,n){return c.call(x(e),n)})),n))for(;u>l;l++)n(e[l],r,s?i:i.call(e[l],l,n(e[l],r)));return o?e:c?n.call(e):u?n(e[0],r):a},now:function(){return(new Date).getTime()},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),x.ready.promise=function(t){if(!n)if(n=x.Deferred(),"complete"===a.readyState)setTimeout(x.ready);else if(a.addEventListener)a.addEventListener("DOMContentLoaded",q,!1),e.addEventListener("load",q,!1);else{a.attachEvent("onreadystatechange",q),e.attachEvent("onload",q);var r=!1;try{r=null==e.frameElement&&a.documentElement}catch(i){}r&&r.doScroll&&function o(){if(!x.isReady){try{r.doScroll("left")}catch(e){return setTimeout(o,50)}_(),x.ready()}}()}return n.promise(t)},x.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){c["[object "+t+"]"]=t.toLowerCase()});function M(e){var t=e.length,n=x.type(e);return x.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}r=x(a),function(e,t){var n,r,i,o,a,s,l,u,c,p,f,d,h,g,m,y,v,b="sizzle"+-new Date,w=e.document,T=0,C=0,N=lt(),k=lt(),E=lt(),S=!1,A=function(){return 0},j=typeof t,D=1<<31,L={}.hasOwnProperty,H=[],q=H.pop,_=H.push,M=H.push,O=H.slice,F=H.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},B="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",P="[\\x20\\t\\r\\n\\f]",R="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",W=R.replace("w","w#"),$="\\["+P+"*("+R+")"+P+"*(?:([*^$|!~]?=)"+P+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+W+")|)|)"+P+"*\\]",I=":("+R+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+$.replace(3,8)+")*)|.*)\\)|)",z=RegExp("^"+P+"+|((?:^|[^\\\\])(?:\\\\.)*)"+P+"+$","g"),X=RegExp("^"+P+"*,"+P+"*"),U=RegExp("^"+P+"*([>+~]|"+P+")"+P+"*"),V=RegExp(P+"*[+~]"),Y=RegExp("="+P+"*([^\\]'\"]*)"+P+"*\\]","g"),J=RegExp(I),G=RegExp("^"+W+"$"),Q={ID:RegExp("^#("+R+")"),CLASS:RegExp("^\\.("+R+")"),TAG:RegExp("^("+R.replace("w","w*")+")"),ATTR:RegExp("^"+$),PSEUDO:RegExp("^"+I),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+P+"*(even|odd|(([+-]|)(\\d*)n|)"+P+"*(?:([+-]|)"+P+"*(\\d+)|))"+P+"*\\)|)","i"),bool:RegExp("^(?:"+B+")$","i"),needsContext:RegExp("^"+P+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+P+"*((?:-\\d)?\\d*)"+P+"*\\)|)(?=[^-]|$)","i")},K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,et=/^(?:input|select|textarea|button)$/i,tt=/^h\d$/i,nt=/'|\\/g,rt=RegExp("\\\\([\\da-f]{1,6}"+P+"?|("+P+")|.)","ig"),it=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:0>r?String.fromCharCode(r+65536):String.fromCharCode(55296|r>>10,56320|1023&r)};try{M.apply(H=O.call(w.childNodes),w.childNodes),H[w.childNodes.length].nodeType}catch(ot){M={apply:H.length?function(e,t){_.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function at(e,t,n,i){var o,a,s,l,u,c,d,m,y,x;if((t?t.ownerDocument||t:w)!==f&&p(t),t=t||f,n=n||[],!e||"string"!=typeof e)return n;if(1!==(l=t.nodeType)&&9!==l)return[];if(h&&!i){if(o=Z.exec(e))if(s=o[1]){if(9===l){if(a=t.getElementById(s),!a||!a.parentNode)return n;if(a.id===s)return n.push(a),n}else if(t.ownerDocument&&(a=t.ownerDocument.getElementById(s))&&v(t,a)&&a.id===s)return n.push(a),n}else{if(o[2])return M.apply(n,t.getElementsByTagName(e)),n;if((s=o[3])&&r.getElementsByClassName&&t.getElementsByClassName)return M.apply(n,t.getElementsByClassName(s)),n}if(r.qsa&&(!g||!g.test(e))){if(m=d=b,y=t,x=9===l&&e,1===l&&"object"!==t.nodeName.toLowerCase()){c=bt(e),(d=t.getAttribute("id"))?m=d.replace(nt,"\\$&"):t.setAttribute("id",m),m="[id='"+m+"'] ",u=c.length;while(u--)c[u]=m+xt(c[u]);y=V.test(e)&&t.parentNode||t,x=c.join(",")}if(x)try{return M.apply(n,y.querySelectorAll(x)),n}catch(T){}finally{d||t.removeAttribute("id")}}}return At(e.replace(z,"$1"),t,n,i)}function st(e){return K.test(e+"")}function lt(){var e=[];function t(n,r){return e.push(n+=" ")>o.cacheLength&&delete t[e.shift()],t[n]=r}return t}function ut(e){return e[b]=!0,e}function ct(e){var t=f.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function pt(e,t,n){e=e.split("|");var r,i=e.length,a=n?null:t;while(i--)(r=o.attrHandle[e[i]])&&r!==t||(o.attrHandle[e[i]]=a)}function ft(e,t){var n=e.getAttributeNode(t);return n&&n.specified?n.value:e[t]===!0?t.toLowerCase():null}function dt(e,t){return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}function ht(e){return"input"===e.nodeName.toLowerCase()?e.defaultValue:t}function gt(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||D)-(~e.sourceIndex||D);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function mt(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function yt(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function vt(e){return ut(function(t){return t=+t,ut(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}s=at.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},r=at.support={},p=at.setDocument=function(e){var n=e?e.ownerDocument||e:w,i=n.parentWindow;return n!==f&&9===n.nodeType&&n.documentElement?(f=n,d=n.documentElement,h=!s(n),i&&i.frameElement&&i.attachEvent("onbeforeunload",function(){p()}),r.attributes=ct(function(e){return e.innerHTML="",pt("type|href|height|width",dt,"#"===e.firstChild.getAttribute("href")),pt(B,ft,null==e.getAttribute("disabled")),e.className="i",!e.getAttribute("className")}),r.input=ct(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")}),pt("value",ht,r.attributes&&r.input),r.getElementsByTagName=ct(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),r.getElementsByClassName=ct(function(e){return e.innerHTML="
    ",e.firstChild.className="i",2===e.getElementsByClassName("i").length}),r.getById=ct(function(e){return d.appendChild(e).id=b,!n.getElementsByName||!n.getElementsByName(b).length}),r.getById?(o.find.ID=function(e,t){if(typeof t.getElementById!==j&&h){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},o.filter.ID=function(e){var t=e.replace(rt,it);return function(e){return e.getAttribute("id")===t}}):(delete o.find.ID,o.filter.ID=function(e){var t=e.replace(rt,it);return function(e){var n=typeof e.getAttributeNode!==j&&e.getAttributeNode("id");return n&&n.value===t}}),o.find.TAG=r.getElementsByTagName?function(e,n){return typeof n.getElementsByTagName!==j?n.getElementsByTagName(e):t}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},o.find.CLASS=r.getElementsByClassName&&function(e,n){return typeof n.getElementsByClassName!==j&&h?n.getElementsByClassName(e):t},m=[],g=[],(r.qsa=st(n.querySelectorAll))&&(ct(function(e){e.innerHTML="",e.querySelectorAll("[selected]").length||g.push("\\["+P+"*(?:value|"+B+")"),e.querySelectorAll(":checked").length||g.push(":checked")}),ct(function(e){var t=n.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("t",""),e.querySelectorAll("[t^='']").length&&g.push("[*^$]="+P+"*(?:''|\"\")"),e.querySelectorAll(":enabled").length||g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(r.matchesSelector=st(y=d.webkitMatchesSelector||d.mozMatchesSelector||d.oMatchesSelector||d.msMatchesSelector))&&ct(function(e){r.disconnectedMatch=y.call(e,"div"),y.call(e,"[s!='']:x"),m.push("!=",I)}),g=g.length&&RegExp(g.join("|")),m=m.length&&RegExp(m.join("|")),v=st(d.contains)||d.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},r.sortDetached=ct(function(e){return 1&e.compareDocumentPosition(n.createElement("div"))}),A=d.compareDocumentPosition?function(e,t){if(e===t)return S=!0,0;var i=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t);return i?1&i||!r.sortDetached&&t.compareDocumentPosition(e)===i?e===n||v(w,e)?-1:t===n||v(w,t)?1:c?F.call(c,e)-F.call(c,t):0:4&i?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var r,i=0,o=e.parentNode,a=t.parentNode,s=[e],l=[t];if(e===t)return S=!0,0;if(!o||!a)return e===n?-1:t===n?1:o?-1:a?1:c?F.call(c,e)-F.call(c,t):0;if(o===a)return gt(e,t);r=e;while(r=r.parentNode)s.unshift(r);r=t;while(r=r.parentNode)l.unshift(r);while(s[i]===l[i])i++;return i?gt(s[i],l[i]):s[i]===w?-1:l[i]===w?1:0},n):f},at.matches=function(e,t){return at(e,null,null,t)},at.matchesSelector=function(e,t){if((e.ownerDocument||e)!==f&&p(e),t=t.replace(Y,"='$1']"),!(!r.matchesSelector||!h||m&&m.test(t)||g&&g.test(t)))try{var n=y.call(e,t);if(n||r.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(i){}return at(t,f,null,[e]).length>0},at.contains=function(e,t){return(e.ownerDocument||e)!==f&&p(e),v(e,t)},at.attr=function(e,n){(e.ownerDocument||e)!==f&&p(e);var i=o.attrHandle[n.toLowerCase()],a=i&&L.call(o.attrHandle,n.toLowerCase())?i(e,n,!h):t;return a===t?r.attributes||!h?e.getAttribute(n):(a=e.getAttributeNode(n))&&a.specified?a.value:null:a},at.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},at.uniqueSort=function(e){var t,n=[],i=0,o=0;if(S=!r.detectDuplicates,c=!r.sortStable&&e.slice(0),e.sort(A),S){while(t=e[o++])t===e[o]&&(i=n.push(o));while(i--)e.splice(n[i],1)}return e},a=at.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=a(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=a(t);return n},o=at.selectors={cacheLength:50,createPseudo:ut,match:Q,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(rt,it),e[3]=(e[4]||e[5]||"").replace(rt,it),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||at.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&at.error(e[0]),e},PSEUDO:function(e){var n,r=!e[5]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]&&e[4]!==t?e[2]=e[4]:r&&J.test(r)&&(n=bt(r,!0))&&(n=r.indexOf(")",r.length-n)-r.length)&&(e[0]=e[0].slice(0,n),e[2]=r.slice(0,n)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(rt,it).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=N[e+" "];return t||(t=RegExp("(^|"+P+")"+e+"("+P+"|$)"))&&N(e,function(e){return t.test("string"==typeof e.className&&e.className||typeof e.getAttribute!==j&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=at.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,l){var u,c,p,f,d,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!l&&!s;if(m){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){c=m[b]||(m[b]={}),u=c[e]||[],d=u[0]===T&&u[1],f=u[0]===T&&u[2],p=d&&m.childNodes[d];while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[T,d,f];break}}else if(v&&(u=(t[b]||(t[b]={}))[e])&&u[0]===T)f=u[1];else while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(v&&((p[b]||(p[b]={}))[e]=[T,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=o.pseudos[e]||o.setFilters[e.toLowerCase()]||at.error("unsupported pseudo: "+e);return r[b]?r(t):r.length>1?(n=[e,e,"",t],o.setFilters.hasOwnProperty(e.toLowerCase())?ut(function(e,n){var i,o=r(e,t),a=o.length;while(a--)i=F.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:ut(function(e){var t=[],n=[],r=l(e.replace(z,"$1"));return r[b]?ut(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:ut(function(e){return function(t){return at(e,t).length>0}}),contains:ut(function(e){return function(t){return(t.textContent||t.innerText||a(t)).indexOf(e)>-1}}),lang:ut(function(e){return G.test(e||"")||at.error("unsupported lang: "+e),e=e.replace(rt,it).toLowerCase(),function(t){var n;do if(n=h?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===d},focus:function(e){return e===f.activeElement&&(!f.hasFocus||f.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!o.pseudos.empty(e)},header:function(e){return tt.test(e.nodeName)},input:function(e){return et.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:vt(function(){return[0]}),last:vt(function(e,t){return[t-1]}),eq:vt(function(e,t,n){return[0>n?n+t:n]}),even:vt(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:vt(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:vt(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:vt(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}};for(n in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})o.pseudos[n]=mt(n);for(n in{submit:!0,reset:!0})o.pseudos[n]=yt(n);function bt(e,t){var n,r,i,a,s,l,u,c=k[e+" "];if(c)return t?0:c.slice(0);s=e,l=[],u=o.preFilter;while(s){(!n||(r=X.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),l.push(i=[])),n=!1,(r=U.exec(s))&&(n=r.shift(),i.push({value:n,type:r[0].replace(z," ")}),s=s.slice(n.length));for(a in o.filter)!(r=Q[a].exec(s))||u[a]&&!(r=u[a](r))||(n=r.shift(),i.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?at.error(e):k(e,l).slice(0)}function xt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function wt(e,t,n){var r=t.dir,o=n&&"parentNode"===r,a=C++;return t.first?function(t,n,i){while(t=t[r])if(1===t.nodeType||o)return e(t,n,i)}:function(t,n,s){var l,u,c,p=T+" "+a;if(s){while(t=t[r])if((1===t.nodeType||o)&&e(t,n,s))return!0}else while(t=t[r])if(1===t.nodeType||o)if(c=t[b]||(t[b]={}),(u=c[r])&&u[0]===p){if((l=u[1])===!0||l===i)return l===!0}else if(u=c[r]=[p],u[1]=e(t,n,s)||i,u[1]===!0)return!0}}function Tt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function Ct(e,t,n,r,i){var o,a=[],s=0,l=e.length,u=null!=t;for(;l>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),u&&t.push(s));return a}function Nt(e,t,n,r,i,o){return r&&!r[b]&&(r=Nt(r)),i&&!i[b]&&(i=Nt(i,o)),ut(function(o,a,s,l){var u,c,p,f=[],d=[],h=a.length,g=o||St(t||"*",s.nodeType?[s]:s,[]),m=!e||!o&&t?g:Ct(g,f,e,s,l),y=n?i||(o?e:h||r)?[]:a:m;if(n&&n(m,y,s,l),r){u=Ct(y,d),r(u,[],s,l),c=u.length;while(c--)(p=u[c])&&(y[d[c]]=!(m[d[c]]=p))}if(o){if(i||e){if(i){u=[],c=y.length;while(c--)(p=y[c])&&u.push(m[c]=p);i(null,y=[],u,l)}c=y.length;while(c--)(p=y[c])&&(u=i?F.call(o,p):f[c])>-1&&(o[u]=!(a[u]=p))}}else y=Ct(y===a?y.splice(h,y.length):y),i?i(null,a,y,l):M.apply(a,y)})}function kt(e){var t,n,r,i=e.length,a=o.relative[e[0].type],s=a||o.relative[" "],l=a?1:0,c=wt(function(e){return e===t},s,!0),p=wt(function(e){return F.call(t,e)>-1},s,!0),f=[function(e,n,r){return!a&&(r||n!==u)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;i>l;l++)if(n=o.relative[e[l].type])f=[wt(Tt(f),n)];else{if(n=o.filter[e[l].type].apply(null,e[l].matches),n[b]){for(r=++l;i>r;r++)if(o.relative[e[r].type])break;return Nt(l>1&&Tt(f),l>1&&xt(e.slice(0,l-1).concat({value:" "===e[l-2].type?"*":""})).replace(z,"$1"),n,r>l&&kt(e.slice(l,r)),i>r&&kt(e=e.slice(r)),i>r&&xt(e))}f.push(n)}return Tt(f)}function Et(e,t){var n=0,r=t.length>0,a=e.length>0,s=function(s,l,c,p,d){var h,g,m,y=[],v=0,b="0",x=s&&[],w=null!=d,C=u,N=s||a&&o.find.TAG("*",d&&l.parentNode||l),k=T+=null==C?1:Math.random()||.1;for(w&&(u=l!==f&&l,i=n);null!=(h=N[b]);b++){if(a&&h){g=0;while(m=e[g++])if(m(h,l,c)){p.push(h);break}w&&(T=k,i=++n)}r&&((h=!m&&h)&&v--,s&&x.push(h))}if(v+=b,r&&b!==v){g=0;while(m=t[g++])m(x,y,l,c);if(s){if(v>0)while(b--)x[b]||y[b]||(y[b]=q.call(p));y=Ct(y)}M.apply(p,y),w&&!s&&y.length>0&&v+t.length>1&&at.uniqueSort(p)}return w&&(T=k,u=C),x};return r?ut(s):s}l=at.compile=function(e,t){var n,r=[],i=[],o=E[e+" "];if(!o){t||(t=bt(e)),n=t.length;while(n--)o=kt(t[n]),o[b]?r.push(o):i.push(o);o=E(e,Et(i,r))}return o};function St(e,t,n){var r=0,i=t.length;for(;i>r;r++)at(e,t[r],n);return n}function At(e,t,n,i){var a,s,u,c,p,f=bt(e);if(!i&&1===f.length){if(s=f[0]=f[0].slice(0),s.length>2&&"ID"===(u=s[0]).type&&r.getById&&9===t.nodeType&&h&&o.relative[s[1].type]){if(t=(o.find.ID(u.matches[0].replace(rt,it),t)||[])[0],!t)return n;e=e.slice(s.shift().value.length)}a=Q.needsContext.test(e)?0:s.length;while(a--){if(u=s[a],o.relative[c=u.type])break;if((p=o.find[c])&&(i=p(u.matches[0].replace(rt,it),V.test(s[0].type)&&t.parentNode||t))){if(s.splice(a,1),e=i.length&&xt(s),!e)return M.apply(n,i),n;break}}}return l(e,f)(i,t,!h,n,V.test(e)),n}o.pseudos.nth=o.pseudos.eq;function jt(){}jt.prototype=o.filters=o.pseudos,o.setFilters=new jt,r.sortStable=b.split("").sort(A).join("")===b,p(),[0,0].sort(A),r.detectDuplicates=S,x.find=at,x.expr=at.selectors,x.expr[":"]=x.expr.pseudos,x.unique=at.uniqueSort,x.text=at.getText,x.isXMLDoc=at.isXML,x.contains=at.contains}(e);var O={};function F(e){var t=O[e]={};return x.each(e.match(T)||[],function(e,n){t[n]=!0}),t}x.Callbacks=function(e){e="string"==typeof e?O[e]||F(e):x.extend({},e);var n,r,i,o,a,s,l=[],u=!e.once&&[],c=function(t){for(r=e.memory&&t,i=!0,a=s||0,s=0,o=l.length,n=!0;l&&o>a;a++)if(l[a].apply(t[0],t[1])===!1&&e.stopOnFalse){r=!1;break}n=!1,l&&(u?u.length&&c(u.shift()):r?l=[]:p.disable())},p={add:function(){if(l){var t=l.length;(function i(t){x.each(t,function(t,n){var r=x.type(n);"function"===r?e.unique&&p.has(n)||l.push(n):n&&n.length&&"string"!==r&&i(n)})})(arguments),n?o=l.length:r&&(s=t,c(r))}return this},remove:function(){return l&&x.each(arguments,function(e,t){var r;while((r=x.inArray(t,l,r))>-1)l.splice(r,1),n&&(o>=r&&o--,a>=r&&a--)}),this},has:function(e){return e?x.inArray(e,l)>-1:!(!l||!l.length)},empty:function(){return l=[],o=0,this},disable:function(){return l=u=r=t,this},disabled:function(){return!l},lock:function(){return u=t,r||p.disable(),this},locked:function(){return!u},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],!l||i&&!u||(n?u.push(t):c(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},x.extend({Deferred:function(e){var t=[["resolve","done",x.Callbacks("once memory"),"resolved"],["reject","fail",x.Callbacks("once memory"),"rejected"],["notify","progress",x.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return x.Deferred(function(n){x.each(t,function(t,o){var a=o[0],s=x.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&x.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?x.extend(e,r):r}},i={};return r.pipe=r.then,x.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=g.call(arguments),r=n.length,i=1!==r||e&&x.isFunction(e.promise)?r:0,o=1===i?e:x.Deferred(),a=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?g.call(arguments):r,n===s?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},s,l,u;if(r>1)for(s=Array(r),l=Array(r),u=Array(r);r>t;t++)n[t]&&x.isFunction(n[t].promise)?n[t].promise().done(a(t,u,n)).fail(o.reject).progress(a(t,l,s)):--i;return i||o.resolveWith(u,n),o.promise()}}),x.support=function(t){var n,r,o,s,l,u,c,p,f,d=a.createElement("div");if(d.setAttribute("className","t"),d.innerHTML="
    a",n=d.getElementsByTagName("*")||[],r=d.getElementsByTagName("a")[0],!r||!r.style||!n.length)return t;s=a.createElement("select"),u=s.appendChild(a.createElement("option")),o=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t.getSetAttribute="t"!==d.className,t.leadingWhitespace=3===d.firstChild.nodeType,t.tbody=!d.getElementsByTagName("tbody").length,t.htmlSerialize=!!d.getElementsByTagName("link").length,t.style=/top/.test(r.getAttribute("style")),t.hrefNormalized="/a"===r.getAttribute("href"),t.opacity=/^0.5/.test(r.style.opacity),t.cssFloat=!!r.style.cssFloat,t.checkOn=!!o.value,t.optSelected=u.selected,t.enctype=!!a.createElement("form").enctype,t.html5Clone="<:nav>"!==a.createElement("nav").cloneNode(!0).outerHTML,t.inlineBlockNeedsLayout=!1,t.shrinkWrapBlocks=!1,t.pixelPosition=!1,t.deleteExpando=!0,t.noCloneEvent=!0,t.reliableMarginRight=!0,t.boxSizingReliable=!0,o.checked=!0,t.noCloneChecked=o.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!u.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}o=a.createElement("input"),o.setAttribute("value",""),t.input=""===o.getAttribute("value"),o.value="t",o.setAttribute("type","radio"),t.radioValue="t"===o.value,o.setAttribute("checked","t"),o.setAttribute("name","t"),l=a.createDocumentFragment(),l.appendChild(o),t.appendChecked=o.checked,t.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,d.attachEvent&&(d.attachEvent("onclick",function(){t.noCloneEvent=!1}),d.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})d.setAttribute(c="on"+f,"t"),t[f+"Bubbles"]=c in e||d.attributes[c].expando===!1;d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip;for(f in x(t))break;return t.ownLast="0"!==f,x(function(){var n,r,o,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",l=a.getElementsByTagName("body")[0];l&&(n=a.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",l.appendChild(n).appendChild(d),d.innerHTML="
    t
    ",o=d.getElementsByTagName("td"),o[0].style.cssText="padding:0;margin:0;border:0;display:none",p=0===o[0].offsetHeight,o[0].style.display="",o[1].style.display="none",t.reliableHiddenOffsets=p&&0===o[0].offsetHeight,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",x.swap(l,null!=l.style.zoom?{zoom:1}:{},function(){t.boxSizing=4===d.offsetWidth}),e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(d,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(d,null)||{width:"4px"}).width,r=d.appendChild(a.createElement("div")),r.style.cssText=d.style.cssText=s,r.style.marginRight=r.style.width="0",d.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),typeof d.style.zoom!==i&&(d.innerHTML="",d.style.cssText=s+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=3===d.offsetWidth,d.style.display="block",d.innerHTML="
    ",d.firstChild.style.width="5px",t.shrinkWrapBlocks=3!==d.offsetWidth,t.inlineBlockNeedsLayout&&(l.style.zoom=1)),l.removeChild(n),n=d=o=r=null) +}),n=s=l=u=r=o=null,t}({});var B=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;function R(e,n,r,i){if(x.acceptData(e)){var o,a,s=x.expando,l=e.nodeType,u=l?x.cache:e,c=l?e[s]:e[s]&&s;if(c&&u[c]&&(i||u[c].data)||r!==t||"string"!=typeof n)return c||(c=l?e[s]=p.pop()||x.guid++:s),u[c]||(u[c]=l?{}:{toJSON:x.noop}),("object"==typeof n||"function"==typeof n)&&(i?u[c]=x.extend(u[c],n):u[c].data=x.extend(u[c].data,n)),a=u[c],i||(a.data||(a.data={}),a=a.data),r!==t&&(a[x.camelCase(n)]=r),"string"==typeof n?(o=a[n],null==o&&(o=a[x.camelCase(n)])):o=a,o}}function W(e,t,n){if(x.acceptData(e)){var r,i,o=e.nodeType,a=o?x.cache:e,s=o?e[x.expando]:x.expando;if(a[s]){if(t&&(r=n?a[s]:a[s].data)){x.isArray(t)?t=t.concat(x.map(t,x.camelCase)):t in r?t=[t]:(t=x.camelCase(t),t=t in r?[t]:t.split(" ")),i=t.length;while(i--)delete r[t[i]];if(n?!I(r):!x.isEmptyObject(r))return}(n||(delete a[s].data,I(a[s])))&&(o?x.cleanData([e],!0):x.support.deleteExpando||a!=a.window?delete a[s]:a[s]=null)}}}x.extend({cache:{},noData:{applet:!0,embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(e){return e=e.nodeType?x.cache[e[x.expando]]:e[x.expando],!!e&&!I(e)},data:function(e,t,n){return R(e,t,n)},removeData:function(e,t){return W(e,t)},_data:function(e,t,n){return R(e,t,n,!0)},_removeData:function(e,t){return W(e,t,!0)},acceptData:function(e){if(e.nodeType&&1!==e.nodeType&&9!==e.nodeType)return!1;var t=e.nodeName&&x.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),x.fn.extend({data:function(e,n){var r,i,o=null,a=0,s=this[0];if(e===t){if(this.length&&(o=x.data(s),1===s.nodeType&&!x._data(s,"parsedAttrs"))){for(r=s.attributes;r.length>a;a++)i=r[a].name,0===i.indexOf("data-")&&(i=x.camelCase(i.slice(5)),$(s,i,o[i]));x._data(s,"parsedAttrs",!0)}return o}return"object"==typeof e?this.each(function(){x.data(this,e)}):arguments.length>1?this.each(function(){x.data(this,e,n)}):s?$(s,e,x.data(s,e)):null},removeData:function(e){return this.each(function(){x.removeData(this,e)})}});function $(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(P,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:B.test(r)?x.parseJSON(r):r}catch(o){}x.data(e,n,r)}else r=t}return r}function I(e){var t;for(t in e)if(("data"!==t||!x.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}x.extend({queue:function(e,n,r){var i;return e?(n=(n||"fx")+"queue",i=x._data(e,n),r&&(!i||x.isArray(r)?i=x._data(e,n,x.makeArray(r)):i.push(r)),i||[]):t},dequeue:function(e,t){t=t||"fx";var n=x.queue(e,t),r=n.length,i=n.shift(),o=x._queueHooks(e,t),a=function(){x.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return x._data(e,n)||x._data(e,n,{empty:x.Callbacks("once memory").add(function(){x._removeData(e,t+"queue"),x._removeData(e,n)})})}}),x.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),r>arguments.length?x.queue(this[0],e):n===t?this:this.each(function(){var t=x.queue(this,e,n);x._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&x.dequeue(this,e)})},dequeue:function(e){return this.each(function(){x.dequeue(this,e)})},delay:function(e,t){return e=x.fx?x.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=x.Deferred(),a=this,s=this.length,l=function(){--i||o.resolveWith(a,[a])};"string"!=typeof e&&(n=e,e=t),e=e||"fx";while(s--)r=x._data(a[s],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(l));return l(),o.promise(n)}});var z,X,U=/[\t\r\n\f]/g,V=/\r/g,Y=/^(?:input|select|textarea|button|object)$/i,J=/^(?:a|area)$/i,G=/^(?:checked|selected)$/i,Q=x.support.getSetAttribute,K=x.support.input;x.fn.extend({attr:function(e,t){return x.access(this,x.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){x.removeAttr(this,e)})},prop:function(e,t){return x.access(this,x.prop,e,t,arguments.length>1)},removeProp:function(e){return e=x.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,o,a=0,s=this.length,l="string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).addClass(e.call(this,t,this.className))});if(l)for(t=(e||"").match(T)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(U," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=x.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,a=0,s=this.length,l=0===arguments.length||"string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).removeClass(e.call(this,t,this.className))});if(l)for(t=(e||"").match(T)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(U," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?x.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e,r="boolean"==typeof t;return x.isFunction(e)?this.each(function(n){x(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var o,a=0,s=x(this),l=t,u=e.match(T)||[];while(o=u[a++])l=r?l:!s.hasClass(o),s[l?"addClass":"removeClass"](o)}else(n===i||"boolean"===n)&&(this.className&&x._data(this,"__className__",this.className),this.className=this.className||e===!1?"":x._data(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(U," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,o=this[0];{if(arguments.length)return i=x.isFunction(e),this.each(function(n){var o;1===this.nodeType&&(o=i?e.call(this,n,x(this).val()):e,null==o?o="":"number"==typeof o?o+="":x.isArray(o)&&(o=x.map(o,function(e){return null==e?"":e+""})),r=x.valHooks[this.type]||x.valHooks[this.nodeName.toLowerCase()],r&&"set"in r&&r.set(this,o,"value")!==t||(this.value=o))});if(o)return r=x.valHooks[o.type]||x.valHooks[o.nodeName.toLowerCase()],r&&"get"in r&&(n=r.get(o,"value"))!==t?n:(n=o.value,"string"==typeof n?n.replace(V,""):null==n?"":n)}}}),x.extend({valHooks:{option:{get:function(e){var t=x.find.attr(e,"value");return null!=t?t:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,a=o?null:[],s=o?i+1:r.length,l=0>i?s:o?i:0;for(;s>l;l++)if(n=r[l],!(!n.selected&&l!==i||(x.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&x.nodeName(n.parentNode,"optgroup"))){if(t=x(n).val(),o)return t;a.push(t)}return a},set:function(e,t){var n,r,i=e.options,o=x.makeArray(t),a=i.length;while(a--)r=i[a],(r.selected=x.inArray(x(r).val(),o)>=0)&&(n=!0);return n||(e.selectedIndex=-1),o}}},attr:function(e,n,r){var o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return typeof e.getAttribute===i?x.prop(e,n,r):(1===s&&x.isXMLDoc(e)||(n=n.toLowerCase(),o=x.attrHooks[n]||(x.expr.match.bool.test(n)?X:z)),r===t?o&&"get"in o&&null!==(a=o.get(e,n))?a:(a=x.find.attr(e,n),null==a?t:a):null!==r?o&&"set"in o&&(a=o.set(e,r,n))!==t?a:(e.setAttribute(n,r+""),r):(x.removeAttr(e,n),t))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(T);if(o&&1===e.nodeType)while(n=o[i++])r=x.propFix[n]||n,x.expr.match.bool.test(n)?K&&Q||!G.test(n)?e[r]=!1:e[x.camelCase("default-"+n)]=e[r]=!1:x.attr(e,n,""),e.removeAttribute(Q?n:r)},attrHooks:{type:{set:function(e,t){if(!x.support.radioValue&&"radio"===t&&x.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{"for":"htmlFor","class":"className"},prop:function(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return a=1!==s||!x.isXMLDoc(e),a&&(n=x.propFix[n]||n,o=x.propHooks[n]),r!==t?o&&"set"in o&&(i=o.set(e,r,n))!==t?i:e[n]=r:o&&"get"in o&&null!==(i=o.get(e,n))?i:e[n]},propHooks:{tabIndex:{get:function(e){var t=x.find.attr(e,"tabindex");return t?parseInt(t,10):Y.test(e.nodeName)||J.test(e.nodeName)&&e.href?0:-1}}}}),X={set:function(e,t,n){return t===!1?x.removeAttr(e,n):K&&Q||!G.test(n)?e.setAttribute(!Q&&x.propFix[n]||n,n):e[x.camelCase("default-"+n)]=e[n]=!0,n}},x.each(x.expr.match.bool.source.match(/\w+/g),function(e,n){var r=x.expr.attrHandle[n]||x.find.attr;x.expr.attrHandle[n]=K&&Q||!G.test(n)?function(e,n,i){var o=x.expr.attrHandle[n],a=i?t:(x.expr.attrHandle[n]=t)!=r(e,n,i)?n.toLowerCase():null;return x.expr.attrHandle[n]=o,a}:function(e,n,r){return r?t:e[x.camelCase("default-"+n)]?n.toLowerCase():null}}),K&&Q||(x.attrHooks.value={set:function(e,n,r){return x.nodeName(e,"input")?(e.defaultValue=n,t):z&&z.set(e,n,r)}}),Q||(z={set:function(e,n,r){var i=e.getAttributeNode(r);return i||e.setAttributeNode(i=e.ownerDocument.createAttribute(r)),i.value=n+="","value"===r||n===e.getAttribute(r)?n:t}},x.expr.attrHandle.id=x.expr.attrHandle.name=x.expr.attrHandle.coords=function(e,n,r){var i;return r?t:(i=e.getAttributeNode(n))&&""!==i.value?i.value:null},x.valHooks.button={get:function(e,n){var r=e.getAttributeNode(n);return r&&r.specified?r.value:t},set:z.set},x.attrHooks.contenteditable={set:function(e,t,n){z.set(e,""===t?!1:t,n)}},x.each(["width","height"],function(e,n){x.attrHooks[n]={set:function(e,r){return""===r?(e.setAttribute(n,"auto"),r):t}}})),x.support.hrefNormalized||x.each(["href","src"],function(e,t){x.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}}),x.support.style||(x.attrHooks.style={get:function(e){return e.style.cssText||t},set:function(e,t){return e.style.cssText=t+""}}),x.support.optSelected||(x.propHooks.selected={get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}}),x.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){x.propFix[this.toLowerCase()]=this}),x.support.enctype||(x.propFix.enctype="encoding"),x.each(["radio","checkbox"],function(){x.valHooks[this]={set:function(e,n){return x.isArray(n)?e.checked=x.inArray(x(e).val(),n)>=0:t}},x.support.checkOn||(x.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var Z=/^(?:input|select|textarea)$/i,et=/^key/,tt=/^(?:mouse|contextmenu)|click/,nt=/^(?:focusinfocus|focusoutblur)$/,rt=/^([^.]*)(?:\.(.+)|)$/;function it(){return!0}function ot(){return!1}function at(){try{return a.activeElement}catch(e){}}x.event={global:{},add:function(e,n,r,o,a){var s,l,u,c,p,f,d,h,g,m,y,v=x._data(e);if(v){r.handler&&(c=r,r=c.handler,a=c.selector),r.guid||(r.guid=x.guid++),(l=v.events)||(l=v.events={}),(f=v.handle)||(f=v.handle=function(e){return typeof x===i||e&&x.event.triggered===e.type?t:x.event.dispatch.apply(f.elem,arguments)},f.elem=e),n=(n||"").match(T)||[""],u=n.length;while(u--)s=rt.exec(n[u])||[],g=y=s[1],m=(s[2]||"").split(".").sort(),g&&(p=x.event.special[g]||{},g=(a?p.delegateType:p.bindType)||g,p=x.event.special[g]||{},d=x.extend({type:g,origType:y,data:o,handler:r,guid:r.guid,selector:a,needsContext:a&&x.expr.match.needsContext.test(a),namespace:m.join(".")},c),(h=l[g])||(h=l[g]=[],h.delegateCount=0,p.setup&&p.setup.call(e,o,m,f)!==!1||(e.addEventListener?e.addEventListener(g,f,!1):e.attachEvent&&e.attachEvent("on"+g,f))),p.add&&(p.add.call(e,d),d.handler.guid||(d.handler.guid=r.guid)),a?h.splice(h.delegateCount++,0,d):h.push(d),x.event.global[g]=!0);e=null}},remove:function(e,t,n,r,i){var o,a,s,l,u,c,p,f,d,h,g,m=x.hasData(e)&&x._data(e);if(m&&(c=m.events)){t=(t||"").match(T)||[""],u=t.length;while(u--)if(s=rt.exec(t[u])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){p=x.event.special[d]||{},d=(r?p.delegateType:p.bindType)||d,f=c[d]||[],s=s[2]&&RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),l=o=f.length;while(o--)a=f[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(f.splice(o,1),a.selector&&f.delegateCount--,p.remove&&p.remove.call(e,a));l&&!f.length&&(p.teardown&&p.teardown.call(e,h,m.handle)!==!1||x.removeEvent(e,d,m.handle),delete c[d])}else for(d in c)x.event.remove(e,d+t[u],n,r,!0);x.isEmptyObject(c)&&(delete m.handle,x._removeData(e,"events"))}},trigger:function(n,r,i,o){var s,l,u,c,p,f,d,h=[i||a],g=v.call(n,"type")?n.type:n,m=v.call(n,"namespace")?n.namespace.split("."):[];if(u=f=i=i||a,3!==i.nodeType&&8!==i.nodeType&&!nt.test(g+x.event.triggered)&&(g.indexOf(".")>=0&&(m=g.split("."),g=m.shift(),m.sort()),l=0>g.indexOf(":")&&"on"+g,n=n[x.expando]?n:new x.Event(g,"object"==typeof n&&n),n.isTrigger=o?2:3,n.namespace=m.join("."),n.namespace_re=n.namespace?RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,n.result=t,n.target||(n.target=i),r=null==r?[n]:x.makeArray(r,[n]),p=x.event.special[g]||{},o||!p.trigger||p.trigger.apply(i,r)!==!1)){if(!o&&!p.noBubble&&!x.isWindow(i)){for(c=p.delegateType||g,nt.test(c+g)||(u=u.parentNode);u;u=u.parentNode)h.push(u),f=u;f===(i.ownerDocument||a)&&h.push(f.defaultView||f.parentWindow||e)}d=0;while((u=h[d++])&&!n.isPropagationStopped())n.type=d>1?c:p.bindType||g,s=(x._data(u,"events")||{})[n.type]&&x._data(u,"handle"),s&&s.apply(u,r),s=l&&u[l],s&&x.acceptData(u)&&s.apply&&s.apply(u,r)===!1&&n.preventDefault();if(n.type=g,!o&&!n.isDefaultPrevented()&&(!p._default||p._default.apply(h.pop(),r)===!1)&&x.acceptData(i)&&l&&i[g]&&!x.isWindow(i)){f=i[l],f&&(i[l]=null),x.event.triggered=g;try{i[g]()}catch(y){}x.event.triggered=t,f&&(i[l]=f)}return n.result}},dispatch:function(e){e=x.event.fix(e);var n,r,i,o,a,s=[],l=g.call(arguments),u=(x._data(this,"events")||{})[e.type]||[],c=x.event.special[e.type]||{};if(l[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){s=x.event.handlers.call(this,e,u),n=0;while((o=s[n++])&&!e.isPropagationStopped()){e.currentTarget=o.elem,a=0;while((i=o.handlers[a++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(i.namespace))&&(e.handleObj=i,e.data=i.data,r=((x.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,l),r!==t&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,n){var r,i,o,a,s=[],l=n.delegateCount,u=e.target;if(l&&u.nodeType&&(!e.button||"click"!==e.type))for(;u!=this;u=u.parentNode||this)if(1===u.nodeType&&(u.disabled!==!0||"click"!==e.type)){for(o=[],a=0;l>a;a++)i=n[a],r=i.selector+" ",o[r]===t&&(o[r]=i.needsContext?x(r,this).index(u)>=0:x.find(r,this,null,[u]).length),o[r]&&o.push(i);o.length&&s.push({elem:u,handlers:o})}return n.length>l&&s.push({elem:this,handlers:n.slice(l)}),s},fix:function(e){if(e[x.expando])return e;var t,n,r,i=e.type,o=e,s=this.fixHooks[i];s||(this.fixHooks[i]=s=tt.test(i)?this.mouseHooks:et.test(i)?this.keyHooks:{}),r=s.props?this.props.concat(s.props):this.props,e=new x.Event(o),t=r.length;while(t--)n=r[t],e[n]=o[n];return e.target||(e.target=o.srcElement||a),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,o):e},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,i,o,s=n.button,l=n.fromElement;return null==e.pageX&&null!=n.clientX&&(i=e.target.ownerDocument||a,o=i.documentElement,r=i.body,e.pageX=n.clientX+(o&&o.scrollLeft||r&&r.scrollLeft||0)-(o&&o.clientLeft||r&&r.clientLeft||0),e.pageY=n.clientY+(o&&o.scrollTop||r&&r.scrollTop||0)-(o&&o.clientTop||r&&r.clientTop||0)),!e.relatedTarget&&l&&(e.relatedTarget=l===e.target?n.toElement:l),e.which||s===t||(e.which=1&s?1:2&s?3:4&s?2:0),e}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==at()&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){return this===at()&&this.blur?(this.blur(),!1):t},delegateType:"focusout"},click:{trigger:function(){return x.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):t},_default:function(e){return x.nodeName(e.target,"a")}},beforeunload:{postDispatch:function(e){e.result!==t&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=x.extend(new x.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?x.event.trigger(i,null,t):x.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},x.removeEvent=a.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]===i&&(e[r]=null),e.detachEvent(r,n))},x.Event=function(e,n){return this instanceof x.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?it:ot):this.type=e,n&&x.extend(this,n),this.timeStamp=e&&e.timeStamp||x.now(),this[x.expando]=!0,t):new x.Event(e,n)},x.Event.prototype={isDefaultPrevented:ot,isPropagationStopped:ot,isImmediatePropagationStopped:ot,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=it,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=it,e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=it,this.stopPropagation()}},x.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){x.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return(!i||i!==r&&!x.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),x.support.submitBubbles||(x.event.special.submit={setup:function(){return x.nodeName(this,"form")?!1:(x.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=x.nodeName(n,"input")||x.nodeName(n,"button")?n.form:t;r&&!x._data(r,"submitBubbles")&&(x.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),x._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&x.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return x.nodeName(this,"form")?!1:(x.event.remove(this,"._submit"),t)}}),x.support.changeBubbles||(x.event.special.change={setup:function(){return Z.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(x.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),x.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),x.event.simulate("change",this,e,!0)})),!1):(x.event.add(this,"beforeactivate._change",function(e){var t=e.target;Z.test(t.nodeName)&&!x._data(t,"changeBubbles")&&(x.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||x.event.simulate("change",this.parentNode,e,!0)}),x._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return x.event.remove(this,"._change"),!Z.test(this.nodeName)}}),x.support.focusinBubbles||x.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){x.event.simulate(t,e.target,x.event.fix(e),!0)};x.event.special[t]={setup:function(){0===n++&&a.addEventListener(e,r,!0)},teardown:function(){0===--n&&a.removeEventListener(e,r,!0)}}}),x.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(a in e)this.on(a,n,r,e[a],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=ot;else if(!i)return this;return 1===o&&(s=i,i=function(e){return x().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=x.guid++)),this.each(function(){x.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,x(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=ot),this.each(function(){x.event.remove(this,e,r,n)})},trigger:function(e,t){return this.each(function(){x.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?x.event.trigger(e,n,r,!0):t}});var st=/^.[^:#\[\.,]*$/,lt=/^(?:parents|prev(?:Until|All))/,ut=x.expr.match.needsContext,ct={children:!0,contents:!0,next:!0,prev:!0};x.fn.extend({find:function(e){var t,n=[],r=this,i=r.length;if("string"!=typeof e)return this.pushStack(x(e).filter(function(){for(t=0;i>t;t++)if(x.contains(r[t],this))return!0}));for(t=0;i>t;t++)x.find(e,r[t],n);return n=this.pushStack(i>1?x.unique(n):n),n.selector=this.selector?this.selector+" "+e:e,n},has:function(e){var t,n=x(e,this),r=n.length;return this.filter(function(){for(t=0;r>t;t++)if(x.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e||[],!0))},filter:function(e){return this.pushStack(ft(this,e||[],!1))},is:function(e){return!!ft(this,"string"==typeof e&&ut.test(e)?x(e):e||[],!1).length},closest:function(e,t){var n,r=0,i=this.length,o=[],a=ut.test(e)||"string"!=typeof e?x(e,t||this.context):0;for(;i>r;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(11>n.nodeType&&(a?a.index(n)>-1:1===n.nodeType&&x.find.matchesSelector(n,e))){n=o.push(n);break}return this.pushStack(o.length>1?x.unique(o):o)},index:function(e){return e?"string"==typeof e?x.inArray(this[0],x(e)):x.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?x(e,t):x.makeArray(e&&e.nodeType?[e]:e),r=x.merge(this.get(),n);return this.pushStack(x.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function pt(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}x.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return x.dir(e,"parentNode")},parentsUntil:function(e,t,n){return x.dir(e,"parentNode",n)},next:function(e){return pt(e,"nextSibling")},prev:function(e){return pt(e,"previousSibling")},nextAll:function(e){return x.dir(e,"nextSibling")},prevAll:function(e){return x.dir(e,"previousSibling")},nextUntil:function(e,t,n){return x.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return x.dir(e,"previousSibling",n)},siblings:function(e){return x.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return x.sibling(e.firstChild)},contents:function(e){return x.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:x.merge([],e.childNodes)}},function(e,t){x.fn[e]=function(n,r){var i=x.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=x.filter(r,i)),this.length>1&&(ct[e]||(i=x.unique(i)),lt.test(e)&&(i=i.reverse())),this.pushStack(i)}}),x.extend({filter:function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?x.find.matchesSelector(r,e)?[r]:[]:x.find.matches(e,x.grep(t,function(e){return 1===e.nodeType}))},dir:function(e,n,r){var i=[],o=e[n];while(o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!x(o).is(r)))1===o.nodeType&&i.push(o),o=o[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function ft(e,t,n){if(x.isFunction(t))return x.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return x.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(st.test(t))return x.filter(t,e,n);t=x.filter(t,e)}return x.grep(e,function(e){return x.inArray(e,t)>=0!==n})}function dt(e){var t=ht.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}var ht="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gt=/ jQuery\d+="(?:null|\d+)"/g,mt=RegExp("<(?:"+ht+")[\\s/>]","i"),yt=/^\s+/,vt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bt=/<([\w:]+)/,xt=/\s*$/g,At={option:[1,""],legend:[1,"
    ","
    "],area:[1,"",""],param:[1,"",""],thead:[1,"","
    "],tr:[2,"","
    "],col:[2,"","
    "],td:[3,"","
    "],_default:x.support.htmlSerialize?[0,"",""]:[1,"X
    ","
    "]},jt=dt(a),Dt=jt.appendChild(a.createElement("div"));At.optgroup=At.option,At.tbody=At.tfoot=At.colgroup=At.caption=At.thead,At.th=At.td,x.fn.extend({text:function(e){return x.access(this,function(e){return e===t?x.text(this):this.empty().append((this[0]&&this[0].ownerDocument||a).createTextNode(e))},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Lt(this,e);t.appendChild(e)}})},prepend:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Lt(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=e?x.filter(e,this):this,i=0;for(;null!=(n=r[i]);i++)t||1!==n.nodeType||x.cleanData(Ft(n)),n.parentNode&&(t&&x.contains(n.ownerDocument,n)&&_t(Ft(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++){1===e.nodeType&&x.cleanData(Ft(e,!1));while(e.firstChild)e.removeChild(e.firstChild);e.options&&x.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return x.clone(this,e,t)})},html:function(e){return x.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return 1===n.nodeType?n.innerHTML.replace(gt,""):t;if(!("string"!=typeof e||Tt.test(e)||!x.support.htmlSerialize&&mt.test(e)||!x.support.leadingWhitespace&&yt.test(e)||At[(bt.exec(e)||["",""])[1].toLowerCase()])){e=e.replace(vt,"<$1>");try{for(;i>r;r++)n=this[r]||{},1===n.nodeType&&(x.cleanData(Ft(n,!1)),n.innerHTML=e);n=0}catch(o){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=x.map(this,function(e){return[e.nextSibling,e.parentNode]}),t=0;return this.domManip(arguments,function(n){var r=e[t++],i=e[t++];i&&(r&&r.parentNode!==i&&(r=this.nextSibling),x(this).remove(),i.insertBefore(n,r))},!0),t?this:this.remove()},detach:function(e){return this.remove(e,!0)},domManip:function(e,t,n){e=d.apply([],e);var r,i,o,a,s,l,u=0,c=this.length,p=this,f=c-1,h=e[0],g=x.isFunction(h);if(g||!(1>=c||"string"!=typeof h||x.support.checkClone)&&Nt.test(h))return this.each(function(r){var i=p.eq(r);g&&(e[0]=h.call(this,r,i.html())),i.domManip(e,t,n)});if(c&&(l=x.buildFragment(e,this[0].ownerDocument,!1,!n&&this),r=l.firstChild,1===l.childNodes.length&&(l=r),r)){for(a=x.map(Ft(l,"script"),Ht),o=a.length;c>u;u++)i=l,u!==f&&(i=x.clone(i,!0,!0),o&&x.merge(a,Ft(i,"script"))),t.call(this[u],i,u);if(o)for(s=a[a.length-1].ownerDocument,x.map(a,qt),u=0;o>u;u++)i=a[u],kt.test(i.type||"")&&!x._data(i,"globalEval")&&x.contains(s,i)&&(i.src?x._evalUrl(i.src):x.globalEval((i.text||i.textContent||i.innerHTML||"").replace(St,"")));l=r=null}return this}});function Lt(e,t){return x.nodeName(e,"table")&&x.nodeName(1===t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function Ht(e){return e.type=(null!==x.find.attr(e,"type"))+"/"+e.type,e}function qt(e){var t=Et.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function _t(e,t){var n,r=0;for(;null!=(n=e[r]);r++)x._data(n,"globalEval",!t||x._data(t[r],"globalEval"))}function Mt(e,t){if(1===t.nodeType&&x.hasData(e)){var n,r,i,o=x._data(e),a=x._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)x.event.add(t,n,s[n][r])}a.data&&(a.data=x.extend({},a.data))}}function Ot(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!x.support.noCloneEvent&&t[x.expando]){i=x._data(t);for(r in i.events)x.removeEvent(t,r,i.handle);t.removeAttribute(x.expando)}"script"===n&&t.text!==e.text?(Ht(t).text=e.text,qt(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),x.support.html5Clone&&e.innerHTML&&!x.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Ct.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}x.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){x.fn[e]=function(e){var n,r=0,i=[],o=x(e),a=o.length-1;for(;a>=r;r++)n=r===a?this:this.clone(!0),x(o[r])[t](n),h.apply(i,n.get());return this.pushStack(i)}});function Ft(e,n){var r,o,a=0,s=typeof e.getElementsByTagName!==i?e.getElementsByTagName(n||"*"):typeof e.querySelectorAll!==i?e.querySelectorAll(n||"*"):t;if(!s)for(s=[],r=e.childNodes||e;null!=(o=r[a]);a++)!n||x.nodeName(o,n)?s.push(o):x.merge(s,Ft(o,n));return n===t||n&&x.nodeName(e,n)?x.merge([e],s):s}function Bt(e){Ct.test(e.type)&&(e.defaultChecked=e.checked)}x.extend({clone:function(e,t,n){var r,i,o,a,s,l=x.contains(e.ownerDocument,e);if(x.support.html5Clone||x.isXMLDoc(e)||!mt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(Dt.innerHTML=e.outerHTML,Dt.removeChild(o=Dt.firstChild)),!(x.support.noCloneEvent&&x.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||x.isXMLDoc(e)))for(r=Ft(o),s=Ft(e),a=0;null!=(i=s[a]);++a)r[a]&&Ot(i,r[a]);if(t)if(n)for(s=s||Ft(e),r=r||Ft(o),a=0;null!=(i=s[a]);a++)Mt(i,r[a]);else Mt(e,o);return r=Ft(o,"script"),r.length>0&&_t(r,!l&&Ft(e,"script")),r=s=i=null,o},buildFragment:function(e,t,n,r){var i,o,a,s,l,u,c,p=e.length,f=dt(t),d=[],h=0;for(;p>h;h++)if(o=e[h],o||0===o)if("object"===x.type(o))x.merge(d,o.nodeType?[o]:o);else if(wt.test(o)){s=s||f.appendChild(t.createElement("div")),l=(bt.exec(o)||["",""])[1].toLowerCase(),c=At[l]||At._default,s.innerHTML=c[1]+o.replace(vt,"<$1>")+c[2],i=c[0];while(i--)s=s.lastChild;if(!x.support.leadingWhitespace&&yt.test(o)&&d.push(t.createTextNode(yt.exec(o)[0])),!x.support.tbody){o="table"!==l||xt.test(o)?""!==c[1]||xt.test(o)?0:s:s.firstChild,i=o&&o.childNodes.length;while(i--)x.nodeName(u=o.childNodes[i],"tbody")&&!u.childNodes.length&&o.removeChild(u)}x.merge(d,s.childNodes),s.textContent="";while(s.firstChild)s.removeChild(s.firstChild);s=f.lastChild}else d.push(t.createTextNode(o));s&&f.removeChild(s),x.support.appendChecked||x.grep(Ft(d,"input"),Bt),h=0;while(o=d[h++])if((!r||-1===x.inArray(o,r))&&(a=x.contains(o.ownerDocument,o),s=Ft(f.appendChild(o),"script"),a&&_t(s),n)){i=0;while(o=s[i++])kt.test(o.type||"")&&n.push(o)}return s=null,f},cleanData:function(e,t){var n,r,o,a,s=0,l=x.expando,u=x.cache,c=x.support.deleteExpando,f=x.event.special;for(;null!=(n=e[s]);s++)if((t||x.acceptData(n))&&(o=n[l],a=o&&u[o])){if(a.events)for(r in a.events)f[r]?x.event.remove(n,r):x.removeEvent(n,r,a.handle); +u[o]&&(delete u[o],c?delete n[l]:typeof n.removeAttribute!==i?n.removeAttribute(l):n[l]=null,p.push(o))}},_evalUrl:function(e){return x.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})}}),x.fn.extend({wrapAll:function(e){if(x.isFunction(e))return this.each(function(t){x(this).wrapAll(e.call(this,t))});if(this[0]){var t=x(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&1===e.firstChild.nodeType)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return x.isFunction(e)?this.each(function(t){x(this).wrapInner(e.call(this,t))}):this.each(function(){var t=x(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=x.isFunction(e);return this.each(function(n){x(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){x.nodeName(this,"body")||x(this).replaceWith(this.childNodes)}).end()}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+w+")(.*)$","i"),Yt=RegExp("^("+w+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+w+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===x.css(e,"display")||!x.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=x._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=x._data(r,"olddisplay",ln(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&x._data(r,"olddisplay",i?n:x.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}x.fn.extend({css:function(e,n){return x.access(this,function(e,n,r){var i,o,a={},s=0;if(x.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=x.css(e,n[s],!1,o);return a}return r!==t?x.style(e,n,r):x.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){var t="boolean"==typeof e;return this.each(function(){(t?e:nn(this))?x(this).show():x(this).hide()})}}),x.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":x.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,l=x.camelCase(n),u=e.style;if(n=x.cssProps[l]||(x.cssProps[l]=tn(u,l)),s=x.cssHooks[n]||x.cssHooks[l],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:u[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(x.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||x.cssNumber[l]||(r+="px"),x.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(u[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{u[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,l=x.camelCase(n);return n=x.cssProps[l]||(x.cssProps[l]=tn(e.style,l)),s=x.cssHooks[n]||x.cssHooks[l],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||x.isNumeric(o)?o||0:a):a}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s.getPropertyValue(n)||s[n]:t,u=e.style;return s&&(""!==l||x.contains(e.ownerDocument,e)||(l=x.style(e,n)),Yt.test(l)&&Ut.test(n)&&(i=u.width,o=u.minWidth,a=u.maxWidth,u.minWidth=u.maxWidth=u.width=l,l=s.width,u.width=i,u.minWidth=o,u.maxWidth=a)),l}):a.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s[n]:t,u=e.style;return null==l&&u&&u[n]&&(l=u[n]),Yt.test(l)&&!zt.test(n)&&(i=u.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),u.left="fontSize"===n?"1em":l,l=u.pixelLeft+"px",u.left=i,a&&(o.left=a)),""===l?"auto":l});function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;for(;4>o;o+=2)"margin"===n&&(a+=x.css(e,n+Zt[o],!0,i)),r?("content"===n&&(a-=x.css(e,"padding"+Zt[o],!0,i)),"margin"!==n&&(a-=x.css(e,"border"+Zt[o]+"Width",!0,i))):(a+=x.css(e,"padding"+Zt[o],!0,i),"padding"!==n&&(a+=x.css(e,"border"+Zt[o]+"Width",!0,i)));return a}function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Rt(e),a=x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=Wt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Yt.test(i))return i;r=a&&(x.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+an(e,t,n||(a?"border":"content"),r,o)+"px"}function ln(e){var t=a,n=Gt[e];return n||(n=un(e,t),"none"!==n&&n||(Pt=(Pt||x("':"application/x-shockwave-flash"==i.source1mime?(r+='',i.poster&&(r+=''),r+=""):-1!=i.source1mime.indexOf("audio")?e.settings.audio_template_callback?r=e.settings.audio_template_callback(i):r+='":r=e.settings.video_template_callback?e.settings.video_template_callback(i):'"),r):""}function o(e){var t={};return new tinymce.html.SaxParser({validate:!1,special:"script,noscript",start:function(e,n){t.source1||"param"!=e||(t.source1=n.map.movie),("iframe"==e||"object"==e||"embed"==e||"video"==e||"audio"==e)&&(t=tinymce.extend(n.map,t)),"source"==e&&(t.source1?t.source2||(t.source2=n.map.src):t.source1=n.map.src),"img"!=e||t.poster||(t.poster=n.map.src)}}).parse(e),t.source1=t.source1||t.src||t.data,t.source2=t.source2||"",t.poster=t.poster||"",t}function s(t){return t.getAttribute("data-mce-object")?o(e.serializer.serialize(t,{selection:!0})):{}}function c(e,t,n){function i(e,t){var n,i,r,a;for(n in t)if(r=""+t[n],e.map[n])for(i=e.length;i--;)a=e[i],a.name==n&&(r?(e.map[n]=r,a.value=r):(delete e.map[n],e.splice(i,1)));else r&&(e.push({name:n,value:r}),e.map[n]=r)}var r,a=new tinymce.html.Writer,o=0;return new tinymce.html.SaxParser({validate:!1,special:"script,noscript",comment:function(e){a.comment(e)},cdata:function(e){a.cdata(e)},text:function(e,t){a.text(e,t)},start:function(e,s,c){switch(e){case"video":case"object":case"img":case"iframe":i(s,{width:t.width,height:t.height})}if(n)switch(e){case"video":i(s,{poster:t.poster,src:""}),t.source2&&i(s,{src:""});break;case"iframe":i(s,{src:t.source1});break;case"source":if(o++,2>=o&&(i(s,{src:t["source"+o],type:t["source"+o+"mime"]}),!t["source"+o]))return;break;case"img":if(!t.poster)return;r=!0}a.start(e,s,c)},end:function(e){if("video"==e&&n)for(var s=1;2>=s;s++)if(t["source"+s]){var c=[];c.map={},s>o&&(i(c,{src:t["source"+s],type:t["source"+s+"mime"]}),a.start("source",c,!0))}if(t.poster&&"object"==e&&n&&!r){var l=[];l.map={},i(l,{src:t.poster,width:t.width,height:t.height}),a.start("img",l,!0)}a.end(e)}},new tinymce.html.Schema({})).parse(e),a.getContent()}var l=[{regex:/youtu\.be\/([a-z1-9.-_]+)/,type:"iframe",w:425,h:350,url:"http://www.youtube.com/embed/$1"},{regex:/youtube\.com(.+)v=([^&]+)/,type:"iframe",w:425,h:350,url:"http://www.youtube.com/embed/$2"},{regex:/vimeo\.com\/([0-9]+)/,type:"iframe",w:425,h:350,url:"http://player.vimeo.com/video/$1?title=0&byline=0&portrait=0&color=8dc7dc"},{regex:/maps\.google\.([a-z]{2,3})\/maps\/(.+)msid=(.+)/,type:"iframe",w:425,h:350,url:'http://maps.google.com/maps/ms?msid=$2&output=embed"'}];e.on("ResolveName",function(e){var t;1==e.target.nodeType&&(t=e.target.getAttribute("data-mce-object"))&&(e.name=t)}),e.on("preInit",function(){var t=e.schema.getSpecialElements();tinymce.each("video audio iframe object".split(" "),function(e){t[e]=new RegExp("]*>","gi")}),e.schema.addValidElements("object[id|style|width|height|classid|codebase|*],embed[id|style|width|height|type|src|*],video[*],audio[*]");var n=e.schema.getBoolAttrs();tinymce.each("webkitallowfullscreen mozallowfullscreen allowfullscreen".split(" "),function(e){n[e]={}}),e.parser.addNodeFilter("iframe,video,audio,object,embed",function(t,n){for(var i,r,a,o,s,c,l,d=t.length;d--;){for(r=t[d],a=new tinymce.html.Node("img",1),a.shortEnded=!0,c=r.attributes,i=c.length;i--;)o=c[i].name,s=c[i].value,"width"!==o&&"height"!==o&&"style"!==o&&(("data"==o||"src"==o)&&(s=e.convertURL(s,o)),a.attr("data-mce-p-"+o,s));l=r.firstChild&&r.firstChild.value,l&&(a.attr("data-mce-html",escape(l)),a.firstChild=null),a.attr({width:r.attr("width")||"300",height:r.attr("height")||("audio"==n?"30":"150"),style:r.attr("style"),src:tinymce.Env.transparentSrc,"data-mce-object":n,"class":"mce-object mce-object-"+n}),r.replace(a)}}),e.serializer.addAttributeFilter("data-mce-object",function(e,t){for(var n,i,r,a,o,s,c=e.length;c--;){for(n=e[c],i=new tinymce.html.Node(n.attr(t),1),"audio"!=n.attr(t)&&i.attr({width:n.attr("width"),height:n.attr("height")}),i.attr({style:n.attr("style")}),a=n.attributes,r=a.length;r--;){var l=a[r].name;0===l.indexOf("data-mce-p-")&&i.attr(l.substr(11),a[r].value)}o=n.attr("data-mce-html"),o&&(s=new tinymce.html.Node("#text",3),s.raw=!0,s.value=unescape(o),i.append(s)),n.replace(i)}})}),e.on("ObjectSelected",function(e){"audio"==e.target.getAttribute("data-mce-object")&&e.preventDefault()}),e.on("objectResized",function(e){var t,n=e.target;n.getAttribute("data-mce-object")&&(t=n.getAttribute("data-mce-html"),t&&(t=unescape(t),n.setAttribute("data-mce-html",escape(c(t,{width:e.width,height:e.height})))))}),e.addButton("media",{tooltip:"Insert/edit video",onclick:i,stateSelector:"img[data-mce-object=video]"}),e.addMenuItem("media",{icon:"media",text:"Insert video",onclick:i,context:"insert",prependToContext:!0})}); \ No newline at end of file diff --git a/web/tinymce/plugins/nonbreaking/plugin.min.js b/web/tinymce/plugins/nonbreaking/plugin.min.js new file mode 100755 index 000000000..866339c7d --- /dev/null +++ b/web/tinymce/plugins/nonbreaking/plugin.min.js @@ -0,0 +1 @@ +tinymce.PluginManager.add("nonbreaking",function(e){var t=e.getParam("nonbreaking_force_tab");if(e.addCommand("mceNonBreaking",function(){e.insertContent(e.plugins.visualchars&&e.plugins.visualchars.state?' ':" ")}),e.addButton("nonbreaking",{title:"Insert nonbreaking space",cmd:"mceNonBreaking"}),e.addMenuItem("nonbreaking",{text:"Nonbreaking space",cmd:"mceNonBreaking",context:"insert"}),t){var n=+t>1?+t:3;e.on("keydown",function(t){if(9==t.keyCode){if(t.shiftKey)return;t.preventDefault();for(var i=0;n>i;i++)e.execCommand("mceNonBreaking")}})}}); \ No newline at end of file diff --git a/web/tinymce/plugins/noneditable/plugin.min.js b/web/tinymce/plugins/noneditable/plugin.min.js new file mode 100755 index 000000000..dd15d59ee --- /dev/null +++ b/web/tinymce/plugins/noneditable/plugin.min.js @@ -0,0 +1 @@ +tinymce.PluginManager.add("noneditable",function(e){function t(){function t(e){var t;if(1===e.nodeType){if(t=e.getAttribute(s),t&&"inherit"!==t)return t;if(t=e.contentEditable,"inherit"!==t)return t}return null}function n(e){for(var n;e;){if(n=t(e))return"false"===n?e:null;e=e.parentNode}}function i(e){for(;e;){if(e.id===g)return e;e=e.parentNode}}function o(e){var t;if(e)for(t=new r(e,e),e=t.current();e;e=t.next())if(3===e.nodeType)return e}function a(n,i){var o,a;return"false"===t(n)&&m.isBlock(n)?(f.select(n),void 0):(a=m.createRng(),"true"===t(n)&&(n.firstChild||n.appendChild(e.getDoc().createTextNode(" ")),n=n.firstChild,i=!0),o=m.create("span",{id:g,"data-mce-bogus":!0},p),i?n.parentNode.insertBefore(o,n):m.insertAfter(o,n),a.setStart(o.firstChild,1),a.collapse(!0),f.setRng(a),o)}function l(e){var t,n,a,r;if(e)t=f.getRng(!0),t.setStartBefore(e),t.setEndBefore(e),n=o(e),n&&n.nodeValue.charAt(0)==p&&(n=n.deleteData(0,1)),m.remove(e,!0),f.setRng(t);else for(a=i(f.getStart());(e=m.get(g))&&e!==r;)a!==e&&(n=o(e),n&&n.nodeValue.charAt(0)==p&&(n=n.deleteData(0,1)),m.remove(e,!0)),r=e}function d(){function e(e,n){var i,o,a,l,s;if(i=c.startContainer,o=c.startOffset,3==i.nodeType){if(s=i.nodeValue.length,o>0&&s>o||(n?o==s:0===o))return}else{if(!(o0?o-1:o;i=i.childNodes[d],i.hasChildNodes()&&(i=i.firstChild)}for(a=new r(i,e);l=a[n?"prev":"next"]();){if(3===l.nodeType&&l.nodeValue.length>0)return;if("true"===t(l))return l}return e}var i,o,s,c,d;l(),s=f.isCollapsed(),i=n(f.getStart()),o=n(f.getEnd()),(i||o)&&(c=f.getRng(!0),s?(i=i||o,(d=e(i,!0))?a(d,!0):(d=e(i,!1))?a(d,!1):f.select(i)):(c=f.getRng(!0),i&&c.setStartBefore(i),o&&c.setEndAfter(o),f.setRng(c)))}function u(o){function a(e,t){for(;e=e[t?"previousSibling":"nextSibling"];)if(3!==e.nodeType||e.nodeValue.length>0)return e}function s(e,t){f.select(e),f.collapse(t)}function u(o){function a(e){for(var t=s;t;){if(t===e)return;t=t.parentNode}m.remove(e),d()}function r(){var i,r,l=e.schema.getNonEmptyElements();for(r=new tinymce.dom.TreeWalker(s,e.getBody());(i=o?r.prev():r.next())&&!l[i.nodeName.toLowerCase()]&&!(3===i.nodeType&&tinymce.trim(i.nodeValue).length>0);)if("false"===t(i))return a(i),!0;return n(i)?!0:!1}var l,s,c,u;if(f.isCollapsed()){if(l=f.getRng(!0),s=l.startContainer,c=l.startOffset,s=i(s)||s,u=n(s))return a(u),!1;if(3==s.nodeType&&(o?c>0:cv||v>124)&&v!=c.DELETE&&v!=c.BACKSPACE){if((tinymce.isMac?o.metaKey:o.ctrlKey)&&(67==v||88==v||86==v))return;if(o.preventDefault(),v==c.LEFT||v==c.RIGHT){var b=v==c.LEFT;if(e.dom.isBlock(g)){var x=b?g.previousSibling:g.nextSibling,w=new r(x,x),C=b?w.prev():w.next();s(C,!b)}else s(g,b)}}else if(v==c.LEFT||v==c.RIGHT||v==c.BACKSPACE||v==c.DELETE){if(p=i(h)){if(v==c.LEFT||v==c.BACKSPACE)if(g=a(p,!0),g&&"false"===t(g)){if(o.preventDefault(),v!=c.LEFT)return m.remove(g),void 0;s(g,!0)}else l(p);if(v==c.RIGHT||v==c.DELETE)if(g=a(p),g&&"false"===t(g)){if(o.preventDefault(),v!=c.RIGHT)return m.remove(g),void 0;s(g,!1)}else l(p)}if((v==c.BACKSPACE||v==c.DELETE)&&!u(v==c.BACKSPACE))return o.preventDefault(),!1}}var m=e.dom,f=e.selection,g="mce_noneditablecaret",p="";e.on("mousedown",function(n){var i=e.selection.getNode();"false"===t(i)&&i==n.target&&d()}),e.on("mouseup keyup",d),e.on("keydown",u)}function n(t){var n=a.length,i=t.content,r=tinymce.trim(o);if("raw"!=t.format){for(;n--;)i=i.replace(a[n],function(t){var n=arguments,o=n[n.length-2];return o>0&&'"'==i.charAt(o-1)?t:''+e.dom.encode("string"==typeof n[1]?n[1]:n[0])+""});t.content=i}}var i,o,a,r=tinymce.dom.TreeWalker,l="contenteditable",s="data-mce-"+l,c=tinymce.util.VK;i=" "+tinymce.trim(e.getParam("noneditable_editable_class","mceEditable"))+" ",o=" "+tinymce.trim(e.getParam("noneditable_noneditable_class","mceNonEditable"))+" ",a=e.getParam("noneditable_regexp"),a&&!a.length&&(a=[a]),e.on("PreInit",function(){t(),a&&e.on("BeforeSetContent",n),e.parser.addAttributeFilter("class",function(e){for(var t,n,a=e.length;a--;)n=e[a],t=" "+n.attr("class")+" ",-1!==t.indexOf(i)?n.attr(s,"true"):-1!==t.indexOf(o)&&n.attr(s,"false")}),e.serializer.addAttributeFilter(s,function(e){for(var t,n=e.length;n--;)t=e[n],a&&t.attr("data-mce-content")?(t.name="#text",t.type=3,t.raw=!0,t.value=t.attr("data-mce-content")):(t.attr(l,null),t.attr(s,null))}),e.parser.addAttributeFilter(l,function(e){for(var t,n=e.length;n--;)t=e[n],t.attr(s,t.attr(l)),t.attr(l,null)})})}); \ No newline at end of file diff --git a/web/tinymce/plugins/pagebreak/plugin.min.js b/web/tinymce/plugins/pagebreak/plugin.min.js new file mode 100755 index 000000000..8f535fa1f --- /dev/null +++ b/web/tinymce/plugins/pagebreak/plugin.min.js @@ -0,0 +1 @@ +tinymce.PluginManager.add("pagebreak",function(e){var t,n="mce-pagebreak",i=e.getParam("pagebreak_separator",""),a='';t=new RegExp(i.replace(/[\?\.\*\[\]\(\)\{\}\+\^\$\:]/g,function(e){return"\\"+e}),"gi"),e.addCommand("mcePageBreak",function(){e.execCommand("mceInsertContent",0,a)}),e.addButton("pagebreak",{title:"Page break",cmd:"mcePageBreak"}),e.addMenuItem("pagebreak",{text:"Page break",icon:"pagebreak",cmd:"mcePageBreak",context:"insert"}),e.on("ResolveName",function(t){"IMG"==t.target.nodeName&&e.dom.hasClass(t.target,n)&&(t.name="pagebreak")}),e.on("click",function(t){t=t.target,"IMG"===t.nodeName&&e.dom.hasClass(t,n)&&e.selection.select(t)}),e.on("BeforeSetContent",function(e){e.content=e.content.replace(t,a)}),e.on("PreInit",function(){e.serializer.addNodeFilter("img",function(e){for(var t,n,a=e.length;a--;)t=e[a],n=t.attr("class"),n&&-1!==n.indexOf("mce-pagebreak")&&(t.type=3,t.value=i,t.raw=!0)})})}); \ No newline at end of file diff --git a/web/tinymce/plugins/paste/plugin.min.js b/web/tinymce/plugins/paste/plugin.min.js new file mode 100755 index 000000000..e660199b1 --- /dev/null +++ b/web/tinymce/plugins/paste/plugin.min.js @@ -0,0 +1 @@ +!function(e,t){"use strict";function n(e,t){for(var n,r=[],i=0;i]+>/g,"")),(i.settings.paste_remove_styles||i.settings.paste_remove_styles_if_webkit!==!1&&e.webkit)&&(t=t.replace(/ style=\"[^\"]+\"/g,"")),n.isDefaultPrevented()||i.insertContent(t)}function d(e){e=i.dom.encode(e).replace(/\r\n/g,"\n");var t=i.dom.getParent(i.selection.getStart(),i.dom.isBlock);e=t&&/^(PRE|DIV)$/.test(t.nodeName)||!i.settings.forced_root_block?c(e,[[/\n/g,"
    "]]):c(e,[[/\n\n/g,"

    "],[/^(.*<\/p>)(

    )$/,"

    $1"],[/\n/g,"
    "]]);var n=i.fire("PastePreProcess",{content:e});n.isDefaultPrevented()||i.insertContent(n.content)}function f(){var e=i.dom.getViewPort().y,t=i.dom.add(i.getBody(),"div",{contentEditable:!1,"data-mce-bogus":"1",style:"position: absolute; top: "+e+"px; left: 0; width: 1px; height: 1px; overflow: hidden"},'

    X
    ');return i.dom.bind(t,"beforedeactivate focusin focusout",function(e){e.stopPropagation()}),t}function p(e){i.dom.unbind(e),i.dom.remove(e)}var m=this,h;if(i.on("keydown",function(e){n.metaKeyPressed(e)&&e.shiftKey&&86==e.keyCode&&(h=o())}),r())i.on("paste",function(e){function t(e,t){for(var r=0;r100){var n,r=f();t.preventDefault(),e.bind(r,"paste",function(e){e.stopPropagation(),n=!0});var a=i.selection.getRng(),c=e.doc.body.createTextRange();if(c.moveToElementText(r.firstChild),c.execCommand("Paste"),p(r),!n)return i.windowManager.alert("Please use Ctrl+V/Cmd+V keyboard shortcuts to paste contents."),void 0;i.selection.setRng(a),l()?d(s(r.firstChild)):u(r.firstChild.innerHTML)}})})}else i.on("init",function(){i.dom.bind(i.getBody(),"paste",function(e){var t=i.getDoc();return e.preventDefault(),e.clipboardData||t.dataTransfer?(d((e.clipboardData||t.dataTransfer).getData("Text")),void 0):(e.preventDefault(),i.windowManager.alert("Please use Ctrl+V/Cmd+V keyboard shortcuts to paste contents."),void 0)})}),i.on("keydown",function(t){if(a(t)&&!t.isDefaultPrevented()){t.stopImmediatePropagation();var n=f(),r=i.selection.getRng();e.webkit&&i.inline&&(n.contentEditable=!0),i.selection.select(n,!0),i.dom.bind(n,"paste",function(e){e.stopPropagation(),setTimeout(function(){p(n),i.lastRng=r,i.selection.setRng(r);var e=n.firstChild;e.lastChild&&"BR"==e.lastChild.nodeName&&e.removeChild(e.lastChild),l()?d(s(e)):u(e.innerHTML)},0)})}});i.settings.paste_data_images||i.on("drop",function(e){var t=e.dataTransfer;t&&t.files&&t.files.length>0&&e.preventDefault()})}i.paste_block_drop&&i.on("dragend dragover draggesture dragdrop drop drag",function(e){e.preventDefault(),e.stopPropagation()}),this.paste=u,this.pasteText=d}}),r(f,[u,p,m,h,g],function(e,t,n,r,i){return function(o){var a=e.each;o.on("PastePreProcess",function(s){function l(e){a(e,function(e){d=e.constructor==RegExp?d.replace(e,""):d.replace(e[0],e[1])})}function c(e){function t(e,t,a,s){var l=e._listLevel||o;l!=o&&(o>l?n&&(n=n.parent.parent):(r=n,n=null)),n&&n.name==a?n.append(e):(r=r||n,n=new i(a,1),s>1&&n.attr("start",""+s),e.wrap(n)),e.name="li",t.value="";var c=t.next;c&&3==c.type&&(c.value=c.value.replace(/^\u00a0+/,"")),l>o&&r&&r.lastChild.append(n),o=l}for(var n,r,o=1,a=e.getAll("p"),s=0;s/gi,/<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|img|meta|link|style|\w:\w+)(?=[\s\/>]))[^>]*>/gi,[/<(\/?)s>/gi,"<$1strike>"],[/ /gi,"\xa0"],[/([\s\u00a0]*)<\/span>/gi,function(e,t){return t.length>0?t.replace(/./," ").slice(Math.floor(t.length/2)).split("").join("\xa0"):""}]]);var m=new n({valid_elements:"@[style],-strong/b,-em/i,-span,-p,-ol,-ul,-li,-h1,-h2,-h3,-h4,-h5,-h6,-table,-tr,-td[colspan|rowspan],-th,-thead,-tfoot,-tbody,-a[!href],sub,sup,strike"}),h=new t({},m);h.addAttributeFilter("style",function(e){for(var t=e.length,n;t--;)n=e[t],n.attr("style",u(n,n.attr("style"))),"span"!=n.name||n.attributes.length||n.unwrap()});var g=h.parse(d);c(g),s.content=new r({},m).serialize(g)}})}}),r(v,[c,u],function(e,t){return function(n){function r(e){n.on("PastePreProcess",function(t){t.content=e(t.content)})}function i(e,n){return t.each(n,function(t){e=t.constructor==RegExp?e.replace(t,""):e.replace(t[0],t[1])}),e}function o(e){return e=i(e,[/^[\s\S]*|[\s\S]*$/g,[/\u00a0<\/span>/g,"\xa0"],/
    $/])}function a(e){if(!s){var r=[];t.each(n.schema.getBlockElements(),function(e,t){r.push(t)}),s=new RegExp("(?:
     [\\s\\r\\n]+|
    )*(<\\/?("+r.join("|")+")[^>]*>)(?:
     [\\s\\r\\n]+|
    )*","g")}return e=i(e,[[s,"$1"]]),e=i(e,[[/

    /g,"

    "],[/
    /g," "],[/

    /g,"
    "]])}var s;e.webkit&&r(o),e.ie&&r(a)}}),r(y,[b,l,f,v],function(e,t,n,r){var i;e.add("paste",function(e){function o(){"text"==s.pasteFormat?(this.active(!1),s.pasteFormat="html"):(s.pasteFormat="text",this.active(!0),i||(e.windowManager.alert("Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off."),i=!0))}var a=this,s;a.clipboard=s=new t(e),a.quirks=new r(e),a.wordFilter=new n(e),e.settings.paste_as_text&&(a.clipboard.pasteFormat="text"),e.addCommand("mceInsertClipboardContent",function(e,t){t.content&&a.clipboard.paste(t.content),t.text&&a.clipboard.pasteText(t.text)}),e.addButton("pastetext",{icon:"pastetext",tooltip:"Paste as text",onclick:o,active:"text"==a.clipboard.pasteFormat}),e.addMenuItem("pastetext",{text:"Paste as text",selectable:!0,active:s.pasteFormat,onclick:o})})}),a([l,f,v,y])}(this); \ No newline at end of file diff --git a/web/tinymce/plugins/preview/plugin.min.js b/web/tinymce/plugins/preview/plugin.min.js new file mode 100755 index 000000000..b8430c648 --- /dev/null +++ b/web/tinymce/plugins/preview/plugin.min.js @@ -0,0 +1 @@ +tinymce.PluginManager.add("preview",function(e){var t=e.settings;e.addCommand("mcePreview",function(){e.windowManager.open({title:"Preview",width:parseInt(e.getParam("plugin_preview_width","650"),10),height:parseInt(e.getParam("plugin_preview_height","500"),10),html:'',buttons:{text:"Close",onclick:function(){this.parent().parent().close()}},onPostRender:function(){var n,i=this.getEl("body").firstChild.contentWindow.document,a="";tinymce.each(e.contentCSS,function(t){a+=''});var r=t.body_id||"tinymce";-1!=r.indexOf("=")&&(r=e.getParam("body_id","","hash"),r=r[e.id]||r);var o=t.body_class||"";-1!=o.indexOf("=")&&(o=e.getParam("body_class","","hash"),o=o[e.id]||""),n=""+a+""+''+e.getContent()+""+"",i.open(),i.write(n),i.close()}})}),e.addButton("preview",{title:"Preview",cmd:"mcePreview"}),e.addMenuItem("preview",{text:"Preview",cmd:"mcePreview",context:"view"})}); \ No newline at end of file diff --git a/web/tinymce/plugins/print/plugin.min.js b/web/tinymce/plugins/print/plugin.min.js new file mode 100755 index 000000000..abc37b5fd --- /dev/null +++ b/web/tinymce/plugins/print/plugin.min.js @@ -0,0 +1 @@ +tinymce.PluginManager.add("print",function(t){t.addCommand("mcePrint",function(){t.getWin().print()}),t.addButton("print",{title:"Print",cmd:"mcePrint"}),t.addShortcut("Ctrl+P","","mcePrint"),t.addMenuItem("print",{text:"Print",cmd:"mcePrint",icon:"print",shortcut:"Ctrl+P",context:"file"})}); \ No newline at end of file diff --git a/web/tinymce/plugins/save/plugin.min.js b/web/tinymce/plugins/save/plugin.min.js new file mode 100755 index 000000000..bd50cec41 --- /dev/null +++ b/web/tinymce/plugins/save/plugin.min.js @@ -0,0 +1 @@ +tinymce.PluginManager.add("save",function(e){function t(){var t,n;return t=tinymce.DOM.getParent(e.id,"form"),!e.getParam("save_enablewhendirty",!0)||e.isDirty()?(tinymce.triggerSave(),(n=e.getParam("save_onsavecallback"))?(e.execCallback("save_onsavecallback",e)&&(e.startContent=tinymce.trim(e.getContent({format:"raw"})),e.nodeChanged()),void 0):(t?(e.isNotDirty=!0,(!t.onsubmit||t.onsubmit())&&("function"==typeof t.submit?t.submit():e.windowManager.alert("Error: Form submit field collision.")),e.nodeChanged()):e.windowManager.alert("Error: No form element found."),void 0)):void 0}function n(){var t,n=tinymce.trim(e.startContent);return(t=e.getParam("save_oncancelcallback"))?(e.execCallback("save_oncancelcallback",e),void 0):(e.setContent(n),e.undoManager.clear(),e.nodeChanged(),void 0)}function i(){var t=this;e.on("nodeChange",function(){t.disabled(e.getParam("save_enablewhendirty",!0)&&!e.isDirty())})}e.addCommand("mceSave",t),e.addCommand("mceCancel",n),e.addButton("save",{icon:"save",text:"Save",cmd:"mceSave",disabled:!0,onPostRender:i}),e.addButton("cancel",{text:"Cancel",icon:!1,cmd:"mceCancel",disabled:!0,onPostRender:i}),e.addShortcut("ctrl+s","","mceSave")}); \ No newline at end of file diff --git a/web/tinymce/plugins/searchreplace/plugin.min.js b/web/tinymce/plugins/searchreplace/plugin.min.js new file mode 100755 index 000000000..b9c4fccfc --- /dev/null +++ b/web/tinymce/plugins/searchreplace/plugin.min.js @@ -0,0 +1 @@ +!function(){function e(e,t,n,i,a){function r(e,t){if(t=t||0,!e[0])throw"findAndReplaceDOMText cannot handle zero-length matches";var n=e.index;if(t>0){var i=e[t];if(!i)throw"Invalid capture group";n+=e[0].indexOf(i),e[0]=i}return[n,n+e[0].length,[e[0]]]}function o(e){var t;if(3===e.nodeType)return e.data;if(f[e.nodeName])return"";if(t="",(m[e.nodeName]||h[e.nodeName])&&(t+="\n"),e=e.firstChild)do t+=o(e);while(e=e.nextSibling);return t}function c(e,t,n){var i,a,r,o,c=[],s=0,d=e,l=t.shift(),u=0;e:for(;;){if((m[d.nodeName]||h[d.nodeName])&&s++,3===d.nodeType&&(!a&&d.length+s>=l[1]?(a=d,o=l[1]-s):i&&c.push(d),!i&&d.length+s>l[0]&&(i=d,r=l[0]-s),s+=d.length),i&&a){if(d=n({startNode:i,startNodeIndex:r,endNode:a,endNodeIndex:o,innerNodes:c,match:l[2],matchIndex:u}),s-=a.length-o,i=null,a=null,c=[],l=t.shift(),u++,!l)break}else{if(!f[d.nodeName]&&d.firstChild){d=d.firstChild;continue}if(d.nextSibling){d=d.nextSibling;continue}}for(;;){if(d.nextSibling){d=d.nextSibling;break}if(d.parentNode===e)break e;d=d.parentNode}}}function s(e){var t;if("function"!=typeof e){var n=e.nodeType?e:u.createElement(e);t=function(e,t){var i=n.cloneNode(!1);return i.setAttribute("data-mce-index",t),e&&i.appendChild(u.createTextNode(e)),i}}else t=e;return function(e){var n,i,a,r=e.startNode,o=e.endNode,c=e.matchIndex;if(r===o){var s=r;a=s.parentNode,e.startNodeIndex>0&&(n=u.createTextNode(s.data.substring(0,e.startNodeIndex)),a.insertBefore(n,s));var d=t(e.match[0],c);return a.insertBefore(d,s),e.endNodeIndexf;++f){var p=e.innerNodes[f],g=t(p.data,c);p.parentNode.replaceChild(g,p),m.push(g)}var v=t(o.data.substring(0,e.endNodeIndex),c);return a=r.parentNode,a.insertBefore(n,r),a.insertBefore(l,r),a.removeChild(r),a=o.parentNode,a.insertBefore(v,o),a.insertBefore(i,o),a.removeChild(o),v}}var d,l,u,m,f,h,p=[],g=0;if(u=t.ownerDocument,m=a.getBlockElements(),f=a.getWhiteSpaceElements(),h=a.getShortEndedElements(),l=o(t)){if(e.global)for(;d=e.exec(l);)p.push(r(d,i));else d=l.match(e),p.push(r(d,i));return p.length&&(g=p.length,c(t,p,s(n))),g}}function t(t){function n(){var e=tinymce.ui.Factory.create({type:"window",layout:"flex",pack:"center",align:"center",onClose:function(){t.focus(),o=!1,c.unmarkAllMatches()},buttons:[{text:"Find",onclick:function(){e.find("form")[0].submit()}},{text:"Replace",disabled:!0,onclick:function(){c.replace(e.find("#replace").value())||e.statusbar.items().slice(1).disabled(!0)}},{text:"Replace all",disabled:!0,onclick:function(){c.replaceAll(e.find("#replace").value()),e.statusbar.items().slice(1).disabled(!0)}},{type:"spacer",flex:1},{text:"Prev",disabled:!0,onclick:function(){c.prev()}},{text:"Next",disabled:!0,onclick:function(){c.next()}}],title:"Find and replace",items:{type:"form",padding:20,labelGap:30,spacing:10,onsubmit:function(t){var n,i,a,r,o;return t.preventDefault(),a=e.find("#case").checked(),o=e.find("#words").checked(),r=e.find("#find").value(),r.length?(r=r.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&"),r=o?"\\b"+r+"\\b":r,i=new RegExp(r,a?"g":"gi"),n=c.markAllMatches(i),n?c.first():tinymce.ui.MessageBox.alert("Could not find the specified string."),e.statusbar.items().slice(1).disabled(0===n),void 0):(c.unmarkAllMatches(),e.statusbar.items().slice(1).disabled(!0),void 0)},items:[{type:"textbox",name:"find",size:40,label:"Find",value:t.selection.getNode().src},{type:"textbox",name:"replace",size:40,label:"Replace with"},{type:"checkbox",name:"case",text:"Match case",label:" "},{type:"checkbox",name:"words",text:"Whole words",label:" "}]}}).renderTo().reflow();o=!0}function i(e){var t=e.parentNode;t.insertBefore(e.firstChild,e),e.parentNode.removeChild(e)}function a(e,n){function i(){var i,o;for(i=n?t.getBody()[e?"firstChild":"lastChild"]:c[e?"endContainer":"startContainer"],o=new tinymce.dom.TreeWalker(i,t.getBody());i=o.current();){if(1==i.nodeType&&"SPAN"==i.nodeName&&null!==i.getAttribute("data-mce-index"))for(s=i.getAttribute("data-mce-index"),a=i.firstChild;i=o.current();){if(1==i.nodeType&&"SPAN"==i.nodeName&&null!==i.getAttribute("data-mce-index")){if(i.getAttribute("data-mce-index")!==s)return;r=i.firstChild}o[e?"next":"prev"]()}o[e?"next":"prev"]()}}var a,r,o=t.selection,c=o.getRng(!0),s=-1;return e=e!==!1,i(),a&&r&&(t.focus(),e?(c.setStart(a,0),c.setEnd(r,r.length)):(c.setStart(r,0),c.setEnd(a,a.length)),o.scrollIntoView(a.parentNode),o.setRng(c)),s}function r(e){e.parentNode.removeChild(e)}var o,c=this,s=-1;c.init=function(e){e.addMenuItem("searchreplace",{text:"Find and replace",shortcut:"Ctrl+F",onclick:n,separator:"before",context:"edit"}),e.addButton("searchreplace",{tooltip:"Find and replace",shortcut:"Ctrl+F",onclick:n}),e.addCommand("SearchReplace",n),e.shortcuts.add("Ctrl+F","",n)},c.markAllMatches=function(n){var i,a;return a=t.dom.create("span",{"class":"mce-match-marker","data-mce-bogus":1}),i=t.getBody(),c.unmarkAllMatches(i),e(n,i,a,!1,t.schema)},c.first=function(){return s=a(!0,!0),-1!==s},c.next=function(){return s=a(!0),-1!==s},c.prev=function(){return s=a(!1),-1!==s},c.replace=function(e,n,o){var c,d,l,u,m,f;if(-1===s&&(s=a(n)),f=a(n),l=t.getBody(),d=tinymce.toArray(l.getElementsByTagName("span")),d.length)for(c=0;c=d[1]?(o=c,a=d[1]-l):r&&s.push(c),!r&&c.length+l>d[0]&&(r=c,i=d[0]-l),l+=c.length),r&&o){if(c=n({startNode:r,startNodeIndex:i,endNode:o,endNodeIndex:a,innerNodes:s,match:d[2],matchIndex:u}),l-=o.length-a,r=null,o=null,s=[],d=t.shift(),u++,!d)break}else{if(!g[c.nodeName]&&c.firstChild){c=c.firstChild;continue}if(c.nextSibling){c=c.nextSibling;continue}}for(;;){if(c.nextSibling){c=c.nextSibling;break}if(c.parentNode===e)break e;c=c.parentNode}}}function a(e){var t;if("function"!=typeof e){var n=e.nodeType?e:m.createElement(e);t=function(e,t){var r=n.cloneNode(!1);return r.setAttribute("data-mce-index",t),e&&r.appendChild(m.createTextNode(e)),r}}else t=e;return function r(e){var n,r,o,i=e.startNode,a=e.endNode,s=e.matchIndex;if(i===a){var l=i;o=l.parentNode,e.startNodeIndex>0&&(n=m.createTextNode(l.data.substring(0,e.startNodeIndex)),o.insertBefore(n,l));var c=t(e.match[0],s);return o.insertBefore(c,l),e.endNodeIndexf;++f){var h=e.innerNodes[f],g=t(h.data,s);h.parentNode.replaceChild(g,h),u.push(g)}var v=t(a.data.substring(0,e.endNodeIndex),s);return o=i.parentNode,o.insertBefore(n,i),o.insertBefore(d,i),o.removeChild(i),o=a.parentNode,o.insertBefore(v,a),o.insertBefore(r,a),o.removeChild(a),v}}function s(e){var t=[];return l(function(n,r){e(n,r)&&t.push(n)}),u=t,this}function l(e){for(var t=0,n=u.length;n>t&&e(u[t],t)!==!1;t++);return this}function c(e){return u.length&&(p=u.length,i(t,u,a(e))),this}var d,u=[],f,p=0,m,h,g,v;if(m=t.ownerDocument,h=n.getBlockElements(),g=n.getWhiteSpaceElements(),v=n.getShortEndedElements(),f=o(t),f&&e.global)for(;d=e.exec(f);)u.push(r(d));return{text:f,count:p,matches:u,each:l,filter:s,mark:c}}}),r(c,[l,d,u,f,p,m,h],function(e,t,n,r,o,i,a){t.add("spellchecker",function(t,s){function l(e){for(var t in e)return!1;return!0}function c(e,i){var a=[],s=g[i];n.each(s,function(e){a.push({text:e,onclick:function(){t.insertContent(e),u()}})}),a.push.apply(a,[{text:"-"},{text:"Ignore",onclick:function(){p(e,i)}},{text:"Ignore all",onclick:function(){p(e,i,!0)}},{text:"Finish",onclick:m}]),y=new r({items:a,context:"contextmenu",onautohide:function(e){-1!=e.target.className.indexOf("spellchecker")&&e.preventDefault()},onhide:function(){y.remove(),y=null}}),y.renderTo(document.body);var l=o.DOM.getPos(t.getContentAreaContainer()),c=t.dom.getPos(e);l.x+=c.x,l.y+=c.y,y.moveTo(l.x,l.y+e.offsetHeight)}function d(){function n(e){return t.setProgressState(!1),l(e)?(t.windowManager.alert("No misspellings found"),v=!1,void 0):(g=e,o.filter(function(t){return!!e[t[2][0]]}).mark(t.dom.create("span",{"class":"mce-spellchecker-word","data-mce-bogus":1})),o=null,t.fire("SpellcheckStart"),void 0)}function r(e,n,r){i.sendRPC({url:new a(s).toAbsolute(b.spellchecker_rpc_url),method:e,params:{lang:b.spellchecker_language||"en",words:n},success:function(e){r(e)},error:function(e,n){e="JSON Parse error."==e?"Non JSON response:"+n.responseText:"Error: "+e,t.windowManager.alert(e),t.setProgressState(!1),o=null,v=!1}})}var o,c=[],d={};if(v)return m(),void 0;v=!0;var u=t.getParam("spellchecker_wordchar_pattern")||new RegExp('[^\\s!"#$%&()*+,-./:;<=>?@[\\]^_{|}`\xa7\xa9\xab\xae\xb1\xb6\xb7\xb8\xbb\xbc\xbd\xbe\xbf\xd7\xf7\xa4\u201d\u201c\u201e]+',"g");o=new e(u,t.getBody(),t.schema).each(function(e){var t=e[2][0];if(!d[t]){if(/^\d+$/.test(t)||1==t.length)return;c.push(t),d[t]=!0}}),t.setProgressState(!0);var f=b.spellchecker_callback||r;f("spellcheck",c,n)}function u(){t.dom.select("span.mce-spellchecker-word").length||m()}function f(e){var t=e.parentNode;t.insertBefore(e.firstChild,e),e.parentNode.removeChild(e)}function p(e,r,o){o?n.each(t.dom.select("span.mce-spellchecker-word"),function(e){var t=e.innerText||e.textContent;t==r&&f(e)}):f(e),u()}function m(){var e,n,r;for(v=!1,r=t.getBody(),n=r.getElementsByTagName("span"),e=n.length;e--;)r=n[e],r.getAttribute("data-mce-index")&&f(r);t.fire("SpellcheckEnd")}function h(e){var n,r,o,i=-1,a,s;for(e=""+e,n=t.getBody().getElementsByTagName("span"),r=0;r0){for(c=u+1;c=0;c--)if(a(d[c]))return d[c];return null}var u,d,a,c;if(9===n.keyCode&&(a=r(e.getParam("tab_focus",e.getParam("tabfocus_elements",":prev,:next"))),1==a.length&&(a[1]=a[0],a[0]=":prev"),d=n.shiftKey?":prev"==a[0]?t(-1):i.get(a[0]):":next"==a[1]?t(1):i.get(a[1]))){var f=tinymce.get(d.id||d.name);d.id&&f?f.focus():window.setTimeout(function(){tinymce.Env.webkit||window.focus(),d.focus()},10),n.preventDefault()}}var i=tinymce.DOM,o=tinymce.each,r=tinymce.explode;e.on("init",function(){e.inline&&tinymce.DOM.setAttrib(e.getBody(),"tabIndex",null)}),e.on("keyup",n),tinymce.Env.gecko?e.on("keypress keydown",t):e.on("keydown",t)}); \ No newline at end of file diff --git a/web/tinymce/plugins/table/plugin.min.js b/web/tinymce/plugins/table/plugin.min.js new file mode 100755 index 000000000..cb082cc83 --- /dev/null +++ b/web/tinymce/plugins/table/plugin.min.js @@ -0,0 +1 @@ +!function(e,t){"use strict";function n(e,t){for(var n,o=[],i=0;i "+t+" tr",r);o(i,function(i,r){r+=e,o(_.select("> td, > th",i),function(e,o){var i,l,a,s;if(k[r])for(;k[r][o];)o++;for(a=n(e,"rowspan"),s=n(e,"colspan"),l=r;r+a>l;l++)for(k[l]||(k[l]=[]),i=o;o+s>i;i++)k[l][i]={part:t,real:l==r&&i==o,elm:e,rowspan:a,colspan:s}})}),e+=i.length})}function a(e,t){return e=e.cloneNode(t),e.removeAttribute("id"),e}function s(e,t){var n;return n=k[t],n?n[e]:void 0}function c(e,t,n){e&&(n=parseInt(n,10),1===n?e.removeAttribute(t,1):e.setAttribute(t,n,1))}function d(e){return e&&(_.hasClass(e.elm,"mce-item-selected")||e==I)}function u(){var e=[];return o(r.rows,function(t){o(t.cells,function(n){return _.hasClass(n,"mce-item-selected")||n==I.elm?(e.push(t),!1):void 0})}),e}function m(){var e=_.createRng();e.setStartAfter(r),e.setEndAfter(r),D.setRng(e),_.remove(r)}function f(n){var r,l={};return i.settings.table_clone_elements!==!1&&(l=e.makeMap((i.settings.table_clone_elements||"strong em b i span font h1 h2 h3 h4 h5 h6 p div").toUpperCase(),/[ ,]/)),e.walk(n,function(e){var i;return 3==e.nodeType?(o(_.getParents(e.parentNode,null,n).reverse(),function(e){l[e.nodeName]&&(e=a(e,!1),r?i&&i.appendChild(e):r=i=e,i=e)}),i&&(i.innerHTML=t.ie?" ":'
    '),!1):void 0},"childNodes"),n=a(n,!1),c(n,"rowSpan",1),c(n,"colSpan",1),r?n.appendChild(r):t.ie||(n.innerHTML='
    '),n}function h(){var e=_.createRng(),t;return o(_.select("tr",r),function(e){0===e.cells.length&&_.remove(e)}),0===_.select("tr",r).length?(e.setStartBefore(r),e.setEndBefore(r),D.setRng(e),_.remove(r),void 0):(o(_.select("thead,tbody,tfoot",r),function(e){0===e.rows.length&&_.remove(e)}),l(),t=k[Math.min(k.length-1,B.y)],t&&(D.select(t[Math.min(t.length-1,B.x)].elm,!0),D.collapse(!0)),void 0)}function p(e,t,n,o){var i,r,l,a,s;for(i=k[t][e].elm.parentNode,l=1;n>=l;l++)if(i=_.getNext(i,"tr")){for(r=e;r>=0;r--)if(s=k[t+l][r].elm,s.parentNode==i){for(a=1;o>=a;a++)_.insertAfter(f(s),s);break}if(-1==r)for(a=1;o>=a;a++)i.insertBefore(f(i.cells[0]),i.cells[0])}}function g(){o(k,function(e,t){o(e,function(e,o){var i,r,l;if(d(e)&&(e=e.elm,i=n(e,"colspan"),r=n(e,"rowspan"),i>1||r>1)){for(c(e,"rowSpan",1),c(e,"colSpan",1),l=0;i-1>l;l++)_.insertAfter(f(e),e);p(o,t,r-1,i)}})})}function b(t,n,i){var r,a,u,m,f,p,b,v,y,w,x;if(t?(r=T(t),a=r.x,u=r.y,m=a+(n-1),f=u+(i-1)):(B=M=null,o(k,function(e,t){o(e,function(e,n){d(e)&&(B||(B={x:n,y:t}),M={x:n,y:t})})}),a=B.x,u=B.y,m=M.x,f=M.y),v=s(a,u),y=s(m,f),v&&y&&v.part==y.part){for(g(),l(),v=s(a,u).elm,c(v,"colSpan",m-a+1),c(v,"rowSpan",f-u+1),b=u;f>=b;b++)for(p=a;m>=p;p++)k[b]&&k[b][p]&&(t=k[b][p].elm,t!=v&&(w=e.grep(t.childNodes),o(w,function(e){v.appendChild(e)}),w.length&&(w=e.grep(v.childNodes),x=0,o(w,function(e){"BR"==e.nodeName&&_.getAttrib(e,"data-mce-bogus")&&x++0&&k[t-1][l]&&(h=k[t-1][l].elm,p=n(h,"rowSpan"),p>1)){c(h,"rowSpan",p+1);continue}}else if(p=n(i,"rowspan"),p>1){c(i,"rowSpan",p+1);continue}m=f(i),c(m,"colSpan",i.colSpan),u.appendChild(m),r=i}u.hasChildNodes()&&(e?s.parentNode.insertBefore(u,s):_.insertAfter(u,s))}function y(e){var t,i;o(k,function(n){return o(n,function(n,o){return d(n)&&(t=o,e)?!1:void 0}),e?!t:void 0}),o(k,function(o,r){var l,a,s;o[t]&&(l=o[t].elm,l!=i&&(s=n(l,"colspan"),a=n(l,"rowspan"),1==s?e?(l.parentNode.insertBefore(f(l),l),p(t,r,a-1,s)):(_.insertAfter(f(l),l),p(t,r,a-1,s)):c(l,"colSpan",l.colSpan+1),i=l))})}function w(){var t=[];o(k,function(i){o(i,function(i,r){d(i)&&-1===e.inArray(t,r)&&(o(k,function(e){var t=e[r].elm,o;o=n(t,"colSpan"),o>1?c(t,"colSpan",o-1):_.remove(t)}),t.push(r))})}),h()}function x(){function e(e){var t,i,r;t=_.getNext(e,"tr"),o(e.cells,function(e){var t=n(e,"rowSpan");t>1&&(c(e,"rowSpan",t-1),i=T(e),p(i.x,i.y,1,1))}),i=T(e.cells[0]),o(k[i.y],function(e){var t;e=e.elm,e!=r&&(t=n(e,"rowSpan"),1>=t?_.remove(e):c(e,"rowSpan",t-1),r=e)})}var t;t=u(),o(t.reverse(),function(t){e(t)}),h()}function C(){var e=u();return _.remove(e),h(),e}function S(){var e=u();return o(e,function(t,n){e[n]=a(t,!0)}),e}function R(e,t){var n=u(),i=n[t?0:n.length-1],r=i.cells.length;e&&(o(k,function(e){var t;return r=0,o(e,function(e){e.real&&(r+=e.colspan),e.elm.parentNode==i&&(t=1)}),t?!1:void 0}),t||e.reverse(),o(e,function(e){var n,o=e.cells.length,l;for(n=0;o>n;n++)l=e.cells[n],c(l,"colSpan",1),c(l,"rowSpan",1);for(n=o;r>n;n++)e.appendChild(f(e.cells[o-1]));for(n=r;o>n;n++)_.remove(e.cells[n]);t?i.parentNode.insertBefore(e,i):_.insertAfter(e,i)}),_.removeClass(_.select("td.mce-item-selected,th.mce-item-selected"),"mce-item-selected"))}function T(e){var t;return o(k,function(n,i){return o(n,function(n,o){return n.elm==e?(t={x:o,y:i},!1):void 0}),!t}),t}function N(e){B=T(e)}function P(){var e,t;return e=t=0,o(k,function(n,i){o(n,function(n,o){var r,l;d(n)&&(n=k[i][o],o>e&&(e=o),i>t&&(t=i),n.real&&(r=n.colspan-1,l=n.rowspan-1,r&&o+r>e&&(e=o+r),l&&i+l>t&&(t=i+l)))})}),{x:e,y:t}}function A(e){var t,n,o,i,r,l,a,s,c,d;if(M=T(e),B&&M){for(t=Math.min(B.x,M.x),n=Math.min(B.y,M.y),o=Math.max(B.x,M.x),i=Math.max(B.y,M.y),r=o,l=i,d=n;l>=d;d++)e=k[d][t],e.real||t-(e.colspan-1)=c;c++)e=k[n][c],e.real||n-(e.rowspan-1)=d;d++)for(c=t;o>=c;c++)e=k[d][c],e.real&&(a=e.colspan-1,s=e.rowspan-1,a&&c+a>r&&(r=c+a),s&&d+s>l&&(l=d+s));for(_.removeClass(_.select("td.mce-item-selected,th.mce-item-selected"),"mce-item-selected"),d=n;l>=d;d++)for(c=t;r>=c;c++)k[d][c]&&_.addClass(k[d][c].elm,"mce-item-selected")}}var k,B,M,I,D=i.selection,_=D.dom;r=r||_.getParent(D.getStart(),"table"),l(),I=_.getParent(D.getStart(),"th,td"),I&&(B=T(I),M=P(),I=s(B.x,B.y)),e.extend(this,{deleteTable:m,split:g,merge:b,insertRow:v,insertCol:y,deleteCols:w,deleteRows:x,cutRows:C,copyRows:S,pasteRows:R,getPos:T,setStartCell:N,setEndCell:A})}}),o(u,[m,d,c],function(e,t,n){function o(e,t){return parseInt(e.getAttribute(t)||1,10)}var i=n.each;return function(n){function r(){function t(t){function r(e,o){var i=e?"previousSibling":"nextSibling",r=n.dom.getParent(o,"tr"),a=r[i];if(a)return g(n,o,a,e),t.preventDefault(),!0;var d=n.dom.getParent(r,"table"),u=r.parentNode,m=u.nodeName.toLowerCase();if("tbody"===m||m===(e?"tfoot":"thead")){var f=l(e,d,u,"tbody");if(null!==f)return s(e,f,o)}return c(e,r,i,d)}function l(e,t,o,i){var r=n.dom.select(">"+i,t),l=r.indexOf(o);if(e&&0===l||!e&&l===r.length-1)return a(e,t);if(-1===l){var s="thead"===o.tagName.toLowerCase()?0:r.length-1;return r[s]}return r[l+(e?-1:1)]}function a(e,t){var o=e?"thead":"tfoot",i=n.dom.select(">"+o,t);return 0!==i.length?i[0]:null}function s(e,o,i){var r=d(o,e);return r&&g(n,i,r,e),t.preventDefault(),!0}function c(e,o,i,l){var a=l[i];if(a)return u(a),!0;var s=n.dom.getParent(l,"td,th");if(s)return r(e,s,t);var c=d(o,!e);return u(c),t.preventDefault(),!1}function d(e,t){var o=e&&e[t?"lastChild":"firstChild"];return o&&"BR"===o.nodeName?n.dom.getParent(o,"td,th"):o}function u(e){n.selection.setCursorLocation(e,0)}function m(){return y==e.UP||y==e.DOWN}function f(e){var t=e.selection.getNode(),n=e.dom.getParent(t,"tr");return null!==n}function h(e){for(var t=0,n=e;n.previousSibling;)n=n.previousSibling,t+=o(n,"colspan");return t}function p(e,t){var n=0,r=0;return i(e.children,function(e,i){return n+=o(e,"colspan"),r=i,n>t?!1:void 0}),r}function g(e,t,o,i){var r=h(n.dom.getParent(t,"td,th")),l=p(o,r),a=o.childNodes[l],s=d(a,i);u(s||a)}function b(e){var t=n.selection.getNode(),o=n.dom.getParent(t,"td,th"),i=n.dom.getParent(e,"td,th");return o&&o!==i&&v(o,i)}function v(e,t){return n.dom.getParent(e,"TABLE")===n.dom.getParent(t,"TABLE")}var y=t.keyCode;if(m()&&f(n)){var w=n.selection.getNode();setTimeout(function(){b(w)&&r(!t.shiftKey&&y===e.UP,w,t)},0)}}n.on("KeyDown",function(e){t(e)})}function l(){function e(e,t){var n=t.ownerDocument,o=n.createRange(),i;return o.setStartBefore(t),o.setEnd(e.endContainer,e.endOffset),i=n.createElement("body"),i.appendChild(o.cloneContents()),0===i.innerHTML.replace(/<(br|img|object|embed|input|textarea)[^>]*>/gi,"-").replace(/<[^>]+>/g,"").length}n.on("KeyDown",function(t){var o,i,r=n.dom;(37==t.keyCode||38==t.keyCode)&&(o=n.selection.getRng(),i=r.getParent(o.startContainer,"table"),i&&n.getBody().firstChild==i&&e(o,i)&&(o=r.createRng(),o.setStartBefore(i),o.setEndBefore(i),n.selection.setRng(o),t.preventDefault()))})}function a(){n.on("KeyDown SetContent VisualAid",function(){var e;for(e=n.getBody().lastChild;e;e=e.previousSibling)if(3==e.nodeType){if(e.nodeValue.length>0)break}else if(1==e.nodeType&&!e.getAttribute("data-mce-bogus"))break;e&&"TABLE"==e.nodeName&&(n.settings.forced_root_block?n.dom.add(n.getBody(),n.settings.forced_root_block,null,t.ie?" ":'
    '):n.dom.add(n.getBody(),"br",{"data-mce-bogus":"1"}))}),n.on("PreProcess",function(e){var t=e.node.lastChild;t&&("BR"==t.nodeName||1==t.childNodes.length&&("BR"==t.firstChild.nodeName||"\xa0"==t.firstChild.nodeValue))&&t.previousSibling&&"TABLE"==t.previousSibling.nodeName&&n.dom.remove(t)})}function s(){function e(e,t,n,o){var i=3,r=e.dom.getParent(t.startContainer,"TABLE"),l,a,s;return r&&(l=r.parentNode),a=t.startContainer.nodeType==i&&0===t.startOffset&&0===t.endOffset&&o&&("TR"==n.nodeName||n==l),s=("TD"==n.nodeName||"TH"==n.nodeName)&&!o,a||s}function t(){var t=n.selection.getRng(),o=n.selection.getNode(),i=n.dom.getParent(t.startContainer,"TD,TH");if(e(n,t,o,i)){i||(i=o);for(var r=i.lastChild;r.lastChild;)r=r.lastChild;t.setEnd(r,r.nodeValue.length),n.selection.setRng(t)}}n.on("KeyDown",function(){t()}),n.on("MouseDown",function(e){2!=e.button&&t()})}t.webkit&&(r(),s()),t.gecko&&(l(),a())}}),o(f,[s,h,c],function(e,t,n){return function(o){function i(){o.getBody().style.webkitUserSelect="",d&&(o.dom.removeClass(o.dom.select("td.mce-item-selected,th.mce-item-selected"),"mce-item-selected"),d=!1)}function r(t){var n,i,r=t.target;if(s&&(a||r!=s)&&("TD"==r.nodeName||"TH"==r.nodeName)){i=l.getParent(r,"table"),i==c&&(a||(a=new e(o,i),a.setStartCell(s),o.getBody().style.webkitUserSelect="none"),a.setEndCell(r),d=!0),n=o.selection.getSel();try{n.removeAllRanges?n.removeAllRanges():n.empty()}catch(u){}t.preventDefault()}}var l=o.dom,a,s,c,d=!0;return o.on("MouseDown",function(e){2!=e.button&&(i(),s=l.getParent(e.target,"td,th"),c=l.getParent(s,"table"))}),l.bind(o.getDoc(),"mouseover",r),o.on("remove",function(){l.unbind(o.getDoc(),"mouseover",r)}),o.on("MouseUp",function(){function e(e,o){var r=new t(e,e);do{if(3==e.nodeType&&0!==n.trim(e.nodeValue).length)return o?i.setStart(e,0):i.setEnd(e,e.nodeValue.length),void 0;if("BR"==e.nodeName)return o?i.setStartBefore(e):i.setEndBefore(e),void 0}while(e=o?r.next():r.prev())}var i,r=o.selection,d,u,m,f,h;if(s){if(a&&(o.getBody().style.webkitUserSelect=""),d=l.select("td.mce-item-selected,th.mce-item-selected"),d.length>0){i=l.createRng(),m=d[0],h=d[d.length-1],i.setStartBefore(m),i.setEndAfter(m),e(m,1),u=new t(m,l.getParent(d[0],"table"));do if("TD"==m.nodeName||"TH"==m.nodeName){if(!l.hasClass(m,"mce-item-selected"))break;f=m}while(m=u.next());e(f),r.setRng(i)}o.nodeChanged(),s=a=c=null}}),o.on("KeyUp",function(){i()}),{clear:i}}}),o(p,[s,u,f,c,h,d,g],function(e,t,n,o,i,r,l){function a(o){function i(e){return e?e.replace(/px$/,""):""}function l(e){return/^[0-9]+$/.test(e)&&(e+="px"),e}function a(e){s("left center right".split(" "),function(t){o.formatter.remove("align"+t,{},e)})}function c(){var e=o.dom,t,n,c;t=o.dom.getParent(o.selection.getStart(),"table"),c=!1,n={width:i(e.getStyle(t,"width")||e.getAttrib(t,"width")),height:i(e.getStyle(t,"height")||e.getAttrib(t,"height")),cellspacing:e.getAttrib(t,"cellspacing"),cellpadding:e.getAttrib(t,"cellpadding"),border:e.getAttrib(t,"border"),caption:!!e.select("caption",t)[0]},s("left center right".split(" "),function(e){o.formatter.matchNode(t,"align"+e)&&(n.align=e)}),o.windowManager.open({title:"Table properties",items:{type:"form",layout:"grid",columns:2,data:n,defaults:{type:"textbox",maxWidth:50},items:[c?{label:"Cols",name:"cols",disabled:!0}:null,c?{label:"Rows",name:"rows",disabled:!0}:null,{label:"Width",name:"width"},{label:"Height",name:"height"},{label:"Cell spacing",name:"cellspacing"},{label:"Cell padding",name:"cellpadding"},{label:"Border",name:"border"},{label:"Caption",name:"caption",type:"checkbox"},{label:"Alignment",minWidth:90,name:"align",type:"listbox",text:"None",maxWidth:null,values:[{text:"None",value:""},{text:"Left",value:"left"},{text:"Center",value:"center"},{text:"Right",value:"right"}]}]},onsubmit:function(){var n=this.toJSON(),i;o.undoManager.transact(function(){o.dom.setAttribs(t,{cellspacing:n.cellspacing,cellpadding:n.cellpadding,border:n.border}),o.dom.setStyles(t,{width:l(n.width),height:l(n.height)}),i=e.select("caption",t)[0],i&&!n.caption&&e.remove(i),!i&&n.caption&&(i=e.create("caption"),r.ie||(i.innerHTML='
    '),t.insertBefore(i,t.firstChild)),a(t),n.align&&o.formatter.apply("align"+n.align,{},t),o.focus(),o.addVisual()})}})}function d(e,t){o.windowManager.open({title:"Merge cells",body:[{label:"Cols",name:"cols",type:"textbox",size:10},{label:"Rows",name:"rows",type:"textbox",size:10}],onsubmit:function(){var n=this.toJSON();o.undoManager.transact(function(){e.merge(t,n.cols,n.rows)})}})}function u(){var e=o.dom,t,n,r=[];r=o.dom.select("td.mce-item-selected,th.mce-item-selected"),t=o.dom.getParent(o.selection.getStart(),"td,th"),!r.length&&t&&r.push(t),t=t||r[0],n={width:i(e.getStyle(t,"width")||e.getAttrib(t,"width")),height:i(e.getStyle(t,"height")||e.getAttrib(t,"height")),scope:e.getAttrib(t,"scope")},n.type=t.nodeName.toLowerCase(),s("left center right".split(" "),function(e){o.formatter.matchNode(t,"align"+e)&&(n.align=e)}),o.windowManager.open({title:"Cell properties",items:{type:"form",data:n,layout:"grid",columns:2,defaults:{type:"textbox",maxWidth:50},items:[{label:"Width",name:"width"},{label:"Height",name:"height"},{label:"Cell type",name:"type",type:"listbox",text:"None",minWidth:90,maxWidth:null,menu:[{text:"Cell",value:"td"},{text:"Header cell",value:"th"}]},{label:"Scope",name:"scope",type:"listbox",text:"None",minWidth:90,maxWidth:null,menu:[{text:"None",value:""},{text:"Row",value:"row"},{text:"Column",value:"col"},{text:"Row group",value:"rowgroup"},{text:"Column group",value:"colgroup"}]},{label:"Alignment",name:"align",type:"listbox",text:"None",minWidth:90,maxWidth:null,values:[{text:"None",value:""},{text:"Left",value:"left"},{text:"Center",value:"center"},{text:"Right",value:"right"}]}]},onsubmit:function(){var t=this.toJSON();o.undoManager.transact(function(){s(r,function(n){o.dom.setAttrib(n,"scope",t.scope),o.dom.setStyles(n,{width:l(t.width),height:l(t.height)}),t.type&&n.nodeName.toLowerCase()!=t.type&&(n=e.rename(n,t.type)),a(n),t.align&&o.formatter.apply("align"+t.align,{},n)}),o.focus()})}})}function m(){var e=o.dom,t,n,r,c,d=[];t=o.dom.getParent(o.selection.getStart(),"table"),n=o.dom.getParent(o.selection.getStart(),"td,th"),s(t.rows,function(t){s(t.cells,function(o){return e.hasClass(o,"mce-item-selected")||o==n?(d.push(t),!1):void 0})}),r=d[0],c={height:i(e.getStyle(r,"height")||e.getAttrib(r,"height")),scope:e.getAttrib(r,"scope")},c.type=r.parentNode.nodeName.toLowerCase(),s("left center right".split(" "),function(e){o.formatter.matchNode(r,"align"+e)&&(c.align=e)}),o.windowManager.open({title:"Row properties",items:{type:"form",data:c,columns:2,defaults:{type:"textbox"},items:[{type:"listbox",name:"type",label:"Row type",text:"None",maxWidth:null,menu:[{text:"Header",value:"thead"},{text:"Body",value:"tbody"},{text:"Footer",value:"tfoot"}]},{type:"listbox",name:"align",label:"Alignment",text:"None",maxWidth:null,menu:[{text:"None",value:""},{text:"Left",value:"left"},{text:"Center",value:"center"},{text:"Right",value:"right"}]},{label:"Height",name:"height"}]},onsubmit:function(){var t=this.toJSON(),n,i,r;o.undoManager.transact(function(){var c=t.type;s(d,function(s){o.dom.setAttrib(s,"scope",t.scope),o.dom.setStyles(s,{height:l(t.height)}),c!=s.parentNode.nodeName.toLowerCase()&&(n=e.getParent(s,"table"),i=s.parentNode,r=e.select(c,n)[0],r||(r=e.create(c),n.firstChild?n.insertBefore(r,n.firstChild):n.appendChild(r)),r.appendChild(s),i.hasChildNodes()||e.remove(i)),a(s),t.align&&o.formatter.apply("align"+t.align,{},s)}),o.focus()})}})}function f(e){return function(){o.execCommand(e)}}function h(e,t){var n,i,l;for(l="
    ",n=0;t>n;n++){for(l+="",i=0;e>i;i++)l+="";l+=""}l+="
    "+(r.ie?" ":"
    ")+"
    ",o.insertContent(l)}function p(e,t){function n(){e.disabled(!o.dom.getParent(o.selection.getStart(),t)),o.selection.selectorChanged(t,function(t){e.disabled(!t)})}o.initialized?n():o.on("init",n)}function g(){p(this,"table")}function b(){p(this,"td,th")}function v(){var e="";e='';for(var t=0;10>t;t++){e+="";for(var n=0;10>n;n++)e+='';e+=""}return e+="",e+='
    0 x 0
    '}var y,w,x=this;o.addMenuItem("inserttable",{text:"Insert table",icon:"table",context:"table",onhide:function(){o.dom.removeClass(this.menu.items()[0].getEl().getElementsByTagName("a"),"mce-active")},menu:[{type:"container",html:v(),onmousemove:function(e){var t=e.target;if("A"==t.nodeName){var n=o.dom.getParent(t,"table"),i=t.getAttribute("data-mce-index");if(i!=this.lastPos){i=i.split(","),i[0]=parseInt(i[0],10),i[1]=parseInt(i[1],10);for(var r=0;10>r;r++)for(var l=0;10>l;l++)o.dom.toggleClass(n.rows[r].childNodes[l].firstChild,"mce-active",l<=i[0]&&r<=i[1]);n.nextSibling.innerHTML=i[0]+1+" x "+(i[1]+1),this.lastPos=i}}},onclick:function(e){"A"==e.target.nodeName&&this.lastPos&&(e.preventDefault(),h(this.lastPos[0]+1,this.lastPos[1]+1),this.parent().cancel())}}]}),o.addMenuItem("tableprops",{text:"Table properties",context:"table",onPostRender:g,onclick:c}),o.addMenuItem("deletetable",{text:"Delete table",context:"table",onPostRender:g,cmd:"mceTableDelete"}),o.addMenuItem("cell",{separator:"before",text:"Cell",context:"table",menu:[{text:"Cell properties",onclick:f("mceTableCellProps"),onPostRender:b},{text:"Merge cells",onclick:f("mceTableMergeCells"),onPostRender:b},{text:"Split cell",onclick:f("mceTableSplitCells"),onPostRender:b}]}),o.addMenuItem("row",{text:"Row",context:"table",menu:[{text:"Insert row before",onclick:f("mceTableInsertRowBefore"),onPostRender:b},{text:"Insert row after",onclick:f("mceTableInsertRowAfter"),onPostRender:b},{text:"Delete row",onclick:f("mceTableDeleteRow"),onPostRender:b},{text:"Row properties",onclick:f("mceTableRowProps"),onPostRender:b},{text:"-"},{text:"Cut row",onclick:f("mceTableCutRow"),onPostRender:b},{text:"Copy row",onclick:f("mceTableCopyRow"),onPostRender:b},{text:"Paste row before",onclick:f("mceTablePasteRowBefore"),onPostRender:b},{text:"Paste row after",onclick:f("mceTablePasteRowAfter"),onPostRender:b}]}),o.addMenuItem("column",{text:"Column",context:"table",menu:[{text:"Insert column before",onclick:f("mceTableInsertColBefore"),onPostRender:b},{text:"Insert column after",onclick:f("mceTableInsertColAfter"),onPostRender:b},{text:"Delete column",onclick:f("mceTableDeleteCol"),onPostRender:b}]});var C=[];s("inserttable tableprops deletetable | cell row column".split(" "),function(e){"|"==e?C.push({text:"-"}):C.push(o.menuItems[e])}),o.addButton("table",{type:"menubutton",title:"Table",menu:C}),r.isIE||o.on("click",function(e){e=e.target,"TABLE"===e.nodeName&&(o.selection.select(e),o.nodeChanged())}),x.quirks=new t(o),o.on("Init",function(){y=o.windowManager,x.cellSelection=new n(o)}),s({mceTableSplitCells:function(e){e.split()},mceTableMergeCells:function(e){var t,n,i;i=o.dom.getParent(o.selection.getStart(),"th,td"),i&&(t=i.rowSpan,n=i.colSpan),o.dom.select("td.mce-item-selected,th.mce-item-selected").length?e.merge():d(e,i)},mceTableInsertRowBefore:function(e){e.insertRow(!0)},mceTableInsertRowAfter:function(e){e.insertRow()},mceTableInsertColBefore:function(e){e.insertCol(!0)},mceTableInsertColAfter:function(e){e.insertCol()},mceTableDeleteCol:function(e){e.deleteCols()},mceTableDeleteRow:function(e){e.deleteRows()},mceTableCutRow:function(e){w=e.cutRows()},mceTableCopyRow:function(e){w=e.copyRows()},mceTablePasteRowBefore:function(e){e.pasteRows(w,!0)},mceTablePasteRowAfter:function(e){e.pasteRows(w)},mceTableDelete:function(e){e.deleteTable()}},function(t,n){o.addCommand(n,function(){var n=new e(o);n&&(t(n),o.execCommand("mceRepaint"),x.cellSelection.clear())})}),s({mceInsertTable:function(){c()},mceTableRowProps:m,mceTableCellProps:u},function(e,t){o.addCommand(t,function(t,n){e(n)})})}var s=o.each;l.add("table",a)}),l([s,u,f,p])}(this); \ No newline at end of file diff --git a/web/tinymce/plugins/template/plugin.min.js b/web/tinymce/plugins/template/plugin.min.js new file mode 100755 index 000000000..47acf74ba --- /dev/null +++ b/web/tinymce/plugins/template/plugin.min.js @@ -0,0 +1 @@ +tinymce.PluginManager.add("template",function(e){function t(){function t(t){function r(t){if(-1==t.indexOf("")){var n="";tinymce.each(e.contentCSS,function(t){n+=''}),t=""+n+""+""+t+""+""}t=l(t,"template_preview_replace_values");var r=a.find("iframe")[0].getEl().contentWindow.document;r.open(),r.write(t),r.close()}var c=t.control.value();c.url?tinymce.util.XHR.send({url:c.url,success:function(e){n=e,r(n)}}):(n=c.content,r(n)),a.find("#description")[0].text(t.control.value().description)}var a,n,c=[];return e.settings.templates?(tinymce.each(e.settings.templates,function(e){c.push({selected:!c.length,text:e.title,value:{url:e.url,content:e.content,description:e.description}})}),a=e.windowManager.open({title:"Insert template",body:[{type:"container",label:"Templates",items:{type:"listbox",name:"template",values:c,onselect:t}},{type:"label",name:"description",label:"Description",text:" "},{type:"iframe",minWidth:600,minHeight:400,border:1}],onsubmit:function(){r(!1,n)}}),a.find("listbox")[0].fire("select"),void 0):(e.windowManager.alert("No templates defined"),void 0)}function a(t,a){function n(e,t){if(e=""+e,e.length0&&(s=m.create("div",null),s.appendChild(i[0].cloneNode(!0))),c(m.select("*",s),function(t){o(t,e.getParam("template_cdate_classes","cdate").replace(/\s+/g,"|"))&&(t.innerHTML=a(e.getParam("template_cdate_format",e.getLang("template.cdate_format")))),o(t,e.getParam("template_mdate_classes","mdate").replace(/\s+/g,"|"))&&(t.innerHTML=a(e.getParam("template_mdate_format",e.getLang("template.mdate_format")))),o(t,e.getParam("template_selected_content_classes","selcontent").replace(/\s+/g,"|"))&&(t.innerHTML=p)}),n(s),e.execCommand("mceInsertContent",!1,s.innerHTML),e.addVisual()}var c=tinymce.each;e.addCommand("mceInsertTemplate",r),e.addButton("template",{title:"Insert template",onclick:t}),e.addMenuItem("template",{text:"Insert template",onclick:t,context:"insert"}),e.on("PreProcess",function(t){var l=e.dom;c(l.select("div",t.node),function(t){l.hasClass(t,"mceTmpl")&&(c(l.select("*",t),function(t){l.hasClass(t,e.getParam("template_mdate_classes","mdate").replace(/\s+/g,"|"))&&(t.innerHTML=a(e.getParam("template_mdate_format",e.getLang("template.mdate_format"))))}),n(t))})})}); \ No newline at end of file diff --git a/web/tinymce/plugins/textcolor/plugin.min.js b/web/tinymce/plugins/textcolor/plugin.min.js new file mode 100755 index 000000000..9f2524fde --- /dev/null +++ b/web/tinymce/plugins/textcolor/plugin.min.js @@ -0,0 +1 @@ +tinymce.PluginManager.add("textcolor",function(e){function t(){var t,n,i=[];for(n=e.settings.textcolor_map||["000000","Black","993300","Burnt orange","333300","Dark olive","003300","Dark green","003366","Dark azure","000080","Navy Blue","333399","Indigo","333333","Very dark gray","800000","Maroon","FF6600","Orange","808000","Olive","008000","Green","008080","Teal","0000FF","Blue","666699","Grayish blue","808080","Gray","FF0000","Red","FF9900","Amber","99CC00","Yellow green","339966","Sea green","33CCCC","Turquoise","3366FF","Royal blue","800080","Purple","999999","Medium gray","FF00FF","Magenta","FFCC00","Gold","FFFF00","Yellow","00FF00","Lime","00FFFF","Aqua","00CCFF","Sky blue","993366","Brown","C0C0C0","Silver","FF99CC","Pink","FFCC99","Peach","FFFF99","Light yellow","CCFFCC","Pale green","CCFFFF","Pale cyan","99CCFF","Light sky blue","CC99FF","Plum","FFFFFF","White"],t=0;t',o=n.length-1,r=e.settings.textcolor_rows||5,l=e.settings.textcolor_cols||8,s=0;r>s;s++){for(a+="",c=0;l>c;c++)u=s*l+c,u>o?a+="":(i=n[u],a+='
    '+"
    "+"");a+=""}return a+=""}function i(t){var n,i=this.parent();(n=t.target.getAttribute("data-mce-color"))&&(i.hidePanel(),n="#"+n,i.color(n),e.execCommand(i.settings.selectcmd,!1,n))}function a(){var t=this;t._color&&e.execCommand(t.settings.selectcmd,!1,t._color)}e.addButton("forecolor",{type:"colorbutton",tooltip:"Text color",popoverAlign:"bc-tl",selectcmd:"ForeColor",panel:{html:n,onclick:i},onclick:a}),e.addButton("backcolor",{type:"colorbutton",tooltip:"Background color",popoverAlign:"bc-tl",selectcmd:"HiliteColor",panel:{html:n,onclick:i},onclick:a})}); \ No newline at end of file diff --git a/web/tinymce/plugins/visualblocks/css/visualblocks.css b/web/tinymce/plugins/visualblocks/css/visualblocks.css new file mode 100755 index 000000000..fe6fa930a --- /dev/null +++ b/web/tinymce/plugins/visualblocks/css/visualblocks.css @@ -0,0 +1,128 @@ +.mce-visualblocks p { + padding-top: 10px; + border: 1px dashed #BBB; + margin-left: 3px; + background: transparent no-repeat url(data:image/gif;base64,R0lGODlhCQAJAJEAAAAAAP///7u7u////yH5BAEAAAMALAAAAAAJAAkAAAIQnG+CqCN/mlyvsRUpThG6AgA7); +} + +.mce-visualblocks h1 { + padding-top: 10px; + border: 1px dashed #BBB; + margin-left: 3px; + background: transparent no-repeat url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybGu1JuxHoAfRNRW3TWXyF2YiRUAOw==); +} + +.mce-visualblocks h2 { + padding-top: 10px; + border: 1px dashed #BBB; + margin-left: 3px; + background: transparent no-repeat url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8Hybbx4oOuqgTynJd6bGlWg3DkJzoaUAAAOw==); +} + +.mce-visualblocks h3 { + padding-top: 10px; + border: 1px dashed #BBB; + margin-left: 3px; + background: transparent no-repeat url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIZjI8Hybbx4oOuqgTynJf2Ln2NOHpQpmhAAQA7); +} + +.mce-visualblocks h4 { + padding-top: 10px; + border: 1px dashed #BBB; + margin-left: 3px; + background: transparent no-repeat url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxInR0zqeAdhtJlXwV1oCll2HaWgAAOw==); +} + +.mce-visualblocks h5 { + padding-top: 10px; + border: 1px dashed #BBB; + margin-left: 3px; + background: transparent no-repeat url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxIoiuwjane4iq5GlW05GgIkIZUAAAOw==); +} + +.mce-visualblocks h6 { + padding-top: 10px; + border: 1px dashed #BBB; + margin-left: 3px; + background: transparent no-repeat url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxIoiuwjan04jep1iZ1XRlAo5bVgAAOw==); +} + +.mce-visualblocks div { + padding-top: 10px; + border: 1px dashed #BBB; + margin-left: 3px; + background: transparent no-repeat url(data:image/gif;base64,R0lGODlhEgAKAIABALu7u////yH5BAEAAAEALAAAAAASAAoAAAIfjI9poI0cgDywrhuxfbrzDEbQM2Ei5aRjmoySW4pAAQA7); +} + +.mce-visualblocks section { + padding-top: 10px; + border: 1px dashed #BBB; + margin: 0 0 1em 3px; + background: transparent no-repeat url(data:image/gif;base64,R0lGODlhKAAKAIABALu7u////yH5BAEAAAEALAAAAAAoAAoAAAI5jI+pywcNY3sBWHdNrplytD2ellDeSVbp+GmWqaDqDMepc8t17Y4vBsK5hDyJMcI6KkuYU+jpjLoKADs=); +} + +.mce-visualblocks article { + padding-top: 10px; + border: 1px dashed #BBB; + margin: 0 0 1em 3px; + background: transparent no-repeat url(data:image/gif;base64,R0lGODlhKgAKAIABALu7u////yH5BAEAAAEALAAAAAAqAAoAAAI6jI+pywkNY3wG0GBvrsd2tXGYSGnfiF7ikpXemTpOiJScasYoDJJrjsG9gkCJ0ag6KhmaIe3pjDYBBQA7); +} + +.mce-visualblocks blockquote { + padding-top: 10px; + border: 1px dashed #BBB; + background: transparent no-repeat url(data:image/gif;base64,R0lGODlhPgAKAIABALu7u////yH5BAEAAAEALAAAAAA+AAoAAAJPjI+py+0Knpz0xQDyuUhvfoGgIX5iSKZYgq5uNL5q69asZ8s5rrf0yZmpNkJZzFesBTu8TOlDVAabUyatguVhWduud3EyiUk45xhTTgMBBQA7); +} + +.mce-visualblocks address { + padding-top: 10px; + border: 1px dashed #BBB; + margin: 0 0 1em 3px; + background: transparent no-repeat url(data:image/gif;base64,R0lGODlhLQAKAIABALu7u////yH5BAEAAAEALAAAAAAtAAoAAAI/jI+pywwNozSP1gDyyZcjb3UaRpXkWaXmZW4OqKLhBmLs+K263DkJK7OJeifh7FicKD9A1/IpGdKkyFpNmCkAADs=); +} + +.mce-visualblocks pre { + padding-top: 10px; + border: 1px dashed #BBB; + margin-left: 3px; + background: transparent no-repeat url(data:image/gif;base64,R0lGODlhFQAKAIABALu7uwAAACH5BAEAAAEALAAAAAAVAAoAAAIjjI+ZoN0cgDwSmnpz1NCueYERhnibZVKLNnbOq8IvKpJtVQAAOw==); +} + +.mce-visualblocks figure { + padding-top: 10px; + border: 1px dashed #BBB; + margin: 0 0 1em 3px; + background: transparent no-repeat url(data:image/gif;base64,R0lGODlhJAAKAIAAALu7u////yH5BAEAAAEALAAAAAAkAAoAAAI0jI+py+2fwAHUSFvD3RlvG4HIp4nX5JFSpnZUJ6LlrM52OE7uSWosBHScgkSZj7dDKnWAAgA7); +} + +.mce-visualblocks hgroup { + padding-top: 10px; + border: 1px dashed #BBB; + margin: 0 0 1em 3px; + background: transparent no-repeat url(data:image/gif;base64,R0lGODlhJwAKAIABALu7uwAAACH5BAEAAAEALAAAAAAnAAoAAAI3jI+pywYNI3uB0gpsRtt5fFnfNZaVSYJil4Wo03Hv6Z62uOCgiXH1kZIIJ8NiIxRrAZNMZAtQAAA7); +} + +.mce-visualblocks aside { + padding-top: 10px; + border: 1px dashed #BBB; + margin: 0 0 1em 3px; + background: transparent no-repeat url(data:image/gif;base64,R0lGODlhHgAKAIABAKqqqv///yH5BAEAAAEALAAAAAAeAAoAAAItjI+pG8APjZOTzgtqy7I3f1yehmQcFY4WKZbqByutmW4aHUd6vfcVbgudgpYCADs=); +} + +.mce-visualblocks figcaption { + border: 1px dashed #BBB; +} + +.mce-visualblocks ul { + padding-top: 10px; + border: 1px dashed #BBB; + margin: 0 0 1em 3px; + background: transparent no-repeat url(data:image/gif;base64,R0lGODlhDQAKAIAAALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybGuYnqUVSjvw26DzzXiqIDlVwAAOw==) +} + +.mce-visualblocks ol { + padding-top: 10px; + border: 1px dashed #BBB; + margin: 0 0 1em 3px; + background: transparent no-repeat url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybH6HHt0qourxC6CvzXieHyeWQAAOw==); +} diff --git a/web/tinymce/plugins/visualblocks/plugin.min.js b/web/tinymce/plugins/visualblocks/plugin.min.js new file mode 100755 index 000000000..cafa41873 --- /dev/null +++ b/web/tinymce/plugins/visualblocks/plugin.min.js @@ -0,0 +1 @@ +tinymce.PluginManager.add("visualblocks",function(e,t){function n(){var t=this;t.active(r),e.on("VisualBlocks",function(){t.active(e.dom.hasClass(e.getBody(),"mce-visualblocks"))})}var i,a,r;window.NodeList&&(e.addCommand("mceVisualBlocks",function(){var n,o=e.dom;i||(i=o.uniqueId(),n=o.create("link",{id:i,rel:"stylesheet",href:t+"/css/visualblocks.css"}),e.getDoc().getElementsByTagName("head")[0].appendChild(n)),e.on("PreviewFormats AfterPreviewFormats",function(t){r&&o.toggleClass(e.getBody(),"mce-visualblocks","afterpreviewformats"==t.type)}),o.toggleClass(e.getBody(),"mce-visualblocks"),r=e.dom.hasClass(e.getBody(),"mce-visualblocks"),a&&a.active(o.hasClass(e.getBody(),"mce-visualblocks")),e.fire("VisualBlocks")}),e.addButton("visualblocks",{title:"Show blocks",cmd:"mceVisualBlocks",onPostRender:n}),e.addMenuItem("visualblocks",{text:"Show blocks",cmd:"mceVisualBlocks",onPostRender:n,selectable:!0,context:"view",prependToContext:!0}),e.on("init",function(){e.settings.visualblocks_default_state&&e.execCommand("mceVisualBlocks",!1,null,{skip_focus:!0})}),e.on("remove",function(){e.dom.removeClass(e.getBody(),"mce-visualblocks")}))}); \ No newline at end of file diff --git a/web/tinymce/plugins/visualchars/plugin.min.js b/web/tinymce/plugins/visualchars/plugin.min.js new file mode 100755 index 000000000..447423884 --- /dev/null +++ b/web/tinymce/plugins/visualchars/plugin.min.js @@ -0,0 +1 @@ +tinymce.PluginManager.add("visualchars",function(e){function t(t){var n,a,r,o,l,s,c=e.getBody(),d=e.selection;if(i=!i,e.fire("VisualChars",{state:i}),t&&(s=d.getBookmark()),i)for(a=[],tinymce.walk(c,function(e){3==e.nodeType&&e.nodeValue&&-1!=e.nodeValue.indexOf(" ")&&a.push(e)},"childNodes"),r=0;r$1'),l=e.dom.create("div",null,o);n=l.lastChild;)e.dom.insertAfter(n,a[r]);e.dom.remove(a[r])}else for(a=e.dom.select("span.mce-nbsp",c),r=a.length-1;r>=0;r--)e.dom.remove(a[r],1);d.moveToBookmark(s)}function n(){var t=this;e.on("VisualChars",function(e){t.active(e.state)})}var i;e.addCommand("mceVisualChars",t),e.addButton("visualchars",{title:"Show invisible characters",cmd:"mceVisualChars",onPostRender:n}),e.addMenuItem("visualchars",{text:"Show invisible characters",cmd:"mceVisualChars",onPostRender:n,selectable:!0,context:"view",prependToContext:!0}),e.on("beforegetcontent",function(e){i&&"raw"!=e.format&&!e.draft&&(i=!0,t(!1))})}); \ No newline at end of file diff --git a/web/tinymce/plugins/wordcount/plugin.min.js b/web/tinymce/plugins/wordcount/plugin.min.js new file mode 100755 index 000000000..8c419801b --- /dev/null +++ b/web/tinymce/plugins/wordcount/plugin.min.js @@ -0,0 +1 @@ +tinymce.PluginManager.add("wordcount",function(e){function t(){e.theme.panel.find("#wordcount").text(["Words: {0}",a.getCount()])}var n,i,a=this;n=e.getParam("wordcount_countregex",/[\w\u2019\x27\-]+/g),i=e.getParam("wordcount_cleanregex",/[0-9.(),;:!?%#$?\x27\x22_+=\\\/\-]*/g),e.on("init",function(){var n=e.theme.panel&&e.theme.panel.find("#statusbar")[0];n&&window.setTimeout(function(){n.insert({type:"label",name:"wordcount",text:["Words: {0}",a.getCount()],classes:"wordcount"},0),e.on("setcontent beforeaddundo",t),e.on("keyup",function(e){32==e.keyCode&&t()})},0)}),a.getCount=function(){var t=e.getContent({format:"raw"}),a=0;if(t){t=t.replace(/\.\.\./g," "),t=t.replace(/<.[^<>]*?>/g," ").replace(/ | /gi," "),t=t.replace(/(\w+)(&.+?;)+(\w+)/,"$1$3").replace(/&.+?;/g," "),t=t.replace(i,"");var o=t.match(n);o&&(a=o.length)}return a}}); \ No newline at end of file diff --git a/web/tinymce/skins/lightgray/content.inline.min.css b/web/tinymce/skins/lightgray/content.inline.min.css new file mode 100755 index 000000000..771b83e55 --- /dev/null +++ b/web/tinymce/skins/lightgray/content.inline.min.css @@ -0,0 +1 @@ +.mce-object{border:1px dotted #3a3a3a;background:#d5d5d5 url(img/object.gif) no-repeat center}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px!important;height:9px!important;border:1px dotted #3a3a3a;background:#d5d5d5 url(img/anchor.gif) no-repeat center}.mce-nbsp{background:#AAA}hr{cursor:default}.mce-match-marker{background:green;color:#fff}.mce-spellchecker-word{background:url(img/wline.gif) repeat-x bottom left;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #BBB}td.mce-item-selected,th.mce-item-selected{background-color:#39f!important}.mce-edit-focus{outline:1px dotted #333} \ No newline at end of file diff --git a/web/tinymce/skins/lightgray/content.min.css b/web/tinymce/skins/lightgray/content.min.css new file mode 100755 index 000000000..b9bbab143 --- /dev/null +++ b/web/tinymce/skins/lightgray/content.min.css @@ -0,0 +1 @@ +body{background-color:#fff;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:11px;scrollbar-3dlight-color:#f0f0ee;scrollbar-arrow-color:#676662;scrollbar-base-color:#f0f0ee;scrollbar-darkshadow-color:#ddd;scrollbar-face-color:#e0e0dd;scrollbar-highlight-color:#f0f0ee;scrollbar-shadow-color:#f0f0ee;scrollbar-track-color:#f5f5f5}td,th{font-family:Verdana,Arial,Helvetica,sans-serif;font-size:11px}.mce-object{border:1px dotted #3a3a3a;background:#d5d5d5 url(img/object.gif) no-repeat center}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px!important;height:9px!important;border:1px dotted #3a3a3a;background:#d5d5d5 url(img/anchor.gif) no-repeat center}.mce-nbsp{background:#AAA}hr{cursor:default}.mce-match-marker{background:green;color:#fff}.mce-spellchecker-word{background:url(img/wline.gif) repeat-x bottom left;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #BBB}td.mce-item-selected,th.mce-item-selected{background-color:#39f!important}.mce-edit-focus{outline:1px dotted #333} \ No newline at end of file diff --git a/web/tinymce/skins/lightgray/fonts/icomoon-small.eot b/web/tinymce/skins/lightgray/fonts/icomoon-small.eot new file mode 100755 index 000000000..43a30f992 Binary files /dev/null and b/web/tinymce/skins/lightgray/fonts/icomoon-small.eot differ diff --git a/web/tinymce/skins/lightgray/fonts/icomoon-small.svg b/web/tinymce/skins/lightgray/fonts/icomoon-small.svg new file mode 100755 index 000000000..d338114f0 --- /dev/null +++ b/web/tinymce/skins/lightgray/fonts/icomoon-small.svg @@ -0,0 +1,175 @@ + + + + +This is a custom SVG font generated by IcoMoon. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/web/tinymce/skins/lightgray/fonts/icomoon-small.ttf b/web/tinymce/skins/lightgray/fonts/icomoon-small.ttf new file mode 100755 index 000000000..841c79c18 Binary files /dev/null and b/web/tinymce/skins/lightgray/fonts/icomoon-small.ttf differ diff --git a/web/tinymce/skins/lightgray/fonts/icomoon-small.woff b/web/tinymce/skins/lightgray/fonts/icomoon-small.woff new file mode 100755 index 000000000..ad14a2406 Binary files /dev/null and b/web/tinymce/skins/lightgray/fonts/icomoon-small.woff differ diff --git a/web/tinymce/skins/lightgray/fonts/icomoon.eot b/web/tinymce/skins/lightgray/fonts/icomoon.eot new file mode 100755 index 000000000..eed4f8149 Binary files /dev/null and b/web/tinymce/skins/lightgray/fonts/icomoon.eot differ diff --git a/web/tinymce/skins/lightgray/fonts/icomoon.svg b/web/tinymce/skins/lightgray/fonts/icomoon.svg new file mode 100755 index 000000000..727f61af1 --- /dev/null +++ b/web/tinymce/skins/lightgray/fonts/icomoon.svg @@ -0,0 +1,153 @@ + + + + +This is a custom SVG font generated by IcoMoon. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/web/tinymce/skins/lightgray/fonts/icomoon.ttf b/web/tinymce/skins/lightgray/fonts/icomoon.ttf new file mode 100755 index 000000000..dea6e458f Binary files /dev/null and b/web/tinymce/skins/lightgray/fonts/icomoon.ttf differ diff --git a/web/tinymce/skins/lightgray/fonts/icomoon.woff b/web/tinymce/skins/lightgray/fonts/icomoon.woff new file mode 100755 index 000000000..f17657986 Binary files /dev/null and b/web/tinymce/skins/lightgray/fonts/icomoon.woff differ diff --git a/web/tinymce/skins/lightgray/fonts/readme.md b/web/tinymce/skins/lightgray/fonts/readme.md new file mode 100755 index 000000000..fa5d63946 --- /dev/null +++ b/web/tinymce/skins/lightgray/fonts/readme.md @@ -0,0 +1 @@ +Icons are generated and provided by the http://icomoon.io service. diff --git a/web/tinymce/skins/lightgray/img/anchor.gif b/web/tinymce/skins/lightgray/img/anchor.gif new file mode 100755 index 000000000..606348c7f Binary files /dev/null and b/web/tinymce/skins/lightgray/img/anchor.gif differ diff --git a/web/tinymce/skins/lightgray/img/loader.gif b/web/tinymce/skins/lightgray/img/loader.gif new file mode 100755 index 000000000..c69e93723 Binary files /dev/null and b/web/tinymce/skins/lightgray/img/loader.gif differ diff --git a/web/tinymce/skins/lightgray/img/object.gif b/web/tinymce/skins/lightgray/img/object.gif new file mode 100755 index 000000000..cccd7f023 Binary files /dev/null and b/web/tinymce/skins/lightgray/img/object.gif differ diff --git a/web/tinymce/skins/lightgray/img/trans.gif b/web/tinymce/skins/lightgray/img/trans.gif new file mode 100755 index 000000000..388486517 Binary files /dev/null and b/web/tinymce/skins/lightgray/img/trans.gif differ diff --git a/web/tinymce/skins/lightgray/img/wline.gif b/web/tinymce/skins/lightgray/img/wline.gif new file mode 100755 index 000000000..7d0a4dbca Binary files /dev/null and b/web/tinymce/skins/lightgray/img/wline.gif differ diff --git a/web/tinymce/skins/lightgray/skin.ie7.min.css b/web/tinymce/skins/lightgray/skin.ie7.min.css new file mode 100755 index 000000000..234b1937b --- /dev/null +++ b/web/tinymce/skins/lightgray/skin.ie7.min.css @@ -0,0 +1 @@ +.mce-container,.mce-container *,.mce-widget,.mce-widget *{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:#000;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;-webkit-tap-highlight-color:transparent;line-height:normal;font-weight:normal;text-align:left;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}.mce-widget button{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.mce-container *[unselectable]{-moz-user-select:none;-webkit-user-select:none;-o-user-select:none;user-select:none}.mce-container ::-webkit-scrollbar{width:8px;height:8px;-webkit-border-radius:4px}.mce-container ::-webkit-scrollbar-track,.mce-container ::-webkit-scrollbar-track-piece{background-color:transparent}.mce-container ::-webkit-scrollbar-thumb{background-color:rgba(53,57,71,0.3);width:6px;height:6px;-webkit-border-radius:4px}.mce-fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.mce-fade.mce-in{opacity:1}.mce-tinymce{visibility:visible!important;position:relative}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;background:#FFF;height:100%;z-index:100}div.mce-fullscreen{position:fixed;top:0;left:0;width:100%;height:auto}.mce-tinymce{display:block;border-radius:2px}.mce-wordcount{position:absolute;top:0;right:0;padding:8px}.mce-edit-area{background:#FFF;filter:none}.mce-statusbar{position:relative}.mce-statusbar .mce-container-body{position:relative}.mce-fullscreen .mce-resizehandle{display:none}.mce-charmap{border-collapse:collapse}.mce-charmap td{cursor:default;border:1px solid #c5c5c5;width:20px;height:20px;line-height:20px;text-align:center;vertical-align:middle;padding:2px}.mce-charmap td div{text-align:center}.mce-charmap td:hover{background:#d9d9d9}.mce-grid td div{border:1px solid #808080;width:12px;height:12px;margin:2px;cursor:pointer}.mce-grid td div:hover{border-color:black}.mce-grid td div:focus{border-color:#59a5e1;outline:1px solid rgba(82,168,236,0.8);border-color:rgba(82,168,236,0.8)}.mce-grid{border-spacing:2px;border-collapse:separate}.mce-grid a{display:block;border:1px solid transparent}.mce-grid a:hover{border-color:#c5c5c5}.mce-grid-border{margin:0 4px 0 4px}.mce-grid-border a{border-color:#e8e8e8;width:13px;height:13px}.mce-grid-border a:hover,.mce-grid-border a.mce-active{border-color:#c4daff;background:#deeafa}.mce-text-center{text-align:center}div.mce-tinymce-inline{width:100%;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-container,.mce-container-body{display:block}.mce-autoscroll{overflow:hidden}.mce-scrollbar{position:absolute;width:7px;height:100%;top:2px;right:2px;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-scrollbar-h{top:auto;right:auto;left:2px;bottom:2px;width:100%;height:7px}.mce-scrollbar-thumb{position:absolute;background-color:#000;border:1px solid #888;border-color:rgba(85,85,85,0.6);width:5px;height:100%;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px}.mce-scrollbar-h .mce-scrollbar-thumb{width:100%;height:5px}.mce-scrollbar:hover,.mce-scrollbar.mce-active{background-color:#AAA;opacity:.6;filter:alpha(opacity=60);zoom:1;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px}.mce-scroll{position:relative}.mce-panel{border:0 solid #9e9e9e;background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fdfdfd,#ddd);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fdfdfd),to(#ddd));background-image:-webkit-linear-gradient(top,#fdfdfd,#ddd);background-image:-o-linear-gradient(top,#fdfdfd,#ddd);background-image:linear-gradient(to bottom,#fdfdfd,#ddd);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffdfdfd',endColorstr='#ffdddddd',GradientType=0);zoom:1}.mce-floatpanel{position:absolute;-webkit-box-shadow:#ccc 5px 5px 5px;-moz-box-shadow:#ccc 5px 5px 5px;box-shadow:#ccc 5px 5px 5px}.mce-floatpanel.mce-fixed{position:fixed}.mce-floatpanel .mce-arrow,.mce-floatpanel .mce-arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.mce-floatpanel .mce-arrow{border-width:11px}.mce-floatpanel .mce-arrow:after{border-width:10px;content:""}.mce-floatpanel.mce-popover{top:0;left:0;background:#fff;-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2)}.mce-floatpanel.mce-popover.mce-bottom{margin-top:10px}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);top:-11px}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow:after{top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.mce-floatpanel.mce-popover.mce-bottom.mce-start{margin-left:-22px}.mce-floatpanel.mce-popover.mce-bottom.mce-start>.mce-arrow{left:20px}.mce-floatpanel.mce-popover.mce-bottom.mce-end{margin-left:22px}.mce-floatpanel.mce-popover.mce-bottom.mce-end>.mce-arrow{right:10px;left:auto}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;background:#FFF;height:100%}div.mce-fullscreen{position:fixed;top:0;left:0}#mce-modal-block{opacity:0;filter:alpha(opacity=0);zoom:1;position:fixed;left:0;top:0;width:100%;height:100%;background:#000}#mce-modal-block.mce-in{opacity:.3;filter:alpha(opacity=30);zoom:1}.mce-window-move{cursor:move}.mce-window{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;background:#FFF;position:fixed;top:0;left:0;opacity:0;-webkit-transition:opacity 150ms ease-in;transition:opacity 150ms ease-in}.mce-window.mce-in{opacity:1}.mce-window-head{padding:9px 15px;border-bottom:1px solid #EEE;position:relative}.mce-window-head .mce-close{position:absolute;right:15px;top:9px;font-size:20px;font-weight:bold;line-height:20px;color:#CCC;text-shadow:0 1px 0 white;cursor:pointer;height:20px;overflow:hidden}.mce-close:hover{color:#AAA}.mce-window-head .mce-title{display:inline-block;*display:inline;*zoom:1;line-height:20px;font-size:20px;font-weight:bold;text-rendering:optimizelegibility;padding-right:10px}.mce-window .mce-container-body{display:block}.mce-foot{display:block;background-color:whiteSmoke;border-top:1px solid #DDD;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.mce-window-head .mce-dragh{position:absolute;top:0;left:0;cursor:move;width:90%;height:100%}.mce-window iframe{width:100%;height:100%}.mce-window.mce-fullscreen,.mce-window.mce-fullscreen .mce-foot{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.mce-abs-layout{position:relative}body .mce-abs-layout-item,.mce-abs-end{position:absolute}.mce-abs-end{width:1px;height:1px}.mce-container-body.mce-abs-layout{overflow:hidden}.mce-tooltip{position:absolute;padding:5px;opacity:.8;filter:alpha(opacity=80);zoom:1}.mce-tooltip-inner{font-size:11px;background-color:#000;color:#fff;max-width:200px;padding:5px 8px 4px 8px;text-align:center;white-space:normal}.mce-tooltip-inner{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-tooltip-inner{-webkit-box-shadow:0 0 5px #000;-moz-box-shadow:0 0 5px #000;box-shadow:0 0 5px #000}.mce-tooltip-arrow{position:absolute;width:0;height:0;line-height:0;border:5px dashed #000}.mce-tooltip-arrow-n{border-bottom-color:#000}.mce-tooltip-arrow-s{border-top-color:#000}.mce-tooltip-arrow-e{border-left-color:#000}.mce-tooltip-arrow-w{border-right-color:#000}.mce-tooltip-nw,.mce-tooltip-sw{margin-left:-14px}.mce-tooltip-n .mce-tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-style:solid;border-top:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-nw .mce-tooltip-arrow{top:0;left:10px;border-bottom-style:solid;border-top:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-ne .mce-tooltip-arrow{top:0;right:10px;border-bottom-style:solid;border-top:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-s .mce-tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-style:solid;border-bottom:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-sw .mce-tooltip-arrow{bottom:0;left:10px;border-top-style:solid;border-bottom:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-se .mce-tooltip-arrow{bottom:0;right:10px;border-top-style:solid;border-bottom:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-e .mce-tooltip-arrow{right:0;top:50%;margin-top:-5px;border-left-style:solid;border-right:0;border-top-color:transparent;border-bottom-color:transparent}.mce-tooltip-w .mce-tooltip-arrow{left:0;top:50%;margin-top:-5px;border-right-style:solid;border-left:none;border-top-color:transparent;border-bottom-color:transparent}.mce-btn{border:1px solid #c5c5c5;position:relative;color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fff,#d9d9d9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#d9d9d9));background-image:-webkit-linear-gradient(top,#fff,#d9d9d9);background-image:-o-linear-gradient(top,#fff,#d9d9d9);background-image:linear-gradient(to bottom,#fff,#d9d9d9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffd9d9d9',GradientType=0);zoom:1;border-color:#d9d9d9 #d9d9d9 #b3b3b3;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);display:inline-block;*display:inline;*zoom:1;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.mce-btn:hover,.mce-btn:focus{text-decoration:none;color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#e3e3e3;background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#ccc));background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(to bottom,#f2f2f2,#ccc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffcccccc',GradientType=0);zoom:1;border-color:#ccc #ccc #a6a6a6;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-btn.mce-disabled,.mce-btn.mce-disabled:hover{cursor:default;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.65;filter:alpha(opacity=65);zoom:1}.mce-btn.mce-active,.mce-btn.mce-active:hover{color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#d6d6d6;background-image:-moz-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:-webkit-gradient(linear,0 0,0 100%,from(#e6e6e6),to(#bfbfbf));background-image:-webkit-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:-o-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:linear-gradient(to bottom,#e6e6e6,#bfbfbf);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe6e6e6',endColorstr='#ffbfbfbf',GradientType=0);zoom:1;border-color:#bfbfbf #bfbfbf #999;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.mce-btn button{padding:4px 10px;font-size:14px;line-height:20px;*line-height:16px;cursor:pointer;color:#333;text-align:center;overflow:visible;-webkit-appearance:none}.mce-btn button::-moz-focus-inner{border:0;padding:0}.mce-btn i{text-shadow:1px 1px #fff}.mce-primary{min-width:50px;color:#fff;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#006dcc;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);zoom:1;border-color:#04c #04c #002b80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-primary:hover,.mce-primary:focus{color:#fff;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#005fb3;background-image:-moz-linear-gradient(top,#0077b3,#003cb3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#0077b3),to(#003cb3));background-image:-webkit-linear-gradient(top,#0077b3,#003cb3);background-image:-o-linear-gradient(top,#0077b3,#003cb3);background-image:linear-gradient(to bottom,#0077b3,#003cb3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0077b3',endColorstr='#ff003cb3',GradientType=0);zoom:1;border-color:#003cb3 #003cb3 #026;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-primary button{color:#fff}.mce-btn-large button{padding:9px 14px;font-size:16px;line-height:normal;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.mce-btn-large i{margin-top:2px}.mce-btn-small button{padding:3px 5px;font-size:12px;line-height:15px}.mce-btn-small i{margin-top:0}.mce-btn .mce-caret{margin-top:8px;*margin-top:6px;margin-left:0}.mce-btn-small .mce-caret{margin-top:6px;*margin-top:4px;margin-left:0}.mce-caret{display:inline-block;*display:inline;*zoom:1;width:0;height:0;vertical-align:top;border-top:4px solid #444;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.mce-disabled .mce-caret{border-top-color:#999}.mce-caret.mce-up{border-bottom:4px solid #444;border-top:0}.mce-btn-group .mce-btn{border-width:1px 0 1px 0;margin:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.mce-btn-group .mce-btn:hover,.mce-btn-group .mce-btn:focus{color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#e3e3e3;background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#ccc));background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(to bottom,#f2f2f2,#ccc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffcccccc',GradientType=0);zoom:1;border-color:#ccc #ccc #a6a6a6;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-btn-group .mce-btn.mce-disabled,.mce-btn-group .mce-btn.mce-disabled:hover{-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fff,#d9d9d9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#d9d9d9));background-image:-webkit-linear-gradient(top,#fff,#d9d9d9);background-image:-o-linear-gradient(top,#fff,#d9d9d9);background-image:linear-gradient(to bottom,#fff,#d9d9d9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffd9d9d9',GradientType=0);zoom:1;border-color:#d9d9d9 #d9d9d9 #b3b3b3;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-btn-group .mce-btn.mce-active,.mce-btn-group .mce-btn.mce-active:hover,.mce-btn-group .mce-btn:active{color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#d6d6d6;background-image:-moz-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:-webkit-gradient(linear,0 0,0 100%,from(#e6e6e6),to(#bfbfbf));background-image:-webkit-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:-o-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:linear-gradient(to bottom,#e6e6e6,#bfbfbf);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe6e6e6',endColorstr='#ffbfbfbf',GradientType=0);zoom:1;border-color:#bfbfbf #bfbfbf #999;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.mce-btn-group .mce-btn.mce-disabled button{opacity:.65;filter:alpha(opacity=65);zoom:1}.mce-btn-group .mce-first{border-left:1px solid #c5c5c5;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.mce-btn-group .mce-last{border-right:1px solid #c5c5c5;-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.mce-btn-group .mce-first.mce-last{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-btn-group .mce-btn.mce-flow-layout-item{margin:0}.mce-checkbox{cursor:pointer}i.mce-i-checkbox{margin:0 3px 0 0;border:1px solid #c5c5c5;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fdfdfd,#ddd);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fdfdfd),to(#ddd));background-image:-webkit-linear-gradient(top,#fdfdfd,#ddd);background-image:-o-linear-gradient(top,#fdfdfd,#ddd);background-image:linear-gradient(to bottom,#fdfdfd,#ddd);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffdfdfd',endColorstr='#ffdddddd',GradientType=0);zoom:1;text-indent:-10em;*font-size:0;*line-height:0;*text-indent:0}.mce-checked i.mce-i-checkbox{color:#000;font-size:16px;line-height:16px;text-indent:0}.mce-checkbox:focus i.mce-i-checkbox{border:1px solid #59a5e1;border:1px solid rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}.mce-colorbutton .mce-ico{position:relative}.mce-colorpicker{background:#FFF}.mce-colorbutton-grid{margin:4px}.mce-colorbutton button{padding-right:4px}.mce-colorbutton .mce-preview{padding-right:3px;display:block;position:absolute;left:50%;top:50%;margin-left:-14px;margin-top:7px;background:gray;width:13px;height:2px;overflow:hidden}.mce-colorbutton.mce-btn-small .mce-preview{margin-left:-17px;padding-right:0;width:16px}.mce-colorbutton .mce-open{padding-left:4px;border-left:1px solid transparent;border-right:1px solid transparent}.mce-colorbutton:hover .mce-open{border-left-color:#c5c5c5;border-right-color:#c5c5c5}.mce-combobox{display:inline-block;*display:inline;*zoom:1;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;width:100px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.mce-combobox input{border:1px solid #c5c5c5;border-right-color:rgba(0,0,0,0.15);height:28px}.mce-combobox.mce-has-open input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.mce-combobox .mce-btn{border-left:0;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.mce-combobox button{padding-right:8px;padding-left:8px}.mce-combobox *:focus{border-color:#59a5e1;border-color:rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}.mce-path{display:inline-block;*display:inline;*zoom:1;padding:8px;white-space:normal}.mce-path .mce-txt{display:inline-block;padding-right:3px}.mce-path .mce-path-body{display:inline-block}.mce-path-item{display:inline-block;*display:inline;*zoom:1;cursor:pointer;color:#000}.mce-path-item:hover{text-decoration:underline}.mce-path-item:focus{background:gray;color:white}.mce-path .mce-divider{display:inline}.mce-fieldset{border:0 solid #9e9e9e;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-fieldset>.mce-container-body{margin-top:-15px}.mce-fieldset-title{margin-left:5px;padding:0 5px 0 5px}.mce-fit-layout{display:inline-block;*display:inline;*zoom:1}.mce-fit-layout-item{position:absolute}.mce-flow-layout-item{display:inline-block;*display:inline;*zoom:1}.mce-flow-layout-item{margin:2px 0 2px 2px}.mce-flow-layout-item.mce-last{margin-right:2px}.mce-flow-layout{white-space:normal}.mce-tinymce-inline .mce-flow-layout{white-space:nowrap}.mce-iframe{border:0 solid #c5c5c5;width:100%;height:100%}.mce-label{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 1px rgba(255,255,255,0.75);border:0 solid #c5c5c5;overflow:hidden}.mce-label.mce-autoscroll{overflow:auto}.mce-label-disabled .mce-text{color:#999}.mce-label.mce-multiline{white-space:pre-wrap}.mce-menubar .mce-menubtn{border-color:transparent;background:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;filter:none}.mce-menubar{border:1px solid #ddd}.mce-menubar .mce-menubtn button{color:#000}.mce-menubar .mce-menubtn:hover,.mce-menubar .mce-menubtn.mce-active,.mce-menubar .mce-menubtn:focus{border-color:transparent;background:#ddd;filter:none}.mce-menubtn.mce-disabled span{color:#999}.mce-menubtn span{margin-right:2px;line-height:20px;*line-height:16px}.mce-menubtn.mce-btn-small span{font-size:12px;line-height:15px;*line-height:16px}.mce-menubtn.mce-fixed-width span{display:inline-block;overflow-x:hidden;text-overflow:ellipsis;width:90px}.mce-menubtn.mce-fixed-width.mce-btn-small span{width:70px}.mce-listbox button{text-align:left;padding-right:20px;position:relative}.mce-listbox .mce-caret{position:absolute;margin-top:-2px;right:8px;top:50%}.mce-menu-item{display:block;padding:6px 15px 6px 12px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap;cursor:pointer;line-height:normal;border-left:4px solid transparent;margin-bottom:1px}.mce-menu-item.mce-disabled .mce-text{color:#999}.mce-menu-item:hover,.mce-menu-item.mce-selected,.mce-menu-item:focus{text-decoration:none;color:#fff;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0);zoom:1}.mce-menu-item:hover .mce-text,.mce-menu-item.mce-selected .mce-text{color:#fff}.mce-menu-item:hover .mce-ico,.mce-menu-item.mce-selected .mce-ico,.mce-menu-item:focus .mce-ico{color:white}.mce-menu-item.mce-disabled:hover{background:#CCC}.mce-menu-shortcut{display:inline-block;color:#999}.mce-menu-shortcut{display:inline-block;*display:inline;*zoom:1;padding:0 15px 0 20px}.mce-menu-item .mce-caret{margin-top:4px;*margin-top:3px;margin-right:6px;border-top:4px solid transparent;border-bottom:4px solid transparent;border-left:4px solid #666}.mce-menu-item.mce-selected .mce-caret,.mce-menu-item:focus .mce-caret{border-left-color:#FFF}.mce-menu-align .mce-menu-shortcut{*margin-top:-2px}.mce-menu-align .mce-menu-shortcut,.mce-menu-align .mce-caret{position:absolute;right:0}.mce-menu-item-sep,.mce-menu-item-sep:hover{padding:0;height:1px;margin:9px 1px;overflow:hidden;background:#e5e5e5;border-bottom:1px solid white;cursor:default;filter:none}.mce-menu-item.mce-active i{visibility:visible}.mce-menu-item.mce-active{background-color:#c8def4;outline:1px solid #c5c5c5}.mce-menu-item-preview.mce-active{border-left:5px solid #aaa;background-color:transparent;outline:0}.mce-menu-item-checkbox.mce-active{background-color:#FFF;outline:0}.mce-menu{filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;z-index:1000;padding:5px 0 5px 0;margin:2px 0 0;min-width:160px;background:#FFF;border:1px solid #CCC;border:1px solid rgba(0,0,0,0.2);z-index:1002;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);max-height:400px;overflow:auto;overflow-x:hidden}.mce-menu i{display:none}.mce-menu-has-icons i{display:inline-block;*display:inline;*zoom:1}.mce-menu-sub-tr-tl{margin:-6px 0 0 -1px}.mce-menu-sub-br-bl{margin:6px 0 0 -1px}.mce-menu-sub-tl-tr{margin:-6px 0 0 1px}.mce-menu-sub-bl-br{margin:6px 0 0 1px}i.mce-radio{padding:1px;margin:0 3px 0 0;background-color:#fafafa;border:1px solid #cacece;-webkit-border-radius:8px;-moz-border-radius:8px;border-radius:8px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fdfdfd,#ddd);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fdfdfd),to(#ddd));background-image:-webkit-linear-gradient(top,#fdfdfd,#ddd);background-image:-o-linear-gradient(top,#fdfdfd,#ddd);background-image:linear-gradient(to bottom,#fdfdfd,#ddd);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffdfdfd',endColorstr='#ffdddddd',GradientType=0);zoom:1}i.mce-radio:after{font-family:Arial;font-size:12px;color:#000;content:'\25cf'}.mce-container-body .mce-resizehandle{position:absolute;right:0;bottom:0;width:16px;height:16px;visibility:visible;cursor:s-resize;margin:0}.mce-container-body .mce-resizehandle-both{cursor:se-resize}i.mce-i-resize{color:#000}.mce-spacer{visibility:hidden}.mce-splitbtn .mce-open{border-left:1px solid transparent;border-right:1px solid transparent}.mce-splitbtn:hover .mce-open{border-left-color:#c5c5c5;border-right-color:#c5c5c5}.mce-splitbtn button{padding-right:4px}.mce-splitbtn .mce-open{padding-left:4px}.mce-splitbtn .mce-open.mce-active{-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.mce-stack-layout-item{display:block}.mce-tabs{display:block;border-bottom:1px solid #ccc}.mce-tab{display:inline-block;*display:inline;*zoom:1;border:1px solid #ccc;border-width:1px 1px 0 0;background:#e3e3e3;padding:8px;text-shadow:0 1px 1px rgba(255,255,255,0.75);height:13px;cursor:pointer}.mce-tab:hover{background:#fdfdfd}.mce-tab.mce-active{background:#fdfdfd;border-bottom-color:transparent;margin-bottom:-1px;height:14px}.mce-textbox{background:#FFF;border:1px solid #c5c5c5;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);display:inline-block;-webkit-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s;height:28px;resize:none;padding:0 4px 0 4px;white-space:pre-wrap;*white-space:pre;color:#000}.mce-textbox:focus{border-color:rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}.mce-placeholder .mce-textbox{color:#aaa}.mce-textbox.mce-multiline{padding:4px}.mce-throbber{position:absolute;top:0;left:0;width:100%;height:100%;opacity:.6;filter:alpha(opacity=60);zoom:1;background:#fff url('img/loader.gif') no-repeat center center}@font-face{font-family:'icomoon';src:url('fonts/icomoon.eot');src:url('fonts/icomoon.eot?#iefix') format('embedded-opentype'),url('fonts/icomoon.svg#icomoon') format('svg'),url('fonts/icomoon.woff') format('woff'),url('fonts/icomoon.ttf') format('truetype');font-weight:normal;font-style:normal}@font-face{font-family:'icomoon-small';src:url('fonts/icomoon-small.eot');src:url('fonts/icomoon-small.eot?#iefix') format('embedded-opentype'),url('fonts/icomoon-small.svg#icomoon') format('svg'),url('fonts/icomoon-small.woff') format('woff'),url('fonts/icomoon-small.ttf') format('truetype');font-weight:normal;font-style:normal}.mce-ico{font-family:'icomoon';font-style:normal;font-weight:normal;font-size:16px;line-height:16px;vertical-align:text-top;-webkit-font-smoothing:antialiased;display:inline-block;background:transparent center center;width:16px;height:16px;color:#333;-ie7-icon:' '}.mce-btn-small .mce-ico{font-family:'icomoon-small'}.mce-ico,i.mce-i-checkbox{zoom:expression(this.runtimeStyle['zoom'] = '1',this.innerHTML = this.currentStyle['-ie7-icon'].substr(1,1)+' ')}.mce-i-save{-ie7-icon:"\e000"}.mce-i-newdocument{-ie7-icon:"\e001"}.mce-i-fullpage{-ie7-icon:"\e002"}.mce-i-alignleft{-ie7-icon:"\e003"}.mce-i-aligncenter{-ie7-icon:"\e004"}.mce-i-alignright{-ie7-icon:"\e005"}.mce-i-alignjustify{-ie7-icon:"\e006"}.mce-i-cut{-ie7-icon:"\e007"}.mce-i-paste{-ie7-icon:"\e008"}.mce-i-searchreplace{-ie7-icon:"\e009"}.mce-i-bullist{-ie7-icon:"\e00a"}.mce-i-numlist{-ie7-icon:"\e00b"}.mce-i-indent{-ie7-icon:"\e00c"}.mce-i-outdent{-ie7-icon:"\e00d"}.mce-i-blockquote{-ie7-icon:"\e00e"}.mce-i-undo{-ie7-icon:"\e00f"}.mce-i-redo{-ie7-icon:"\e010"}.mce-i-link{-ie7-icon:"\e011"}.mce-i-unlink{-ie7-icon:"\e012"}.mce-i-anchor{-ie7-icon:"\e013"}.mce-i-image{-ie7-icon:"\e014"}.mce-i-media{-ie7-icon:"\e015"}.mce-i-help{-ie7-icon:"\e016"}.mce-i-code{-ie7-icon:"\e017"}.mce-i-inserttime{-ie7-icon:"\e018"}.mce-i-preview{-ie7-icon:"\e019"}.mce-i-forecolor{-ie7-icon:"\e01a"}.mce-i-backcolor{-ie7-icon:"\e01a"}.mce-i-table{-ie7-icon:"\e01b"}.mce-i-hr{-ie7-icon:"\e01c"}.mce-i-removeformat{-ie7-icon:"\e01d"}.mce-i-subscript{-ie7-icon:"\e01e"}.mce-i-superscript{-ie7-icon:"\e01f"}.mce-i-charmap{-ie7-icon:"\e020"}.mce-i-emoticons{-ie7-icon:"\e021"}.mce-i-print{-ie7-icon:"\e022"}.mce-i-fullscreen{-ie7-icon:"\e023"}.mce-i-spellchecker{-ie7-icon:"\e024"}.mce-i-nonbreaking{-ie7-icon:"\e025"}.mce-i-template{-ie7-icon:"\e026"}.mce-i-pagebreak{-ie7-icon:"\e027"}.mce-i-restoredraft{-ie7-icon:"\e028"}.mce-i-untitled{-ie7-icon:"\e029"}.mce-i-bold{-ie7-icon:"\e02a"}.mce-i-italic{-ie7-icon:"\e02b"}.mce-i-underline{-ie7-icon:"\e02c"}.mce-i-strikethrough{-ie7-icon:"\e02d"}.mce-i-visualchars{-ie7-icon:"\e02e"}.mce-i-ltr{-ie7-icon:"\e02f"}.mce-i-rtl{-ie7-icon:"\e030"}.mce-i-copy{-ie7-icon:"\e031"}.mce-i-resize{-ie7-icon:"\e032"}.mce-i-browse{-ie7-icon:"\e034"}.mce-i-checkbox,.mce-i-selected{-ie7-icon:"\e033"}.mce-i-selected{visibility:hidden}.mce-i-backcolor{background:#BBB} \ No newline at end of file diff --git a/web/tinymce/skins/lightgray/skin.min.css b/web/tinymce/skins/lightgray/skin.min.css new file mode 100755 index 000000000..86fd63191 --- /dev/null +++ b/web/tinymce/skins/lightgray/skin.min.css @@ -0,0 +1 @@ +.mce-container,.mce-container *,.mce-widget,.mce-widget *{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:#000;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;-webkit-tap-highlight-color:transparent;line-height:normal;font-weight:normal;text-align:left;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}.mce-widget button{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.mce-container *[unselectable]{-moz-user-select:none;-webkit-user-select:none;-o-user-select:none;user-select:none}.mce-container ::-webkit-scrollbar{width:8px;height:8px;-webkit-border-radius:4px}.mce-container ::-webkit-scrollbar-track,.mce-container ::-webkit-scrollbar-track-piece{background-color:transparent}.mce-container ::-webkit-scrollbar-thumb{background-color:rgba(53,57,71,0.3);width:6px;height:6px;-webkit-border-radius:4px}.mce-fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.mce-fade.mce-in{opacity:1}.mce-tinymce{visibility:visible!important;position:relative}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;background:#FFF;height:100%;z-index:100}div.mce-fullscreen{position:fixed;top:0;left:0;width:100%;height:auto}.mce-tinymce{display:block;border-radius:2px}.mce-wordcount{position:absolute;top:0;right:0;padding:8px}.mce-edit-area{background:#FFF;filter:none}.mce-statusbar{position:relative}.mce-statusbar .mce-container-body{position:relative}.mce-fullscreen .mce-resizehandle{display:none}.mce-charmap{border-collapse:collapse}.mce-charmap td{cursor:default;border:1px solid #c5c5c5;width:20px;height:20px;line-height:20px;text-align:center;vertical-align:middle;padding:2px}.mce-charmap td div{text-align:center}.mce-charmap td:hover{background:#d9d9d9}.mce-grid td div{border:1px solid #808080;width:12px;height:12px;margin:2px;cursor:pointer}.mce-grid td div:hover{border-color:black}.mce-grid td div:focus{border-color:#59a5e1;outline:1px solid rgba(82,168,236,0.8);border-color:rgba(82,168,236,0.8)}.mce-grid{border-spacing:2px;border-collapse:separate}.mce-grid a{display:block;border:1px solid transparent}.mce-grid a:hover{border-color:#c5c5c5}.mce-grid-border{margin:0 4px 0 4px}.mce-grid-border a{border-color:#e8e8e8;width:13px;height:13px}.mce-grid-border a:hover,.mce-grid-border a.mce-active{border-color:#c4daff;background:#deeafa}.mce-text-center{text-align:center}div.mce-tinymce-inline{width:100%;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-container,.mce-container-body{display:block}.mce-autoscroll{overflow:hidden}.mce-scrollbar{position:absolute;width:7px;height:100%;top:2px;right:2px;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-scrollbar-h{top:auto;right:auto;left:2px;bottom:2px;width:100%;height:7px}.mce-scrollbar-thumb{position:absolute;background-color:#000;border:1px solid #888;border-color:rgba(85,85,85,0.6);width:5px;height:100%;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px}.mce-scrollbar-h .mce-scrollbar-thumb{width:100%;height:5px}.mce-scrollbar:hover,.mce-scrollbar.mce-active{background-color:#AAA;opacity:.6;filter:alpha(opacity=60);zoom:1;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px}.mce-scroll{position:relative}.mce-panel{border:0 solid #9e9e9e;background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fdfdfd,#ddd);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fdfdfd),to(#ddd));background-image:-webkit-linear-gradient(top,#fdfdfd,#ddd);background-image:-o-linear-gradient(top,#fdfdfd,#ddd);background-image:linear-gradient(to bottom,#fdfdfd,#ddd);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffdfdfd',endColorstr='#ffdddddd',GradientType=0);zoom:1}.mce-floatpanel{position:absolute;-webkit-box-shadow:#ccc 5px 5px 5px;-moz-box-shadow:#ccc 5px 5px 5px;box-shadow:#ccc 5px 5px 5px}.mce-floatpanel.mce-fixed{position:fixed}.mce-floatpanel .mce-arrow,.mce-floatpanel .mce-arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.mce-floatpanel .mce-arrow{border-width:11px}.mce-floatpanel .mce-arrow:after{border-width:10px;content:""}.mce-floatpanel.mce-popover{top:0;left:0;background:#fff;-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2)}.mce-floatpanel.mce-popover.mce-bottom{margin-top:10px}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);top:-11px}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow:after{top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.mce-floatpanel.mce-popover.mce-bottom.mce-start{margin-left:-22px}.mce-floatpanel.mce-popover.mce-bottom.mce-start>.mce-arrow{left:20px}.mce-floatpanel.mce-popover.mce-bottom.mce-end{margin-left:22px}.mce-floatpanel.mce-popover.mce-bottom.mce-end>.mce-arrow{right:10px;left:auto}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;background:#FFF;height:100%}div.mce-fullscreen{position:fixed;top:0;left:0}#mce-modal-block{opacity:0;filter:alpha(opacity=0);zoom:1;position:fixed;left:0;top:0;width:100%;height:100%;background:#000}#mce-modal-block.mce-in{opacity:.3;filter:alpha(opacity=30);zoom:1}.mce-window-move{cursor:move}.mce-window{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;background:#FFF;position:fixed;top:0;left:0;opacity:0;-webkit-transition:opacity 150ms ease-in;transition:opacity 150ms ease-in}.mce-window.mce-in{opacity:1}.mce-window-head{padding:9px 15px;border-bottom:1px solid #EEE;position:relative}.mce-window-head .mce-close{position:absolute;right:15px;top:9px;font-size:20px;font-weight:bold;line-height:20px;color:#CCC;text-shadow:0 1px 0 white;cursor:pointer;height:20px;overflow:hidden}.mce-close:hover{color:#AAA}.mce-window-head .mce-title{display:inline-block;*display:inline;*zoom:1;line-height:20px;font-size:20px;font-weight:bold;text-rendering:optimizelegibility;padding-right:10px}.mce-window .mce-container-body{display:block}.mce-foot{display:block;background-color:whiteSmoke;border-top:1px solid #DDD;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.mce-window-head .mce-dragh{position:absolute;top:0;left:0;cursor:move;width:90%;height:100%}.mce-window iframe{width:100%;height:100%}.mce-window.mce-fullscreen,.mce-window.mce-fullscreen .mce-foot{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.mce-abs-layout{position:relative}body .mce-abs-layout-item,.mce-abs-end{position:absolute}.mce-abs-end{width:1px;height:1px}.mce-container-body.mce-abs-layout{overflow:hidden}.mce-tooltip{position:absolute;padding:5px;opacity:.8;filter:alpha(opacity=80);zoom:1}.mce-tooltip-inner{font-size:11px;background-color:#000;color:#fff;max-width:200px;padding:5px 8px 4px 8px;text-align:center;white-space:normal}.mce-tooltip-inner{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-tooltip-inner{-webkit-box-shadow:0 0 5px #000;-moz-box-shadow:0 0 5px #000;box-shadow:0 0 5px #000}.mce-tooltip-arrow{position:absolute;width:0;height:0;line-height:0;border:5px dashed #000}.mce-tooltip-arrow-n{border-bottom-color:#000}.mce-tooltip-arrow-s{border-top-color:#000}.mce-tooltip-arrow-e{border-left-color:#000}.mce-tooltip-arrow-w{border-right-color:#000}.mce-tooltip-nw,.mce-tooltip-sw{margin-left:-14px}.mce-tooltip-n .mce-tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-style:solid;border-top:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-nw .mce-tooltip-arrow{top:0;left:10px;border-bottom-style:solid;border-top:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-ne .mce-tooltip-arrow{top:0;right:10px;border-bottom-style:solid;border-top:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-s .mce-tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-style:solid;border-bottom:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-sw .mce-tooltip-arrow{bottom:0;left:10px;border-top-style:solid;border-bottom:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-se .mce-tooltip-arrow{bottom:0;right:10px;border-top-style:solid;border-bottom:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-e .mce-tooltip-arrow{right:0;top:50%;margin-top:-5px;border-left-style:solid;border-right:0;border-top-color:transparent;border-bottom-color:transparent}.mce-tooltip-w .mce-tooltip-arrow{left:0;top:50%;margin-top:-5px;border-right-style:solid;border-left:none;border-top-color:transparent;border-bottom-color:transparent}.mce-btn{border:1px solid #c5c5c5;position:relative;color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fff,#d9d9d9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#d9d9d9));background-image:-webkit-linear-gradient(top,#fff,#d9d9d9);background-image:-o-linear-gradient(top,#fff,#d9d9d9);background-image:linear-gradient(to bottom,#fff,#d9d9d9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffd9d9d9',GradientType=0);zoom:1;border-color:#d9d9d9 #d9d9d9 #b3b3b3;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);display:inline-block;*display:inline;*zoom:1;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.mce-btn:hover,.mce-btn:focus{text-decoration:none;color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#e3e3e3;background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#ccc));background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(to bottom,#f2f2f2,#ccc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffcccccc',GradientType=0);zoom:1;border-color:#ccc #ccc #a6a6a6;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-btn.mce-disabled,.mce-btn.mce-disabled:hover{cursor:default;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.65;filter:alpha(opacity=65);zoom:1}.mce-btn.mce-active,.mce-btn.mce-active:hover{color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#d6d6d6;background-image:-moz-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:-webkit-gradient(linear,0 0,0 100%,from(#e6e6e6),to(#bfbfbf));background-image:-webkit-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:-o-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:linear-gradient(to bottom,#e6e6e6,#bfbfbf);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe6e6e6',endColorstr='#ffbfbfbf',GradientType=0);zoom:1;border-color:#bfbfbf #bfbfbf #999;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.mce-btn button{padding:4px 10px;font-size:14px;line-height:20px;*line-height:16px;cursor:pointer;color:#333;text-align:center;overflow:visible;-webkit-appearance:none}.mce-btn button::-moz-focus-inner{border:0;padding:0}.mce-btn i{text-shadow:1px 1px #fff}.mce-primary{min-width:50px;color:#fff;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#006dcc;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);zoom:1;border-color:#04c #04c #002b80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-primary:hover,.mce-primary:focus{color:#fff;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#005fb3;background-image:-moz-linear-gradient(top,#0077b3,#003cb3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#0077b3),to(#003cb3));background-image:-webkit-linear-gradient(top,#0077b3,#003cb3);background-image:-o-linear-gradient(top,#0077b3,#003cb3);background-image:linear-gradient(to bottom,#0077b3,#003cb3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0077b3',endColorstr='#ff003cb3',GradientType=0);zoom:1;border-color:#003cb3 #003cb3 #026;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-primary button{color:#fff}.mce-btn-large button{padding:9px 14px;font-size:16px;line-height:normal;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.mce-btn-large i{margin-top:2px}.mce-btn-small button{padding:3px 5px;font-size:12px;line-height:15px}.mce-btn-small i{margin-top:0}.mce-btn .mce-caret{margin-top:8px;*margin-top:6px;margin-left:0}.mce-btn-small .mce-caret{margin-top:6px;*margin-top:4px;margin-left:0}.mce-caret{display:inline-block;*display:inline;*zoom:1;width:0;height:0;vertical-align:top;border-top:4px solid #444;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.mce-disabled .mce-caret{border-top-color:#999}.mce-caret.mce-up{border-bottom:4px solid #444;border-top:0}.mce-btn-group .mce-btn{border-width:1px 0 1px 0;margin:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.mce-btn-group .mce-btn:hover,.mce-btn-group .mce-btn:focus{color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#e3e3e3;background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#ccc));background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(to bottom,#f2f2f2,#ccc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffcccccc',GradientType=0);zoom:1;border-color:#ccc #ccc #a6a6a6;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-btn-group .mce-btn.mce-disabled,.mce-btn-group .mce-btn.mce-disabled:hover{-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fff,#d9d9d9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#d9d9d9));background-image:-webkit-linear-gradient(top,#fff,#d9d9d9);background-image:-o-linear-gradient(top,#fff,#d9d9d9);background-image:linear-gradient(to bottom,#fff,#d9d9d9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffd9d9d9',GradientType=0);zoom:1;border-color:#d9d9d9 #d9d9d9 #b3b3b3;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-btn-group .mce-btn.mce-active,.mce-btn-group .mce-btn.mce-active:hover,.mce-btn-group .mce-btn:active{color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#d6d6d6;background-image:-moz-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:-webkit-gradient(linear,0 0,0 100%,from(#e6e6e6),to(#bfbfbf));background-image:-webkit-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:-o-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:linear-gradient(to bottom,#e6e6e6,#bfbfbf);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe6e6e6',endColorstr='#ffbfbfbf',GradientType=0);zoom:1;border-color:#bfbfbf #bfbfbf #999;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.mce-btn-group .mce-btn.mce-disabled button{opacity:.65;filter:alpha(opacity=65);zoom:1}.mce-btn-group .mce-first{border-left:1px solid #c5c5c5;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.mce-btn-group .mce-last{border-right:1px solid #c5c5c5;-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.mce-btn-group .mce-first.mce-last{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-btn-group .mce-btn.mce-flow-layout-item{margin:0}.mce-checkbox{cursor:pointer}i.mce-i-checkbox{margin:0 3px 0 0;border:1px solid #c5c5c5;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fdfdfd,#ddd);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fdfdfd),to(#ddd));background-image:-webkit-linear-gradient(top,#fdfdfd,#ddd);background-image:-o-linear-gradient(top,#fdfdfd,#ddd);background-image:linear-gradient(to bottom,#fdfdfd,#ddd);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffdfdfd',endColorstr='#ffdddddd',GradientType=0);zoom:1;text-indent:-10em;*font-size:0;*line-height:0;*text-indent:0}.mce-checked i.mce-i-checkbox{color:#000;font-size:16px;line-height:16px;text-indent:0}.mce-checkbox:focus i.mce-i-checkbox{border:1px solid #59a5e1;border:1px solid rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}.mce-colorbutton .mce-ico{position:relative}.mce-colorpicker{background:#FFF}.mce-colorbutton-grid{margin:4px}.mce-colorbutton button{padding-right:4px}.mce-colorbutton .mce-preview{padding-right:3px;display:block;position:absolute;left:50%;top:50%;margin-left:-14px;margin-top:7px;background:gray;width:13px;height:2px;overflow:hidden}.mce-colorbutton.mce-btn-small .mce-preview{margin-left:-17px;padding-right:0;width:16px}.mce-colorbutton .mce-open{padding-left:4px;border-left:1px solid transparent;border-right:1px solid transparent}.mce-colorbutton:hover .mce-open{border-left-color:#c5c5c5;border-right-color:#c5c5c5}.mce-combobox{display:inline-block;*display:inline;*zoom:1;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;width:100px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.mce-combobox input{border:1px solid #c5c5c5;border-right-color:rgba(0,0,0,0.15);height:28px}.mce-combobox.mce-has-open input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.mce-combobox .mce-btn{border-left:0;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.mce-combobox button{padding-right:8px;padding-left:8px}.mce-combobox *:focus{border-color:#59a5e1;border-color:rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}.mce-path{display:inline-block;*display:inline;*zoom:1;padding:8px;white-space:normal}.mce-path .mce-txt{display:inline-block;padding-right:3px}.mce-path .mce-path-body{display:inline-block}.mce-path-item{display:inline-block;*display:inline;*zoom:1;cursor:pointer;color:#000}.mce-path-item:hover{text-decoration:underline}.mce-path-item:focus{background:gray;color:white}.mce-path .mce-divider{display:inline}.mce-fieldset{border:0 solid #9e9e9e;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-fieldset>.mce-container-body{margin-top:-15px}.mce-fieldset-title{margin-left:5px;padding:0 5px 0 5px}.mce-fit-layout{display:inline-block;*display:inline;*zoom:1}.mce-fit-layout-item{position:absolute}.mce-flow-layout-item{display:inline-block;*display:inline;*zoom:1}.mce-flow-layout-item{margin:2px 0 2px 2px}.mce-flow-layout-item.mce-last{margin-right:2px}.mce-flow-layout{white-space:normal}.mce-tinymce-inline .mce-flow-layout{white-space:nowrap}.mce-iframe{border:0 solid #c5c5c5;width:100%;height:100%}.mce-label{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 1px rgba(255,255,255,0.75);border:0 solid #c5c5c5;overflow:hidden}.mce-label.mce-autoscroll{overflow:auto}.mce-label-disabled .mce-text{color:#999}.mce-label.mce-multiline{white-space:pre-wrap}.mce-menubar .mce-menubtn{border-color:transparent;background:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;filter:none}.mce-menubar{border:1px solid #ddd}.mce-menubar .mce-menubtn button{color:#000}.mce-menubar .mce-menubtn:hover,.mce-menubar .mce-menubtn.mce-active,.mce-menubar .mce-menubtn:focus{border-color:transparent;background:#ddd;filter:none}.mce-menubtn.mce-disabled span{color:#999}.mce-menubtn span{margin-right:2px;line-height:20px;*line-height:16px}.mce-menubtn.mce-btn-small span{font-size:12px;line-height:15px;*line-height:16px}.mce-menubtn.mce-fixed-width span{display:inline-block;overflow-x:hidden;text-overflow:ellipsis;width:90px}.mce-menubtn.mce-fixed-width.mce-btn-small span{width:70px}.mce-listbox button{text-align:left;padding-right:20px;position:relative}.mce-listbox .mce-caret{position:absolute;margin-top:-2px;right:8px;top:50%}.mce-menu-item{display:block;padding:6px 15px 6px 12px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap;cursor:pointer;line-height:normal;border-left:4px solid transparent;margin-bottom:1px}.mce-menu-item.mce-disabled .mce-text{color:#999}.mce-menu-item:hover,.mce-menu-item.mce-selected,.mce-menu-item:focus{text-decoration:none;color:#fff;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0);zoom:1}.mce-menu-item:hover .mce-text,.mce-menu-item.mce-selected .mce-text{color:#fff}.mce-menu-item:hover .mce-ico,.mce-menu-item.mce-selected .mce-ico,.mce-menu-item:focus .mce-ico{color:white}.mce-menu-item.mce-disabled:hover{background:#CCC}.mce-menu-shortcut{display:inline-block;color:#999}.mce-menu-shortcut{display:inline-block;*display:inline;*zoom:1;padding:0 15px 0 20px}.mce-menu-item .mce-caret{margin-top:4px;*margin-top:3px;margin-right:6px;border-top:4px solid transparent;border-bottom:4px solid transparent;border-left:4px solid #666}.mce-menu-item.mce-selected .mce-caret,.mce-menu-item:focus .mce-caret{border-left-color:#FFF}.mce-menu-align .mce-menu-shortcut{*margin-top:-2px}.mce-menu-align .mce-menu-shortcut,.mce-menu-align .mce-caret{position:absolute;right:0}.mce-menu-item-sep,.mce-menu-item-sep:hover{padding:0;height:1px;margin:9px 1px;overflow:hidden;background:#e5e5e5;border-bottom:1px solid white;cursor:default;filter:none}.mce-menu-item.mce-active i{visibility:visible}.mce-menu-item.mce-active{background-color:#c8def4;outline:1px solid #c5c5c5}.mce-menu-item-preview.mce-active{border-left:5px solid #aaa;background-color:transparent;outline:0}.mce-menu-item-checkbox.mce-active{background-color:#FFF;outline:0}.mce-menu{filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;z-index:1000;padding:5px 0 5px 0;margin:2px 0 0;min-width:160px;background:#FFF;border:1px solid #CCC;border:1px solid rgba(0,0,0,0.2);z-index:1002;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);max-height:400px;overflow:auto;overflow-x:hidden}.mce-menu i{display:none}.mce-menu-has-icons i{display:inline-block;*display:inline;*zoom:1}.mce-menu-sub-tr-tl{margin:-6px 0 0 -1px}.mce-menu-sub-br-bl{margin:6px 0 0 -1px}.mce-menu-sub-tl-tr{margin:-6px 0 0 1px}.mce-menu-sub-bl-br{margin:6px 0 0 1px}i.mce-radio{padding:1px;margin:0 3px 0 0;background-color:#fafafa;border:1px solid #cacece;-webkit-border-radius:8px;-moz-border-radius:8px;border-radius:8px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fdfdfd,#ddd);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fdfdfd),to(#ddd));background-image:-webkit-linear-gradient(top,#fdfdfd,#ddd);background-image:-o-linear-gradient(top,#fdfdfd,#ddd);background-image:linear-gradient(to bottom,#fdfdfd,#ddd);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffdfdfd',endColorstr='#ffdddddd',GradientType=0);zoom:1}i.mce-radio:after{font-family:Arial;font-size:12px;color:#000;content:'\25cf'}.mce-container-body .mce-resizehandle{position:absolute;right:0;bottom:0;width:16px;height:16px;visibility:visible;cursor:s-resize;margin:0}.mce-container-body .mce-resizehandle-both{cursor:se-resize}i.mce-i-resize{color:#000}.mce-spacer{visibility:hidden}.mce-splitbtn .mce-open{border-left:1px solid transparent;border-right:1px solid transparent}.mce-splitbtn:hover .mce-open{border-left-color:#c5c5c5;border-right-color:#c5c5c5}.mce-splitbtn button{padding-right:4px}.mce-splitbtn .mce-open{padding-left:4px}.mce-splitbtn .mce-open.mce-active{-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.mce-stack-layout-item{display:block}.mce-tabs{display:block;border-bottom:1px solid #ccc}.mce-tab{display:inline-block;*display:inline;*zoom:1;border:1px solid #ccc;border-width:1px 1px 0 0;background:#e3e3e3;padding:8px;text-shadow:0 1px 1px rgba(255,255,255,0.75);height:13px;cursor:pointer}.mce-tab:hover{background:#fdfdfd}.mce-tab.mce-active{background:#fdfdfd;border-bottom-color:transparent;margin-bottom:-1px;height:14px}.mce-textbox{background:#FFF;border:1px solid #c5c5c5;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);display:inline-block;-webkit-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s;height:28px;resize:none;padding:0 4px 0 4px;white-space:pre-wrap;*white-space:pre;color:#000}.mce-textbox:focus{border-color:rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}.mce-placeholder .mce-textbox{color:#aaa}.mce-textbox.mce-multiline{padding:4px}.mce-throbber{position:absolute;top:0;left:0;width:100%;height:100%;opacity:.6;filter:alpha(opacity=60);zoom:1;background:#fff url('img/loader.gif') no-repeat center center}@font-face{font-family:'tinymce';src:url('fonts/icomoon.eot');src:url('fonts/icomoon.eot?#iefix') format('embedded-opentype'),url('fonts/icomoon.svg#icomoon') format('svg'),url('fonts/icomoon.woff') format('woff'),url('fonts/icomoon.ttf') format('truetype');font-weight:normal;font-style:normal}@font-face{font-family:'tinymce-small';src:url('fonts/icomoon-small.eot');src:url('fonts/icomoon-small.eot?#iefix') format('embedded-opentype'),url('fonts/icomoon-small.svg#icomoon') format('svg'),url('fonts/icomoon-small.woff') format('woff'),url('fonts/icomoon-small.ttf') format('truetype');font-weight:normal;font-style:normal}.mce-ico{font-family:'tinymce',Arial;font-style:normal;font-weight:normal;font-size:16px;line-height:16px;vertical-align:text-top;-webkit-font-smoothing:antialiased;display:inline-block;background:transparent center center;width:16px;height:16px;color:#333}.mce-btn-small .mce-ico{font-family:'tinymce-small',Arial}.mce-i-save:before{content:"\e000"}.mce-i-newdocument:before{content:"\e001"}.mce-i-fullpage:before{content:"\e002"}.mce-i-alignleft:before{content:"\e003"}.mce-i-aligncenter:before{content:"\e004"}.mce-i-alignright:before{content:"\e005"}.mce-i-alignjustify:before{content:"\e006"}.mce-i-cut:before{content:"\e007"}.mce-i-paste:before{content:"\e008"}.mce-i-searchreplace:before{content:"\e009"}.mce-i-bullist:before{content:"\e00a"}.mce-i-numlist:before{content:"\e00b"}.mce-i-indent:before{content:"\e00c"}.mce-i-outdent:before{content:"\e00d"}.mce-i-blockquote:before{content:"\e00e"}.mce-i-undo:before{content:"\e00f"}.mce-i-redo:before{content:"\e010"}.mce-i-link:before{content:"\e011"}.mce-i-unlink:before{content:"\e012"}.mce-i-anchor:before{content:"\e013"}.mce-i-image:before{content:"\e014"}.mce-i-media:before{content:"\e015"}.mce-i-help:before{content:"\e016"}.mce-i-code:before{content:"\e017"}.mce-i-inserttime:before{content:"\e018"}.mce-i-preview:before{content:"\e019"}.mce-i-forecolor:before{content:"\e01a"}.mce-i-backcolor:before{content:"\e01a"}.mce-i-table:before{content:"\e01b"}.mce-i-hr:before{content:"\e01c"}.mce-i-removeformat:before{content:"\e01d"}.mce-i-subscript:before{content:"\e01e"}.mce-i-superscript:before{content:"\e01f"}.mce-i-charmap:before{content:"\e020"}.mce-i-emoticons:before{content:"\e021"}.mce-i-print:before{content:"\e022"}.mce-i-fullscreen:before{content:"\e023"}.mce-i-spellchecker:before{content:"\e024"}.mce-i-nonbreaking:before{content:"\e025"}.mce-i-template:before{content:"\e026"}.mce-i-pagebreak:before{content:"\e027"}.mce-i-restoredraft:before{content:"\e028"}.mce-i-untitled:before{content:"\e029"}.mce-i-bold:before{content:"\e02a"}.mce-i-italic:before{content:"\e02b"}.mce-i-underline:before{content:"\e02c"}.mce-i-strikethrough:before{content:"\e02d"}.mce-i-visualchars:before{content:"\e02e"}.mce-i-visualblocks:before{content:"\e02e"}.mce-i-ltr:before{content:"\e02f"}.mce-i-rtl:before{content:"\e030"}.mce-i-copy:before{content:"\e031"}.mce-i-resize:before{content:"\e032"}.mce-i-browse:before{content:"\e034"}.mce-i-pastetext:before{content:"\e035"}.mce-i-checkbox:before,.mce-i-selected:before{content:"\e033"}.mce-i-selected{visibility:hidden}i.mce-i-backcolor{text-shadow:none;background:#BBB} \ No newline at end of file diff --git a/web/tinymce/themes/modern/theme.min.js b/web/tinymce/themes/modern/theme.min.js new file mode 100755 index 000000000..da7ab2587 --- /dev/null +++ b/web/tinymce/themes/modern/theme.min.js @@ -0,0 +1 @@ +tinymce.ThemeManager.add("modern",function(e){function t(){function t(t){var i,o=[];if(t)return d(t.split(/[ ,]/),function(t){function n(){var n=e.selection;"bullist"==r&&n.selectorChanged("ul > li",function(e,n){for(var i,o=n.parents.length;o--&&(i=n.parents[o].nodeName,"OL"!=i&&"UL"!=i););t.active(e&&"UL"==i)}),"numlist"==r&&n.selectorChanged("ol > li",function(e,n){for(var i,o=n.parents.length;o--&&(i=n.parents[o].nodeName,"OL"!=i&&"UL"!=i););t.active(e&&"OL"==i)}),t.settings.stateSelector&&n.selectorChanged(t.settings.stateSelector,function(e){t.active(e)},!0),t.settings.disabledStateSelector&&n.selectorChanged(t.settings.disabledStateSelector,function(e){t.disabled(e)})}var r;"|"==t?i=null:c.has(t)?(t={type:t},u.toolbar_items_size&&(t.size=u.toolbar_items_size),o.push(t),i=null):(i||(i={type:"buttongroup",items:[]},o.push(i)),e.buttons[t]&&(r=t,t=e.buttons[r],"function"==typeof t&&(t=t()),t.type=t.type||"button",u.toolbar_items_size&&(t.size=u.toolbar_items_size),t=c.create(t),i.items.push(t),e.initialized?n():e.on("init",n)))}),n.push({type:"toolbar",layout:"flow",items:o}),!0}for(var n=[],i=1;10>i&&t(u["toolbar"+i]);i++);return n.length||t(u.toolbar||f),n}function n(){function t(t){var n;return"|"==t?{text:"|"}:n=e.menuItems[t]}function n(n){var i,o,r,a,s;if(s=tinymce.makeMap((u.removed_menuitems||"").split(/[ ,]/)),u.menu?(o=u.menu[n],a=!0):o=h[n],o){i={text:o.title},r=[],d((o.items||"").split(/[ ,]/),function(e){var n=t(e);n&&!s[e]&&r.push(t(e))}),a||d(e.menuItems,function(e){e.context==n&&("before"==e.separator&&r.push({text:"|"}),e.prependToContext?r.unshift(e):r.push(e),"after"==e.separator&&r.push({text:"|"}))});for(var l=0;lr;r++)if(o=n[r],o&&o.func.call(o.scope,e)===!1&&e.preventDefault(),e.isImmediatePropagationStopped())return}var a=this,s={},l,c,u,d,f;c=o+(+new Date).toString(32),d="onmouseenter"in document.documentElement,u="onfocusin"in document.documentElement,f={mouseenter:"mouseover",mouseleave:"mouseout"},l=1,a.domLoaded=!1,a.events=s,a.bind=function(t,o,p,h){function m(e){i(n(e||_.event),g)}var g,v,y,b,C,x,w,_=window;if(t&&3!==t.nodeType&&8!==t.nodeType){for(t[c]?g=t[c]:(g=l++,t[c]=g,s[g]={}),h=h||t,o=o.split(" "),y=o.length;y--;)b=o[y],x=m,C=w=!1,"DOMContentLoaded"===b&&(b="ready"),a.domLoaded&&"ready"===b&&"complete"==t.readyState?p.call(h,n({type:b})):(d||(C=f[b],C&&(x=function(e){var t,r;if(t=e.currentTarget,r=e.relatedTarget,r&&t.contains)r=t.contains(r);else for(;r&&r!==t;)r=r.parentNode;r||(e=n(e||_.event),e.type="mouseout"===e.type?"mouseleave":"mouseenter",e.target=t,i(e,g))})),u||"focusin"!==b&&"focusout"!==b||(w=!0,C="focusin"===b?"focus":"blur",x=function(e){e=n(e||_.event),e.type="focus"===e.type?"focusin":"focusout",i(e,g)}),v=s[g][b],v?"ready"===b&&a.domLoaded?p({type:b}):v.push({func:p,scope:h}):(s[g][b]=v=[{func:p,scope:h}],v.fakeName=C,v.capture=w,v.nativeHandler=x,"ready"===b?r(t,x,a):e(t,C||b,x,w)));return t=v=0,p}},a.unbind=function(e,n,r){var i,o,l,u,d,f;if(!e||3===e.nodeType||8===e.nodeType)return a;if(i=e[c]){if(f=s[i],n){for(n=n.split(" "),l=n.length;l--;)if(d=n[l],o=f[d]){if(r)for(u=o.length;u--;)if(o[u].func===r){var p=o.nativeHandler;o=o.slice(0,u).concat(o.slice(u+1)),o.nativeHandler=p,f[d]=o,o.splice(u,1)}r&&0!==o.length||(delete f[d],t(e,o.fakeName||d,o.nativeHandler,o.capture))}}else{for(d in f)o=f[d],t(e,o.fakeName||d,o.nativeHandler,o.capture);f={}}for(d in f)return a;delete s[i];try{delete e[c]}catch(h){e[c]=null}}return a},a.fire=function(e,t,r){var o;if(!e||3===e.nodeType||8===e.nodeType)return a;r=n(null,r),r.type=t,r.target=e;do o=e[c],o&&i(r,o),e=e.parentNode||e.ownerDocument||e.defaultView||e.parentWindow;while(e&&!r.isPropagationStopped());return a},a.clean=function(e){var t,n,r=a.unbind;if(!e||3===e.nodeType||8===e.nodeType)return a;if(e[c]&&r(e),e.getElementsByTagName||(e=e.document),e&&e.getElementsByTagName)for(r(e),n=e.getElementsByTagName("*"),t=n.length;t--;)e=n[t],e[c]&&r(e);return a},a.destroy=function(){s={}},a.cancel=function(e){return e&&(e.preventDefault(),e.stopImmediatePropagation()),!1}}var o="mce-data-",a=/^(?:mouse|contextmenu)|click/,s={keyLocation:1,layerX:1,layerY:1,returnValue:1};return i.Event=new i,i.Event.bind(window,"ready",function(){}),i}),r(c,[],function(){function e(e){return gt.test(e+"")}function n(){var e,t=[];return e=function(n,r){return t.push(n+=" ")>N.cacheLength&&delete e[t.shift()],e[n]=r,r}}function i(e){return e[F]=!0,e}function o(e){var t=D.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t=null}}function a(e,t,n,r){var i,o,a,s,l,c,u,p,h,m;if((t?t.ownerDocument||t:W)!==D&&B(t),t=t||D,n=n||[],!e||"string"!=typeof e)return n;if(1!==(s=t.nodeType)&&9!==s)return[];if(L&&!r){if(i=vt.exec(e))if(a=i[1]){if(9===s){if(o=t.getElementById(a),!o||!o.parentNode)return n;if(o.id===a)return n.push(o),n}else if(t.ownerDocument&&(o=t.ownerDocument.getElementById(a))&&I(t,o)&&o.id===a)return n.push(o),n}else{if(i[2])return et.apply(n,t.getElementsByTagName(e)),n;if((a=i[3])&&z.getElementsByClassName&&t.getElementsByClassName)return et.apply(n,t.getElementsByClassName(a)),n}if(z.qsa&&!M.test(e)){if(u=!0,p=F,h=t,m=9===s&&e,1===s&&"object"!==t.nodeName.toLowerCase()){for(c=d(e),(u=t.getAttribute("id"))?p=u.replace(Ct,"\\$&"):t.setAttribute("id",p),p="[id='"+p+"'] ",l=c.length;l--;)c[l]=p+f(c[l]);h=mt.test(e)&&t.parentNode||t,m=c.join(",")}if(m)try{return et.apply(n,h.querySelectorAll(m)),n}catch(g){}finally{u||t.removeAttribute("id")}}}return C(e.replace(ct,"$1"),t,n,r)}function s(e,t){var n=t&&e,r=n&&(~t.sourceIndex||X)-(~e.sourceIndex||X);if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function l(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function c(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function u(e){return i(function(t){return t=+t,i(function(n,r){for(var i,o=e([],n.length,t),a=o.length;a--;)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function d(e,t){var n,r,i,o,s,l,c,u=j[e+" "];if(u)return t?0:u.slice(0);for(s=e,l=[],c=N.preFilter;s;){(!n||(r=ut.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),l.push(i=[])),n=!1,(r=dt.exec(s))&&(n=r.shift(),i.push({value:n,type:r[0].replace(ct," ")}),s=s.slice(n.length));for(o in N.filter)!(r=ht[o].exec(s))||c[o]&&!(r=c[o](r))||(n=r.shift(),i.push({value:n,type:o,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?a.error(e):j(e,l).slice(0)}function f(e){for(var t=0,n=e.length,r="";n>t;t++)r+=e[t].value;return r}function p(e,t,n){var r=t.dir,i=n&&"parentNode"===r,o=U++;return t.first?function(t,n,o){for(;t=t[r];)if(1===t.nodeType||i)return e(t,n,o)}:function(t,n,a){var s,l,c,u=V+" "+o;if(a){for(;t=t[r];)if((1===t.nodeType||i)&&e(t,n,a))return!0}else for(;t=t[r];)if(1===t.nodeType||i)if(c=t[F]||(t[F]={}),(l=c[r])&&l[0]===u){if((s=l[1])===!0||s===_)return s===!0}else if(l=c[r]=[u],l[1]=e(t,n,a)||_,l[1]===!0)return!0}}function h(e){return e.length>1?function(t,n,r){for(var i=e.length;i--;)if(!e[i](t,n,r))return!1;return!0}:e[0]}function m(e,t,n,r,i){for(var o,a=[],s=0,l=e.length,c=null!=t;l>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),c&&t.push(s));return a}function g(e,t,n,r,o,a){return r&&!r[F]&&(r=g(r)),o&&!o[F]&&(o=g(o,a)),i(function(i,a,s,l){var c,u,d,f=[],p=[],h=a.length,g=i||b(t||"*",s.nodeType?[s]:s,[]),v=!e||!i&&t?g:m(g,f,e,s,l),y=n?o||(i?e:h||r)?[]:a:v;if(n&&n(v,y,s,l),r)for(c=m(y,p),r(c,[],s,l),u=c.length;u--;)(d=c[u])&&(y[p[u]]=!(v[p[u]]=d));if(i){if(o||e){if(o){for(c=[],u=y.length;u--;)(d=y[u])&&c.push(v[u]=d);o(null,y=[],c,l)}for(u=y.length;u--;)(d=y[u])&&(c=o?nt.call(i,d):f[u])>-1&&(i[c]=!(a[c]=d))}}else y=m(y===a?y.splice(h,y.length):y),o?o(null,a,y,l):et.apply(a,y)})}function v(e){for(var t,n,r,i=e.length,o=N.relative[e[0].type],a=o||N.relative[" "],s=o?1:0,l=p(function(e){return e===t},a,!0),c=p(function(e){return nt.call(t,e)>-1},a,!0),u=[function(e,n,r){return!o&&(r||n!==T)||((t=n).nodeType?l(e,n,r):c(e,n,r))}];i>s;s++)if(n=N.relative[e[s].type])u=[p(h(u),n)];else{if(n=N.filter[e[s].type].apply(null,e[s].matches),n[F]){for(r=++s;i>r&&!N.relative[e[r].type];r++);return g(s>1&&h(u),s>1&&f(e.slice(0,s-1)).replace(ct,"$1"),n,r>s&&v(e.slice(s,r)),i>r&&v(e=e.slice(r)),i>r&&f(e))}u.push(n)}return h(u)}function y(e,t){var n=0,r=t.length>0,o=e.length>0,s=function(i,s,l,c,u){var d,f,p,h=[],g=0,v="0",y=i&&[],b=null!=u,C=T,x=i||o&&N.find.TAG("*",u&&s.parentNode||s),w=V+=null==C?1:Math.random()||.1;for(b&&(T=s!==D&&s,_=n);null!=(d=x[v]);v++){if(o&&d){for(f=0;p=e[f++];)if(p(d,s,l)){c.push(d);break}b&&(V=w,_=++n)}r&&((d=!p&&d)&&g--,i&&y.push(d))}if(g+=v,r&&v!==g){for(f=0;p=t[f++];)p(y,h,s,l);if(i){if(g>0)for(;v--;)y[v]||h[v]||(h[v]=Q.call(c));h=m(h)}et.apply(c,h),b&&!i&&h.length>0&&g+t.length>1&&a.uniqueSort(c)}return b&&(V=w,T=C),y};return r?i(s):s}function b(e,t,n){for(var r=0,i=t.length;i>r;r++)a(e,t[r],n);return n}function C(e,t,n,r){var i,o,a,s,l,c=d(e);if(!r&&1===c.length){if(o=c[0]=c[0].slice(0),o.length>2&&"ID"===(a=o[0]).type&&9===t.nodeType&&L&&N.relative[o[1].type]){if(t=(N.find.ID(a.matches[0].replace(wt,_t),t)||[])[0],!t)return n;e=e.slice(o.shift().value.length)}for(i=ht.needsContext.test(e)?0:o.length;i--&&(a=o[i],!N.relative[s=a.type]);)if((l=N.find[s])&&(r=l(a.matches[0].replace(wt,_t),mt.test(o[0].type)&&t.parentNode||t))){if(o.splice(i,1),e=r.length&&f(o),!e)return et.apply(n,r),n;break}}return S(e,c)(r,t,!L,n,mt.test(e)),n}function x(){}var w,_,N,E,k,S,T,R,A,B,D,H,L,M,P,O,I,F="sizzle"+-new Date,W=window.document,z={},V=0,U=0,q=n(),j=n(),$=n(),K=!1,G=function(){return 0},Y=typeof t,X=1<<31,J=[],Q=J.pop,Z=J.push,et=J.push,tt=J.slice,nt=J.indexOf||function(e){for(var t=0,n=this.length;n>t;t++)if(this[t]===e)return t;return-1},rt="[\\x20\\t\\r\\n\\f]",it="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",ot=it.replace("w","w#"),at="([*^$|!~]?=)",st="\\["+rt+"*("+it+")"+rt+"*(?:"+at+rt+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+ot+")|)|)"+rt+"*\\]",lt=":("+it+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+st.replace(3,8)+")*)|.*)\\)|)",ct=new RegExp("^"+rt+"+|((?:^|[^\\\\])(?:\\\\.)*)"+rt+"+$","g"),ut=new RegExp("^"+rt+"*,"+rt+"*"),dt=new RegExp("^"+rt+"*([\\x20\\t\\r\\n\\f>+~])"+rt+"*"),ft=new RegExp(lt),pt=new RegExp("^"+ot+"$"),ht={ID:new RegExp("^#("+it+")"),CLASS:new RegExp("^\\.("+it+")"),NAME:new RegExp("^\\[name=['\"]?("+it+")['\"]?\\]"),TAG:new RegExp("^("+it.replace("w","w*")+")"),ATTR:new RegExp("^"+st),PSEUDO:new RegExp("^"+lt),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+rt+"*(even|odd|(([+-]|)(\\d*)n|)"+rt+"*(?:([+-]|)"+rt+"*(\\d+)|))"+rt+"*\\)|)","i"),needsContext:new RegExp("^"+rt+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+rt+"*((?:-\\d)?\\d*)"+rt+"*\\)|)(?=[^-]|$)","i")},mt=/[\x20\t\r\n\f]*[+~]/,gt=/^[^{]+\{\s*\[native code/,vt=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,yt=/^(?:input|select|textarea|button)$/i,bt=/^h\d$/i,Ct=/'|\\/g,xt=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,wt=/\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g,_t=function(e,t){var n="0x"+t-65536;return n!==n?t:0>n?String.fromCharCode(n+65536):String.fromCharCode(55296|n>>10,56320|1023&n)};try{et.apply(J=tt.call(W.childNodes),W.childNodes),J[W.childNodes.length].nodeType}catch(Nt){et={apply:J.length?function(e,t){Z.apply(e,tt.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}k=a.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},B=a.setDocument=function(n){var r=n?n.ownerDocument||n:W;return r!==D&&9===r.nodeType&&r.documentElement?(D=r,H=r.documentElement,L=!k(r),z.getElementsByTagName=o(function(e){return e.appendChild(r.createComment("")),!e.getElementsByTagName("*").length}),z.attributes=o(function(e){e.innerHTML="";var t=typeof e.lastChild.getAttribute("multiple");return"boolean"!==t&&"string"!==t}),z.getElementsByClassName=o(function(e){return e.innerHTML="",e.getElementsByClassName&&e.getElementsByClassName("e").length?(e.lastChild.className="e",2===e.getElementsByClassName("e").length):!1}),z.getByName=o(function(e){e.id=F+0,e.appendChild(D.createElement("a")).setAttribute("name",F),e.appendChild(D.createElement("i")).setAttribute("name",F),H.appendChild(e);var t=r.getElementsByName&&r.getElementsByName(F).length===2+r.getElementsByName(F+0).length;return H.removeChild(e),t}),z.sortDetached=o(function(e){return e.compareDocumentPosition&&1&e.compareDocumentPosition(D.createElement("div"))}),N.attrHandle=o(function(e){return e.innerHTML="",e.firstChild&&typeof e.firstChild.getAttribute!==Y&&"#"===e.firstChild.getAttribute("href")})?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},z.getByName?(N.find.ID=function(e,t){if(typeof t.getElementById!==Y&&L){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},N.filter.ID=function(e){var t=e.replace(wt,_t);return function(e){return e.getAttribute("id")===t}}):(N.find.ID=function(e,n){if(typeof n.getElementById!==Y&&L){var r=n.getElementById(e);return r?r.id===e||typeof r.getAttributeNode!==Y&&r.getAttributeNode("id").value===e?[r]:t:[]}},N.filter.ID=function(e){var t=e.replace(wt,_t);return function(e){var n=typeof e.getAttributeNode!==Y&&e.getAttributeNode("id");return n&&n.value===t}}),N.find.TAG=z.getElementsByTagName?function(e,t){return typeof t.getElementsByTagName!==Y?t.getElementsByTagName(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){for(;n=o[i++];)1===n.nodeType&&r.push(n);return r}return o},N.find.NAME=z.getByName&&function(e,t){return typeof t.getElementsByName!==Y?t.getElementsByName(name):void 0},N.find.CLASS=z.getElementsByClassName&&function(e,t){return typeof t.getElementsByClassName!==Y&&L?t.getElementsByClassName(e):void 0},P=[],M=[":focus"],(z.qsa=e(r.querySelectorAll))&&(o(function(e){e.innerHTML="",e.querySelectorAll("[selected]").length||M.push("\\["+rt+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||M.push(":checked")}),o(function(e){e.innerHTML="",e.querySelectorAll("[i^='']").length&&M.push("[*^$]="+rt+"*(?:\"\"|'')"),e.querySelectorAll(":enabled").length||M.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),M.push(",.*:")})),(z.matchesSelector=e(O=H.matchesSelector||H.mozMatchesSelector||H.webkitMatchesSelector||H.oMatchesSelector||H.msMatchesSelector))&&o(function(e){z.disconnectedMatch=O.call(e,"div"),O.call(e,"[s!='']:x"),P.push("!=",lt)}),M=new RegExp(M.join("|")),P=P.length&&new RegExp(P.join("|")),I=e(H.contains)||H.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},G=H.compareDocumentPosition?function(e,t){if(e===t)return K=!0,0;var n=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t);return n?1&n||R&&t.compareDocumentPosition(e)===n?e===r||I(W,e)?-1:t===r||I(W,t)?1:A?nt.call(A,e)-nt.call(A,t):0:4&n?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var n,i=0,o=e.parentNode,a=t.parentNode,l=[e],c=[t];if(e===t)return K=!0,0;if(!o||!a)return e===r?-1:t===r?1:o?-1:a?1:0;if(o===a)return s(e,t);for(n=e;n=n.parentNode;)l.unshift(n);for(n=t;n=n.parentNode;)c.unshift(n);for(;l[i]===c[i];)i++;return i?s(l[i],c[i]):l[i]===W?-1:c[i]===W?1:0},D):D},a.matches=function(e,t){return a(e,null,null,t)},a.matchesSelector=function(e,t){if((e.ownerDocument||e)!==D&&B(e),t=t.replace(xt,"='$1']"),z.matchesSelector&&L&&(!P||!P.test(t))&&!M.test(t))try{var n=O.call(e,t);if(n||z.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(r){}return a(t,D,null,[e]).length>0},a.contains=function(e,t){return(e.ownerDocument||e)!==D&&B(e),I(e,t)},a.attr=function(e,t){var n;return(e.ownerDocument||e)!==D&&B(e),L&&(t=t.toLowerCase()),(n=N.attrHandle[t])?n(e):!L||z.attributes?e.getAttribute(t):((n=e.getAttributeNode(t))||e.getAttribute(t))&&e[t]===!0?t:n&&n.specified?n.value:null},a.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},a.uniqueSort=function(e){var t,n=[],r=0,i=0;if(K=!z.detectDuplicates,R=!z.sortDetached,A=!z.sortStable&&e.slice(0),e.sort(G),K){for(;t=e[i++];)t===e[i]&&(r=n.push(i));for(;r--;)e.splice(n[r],1)}return e},E=a.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=E(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=E(t);return n},N=a.selectors={cacheLength:50,createPseudo:i,match:ht,find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(wt,_t),e[3]=(e[4]||e[5]||"").replace(wt,_t),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||a.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&a.error(e[0]),e},PSEUDO:function(e){var t,n=!e[5]&&e[2];return ht.CHILD.test(e[0])?null:(e[4]?e[2]=e[4]:n&&ft.test(n)&&(t=d(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){return"*"===e?function(){return!0}:(e=e.replace(wt,_t).toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=q[e+" "];return t||(t=new RegExp("(^|"+rt+")"+e+"("+rt+"|$)"))&&q(e,function(e){return t.test(e.className||typeof e.getAttribute!==Y&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=a.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,l){var c,u,d,f,p,h,m=o!==a?"nextSibling":"previousSibling",g=t.parentNode,v=s&&t.nodeName.toLowerCase(),y=!l&&!s;if(g){if(o){for(;m;){for(d=t;d=d[m];)if(s?d.nodeName.toLowerCase()===v:1===d.nodeType)return!1;h=m="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?g.firstChild:g.lastChild],a&&y){for(u=g[F]||(g[F]={}),c=u[e]||[],p=c[0]===V&&c[1],f=c[0]===V&&c[2],d=p&&g.childNodes[p];d=++p&&d&&d[m]||(f=p=0)||h.pop();)if(1===d.nodeType&&++f&&d===t){u[e]=[V,p,f];break}}else if(y&&(c=(t[F]||(t[F]={}))[e])&&c[0]===V)f=c[1];else for(;(d=++p&&d&&d[m]||(f=p=0)||h.pop())&&((s?d.nodeName.toLowerCase()!==v:1!==d.nodeType)||!++f||(y&&((d[F]||(d[F]={}))[e]=[V,f]),d!==t)););return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=N.pseudos[e]||N.setFilters[e.toLowerCase()]||a.error("unsupported pseudo: "+e);return r[F]?r(t):r.length>1?(n=[e,e,"",t],N.setFilters.hasOwnProperty(e.toLowerCase())?i(function(e,n){for(var i,o=r(e,t),a=o.length;a--;)i=nt.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:i(function(e){var t=[],n=[],r=S(e.replace(ct,"$1"));return r[F]?i(function(e,t,n,i){for(var o,a=r(e,null,i,[]),s=e.length;s--;)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:i(function(e){return function(t){return a(e,t).length>0}}),contains:i(function(e){return function(t){return(t.textContent||t.innerText||E(t)).indexOf(e)>-1}}),lang:i(function(e){return pt.test(e||"")||a.error("unsupported lang: "+e),e=e.replace(wt,_t).toLowerCase(),function(t){var n;do if(n=L?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(e){var t=window.location&&window.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===H},focus:function(e){return e===D.activeElement&&(!D.hasFocus||D.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!N.pseudos.empty(e)},header:function(e){return bt.test(e.nodeName)},input:function(e){return yt.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:u(function(){return[0]}),last:u(function(e,t){return[t-1]}),eq:u(function(e,t,n){return[0>n?n+t:n]}),even:u(function(e,t){for(var n=0;t>n;n+=2)e.push(n);return e}),odd:u(function(e,t){for(var n=1;t>n;n+=2)e.push(n);return e}),lt:u(function(e,t,n){for(var r=0>n?n+t:n;--r>=0;)e.push(r);return e}),gt:u(function(e,t,n){for(var r=0>n?n+t:n;++rn;n++)t[n]=e[n];return t}function f(e,t){var n;if(t.indexOf)return t.indexOf(e);for(n=t.length;n--;)if(t[n]===e)return n;return-1}function p(e,t){var n,r,i,o,a;if(e)if(n=e.length,n===o){for(r in e)if(e.hasOwnProperty(r)&&(a=e[r],t.call(a,a,r)===!1))break}else for(i=0;n>i&&(a=e[i],t.call(a,a,r)!==!1);i++);return e}function h(e,n,r){for(var i=[],o=e[n];o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!c(o).is(r));)1===o.nodeType&&i.push(o),o=o[n];return i}function m(e,t,n,r){for(var i=[];e;e=e[n])r&&e.nodeType!==r||e===t||i.push(e);return i}var g=document,v=Array.prototype.push,y=Array.prototype.slice,b=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,C=e.Event,x=l("fillOpacity fontWeight lineHeight opacity orphans widows zIndex zoom"),w=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)},_=/^\s*|\s*$/g,N=function(e){return null===e||e===t?"":(""+e).replace(_,"")};return c.fn=c.prototype={constructor:c,selector:"",length:0,init:function(e,t){var n=this,r,a;if(!e)return n;if(e.nodeType)return n.context=n[0]=e,n.length=1,n;if(i(e)){if(r="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:b.exec(e),!r)return c(t||document).find(e);if(r[1])for(a=o(e).firstChild;a;)this.add(a),a=a.nextSibling;else{if(a=g.getElementById(r[2]),a.id!==r[2])return n.find(e);n.length=1,n[0]=a}}else this.add(e);return n},toArray:function(){return d(this)},add:function(e){var t=this;return w(e)?v.apply(t,e):e instanceof c?t.add(e.toArray()):v.call(t,e),t},attr:function(e,n){var i=this;if("object"==typeof e)p(e,function(e,t){i.attr(t,e)});else{if(!r(n))return i[0]&&1===i[0].nodeType?i[0].getAttribute(e):t;this.each(function(){1===this.nodeType&&this.setAttribute(e,n)})}return i},css:function(e,n){var i=this;if("object"==typeof e)p(e,function(e,t){i.css(t,e)});else{if(e=e.replace(/-(\D)/g,function(e,t){return t.toUpperCase()}),!r(n))return i[0]?i[0].style[e]:t;"number"!=typeof n||x[e]||(n+="px"),i.each(function(){var t=this.style;"opacity"===e&&this.runtimeStyle&&"undefined"==typeof this.runtimeStyle.opacity&&(t.filter=""===n?"":"alpha(opacity="+100*n+")");try{t[e]=n}catch(r){}})}return i},remove:function(){for(var e=this,t,n=this.length;n--;)t=e[n],C.clean(t),t.parentNode&&t.parentNode.removeChild(t);return this},empty:function(){for(var e=this,t,n=this.length;n--;)for(t=e[n];t.firstChild;)t.removeChild(t.firstChild);return this},html:function(e){var t=this,n;if(r(e)){for(n=t.length;n--;)t[n].innerHTML=e;return t}return t[0]?t[0].innerHTML:""},text:function(e){var t=this,n;if(r(e)){for(n=t.length;n--;)t[n].innerText=t[0].textContent=e;return t}return t[0]?t[0].innerText||t[0].textContent:""},append:function(){return a(this,arguments,function(e){1===this.nodeType&&this.appendChild(e)})},prepend:function(){return a(this,arguments,function(e){1===this.nodeType&&this.insertBefore(e,this.firstChild)})},before:function(){var e=this;return e[0]&&e[0].parentNode?a(e,arguments,function(e){this.parentNode.insertBefore(e,this.nextSibling)}):e},after:function(){var e=this;return e[0]&&e[0].parentNode?a(e,arguments,function(e){this.parentNode.insertBefore(e,this)}):e},appendTo:function(e){return c(e).append(this),this},addClass:function(e){return this.toggleClass(e,!0)},removeClass:function(e){return this.toggleClass(e,!1)},toggleClass:function(e,t){var n=this;return-1!==e.indexOf(" ")?p(e.split(" "),function(){n.toggleClass(this,t)}):n.each(function(){var n=this,r;s(n,e)!==t&&(r=n.className,t?n.className+=r?" "+e:e:n.className=N((" "+r+" ").replace(" "+e+" "," ")))}),n},hasClass:function(e){return s(this[0],e)},each:function(e){return p(this,e)},on:function(e,t){return this.each(function(){C.bind(this,e,t)})},off:function(e,t){return this.each(function(){C.unbind(this,e,t)})},show:function(){return this.css("display","")},hide:function(){return this.css("display","none")},slice:function(){return new c(y.apply(this,arguments))},eq:function(e){return-1===e?this.slice(e):this.slice(e,+e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},replaceWith:function(e){var t=this;return t[0]&&t[0].parentNode.replaceChild(c(e)[0],t[0]),t},wrap:function(e){return e=c(e)[0],this.each(function(){var t=this,n=e.cloneNode(!1);t.parentNode.insertBefore(n,t),n.appendChild(t)})},unwrap:function(){return this.each(function(){for(var e=this,t=e.firstChild,n;t;)n=t,t=t.nextSibling,e.parentNode.insertBefore(n,e)})},clone:function(){var e=[];return this.each(function(){e.push(this.cloneNode(!0))}),c(e)},find:function(e){var t,n,r=[];for(t=0,n=this.length;n>t;t++)c.find(e,this[t],r);return c(r)},push:v,sort:[].sort,splice:[].splice},u(c,{extend:u,toArray:d,inArray:f,isArray:w,each:p,trim:N,makeMap:l,find:n,expr:n.selectors,unique:n.uniqueSort,text:n.getText,isXMLDoc:n.isXML,contains:n.contains,filter:function(e,t,n){return n&&(e=":not("+e+")"),1===t.length?c.find.matchesSelector(t[0],e)?[t[0]]:[]:c.find.matches(e,t)}}),p({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return h(e,"parentNode")},parentsUntil:function(e,t){return h(e,"parentNode",t)},next:function(e){return m(e,"nextSibling",1)},prev:function(e){return m(e,"previousSibling",1)},nextNodes:function(e){return m(e,"nextSibling")},prevNodes:function(e){return m(e,"previousSibling")},children:function(e){return m(e.firstChild,"nextSibling",1)},contents:function(e){return d(("iframe"===e.nodeName?e.contentDocument||e.contentWindow.document:e).childNodes)}},function(e,t){c.fn[e]=function(n){var r=this,i;if(r.length>1)throw new Error("DomQuery only supports traverse functions on a single node.");return r[0]&&(i=t(r[0],n)),i=c(i),n&&"parentsUntil"!==e?i.filter(n):i}}),c.fn.filter=function(e){return c.filter(e)},c.fn.is=function(e){return!!e&&this.filter(e).length>0},c.fn.init.prototype=c.fn,c}),r(d,[],function(){return function(e,t){function n(e,t,n,r){function i(e){return e=parseInt(e,10).toString(16),e.length>1?e:"0"+e}return"#"+i(t)+i(n)+i(r)}var r=/rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)/gi,i=/(?:url(?:(?:\(\s*\"([^\"]+)\"\s*\))|(?:\(\s*\'([^\']+)\'\s*\))|(?:\(\s*([^)\s]+)\s*\))))|(?:\'([^\']+)\')|(?:\"([^\"]+)\")/gi,o=/\s*([^:]+):\s*([^;]+);?/g,a=/\s+$/,s,l,c={},u,d="\ufeff"; +for(e=e||{},u=("\\\" \\' \\; \\: ; : "+d).split(" "),l=0;l0&&("font-weight"===g&&"700"===v?v="bold":("color"===g||"background-color"===g)&&(v=v.toLowerCase()),v=v.replace(r,n),v=v.replace(i,p),h[g]=y?f(v,!0):v),o.lastIndex=m.index+m[0].length;s("border",""),s("border","-width"),s("border","-color"),s("border","-style"),s("padding",""),s("margin",""),u("border","border-width","border-style","border-color"),"medium none"===h.border&&delete h.border}return h},serialize:function(e,n){function r(n){var r,o,a,l;if(r=t.styles[n])for(o=0,a=r.length;a>o;o++)n=r[o],l=e[n],l!==s&&l.length>0&&(i+=(i.length>0?" ":"")+n+": "+l+";")}var i="",o,a;if(n&&t&&t.styles)r("*"),r(n);else for(o in e)a=e[o],a!==s&&a.length>0&&(i+=(i.length>0?" ":"")+o+": "+a+";");return i}}}}),r(f,[],function(){return function(e,t){function n(e,n,r,i){var o,a;if(e){if(!i&&e[n])return e[n];if(e!=t){if(o=e[r])return o;for(a=e.parentNode;a&&a!=t;a=a.parentNode)if(o=a[r])return o}}}var r=e;this.current=function(){return r},this.next=function(e){return r=n(r,"firstChild","nextSibling",e)},this.prev=function(e){return r=n(r,"lastChild","previousSibling",e)}}}),r(p,[],function(){function e(e,n){return n?"array"==n&&g(e)?!0:typeof e==n:e!==t}function n(e){var t=[],n,r;for(n=0,r=e.length;r>n;n++)t[n]=e[n];return t}function r(e,t,n){var r;for(e=e||[],t=t||",","string"==typeof e&&(e=e.split(t)),n=n||{},r=e.length;r--;)n[e[r]]={};return n}function i(e,n,r){var i,o;if(!e)return 0;if(r=r||e,e.length!==t){for(i=0,o=e.length;o>i;i++)if(n.call(r,e[i],i,e)===!1)return 0}else for(i in e)if(e.hasOwnProperty(i)&&n.call(r,e[i],i,e)===!1)return 0;return 1}function o(e,t){var n=[];return i(e,function(e){n.push(t(e))}),n}function a(e,t){var n=[];return i(e,function(e){(!t||t(e))&&n.push(e)}),n}function s(e,t,n){var r=this,i,o,a,s,l,c=0;if(e=/^((static) )?([\w.]+)(:([\w.]+))?/.exec(e),a=e[3].match(/(^|\.)(\w+)$/i)[2],o=r.createNS(e[3].replace(/\.\w+$/,""),n),!o[a]){if("static"==e[2])return o[a]=t,this.onCreate&&this.onCreate(e[2],e[3],o[a]),void 0;t[a]||(t[a]=function(){},c=1),o[a]=t[a],r.extend(o[a].prototype,t),e[5]&&(i=r.resolve(e[5]).prototype,s=e[5].match(/\.(\w+)$/i)[1],l=o[a],o[a]=c?function(){return i[s].apply(this,arguments)}:function(){return this.parent=i[s],l.apply(this,arguments)},o[a].prototype[a]=o[a],r.each(i,function(e,t){o[a].prototype[t]=i[t]}),r.each(t,function(e,t){i[t]?o[a].prototype[t]=function(){return this.parent=i[t],e.apply(this,arguments)}:t!=a&&(o[a].prototype[t]=e)})),r.each(t["static"],function(e,t){o[a][t]=e})}}function l(e,t){var n,r;if(e)for(n=0,r=e.length;r>n;n++)if(e[n]===t)return n;return-1}function c(e,n){var r,i,o,a=arguments,s;for(r=1,i=a.length;i>r;r++){n=a[r];for(o in n)n.hasOwnProperty(o)&&(s=n[o],s!==t&&(e[o]=s))}return e}function u(e,t,n,r){r=r||this,e&&(n&&(e=e[n]),i(e,function(e,i){return t.call(r,e,i,n)===!1?!1:(u(e,t,n,r),void 0)}))}function d(e,t){var n,r;for(t=t||window,e=e.split("."),n=0;nn&&(t=t[e[n]],t);n++);return t}function p(t,n){return!t||e(t,"array")?t:o(t.split(n||","),m)}var h=/^\s*|\s*$/g,m=function(e){return null===e||e===t?"":(""+e).replace(h,"")},g=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)};return{trim:m,isArray:g,is:e,toArray:n,makeMap:r,each:i,map:o,grep:a,inArray:l,extend:c,create:s,walk:u,createNS:d,resolve:f,explode:p}}),r(h,[p],function(e){function t(n){function r(){return M.createDocumentFragment()}function i(e,t){_(F,e,t)}function o(e,t){_(W,e,t)}function a(e){i(e.parentNode,$(e))}function s(e){i(e.parentNode,$(e)+1)}function l(e){o(e.parentNode,$(e))}function c(e){o(e.parentNode,$(e)+1)}function u(e){e?(L[U]=L[V],L[q]=L[z]):(L[V]=L[U],L[z]=L[q]),L.collapsed=F}function d(e){a(e),c(e)}function f(e){i(e,0),o(e,1===e.nodeType?e.childNodes.length:e.nodeValue.length)}function p(e,t){var n=L[V],r=L[z],i=L[U],o=L[q],a=t.startContainer,s=t.startOffset,l=t.endContainer,c=t.endOffset;return 0===e?w(n,r,a,s):1===e?w(i,o,a,s):2===e?w(i,o,l,c):3===e?w(n,r,l,c):void 0}function h(){N(I)}function m(){return N(P)}function g(){return N(O)}function v(e){var t=this[V],r=this[z],i,o;3!==t.nodeType&&4!==t.nodeType||!t.nodeValue?(t.childNodes.length>0&&(o=t.childNodes[r]),o?t.insertBefore(e,o):3==t.nodeType?n.insertAfter(e,t):t.appendChild(e)):r?r>=t.nodeValue.length?n.insertAfter(e,t):(i=t.splitText(r),t.parentNode.insertBefore(e,i)):t.parentNode.insertBefore(e,t)}function y(e){var t=L.extractContents();L.insertNode(e),e.appendChild(t),L.selectNode(e)}function b(){return j(new t(n),{startContainer:L[V],startOffset:L[z],endContainer:L[U],endOffset:L[q],collapsed:L.collapsed,commonAncestorContainer:L.commonAncestorContainer})}function C(e,t){var n;if(3==e.nodeType)return e;if(0>t)return e;for(n=e.firstChild;n&&t>0;)--t,n=n.nextSibling;return n?n:e}function x(){return L[V]==L[U]&&L[z]==L[q]}function w(e,t,r,i){var o,a,s,l,c,u;if(e==r)return t==i?0:i>t?-1:1;for(o=r;o&&o.parentNode!=e;)o=o.parentNode;if(o){for(a=0,s=e.firstChild;s!=o&&t>a;)a++,s=s.nextSibling;return a>=t?-1:1}for(o=e;o&&o.parentNode!=r;)o=o.parentNode;if(o){for(a=0,s=r.firstChild;s!=o&&i>a;)a++,s=s.nextSibling;return i>a?-1:1}for(l=n.findCommonAncestor(e,r),c=e;c&&c.parentNode!=l;)c=c.parentNode;for(c||(c=l),u=r;u&&u.parentNode!=l;)u=u.parentNode;if(u||(u=l),c==u)return 0;for(s=l.firstChild;s;){if(s==c)return-1;if(s==u)return 1;s=s.nextSibling}}function _(e,t,r){var i,o;for(e?(L[V]=t,L[z]=r):(L[U]=t,L[q]=r),i=L[U];i.parentNode;)i=i.parentNode;for(o=L[V];o.parentNode;)o=o.parentNode;o==i?w(L[V],L[z],L[U],L[q])>0&&L.collapse(e):L.collapse(e),L.collapsed=x(),L.commonAncestorContainer=n.findCommonAncestor(L[V],L[U])}function N(e){var t,n=0,r=0,i,o,a,s,l,c;if(L[V]==L[U])return E(e);for(t=L[U],i=t.parentNode;i;t=i,i=i.parentNode){if(i==L[V])return k(t,e);++n}for(t=L[V],i=t.parentNode;i;t=i,i=i.parentNode){if(i==L[U])return S(t,e);++r}for(o=r-n,a=L[V];o>0;)a=a.parentNode,o--;for(s=L[U];0>o;)s=s.parentNode,o++;for(l=a.parentNode,c=s.parentNode;l!=c;l=l.parentNode,c=c.parentNode)a=l,s=c;return T(a,s,e)}function E(e){var t,n,i,o,a,s,l,c,u;if(e!=I&&(t=r()),L[z]==L[q])return t;if(3==L[V].nodeType){if(n=L[V].nodeValue,i=n.substring(L[z],L[q]),e!=O&&(o=L[V],c=L[z],u=L[q]-L[z],0===c&&u>=o.nodeValue.length-1?o.parentNode.removeChild(o):o.deleteData(c,u),L.collapse(F)),e==I)return;return i.length>0&&t.appendChild(M.createTextNode(i)),t}for(o=C(L[V],L[z]),a=L[q]-L[z];o&&a>0;)s=o.nextSibling,l=D(o,e),t&&t.appendChild(l),--a,o=s;return e!=O&&L.collapse(F),t}function k(e,t){var n,i,o,a,s,l;if(t!=I&&(n=r()),i=R(e,t),n&&n.appendChild(i),o=$(e),a=o-L[z],0>=a)return t!=O&&(L.setEndBefore(e),L.collapse(W)),n;for(i=e.previousSibling;a>0;)s=i.previousSibling,l=D(i,t),n&&n.insertBefore(l,n.firstChild),--a,i=s;return t!=O&&(L.setEndBefore(e),L.collapse(W)),n}function S(e,t){var n,i,o,a,s,l;for(t!=I&&(n=r()),o=A(e,t),n&&n.appendChild(o),i=$(e),++i,a=L[q]-i,o=e.nextSibling;o&&a>0;)s=o.nextSibling,l=D(o,t),n&&n.appendChild(l),--a,o=s;return t!=O&&(L.setStartAfter(e),L.collapse(F)),n}function T(e,t,n){var i,o,a,s,l,c,u,d;for(n!=I&&(o=r()),i=A(e,n),o&&o.appendChild(i),a=e.parentNode,s=$(e),l=$(t),++s,c=l-s,u=e.nextSibling;c>0;)d=u.nextSibling,i=D(u,n),o&&o.appendChild(i),u=d,--c;return i=R(t,n),o&&o.appendChild(i),n!=O&&(L.setStartAfter(e),L.collapse(F)),o}function R(e,t){var n=C(L[U],L[q]-1),r,i,o,a,s,l=n!=L[U];if(n==e)return B(n,l,W,t);for(r=n.parentNode,i=B(r,W,W,t);r;){for(;n;)o=n.previousSibling,a=B(n,l,W,t),t!=I&&i.insertBefore(a,i.firstChild),l=F,n=o;if(r==e)return i;n=r.previousSibling,r=r.parentNode,s=B(r,W,W,t),t!=I&&s.appendChild(i),i=s}}function A(e,t){var n=C(L[V],L[z]),r=n!=L[V],i,o,a,s,l;if(n==e)return B(n,r,F,t);for(i=n.parentNode,o=B(i,W,F,t);i;){for(;n;)a=n.nextSibling,s=B(n,r,F,t),t!=I&&o.appendChild(s),r=F,n=a;if(i==e)return o;n=i.nextSibling,i=i.parentNode,l=B(i,W,F,t),t!=I&&l.appendChild(o),o=l}}function B(e,t,r,i){var o,a,s,l,c;if(t)return D(e,i);if(3==e.nodeType){if(o=e.nodeValue,r?(l=L[z],a=o.substring(l),s=o.substring(0,l)):(l=L[q],a=o.substring(0,l),s=o.substring(l)),i!=O&&(e.nodeValue=s),i==I)return;return c=n.clone(e,W),c.nodeValue=a,c}if(i!=I)return n.clone(e,W)}function D(e,t){return t!=I?t==O?n.clone(e,F):e:(e.parentNode.removeChild(e),void 0)}function H(){return n.create("body",null,g()).outerText}var L=this,M=n.doc,P=0,O=1,I=2,F=!0,W=!1,z="startOffset",V="startContainer",U="endContainer",q="endOffset",j=e.extend,$=n.nodeIndex;return j(L,{startContainer:M,startOffset:0,endContainer:M,endOffset:0,collapsed:F,commonAncestorContainer:M,START_TO_START:0,START_TO_END:1,END_TO_END:2,END_TO_START:3,setStart:i,setEnd:o,setStartBefore:a,setStartAfter:s,setEndBefore:l,setEndAfter:c,collapse:u,selectNode:d,selectNodeContents:f,compareBoundaryPoints:p,deleteContents:h,extractContents:m,cloneContents:g,insertNode:v,surroundContents:y,cloneRange:b,toStringIE:H}),L}return t.prototype.toString=function(){return this.toStringIE()},t}),r(m,[p],function(e){function t(e){var t;return t=document.createElement("div"),t.innerHTML=e,t.textContent||t.innerText||e}function n(e,t){var n,r,i,a={};if(e){for(e=e.split(","),t=t||10,n=0;n\"\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,l=/[<>&\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,c=/[<>&\"\']/g,u=/&(#x|#)?([\w]+);/g,d={128:"\u20ac",130:"\u201a",131:"\u0192",132:"\u201e",133:"\u2026",134:"\u2020",135:"\u2021",136:"\u02c6",137:"\u2030",138:"\u0160",139:"\u2039",140:"\u0152",142:"\u017d",145:"\u2018",146:"\u2019",147:"\u201c",148:"\u201d",149:"\u2022",150:"\u2013",151:"\u2014",152:"\u02dc",153:"\u2122",154:"\u0161",155:"\u203a",156:"\u0153",158:"\u017e",159:"\u0178"};o={'"':""","'":"'","<":"<",">":">","&":"&"},a={"<":"<",">":">","&":"&",""":'"',"'":"'"},i=n("50,nbsp,51,iexcl,52,cent,53,pound,54,curren,55,yen,56,brvbar,57,sect,58,uml,59,copy,5a,ordf,5b,laquo,5c,not,5d,shy,5e,reg,5f,macr,5g,deg,5h,plusmn,5i,sup2,5j,sup3,5k,acute,5l,micro,5m,para,5n,middot,5o,cedil,5p,sup1,5q,ordm,5r,raquo,5s,frac14,5t,frac12,5u,frac34,5v,iquest,60,Agrave,61,Aacute,62,Acirc,63,Atilde,64,Auml,65,Aring,66,AElig,67,Ccedil,68,Egrave,69,Eacute,6a,Ecirc,6b,Euml,6c,Igrave,6d,Iacute,6e,Icirc,6f,Iuml,6g,ETH,6h,Ntilde,6i,Ograve,6j,Oacute,6k,Ocirc,6l,Otilde,6m,Ouml,6n,times,6o,Oslash,6p,Ugrave,6q,Uacute,6r,Ucirc,6s,Uuml,6t,Yacute,6u,THORN,6v,szlig,70,agrave,71,aacute,72,acirc,73,atilde,74,auml,75,aring,76,aelig,77,ccedil,78,egrave,79,eacute,7a,ecirc,7b,euml,7c,igrave,7d,iacute,7e,icirc,7f,iuml,7g,eth,7h,ntilde,7i,ograve,7j,oacute,7k,ocirc,7l,otilde,7m,ouml,7n,divide,7o,oslash,7p,ugrave,7q,uacute,7r,ucirc,7s,uuml,7t,yacute,7u,thorn,7v,yuml,ci,fnof,sh,Alpha,si,Beta,sj,Gamma,sk,Delta,sl,Epsilon,sm,Zeta,sn,Eta,so,Theta,sp,Iota,sq,Kappa,sr,Lambda,ss,Mu,st,Nu,su,Xi,sv,Omicron,t0,Pi,t1,Rho,t3,Sigma,t4,Tau,t5,Upsilon,t6,Phi,t7,Chi,t8,Psi,t9,Omega,th,alpha,ti,beta,tj,gamma,tk,delta,tl,epsilon,tm,zeta,tn,eta,to,theta,tp,iota,tq,kappa,tr,lambda,ts,mu,tt,nu,tu,xi,tv,omicron,u0,pi,u1,rho,u2,sigmaf,u3,sigma,u4,tau,u5,upsilon,u6,phi,u7,chi,u8,psi,u9,omega,uh,thetasym,ui,upsih,um,piv,812,bull,816,hellip,81i,prime,81j,Prime,81u,oline,824,frasl,88o,weierp,88h,image,88s,real,892,trade,89l,alefsym,8cg,larr,8ch,uarr,8ci,rarr,8cj,darr,8ck,harr,8dl,crarr,8eg,lArr,8eh,uArr,8ei,rArr,8ej,dArr,8ek,hArr,8g0,forall,8g2,part,8g3,exist,8g5,empty,8g7,nabla,8g8,isin,8g9,notin,8gb,ni,8gf,prod,8gh,sum,8gi,minus,8gn,lowast,8gq,radic,8gt,prop,8gu,infin,8h0,ang,8h7,and,8h8,or,8h9,cap,8ha,cup,8hb,int,8hk,there4,8hs,sim,8i5,cong,8i8,asymp,8j0,ne,8j1,equiv,8j4,le,8j5,ge,8k2,sub,8k3,sup,8k4,nsub,8k6,sube,8k7,supe,8kl,oplus,8kn,otimes,8l5,perp,8m5,sdot,8o8,lceil,8o9,rceil,8oa,lfloor,8ob,rfloor,8p9,lang,8pa,rang,9ea,loz,9j0,spades,9j3,clubs,9j5,hearts,9j6,diams,ai,OElig,aj,oelig,b0,Scaron,b1,scaron,bo,Yuml,m6,circ,ms,tilde,802,ensp,803,emsp,809,thinsp,80c,zwnj,80d,zwj,80e,lrm,80f,rlm,80j,ndash,80k,mdash,80o,lsquo,80p,rsquo,80q,sbquo,80s,ldquo,80t,rdquo,80u,bdquo,810,dagger,811,Dagger,81g,permil,81p,lsaquo,81q,rsaquo,85c,euro",32);var f={encodeRaw:function(e,t){return e.replace(t?s:l,function(e){return o[e]||e})},encodeAllRaw:function(e){return(""+e).replace(c,function(e){return o[e]||e})},encodeNumeric:function(e,t){return e.replace(t?s:l,function(e){return e.length>1?"&#"+(1024*(e.charCodeAt(0)-55296)+(e.charCodeAt(1)-56320)+65536)+";":o[e]||"&#"+e.charCodeAt(0)+";"})},encodeNamed:function(e,t,n){return n=n||i,e.replace(t?s:l,function(e){return o[e]||n[e]||e})},getEncodeFunc:function(e,t){function a(e,n){return e.replace(n?s:l,function(e){return o[e]||t[e]||"&#"+e.charCodeAt(0)+";"||e})}function c(e,n){return f.encodeNamed(e,n,t)}return t=n(t)||i,e=r(e.replace(/\+/g,",")),e.named&&e.numeric?a:e.named?t?c:f.encodeNamed:e.numeric?f.encodeNumeric:f.encodeRaw},decode:function(e){return e.replace(u,function(e,n,r){return n?(r=parseInt(r,2===n.length?16:10),r>65535?(r-=65536,String.fromCharCode(55296+(r>>10),56320+(1023&r))):d[r]||String.fromCharCode(r)):a[e]||i[e]||t(e)})}};return f}),r(g,[],function(){var e=navigator,t=e.userAgent,n,r,i,o,a,s,l;n=window.opera&&window.opera.buildNumber,r=/WebKit/.test(t),i=!r&&!n&&/MSIE/gi.test(t)&&/Explorer/gi.test(e.appName),i=i&&/MSIE (\w+)\./.exec(t)[1],o=-1!=t.indexOf("Trident")?11:!1,i=i||o,a=!r&&/Gecko/.test(t),s=-1!=t.indexOf("Mac"),l=/(iPad|iPhone)/.test(t);var c=!l||t.match(/AppleWebKit\/(\d*)/)[1]>=534;return{opera:n,webkit:r,ie:i,gecko:a,mac:s,iOS:l,contentEditable:c,transparentSrc:"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",caretAfter:8!=i,range:window.getSelection&&"Range"in window,documentMode:i?document.documentMode||7:10}}),r(v,[c,d,l,f,h,m,g,p],function(e,n,r,i,o,a,s,l){function c(e,t){var i=this,o;i.doc=e,i.win=window,i.files={},i.counter=0,i.stdMode=!g||e.documentMode>=8,i.boxModel=!g||"CSS1Compat"==e.compatMode||i.stdMode,i.hasOuterHTML="outerHTML"in e.createElement("a"),this.boundEvents=[],i.settings=t=h({keep_values:!1,hex_colors:1},t),i.schema=t.schema,i.styles=new n({url_converter:t.url_converter,url_converter_scope:t.url_converter_scope},t.schema),i.fixDoc(e),i.events=t.ownEvents?new r(t.proxy):r.Event,o=t.schema?t.schema.getBlockElements():{},i.isBlock=function(e){if(!e)return!1;var t=e.nodeType;return t?!(1!==t||!o[e.nodeName]):!!o[e]}}var u=l.each,d=l.is,f=l.grep,p=l.trim,h=l.extend,m=s.webkit,g=s.ie,v=/^([a-z0-9],?)+$/i,y=/^[ \t\r\n]*$/,b=l.makeMap("fillOpacity fontWeight lineHeight opacity orphans widows zIndex zoom"," ");return c.prototype={root:null,props:{"for":"htmlFor","class":"className",className:"className",checked:"checked",disabled:"disabled",maxlength:"maxLength",readonly:"readOnly",selected:"selected",value:"value",id:"id",name:"name",type:"type"},fixDoc:function(e){var t=this.settings,n;if(g&&t.schema){"abbr article aside audio canvas details figcaption figure footer header hgroup mark menu meter nav output progress section summary time video".replace(/\w+/g,function(t){e.createElement(t)});for(n in t.schema.getCustomElements())e.createElement(n)}},clone:function(e,t){var n=this,r,i;return!g||1!==e.nodeType||t?e.cloneNode(t):(i=n.doc,t?r.firstChild:(r=i.createElement(e.nodeName),u(n.getAttribs(e),function(t){n.setAttrib(r,t.nodeName,n.getAttrib(e,t.nodeName))}),r))},getRoot:function(){var e=this;return e.get(e.settings.root_element)||e.doc.body},getViewPort:function(e){var t,n;return e=e?e:this.win,t=e.document,n=this.boxModel?t.documentElement:t.body,{x:e.pageXOffset||n.scrollLeft,y:e.pageYOffset||n.scrollTop,w:e.innerWidth||n.clientWidth,h:e.innerHeight||n.clientHeight}},getRect:function(e){var t=this,n,r;return e=t.get(e),n=t.getPos(e),r=t.getSize(e),{x:n.x,y:n.y,w:r.w,h:r.h}},getSize:function(e){var t=this,n,r;return e=t.get(e),n=t.getStyle(e,"width"),r=t.getStyle(e,"height"),-1===n.indexOf("px")&&(n=0),-1===r.indexOf("px")&&(r=0),{w:parseInt(n,10)||e.offsetWidth||e.clientWidth,h:parseInt(r,10)||e.offsetHeight||e.clientHeight}},getParent:function(e,t,n){return this.getParents(e,t,n,!1)},getParents:function(e,n,r,i){var o=this,a,s=[];for(e=o.get(e),i=i===t,r=r||("BODY"!=o.getRoot().nodeName?o.getRoot().parentNode:null),d(n,"string")&&(a=n,n="*"===n?function(e){return 1==e.nodeType}:function(e){return o.is(e,a)});e&&e!=r&&e.nodeType&&9!==e.nodeType;){if(!n||n(e)){if(!i)return e;s.push(e)}e=e.parentNode}return i?s:null},get:function(e){var t;return e&&this.doc&&"string"==typeof e&&(t=e,e=this.doc.getElementById(e),e&&e.id!==t)?this.doc.getElementsByName(t)[1]:e},getNext:function(e,t){return this._findSib(e,t,"nextSibling")},getPrev:function(e,t){return this._findSib(e,t,"previousSibling")},select:function(t,n){var r=this;return e(t,r.get(n)||r.get(r.settings.root_element)||r.doc,[])},is:function(n,r){var i;if(n.length===t){if("*"===r)return 1==n.nodeType;if(v.test(r)){for(r=r.toLowerCase().split(/,/),n=n.nodeName.toLowerCase(),i=r.length-1;i>=0;i--)if(r[i]==n)return!0;return!1}}return n.nodeType&&1!=n.nodeType?!1:e.matches(r,n.nodeType?[n]:n).length>0},add:function(e,t,n,r,i){var o=this;return this.run(e,function(e){var a;return a=d(t,"string")?o.doc.createElement(t):t,o.setAttribs(a,n),r&&(r.nodeType?a.appendChild(r):o.setHTML(a,r)),i?a:e.appendChild(a)})},create:function(e,t,n){return this.add(this.doc.createElement(e),e,t,n,1)},createHTML:function(e,t,n){var r="",i;r+="<"+e;for(i in t)t.hasOwnProperty(i)&&null!==t[i]&&(r+=" "+i+'="'+this.encode(t[i])+'"');return"undefined"!=typeof n?r+">"+n+"":r+" />"},createFragment:function(e){var t,n,r=this.doc,i;for(i=r.createElement("div"),t=r.createDocumentFragment(),e&&(i.innerHTML=e);n=i.firstChild;)t.appendChild(n);return t},remove:function(e,t){return this.run(e,function(e){var n,r=e.parentNode;if(!r)return null;if(t)for(;n=e.firstChild;)!g||3!==n.nodeType||n.nodeValue?r.insertBefore(n,e):e.removeChild(n);return r.removeChild(e)})},setStyle:function(e,t,n){return this.run(e,function(e){var r=this,i,o;if(t)if("string"==typeof t){i=e.style,t=t.replace(/-(\D)/g,function(e,t){return t.toUpperCase()}),"number"!=typeof n||b[t]||(n+="px"),"opacity"===t&&e.runtimeStyle&&"undefined"==typeof e.runtimeStyle.opacity&&(i.filter=""===n?"":"alpha(opacity="+100*n+")"),"float"==t&&(t="cssFloat"in e.style?"cssFloat":"styleFloat");try{i[t]=n}catch(a){}r.settings.update_styles&&e.removeAttribute("data-mce-style")}else for(o in t)r.setStyle(e,o,t[o])})},getStyle:function(e,n,r){if(e=this.get(e)){if(this.doc.defaultView&&r){n=n.replace(/[A-Z]/g,function(e){return"-"+e});try{return this.doc.defaultView.getComputedStyle(e,null).getPropertyValue(n)}catch(i){return null}}return n=n.replace(/-(\D)/g,function(e,t){return t.toUpperCase()}),"float"==n&&(n=g?"styleFloat":"cssFloat"),e.currentStyle&&r?e.currentStyle[n]:e.style?e.style[n]:t}},setStyles:function(e,t){this.setStyle(e,t)},css:function(e,t,n){this.setStyle(e,t,n)},removeAllAttribs:function(e){return this.run(e,function(e){var t,n=e.attributes;for(t=n.length-1;t>=0;t--)e.removeAttributeNode(n.item(t))})},setAttrib:function(e,t,n){var r=this;if(e&&t)return this.run(e,function(e){var i=r.settings,o=e.getAttribute(t);if(null!==n)switch(t){case"style":if(!d(n,"string"))return u(n,function(t,n){r.setStyle(e,n,t)}),void 0;i.keep_values&&(n?e.setAttribute("data-mce-style",n,2):e.removeAttribute("data-mce-style",2)),e.style.cssText=n;break;case"class":e.className=n||"";break;case"src":case"href":i.keep_values&&(i.url_converter&&(n=i.url_converter.call(i.url_converter_scope||r,n,t,e)),r.setAttrib(e,"data-mce-"+t,n,2));break;case"shape":e.setAttribute("data-mce-style",n)}d(n)&&null!==n&&0!==n.length?e.setAttribute(t,""+n,2):e.removeAttribute(t,2),o!=n&&i.onSetAttrib&&i.onSetAttrib({attrElm:e,attrName:t,attrValue:n})})},setAttribs:function(e,t){var n=this;return this.run(e,function(e){u(t,function(t,r){n.setAttrib(e,r,t)})})},getAttrib:function(e,t,n){var r,i=this,o;if(e=i.get(e),!e||1!==e.nodeType)return n===o?!1:n;if(d(n)||(n=""),/^(src|href|style|coords|shape)$/.test(t)&&(r=e.getAttribute("data-mce-"+t)))return r;if(g&&i.props[t]&&(r=e[i.props[t]],r=r&&r.nodeValue?r.nodeValue:r),r||(r=e.getAttribute(t,2)),/^(checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)$/.test(t))return e[i.props[t]]===!0&&""===r?t:r?t:"";if("FORM"===e.nodeName&&e.getAttributeNode(t))return e.getAttributeNode(t).nodeValue;if("style"===t&&(r=r||e.style.cssText,r&&(r=i.serializeStyle(i.parseStyle(r),e.nodeName),i.settings.keep_values&&e.setAttribute("data-mce-style",r))),m&&"class"===t&&r&&(r=r.replace(/(apple|webkit)\-[a-z\-]+/gi,"")),g)switch(t){case"rowspan":case"colspan":1===r&&(r="");break;case"size":("+0"===r||20===r||0===r)&&(r="");break;case"width":case"height":case"vspace":case"checked":case"disabled":case"readonly":0===r&&(r="");break;case"hspace":-1===r&&(r="");break;case"maxlength":case"tabindex":(32768===r||2147483647===r||"32768"===r)&&(r="");break;case"multiple":case"compact":case"noshade":case"nowrap":return 65535===r?t:n;case"shape":r=r.toLowerCase();break;default:0===t.indexOf("on")&&r&&(r=(""+r).replace(/^function\s+\w+\(\)\s+\{\s+(.*)\s+\}$/,"$1"))}return r!==o&&null!==r&&""!==r?""+r:n},getPos:function(e,t){var n=this,r=0,i=0,o,a=n.doc,s;if(e=n.get(e),t=t||a.body,e){if(t===a.body&&e.getBoundingClientRect)return s=e.getBoundingClientRect(),t=n.boxModel?a.documentElement:a.body,r=s.left+(a.documentElement.scrollLeft||a.body.scrollLeft)-t.clientTop,i=s.top+(a.documentElement.scrollTop||a.body.scrollTop)-t.clientLeft,{x:r,y:i};for(o=e;o&&o!=t&&o.nodeType;)r+=o.offsetLeft||0,i+=o.offsetTop||0,o=o.offsetParent;for(o=e.parentNode;o&&o!=t&&o.nodeType;)r-=o.scrollLeft||0,i-=o.scrollTop||0,o=o.parentNode}return{x:r,y:i}},parseStyle:function(e){return this.styles.parse(e)},serializeStyle:function(e,t){return this.styles.serialize(e,t)},addStyle:function(e){var t=this,n=t.doc,r,i;if(t!==c.DOM&&n===document){var o=c.DOM.addedStyles;if(o=o||[],o[e])return;o[e]=!0,c.DOM.addedStyles=o}i=n.getElementById("mceDefaultStyles"),i||(i=n.createElement("style"),i.id="mceDefaultStyles",i.type="text/css",r=n.getElementsByTagName("head")[0],r.firstChild?r.insertBefore(i,r.firstChild):r.appendChild(i)),i.styleSheet?i.styleSheet.cssText+=e:i.appendChild(n.createTextNode(e))},loadCSS:function(e){var t=this,n=t.doc,r;return t!==c.DOM&&n===document?(c.DOM.loadCSS(e),void 0):(e||(e=""),r=n.getElementsByTagName("head")[0],u(e.split(","),function(e){var i;t.files[e]||(t.files[e]=!0,i=t.create("link",{rel:"stylesheet",href:e}),g&&n.documentMode&&n.recalc&&(i.onload=function(){n.recalc&&n.recalc(),i.onload=null}),r.appendChild(i))}),void 0)},addClass:function(e,t){return this.run(e,function(e){var n;return t?this.hasClass(e,t)?e.className:(n=this.removeClass(e,t),e.className=n=(""!==n?n+" ":"")+t,n):0})},removeClass:function(e,t){var n=this,r;return n.run(e,function(e){var i;return n.hasClass(e,t)?(r||(r=new RegExp("(^|\\s+)"+t+"(\\s+|$)","g")),i=e.className.replace(r," "),i=p(" "!=i?i:""),e.className=i,i||(e.removeAttribute("class"),e.removeAttribute("className")),i):e.className})},hasClass:function(e,t){return e=this.get(e),e&&t?-1!==(" "+e.className+" ").indexOf(" "+t+" "):!1},toggleClass:function(e,n,r){r=r===t?!this.hasClass(e,n):r,this.hasClass(e,n)!==r&&(r?this.addClass(e,n):this.removeClass(e,n))},show:function(e){return this.setStyle(e,"display","block")},hide:function(e){return this.setStyle(e,"display","none")},isHidden:function(e){return e=this.get(e),!e||"none"==e.style.display||"none"==this.getStyle(e,"display")},uniqueId:function(e){return(e?e:"mce_")+this.counter++},setHTML:function(e,t){var n=this;return n.run(e,function(e){if(g){for(;e.firstChild;)e.removeChild(e.firstChild);try{e.innerHTML="
    "+t,e.removeChild(e.firstChild)}catch(r){var i=n.create("div");i.innerHTML="
    "+t,u(f(i.childNodes),function(t,n){n&&e.canHaveHTML&&e.appendChild(t)})}}else e.innerHTML=t;return t})},getOuterHTML:function(e){var t,n=this;return(e=n.get(e))?1===e.nodeType&&n.hasOuterHTML?e.outerHTML:(t=(e.ownerDocument||n.doc).createElement("body"),t.appendChild(e.cloneNode(!0)),t.innerHTML):null},setOuterHTML:function(e,t,n){var r=this;return r.run(e,function(e){function i(){var i,o;for(o=n.createElement("body"),o.innerHTML=t,i=o.lastChild;i;)r.insertAfter(i.cloneNode(!0),e),i=i.previousSibling;r.remove(e)}if(1==e.nodeType)if(n=n||e.ownerDocument||r.doc,g)try{1==e.nodeType&&r.hasOuterHTML?e.outerHTML=t:i()}catch(o){i()}else i()})},decode:a.decode,encode:a.encodeAllRaw,insertAfter:function(e,t){return t=this.get(t),this.run(e,function(e){var n,r;return n=t.parentNode,r=t.nextSibling,r?n.insertBefore(e,r):n.appendChild(e),e})},replace:function(e,t,n){var r=this;return r.run(t,function(t){return d(t,"array")&&(e=e.cloneNode(!0)),n&&u(f(t.childNodes),function(t){e.appendChild(t)}),t.parentNode.replaceChild(e,t)})},rename:function(e,t){var n=this,r;return e.nodeName!=t.toUpperCase()&&(r=n.create(t),u(n.getAttribs(e),function(t){n.setAttrib(r,t.nodeName,n.getAttrib(e,t.nodeName))}),n.replace(r,e,1)),r||e},findCommonAncestor:function(e,t){for(var n=e,r;n;){for(r=t;r&&n!=r;)r=r.parentNode;if(n==r)break;n=n.parentNode}return!n&&e.ownerDocument?e.ownerDocument.documentElement:n},toHex:function(e){return this.styles.toHex(l.trim(e))},run:function(e,t,n){var r=this,i;return"string"==typeof e&&(e=r.get(e)),e?(n=n||this,e.nodeType||!e.length&&0!==e.length?t.call(n,e):(i=[],u(e,function(e,o){e&&("string"==typeof e&&(e=r.get(e)),i.push(t.call(n,e,o)))}),i)):!1},getAttribs:function(e){var t;if(e=this.get(e),!e)return[];if(g){if(t=[],"OBJECT"==e.nodeName)return e.attributes;"OPTION"===e.nodeName&&this.getAttrib(e,"selected")&&t.push({specified:1,nodeName:"selected"});var n=/<\/?[\w:\-]+ ?|=[\"][^\"]+\"|=\'[^\']+\'|=[\w\-]+|>/gi;return e.cloneNode(!1).outerHTML.replace(n,"").replace(/[\w:\-]+/gi,function(e){t.push({specified:1,nodeName:e})}),t}return e.attributes},isEmpty:function(e,t){var n=this,r,o,a,s,l,c=0;if(e=e.firstChild){s=new i(e,e.parentNode),t=t||n.schema?n.schema.getNonEmptyElements():null;do{if(a=e.nodeType,1===a){if(e.getAttribute("data-mce-bogus"))continue;if(l=e.nodeName.toLowerCase(),t&&t[l]){if("br"===l){c++;continue}return!1}for(o=n.getAttribs(e),r=e.attributes.length;r--;)if(l=e.attributes[r].nodeName,"name"===l||"data-mce-bookmark"===l)return!1}if(8==a)return!1;if(3===a&&!y.test(e.nodeValue))return!1}while(e=s.next())}return 1>=c},createRng:function(){var e=this.doc;return e.createRange?e.createRange():new o(this)},nodeIndex:function(e,t){var n=0,r,i,o;if(e)for(r=e.nodeType,e=e.previousSibling,i=e;e;e=e.previousSibling)o=e.nodeType,(!t||3!=o||o!=r&&e.nodeValue.length)&&(n++,r=o);return n},split:function(e,t,n){function r(e){function t(e){var t=e.previousSibling&&"SPAN"==e.previousSibling.nodeName,n=e.nextSibling&&"SPAN"==e.nextSibling.nodeName;return t&&n}var n,o=e.childNodes,a=e.nodeType;if(1!=a||"bookmark"!=e.getAttribute("data-mce-type")){for(n=o.length-1;n>=0;n--)r(o[n]);if(9!=a){if(3==a&&e.nodeValue.length>0){var s=p(e.nodeValue).length;if(!i.isBlock(e.parentNode)||s>0||0===s&&t(e))return}else if(1==a&&(o=e.childNodes,1==o.length&&o[0]&&1==o[0].nodeType&&"bookmark"==o[0].getAttribute("data-mce-type")&&e.parentNode.insertBefore(o[0],e),o.length||/^(br|hr|input|img)$/i.test(e.nodeName)))return;i.remove(e)}return e}}var i=this,o=i.createRng(),a,s,l;return e&&t?(o.setStart(e.parentNode,i.nodeIndex(e)),o.setEnd(t.parentNode,i.nodeIndex(t)),a=o.extractContents(),o=i.createRng(),o.setStart(t.parentNode,i.nodeIndex(t)+1),o.setEnd(e.parentNode,i.nodeIndex(e)+1),s=o.extractContents(),l=e.parentNode,l.insertBefore(r(a),e),n?l.replaceChild(n,t):l.insertBefore(t,e),l.insertBefore(r(s),e),i.remove(e),n||t):void 0},bind:function(e,t,n,r){var i=this;if(l.isArray(e)){for(var o=e.length;o--;)e[o]=i.bind(e[o],t,n,r);return e}return!i.settings.collect||e!==i.doc&&e!==i.win||i.boundEvents.push([e,t,n,r]),i.events.bind(e,t,n,r||i)},unbind:function(e,t,n){var r=this,i;if(l.isArray(e)){for(i=e.length;i--;)e[i]=r.unbind(e[i],t,n);return e}if(r.boundEvents&&(e===r.doc||e===r.win))for(i=r.boundEvents.length;i--;){var o=r.boundEvents[i];e!=o[0]||t&&t!=o[1]||n&&n!=o[2]||this.events.unbind(o[0],o[1],o[2])}return this.events.unbind(e,t,n)},fire:function(e,t,n){return this.events.fire(e,t,n)},getContentEditable:function(e){var t;return 1!=e.nodeType?null:(t=e.getAttribute("data-mce-contenteditable"),t&&"inherit"!==t?t:"inherit"!==e.contentEditable?e.contentEditable:null)},destroy:function(){var e=this;if(e.boundEvents){for(var t=e.boundEvents.length;t--;){var n=e.boundEvents[t];this.events.unbind(n[0],n[1],n[2])}e.boundEvents=null}e.win=e.doc=e.root=e.events=e.frag=null},dumpRng:function(e){return"startContainer: "+e.startContainer.nodeName+", startOffset: "+e.startOffset+", endContainer: "+e.endContainer.nodeName+", endOffset: "+e.endOffset},_findSib:function(e,t,n){var r=this,i=t;if(e)for("string"==typeof i&&(i=function(e){return r.is(e,t)}),e=e[n];e;e=e[n])if(i(e))return e;return null}},c.DOM=new c(document),c}),r(y,[v,p],function(e,t){function n(){function e(e,t){function n(){o.remove(s),a&&(a.onreadystatechange=a.onload=a=null),t()}function i(){"undefined"!=typeof console&&console.log&&console.log("Failed to load: "+e)}var o=r,a,s;s=o.uniqueId(),a=document.createElement("script"),a.id=s,a.type="text/javascript",a.src=e,"onreadystatechange"in a?a.onreadystatechange=function(){/loaded|complete/.test(a.readyState)&&n()}:a.onload=n,a.onerror=i,(document.getElementsByTagName("head")[0]||document.body).appendChild(a)}var t=0,n=1,a=2,s={},l=[],c={},u=[],d=0,f;this.isDone=function(e){return s[e]==a},this.markDone=function(e){s[e]=a},this.add=this.load=function(e,n,r){var i=s[e];i==f&&(l.push(e),s[e]=t),n&&(c[e]||(c[e]=[]),c[e].push({func:n,scope:r||this}))},this.loadQueue=function(e,t){this.loadScripts(l,e,t)},this.loadScripts=function(t,r,l){function p(e){i(c[e],function(e){e.func.call(e.scope)}),c[e]=f}var h;u.push({func:r,scope:l||this}),h=function(){var r=o(t);t.length=0,i(r,function(t){return s[t]==a?(p(t),void 0):(s[t]!=n&&(s[t]=n,d++,e(t,function(){s[t]=a,d--,p(t),h()})),void 0)}),d||(i(u,function(e){e.func.call(e.scope)}),u.length=0)},h()}}var r=e.DOM,i=t.each,o=t.grep;return n.ScriptLoader=new n,n}),r(b,[y,p],function(e,n){function r(){var e=this;e.items=[],e.urls={},e.lookup={}}var i=n.each;return r.prototype={get:function(e){return this.lookup[e]?this.lookup[e].instance:t},dependencies:function(e){var t;return this.lookup[e]&&(t=this.lookup[e].dependencies),t||[]},requireLangPack:function(t){r.language&&r.languageLoad!==!1&&e.ScriptLoader.add(this.urls[t]+"/langs/"+r.language+".js")},add:function(e,t,n){return this.items.push(t),this.lookup[e]={instance:t,dependencies:n},t},createUrl:function(e,t){return"object"==typeof t?t:{prefix:e.prefix,resource:t,suffix:e.suffix} +},addComponents:function(t,n){var r=this.urls[t];i(n,function(t){e.ScriptLoader.add(r+"/"+t)})},load:function(n,o,a,s){function l(){var r=c.dependencies(n);i(r,function(e){var n=c.createUrl(o,e);c.load(n.resource,n,t,t)}),a&&(s?a.call(s):a.call(e))}var c=this,u=o;c.urls[n]||("object"==typeof o&&(u=o.prefix+o.resource+o.suffix),0!==u.indexOf("/")&&-1==u.indexOf("://")&&(u=r.baseURL+"/"+u),c.urls[n]=u.substring(0,u.lastIndexOf("/")),c.lookup[n]?l():e.ScriptLoader.add(u,l,s))}},r.PluginManager=new r,r.ThemeManager=new r,r}),r(C,[],function(){function e(e,t,n){var r,i,o=n?"lastChild":"firstChild",a=n?"prev":"next";if(e[o])return e[o];if(e!==t){if(r=e[a])return r;for(i=e.parent;i&&i!==t;i=i.parent)if(r=i[a])return r}}function t(e,t){this.name=e,this.type=t,1===t&&(this.attributes=[],this.attributes.map={})}var n=/^[ \t\r\n]*$/,r={"#text":3,"#comment":8,"#cdata":4,"#pi":7,"#doctype":10,"#document-fragment":11};return t.prototype={replace:function(e){var t=this;return e.parent&&e.remove(),t.insert(e,t),t.remove(),t},attr:function(e,t){var n=this,r,i,o;if("string"!=typeof e){for(i in e)n.attr(i,e[i]);return n}if(r=n.attributes){if(t!==o){if(null===t){if(e in r.map)for(delete r.map[e],i=r.length;i--;)if(r[i].name===e)return r=r.splice(i,1),n;return n}if(e in r.map){for(i=r.length;i--;)if(r[i].name===e){r[i].value=t;break}}else r.push({name:e,value:t});return r.map[e]=t,n}return r.map[e]}},clone:function(){var e=this,n=new t(e.name,e.type),r,i,o,a,s;if(o=e.attributes){for(s=[],s.map={},r=0,i=o.length;i>r;r++)a=o[r],"id"!==a.name&&(s[s.length]={name:a.name,value:a.value},s.map[a.name]=a.value);n.attributes=s}return n.value=e.value,n.shortEnded=e.shortEnded,n},wrap:function(e){var t=this;return t.parent.insert(e,t),e.append(t),t},unwrap:function(){var e=this,t,n;for(t=e.firstChild;t;)n=t.next,e.insert(t,e,!0),t=n;e.remove()},remove:function(){var e=this,t=e.parent,n=e.next,r=e.prev;return t&&(t.firstChild===e?(t.firstChild=n,n&&(n.prev=null)):r.next=n,t.lastChild===e?(t.lastChild=r,r&&(r.next=null)):n.prev=r,e.parent=e.next=e.prev=null),e},append:function(e){var t=this,n;return e.parent&&e.remove(),n=t.lastChild,n?(n.next=e,e.prev=n,t.lastChild=e):t.lastChild=t.firstChild=e,e.parent=t,e},insert:function(e,t,n){var r;return e.parent&&e.remove(),r=t.parent||this,n?(t===r.firstChild?r.firstChild=e:t.prev.next=e,e.prev=t.prev,e.next=t,t.prev=e):(t===r.lastChild?r.lastChild=e:t.next.prev=e,e.next=t.next,e.prev=t,t.next=e),e.parent=r,e},getAll:function(t){var n=this,r,i=[];for(r=n.firstChild;r;r=e(r,n))r.name===t&&i.push(r);return i},empty:function(){var t=this,n,r,i;if(t.firstChild){for(n=[],i=t.firstChild;i;i=e(i,t))n.push(i);for(r=n.length;r--;)i=n[r],i.parent=i.firstChild=i.lastChild=i.next=i.prev=null}return t.firstChild=t.lastChild=null,t},isEmpty:function(t){var r=this,i=r.firstChild,o,a;if(i)do{if(1===i.type){if(i.attributes.map["data-mce-bogus"])continue;if(t[i.name])return!1;for(o=i.attributes.length;o--;)if(a=i.attributes[o].name,"name"===a||0===a.indexOf("data-mce-"))return!1}if(8===i.type)return!1;if(3===i.type&&!n.test(i.value))return!1}while(i=e(i,r));return!0},walk:function(t){return e(this,null,t)}},t.create=function(e,n){var i,o;if(i=new t(e,r[e]||1),n)for(o in n)i.attr(o,n[o]);return i},t}),r(x,[p],function(e){function t(e,t){return e?e.split(t||" "):[]}function n(e){function n(e,n,r){function i(e){var t={},n,r;for(n=0,r=e.length;r>n;n++)t[e[n]]={};return t}var o,l,c,u=arguments;for(r=r||[],n=n||"","string"==typeof r&&(r=t(r)),l=3;lo;o++)i.attributes[n[o]]={},i.attributesOrder.push(n[o])}var a={},s,l,c,u,d,f,p;return r[e]?r[e]:(s=t("id accesskey class dir lang style tabindex title"),l=t("onabort onblur oncancel oncanplay oncanplaythrough onchange onclick onclose oncontextmenu oncuechange ondblclick ondrag ondragend ondragenter ondragleave ondragover ondragstart ondrop ondurationchange onemptied onended onerror onfocus oninput oninvalid onkeydown onkeypress onkeyup onload onloadeddata onloadedmetadata onloadstart onmousedown onmousemove onmouseout onmouseover onmouseup onmousewheel onpause onplay onplaying onprogress onratechange onreset onscroll onseeked onseeking onseeking onselect onshow onstalled onsubmit onsuspend ontimeupdate onvolumechange onwaiting"),c=t("address blockquote div dl fieldset form h1 h2 h3 h4 h5 h6 hr menu ol p pre table ul"),u=t("a abbr b bdo br button cite code del dfn em embed i iframe img input ins kbd label map noscript object q s samp script select small span strong sub sup textarea u var #text #comment"),"html4"!=e&&(s.push.apply(s,t("contenteditable contextmenu draggable dropzone hidden spellcheck translate")),c.push.apply(c,t("article aside details dialog figure header footer hgroup section nav")),u.push.apply(u,t("audio canvas command datalist mark meter output progress time wbr video ruby bdi keygen"))),"html5-strict"!=e&&(s.push("xml:lang"),p=t("acronym applet basefont big font strike tt"),u.push.apply(u,p),o(p,function(e){n(e,"",u)}),f=t("center dir isindex noframes"),c.push.apply(c,f),d=[].concat(c,u),o(f,function(e){n(e,"",d)})),d=d||[].concat(c,u),n("html","manifest","head body"),n("head","","base command link meta noscript script style title"),n("title hr noscript br"),n("base","href target"),n("link","href rel media hreflang type sizes hreflang"),n("meta","name http-equiv content charset"),n("style","media type scoped"),n("script","src async defer type charset"),n("body","onafterprint onbeforeprint onbeforeunload onblur onerror onfocus onhashchange onload onmessage onoffline ononline onpagehide onpageshow onpopstate onresize onscroll onstorage onunload",d),n("address dt dd div caption","",d),n("h1 h2 h3 h4 h5 h6 pre p abbr code var samp kbd sub sup i b u bdo span legend em strong small s cite dfn","",u),n("blockquote","cite",d),n("ol","reversed start type","li"),n("ul","","li"),n("li","value",d),n("dl","","dt dd"),n("a","href target rel media hreflang type",u),n("q","cite",u),n("ins del","cite datetime",d),n("img","src alt usemap ismap width height"),n("iframe","src name width height",d),n("embed","src type width height"),n("object","data type typemustmatch name usemap form width height",d,"param"),n("param","name value"),n("map","name",d,"area"),n("area","alt coords shape href target rel media hreflang type"),n("table","border","caption colgroup thead tfoot tbody tr"+("html4"==e?" col":"")),n("colgroup","span","col"),n("col","span"),n("tbody thead tfoot","","tr"),n("tr","","td th"),n("td","colspan rowspan headers",d),n("th","colspan rowspan headers scope abbr",d),n("form","accept-charset action autocomplete enctype method name novalidate target",d),n("fieldset","disabled form name",d,"legend"),n("label","form for",u),n("input","accept alt autocomplete checked dirname disabled form formaction formenctype formmethod formnovalidate formtarget height list max maxlength min multiple name pattern readonly required size src step type value width"),n("button","disabled form formaction formenctype formmethod formnovalidate formtarget name type value","html4"==e?d:u),n("select","disabled form multiple name required size","option optgroup"),n("optgroup","disabled label","option"),n("option","disabled label selected value"),n("textarea","cols dirname disabled form maxlength name readonly required rows wrap"),n("menu","type label",d,"li"),n("noscript","",d),"html4"!=e&&(n("wbr"),n("ruby","",u,"rt rp"),n("figcaption","",d),n("mark rt rp summary bdi","",u),n("canvas","width height",d),n("video","src crossorigin poster preload autoplay mediagroup loop muted controls width height",d,"track source"),n("audio","src crossorigin preload autoplay mediagroup loop muted controls",d,"track source"),n("source","src type media"),n("track","kind src srclang label default"),n("datalist","",u,"option"),n("article section nav aside header footer","",d),n("hgroup","","h1 h2 h3 h4 h5 h6"),n("figure","",d,"figcaption"),n("time","datetime",u),n("dialog","open",d),n("command","type label icon disabled checked radiogroup command"),n("output","for form name",u),n("progress","value max",u),n("meter","value min max low high optimum",u),n("details","open",d,"summary"),n("keygen","autofocus challenge disabled form keytype name")),"html5-strict"!=e&&(i("script","language xml:space"),i("style","xml:space"),i("object","declare classid codebase codetype archive standby align border hspace vspace"),i("param","valuetype type"),i("a","charset name rev shape coords"),i("br","clear"),i("applet","codebase archive code object alt name width height align hspace vspace"),i("img","name longdesc align border hspace vspace"),i("iframe","longdesc frameborder marginwidth marginheight scrolling align"),i("font basefont","size color face"),i("input","usemap align"),i("select","onchange"),i("textarea"),i("h1 h2 h3 h4 h5 h6 div p legend caption","align"),i("ul","type compact"),i("li","type"),i("ol dl menu dir","compact"),i("pre","width xml:space"),i("hr","align noshade size width"),i("isindex","prompt"),i("table","summary width frame rules cellspacing cellpadding align bgcolor"),i("col","width align char charoff valign"),i("colgroup","width align char charoff valign"),i("thead","align char charoff valign"),i("tr","align char charoff valign bgcolor"),i("th","axis align char charoff valign nowrap bgcolor width height"),i("form","accept"),i("td","abbr axis scope align char charoff valign nowrap bgcolor width height"),i("tfoot","align char charoff valign"),i("tbody","align char charoff valign"),i("area","nohref"),i("body","background bgcolor text link vlink alink")),"html4"!=e&&(i("input button select textarea","autofocus"),i("input textarea","placeholder"),i("a","download"),i("link script img","crossorigin"),i("iframe","srcdoc sandbox seamless allowfullscreen")),o(t("a form meter progress dfn"),function(e){a[e]&&delete a[e].children[e]}),delete a.caption.children.table,r[e]=a,a)}var r={},i=e.makeMap,o=e.each,a=e.extend,s=e.explode,l=e.inArray;return function(e){function c(t,n,o){var s=e[t];return s?s=i(s,",",i(s.toUpperCase()," ")):(s=r[t],s||(s=i(n," ",i(n.toUpperCase()," ")),s=a(s,o),r[t]=s)),s}function u(e){return new RegExp("^"+e.replace(/([?+*])/g,".$1")+"$")}function d(e){var n,r,o,a,s,c,d,f,p,h,m,g,y,C,x,w,_,N,E,k=/^([#+\-])?([^\[!\/]+)(?:\/([^\[!]+))?(?:(!?)\[([^\]]+)\])?$/,S=/^([!\-])?(\w+::\w+|[^=:<]+)?(?:([=:<])(.*))?$/,T=/[*?+]/;if(e)for(e=t(e,","),v["@"]&&(w=v["@"].attributes,_=v["@"].attributesOrder),n=0,r=e.length;r>n;n++)if(s=k.exec(e[n])){if(C=s[1],p=s[2],x=s[3],f=s[5],g={},y=[],c={attributes:g,attributesOrder:y},"#"===C&&(c.paddEmpty=!0),"-"===C&&(c.removeEmpty=!0),"!"===s[4]&&(c.removeEmptyAttrs=!0),w){for(N in w)g[N]=w[N];y.push.apply(y,_)}if(f)for(f=t(f,"|"),o=0,a=f.length;a>o;o++)if(s=S.exec(f[o])){if(d={},m=s[1],h=s[2].replace(/::/g,":"),C=s[3],E=s[4],"!"===m&&(c.attributesRequired=c.attributesRequired||[],c.attributesRequired.push(h),d.required=!0),"-"===m){delete g[h],y.splice(l(y,h),1);continue}C&&("="===C&&(c.attributesDefault=c.attributesDefault||[],c.attributesDefault.push({name:h,value:E}),d.defaultValue=E),":"===C&&(c.attributesForced=c.attributesForced||[],c.attributesForced.push({name:h,value:E}),d.forcedValue=E),"<"===C&&(d.validValues=i(E,"?"))),T.test(h)?(c.attributePatterns=c.attributePatterns||[],d.pattern=u(h),c.attributePatterns.push(d)):(g[h]||y.push(h),g[h]=d)}w||"@"!=p||(w=g,_=y),x&&(c.outputName=p,v[x]=c),T.test(p)?(c.pattern=u(p),b.push(c)):v[p]=c}}function f(e){v={},b=[],d(e),o(x,function(e,t){y[t]=e.children})}function p(e){var n=/^(~)?(.+)$/;e&&o(t(e,","),function(e){var t=n.exec(e),r="~"===t[1],i=r?"span":"div",s=t[2];if(y[s]=y[i],R[s]=i,r||(k[s.toUpperCase()]={},k[s]={}),!v[s]){var l=v[i];l=a({},l),delete l.removeEmptyAttrs,delete l.removeEmpty,v[s]=l}o(y,function(e){e[i]&&(e[s]=e[i])})})}function h(e){var n=/^([+\-]?)(\w+)\[([^\]]+)\]$/;e&&o(t(e,","),function(e){var r=n.exec(e),i,a;r&&(a=r[1],i=a?y[r[2]]:y[r[2]]={"#comment":{}},i=y[r[2]],o(t(r[3],"|"),function(e){"-"===a?delete i[e]:i[e]={}}))})}function m(e){var t=v[e],n;if(t)return t;for(n=b.length;n--;)if(t=b[n],t.pattern.test(e))return t}var g=this,v={},y={},b=[],C,x,w,_,N,E,k,S,T,R={},A={};e=e||{},x=n(e.schema),e.verify_html===!1&&(e.valid_elements="*[*]"),e.valid_styles&&(C={},o(e.valid_styles,function(e,t){C[t]=s(e)})),w=c("whitespace_elements","pre script noscript style textarea video audio iframe object"),_=c("self_closing_elements","colgroup dd dt li option p td tfoot th thead tr"),N=c("short_ended_elements","area base basefont br col frame hr img input isindex link meta param embed source wbr track"),E=c("boolean_attributes","checked compact declare defer disabled ismap multiple nohref noresize noshade nowrap readonly selected autoplay loop controls"),S=c("non_empty_elements","td th iframe video audio object",N),T=c("text_block_elements","h1 h2 h3 h4 h5 h6 p div address pre form blockquote center dir fieldset header footer article section hgroup aside nav figure"),k=c("block_elements","hr table tbody thead tfoot th tr td li ol ul caption dl dt dd noscript menu isindex samp option datalist select optgroup",T),o((e.special||"script noscript style textarea").split(" "),function(e){A[e]=new RegExp("]*>","gi")}),e.valid_elements?f(e.valid_elements):(o(x,function(e,t){v[t]={attributes:e.attributes,attributesOrder:e.attributesOrder},y[t]=e.children}),"html5"!=e.schema&&o(t("strong/b em/i"),function(e){e=t(e,"/"),v[e[1]].outputName=e[0]}),v.img.attributesDefault=[{name:"alt",value:""}],o(t("ol ul sub sup blockquote span font a table tbody tr strong em b i"),function(e){v[e]&&(v[e].removeEmpty=!0)}),o(t("p h1 h2 h3 h4 h5 h6 th td pre div address caption"),function(e){v[e].paddEmpty=!0}),o(t("span"),function(e){v[e].removeEmptyAttrs=!0})),p(e.custom_elements),h(e.valid_children),d(e.extended_valid_elements),h("+ol[ul|ol],+ul[ul|ol]"),e.invalid_elements&&o(s(e.invalid_elements),function(e){v[e]&&delete v[e]}),m("span")||d("span[!data-mce-type|*]"),g.children=y,g.styles=C,g.getBoolAttrs=function(){return E},g.getBlockElements=function(){return k},g.getTextBlockElements=function(){return T},g.getShortEndedElements=function(){return N},g.getSelfClosingElements=function(){return _},g.getNonEmptyElements=function(){return S},g.getWhiteSpaceElements=function(){return w},g.getSpecialElements=function(){return A},g.isValidChild=function(e,t){var n=y[e];return!(!n||!n[t])},g.isValid=function(e,t){var n,r,i=m(e);if(i){if(!t)return!0;if(i.attributes[t])return!0;if(n=i.attributePatterns)for(r=n.length;r--;)if(n[r].pattern.test(e))return!0}return!1},g.getElementRule=m,g.getCustomElements=function(){return R},g.addValidElements=d,g.setValidElements=f,g.addCustomElements=p,g.addValidChildren=h,g.elements=v}}),r(w,[x,m,p],function(e,t,n){var r=n.each;return function(n,i){var o=this,a=function(){};n=n||{},o.schema=i=i||new e,n.fix_self_closing!==!1&&(n.fix_self_closing=!0),r("comment cdata text start end pi doctype".split(" "),function(e){e&&(o[e]=n[e]||a)}),o.parse=function(e){function r(e){var t,n;for(t=d.length;t--&&d[t].name!==e;);if(t>=0){for(n=d.length-1;n>=t;n--)e=d[n],e.valid&&a.end(e.name);d.length=t}}function o(e,t,n,r,i){var o,a;if(t=t.toLowerCase(),n=t in b?t:I(n||r||i||""),x&&!g&&0!==t.indexOf("data-")){if(o=k[t],!o&&S){for(a=S.length;a--&&(o=S[a],!o.pattern.test(t)););-1===a&&(o=null)}if(!o)return;if(o.validValues&&!(n in o.validValues))return}f.map[t]=n,f.push({name:t,value:n})}var a=this,s,l=0,c,u,d=[],f,p,h,m,g,v,y,b,C,x,w,_,N,E,k,S,T,R,A,B,D,H,L,M,P,O=0,I=t.decode,F;for(H=new RegExp("<(?:(?:!--([\\w\\W]*?)-->)|(?:!\\[CDATA\\[([\\w\\W]*?)\\]\\]>)|(?:!DOCTYPE([\\w\\W]*?)>)|(?:\\?([^\\s\\/<>]+) ?([\\w\\W]*?)[?/]>)|(?:\\/([^>]+)>)|(?:([A-Za-z0-9\\-\\:\\.]+)((?:\\s+[^\"'>]+(?:(?:\"[^\"]*\")|(?:'[^']*')|[^>]*))*|\\/|\\s+)>))","g"),L=/([\w:\-]+)(?:\s*=\s*(?:(?:\"((?:[^\"])*)\")|(?:\'((?:[^\'])*)\')|([^>\s]+)))?/g,y=i.getShortEndedElements(),D=n.self_closing_elements||i.getSelfClosingElements(),b=i.getBoolAttrs(),x=n.validate,v=n.remove_internals,F=n.fix_self_closing,M=i.getSpecialElements();s=H.exec(e);){if(l0&&d[d.length-1].name===c&&r(c),!x||(w=i.getElementRule(c))){if(_=!0,x&&(k=w.attributes,S=w.attributePatterns),(E=s[8])?(g=-1!==E.indexOf("data-mce-type"),g&&v&&(_=!1),f=[],f.map={},E.replace(L,o)):(f=[],f.map={}),x&&!g){if(T=w.attributesRequired,R=w.attributesDefault,A=w.attributesForced,B=w.removeEmptyAttrs,B&&!f.length&&(_=!1),A)for(p=A.length;p--;)N=A[p],m=N.name,P=N.value,"{$uid}"===P&&(P="mce_"+O++),f.map[m]=P,f.push({name:m,value:P});if(R)for(p=R.length;p--;)N=R[p],m=N.name,m in f.map||(P=N.value,"{$uid}"===P&&(P="mce_"+O++),f.map[m]=P,f.push({name:m,value:P}));if(T){for(p=T.length;p--&&!(T[p]in f.map););-1===p&&(_=!1)}f.map["data-mce-bogus"]&&(_=!1)}_&&a.start(c,f,C)}else _=!1;if(u=M[c]){u.lastIndex=l=s.index+s[0].length,(s=u.exec(e))?(_&&(h=e.substr(l,s.index-l)),l=s.index+s[0].length):(h=e.substr(l),l=e.length),_&&(h.length>0&&a.text(h,!0),a.end(c)),H.lastIndex=l;continue}C||(E&&E.indexOf("/")==E.length-1?_&&a.end(c):d.push({name:c,valid:_}))}else(c=s[1])?a.comment(c):(c=s[2])?a.cdata(c):(c=s[3])?a.doctype(c):(c=s[4])&&a.pi(c,s[5]);l=s.index+s[0].length}for(l=0;p--)c=d[p],c.valid&&a.end(c.name)}}}),r(_,[C,x,w,p],function(e,t,n,r){var i=r.makeMap,o=r.each,a=r.explode,s=r.extend;return function(r,l){function c(t){var n,r,o,a,s,c,d,f,p,h,m,g,v,y;for(m=i("tr,td,th,tbody,thead,tfoot,table"),h=l.getNonEmptyElements(),g=l.getTextBlockElements(),n=0;n1){for(a.reverse(),s=c=u.filterNode(a[0].clone()),p=0;p0?(t.value=n,t=t.prev):(r=t.prev,t.remove(),t=r)}function g(e){var t,n={};for(t in e)"li"!==t&&"p"!=t&&(n[t]=e[t]);return n}var v,y,b,C,x,w,_,N,E,k,S,T,R,A=[],B,D,H,L,M,P,O,I;if(o=o||{},p={},h={},T=s(i("script,style,head,html,body,title,meta,param"),l.getBlockElements()),O=l.getNonEmptyElements(),P=l.children,S=r.validate,I="forced_root_block"in o?o.forced_root_block:r.forced_root_block,M=l.getWhiteSpaceElements(),R=/^[ \t\r\n]+/,D=/[ \t\r\n]+$/,H=/[ \t\r\n]+/g,L=/^[ \t\r\n]+$/,v=new n({validate:S,self_closing_elements:g(l.getSelfClosingElements()),cdata:function(e){b.append(u("#cdata",4)).value=e},text:function(e,t){var n;B||(e=e.replace(H," "),b.lastChild&&T[b.lastChild.name]&&(e=e.replace(R,""))),0!==e.length&&(n=u("#text",3),n.raw=!!t,b.append(n).value=e)},comment:function(e){b.append(u("#comment",8)).value=e},pi:function(e,t){b.append(u(e,7)).value=t,m(b)},doctype:function(e){var t;t=b.append(u("#doctype",10)),t.value=e,m(b)},start:function(e,t,n){var r,i,o,a,s;if(o=S?l.getElementRule(e):{}){for(r=u(o.outputName||e,1),r.attributes=t,r.shortEnded=n,b.append(r),s=P[b.name],s&&P[r.name]&&!s[r.name]&&A.push(r),i=f.length;i--;)a=f[i].name,a in t.map&&(E=h[a],E?E.push(r):h[a]=[r]);T[e]&&m(r),n||(b=r),!B&&M[e]&&(B=!0)}},end:function(t){var n,r,i,o,a;if(r=S?l.getElementRule(t):{}){if(T[t]&&!B){if(n=b.firstChild,n&&3===n.type)if(i=n.value.replace(R,""),i.length>0)n.value=i,n=n.next;else for(o=n.next,n.remove(),n=o;n&&3===n.type;)i=n.value,o=n.next,(0===i.length||L.test(i))&&(n.remove(),n=o),n=o;if(n=b.lastChild,n&&3===n.type)if(i=n.value.replace(D,""),i.length>0)n.value=i,n=n.prev;else for(o=n.prev,n.remove(),n=o;n&&3===n.type;)i=n.value,o=n.prev,(0===i.length||L.test(i))&&(n.remove(),n=o),n=o}if(B&&M[t]&&(B=!1),(r.removeEmpty||r.paddEmpty)&&b.isEmpty(O))if(r.paddEmpty)b.empty().append(new e("#text","3")).value="\xa0";else if(!b.attributes.map.name&&!b.attributes.map.id)return a=b.parent,b.empty().remove(),b=a,void 0;b=b.parent}}},l),y=b=new e(o.context||r.root_name,11),v.parse(t),S&&A.length&&(o.context?o.invalid=!0:c(A)),I&&("body"==y.name||o.isRootContent)&&a(),!o.invalid){for(k in p){for(E=d[k],C=p[k],_=C.length;_--;)C[_].parent||C.splice(_,1);for(x=0,w=E.length;w>x;x++)E[x](C,k,o)}for(x=0,w=f.length;w>x;x++)if(E=f[x],E.name in h){for(C=h[E.name],_=C.length;_--;)C[_].parent||C.splice(_,1);for(_=0,N=E.callbacks.length;N>_;_++)E.callbacks[_](C,E.name,o)}}return y},r.remove_trailing_brs&&u.addNodeFilter("br",function(t){var n,r=t.length,i,o=s({},l.getBlockElements()),a=l.getNonEmptyElements(),c,u,d,f,p,h;for(o.body=1,n=0;r>n;n++)if(i=t[n],c=i.parent,o[i.parent.name]&&i===c.lastChild){for(d=i.prev;d;){if(f=d.name,"span"!==f||"bookmark"!==d.attr("data-mce-type")){if("br"!==f)break;if("br"===f){i=null;break}}d=d.prev}i&&(i.remove(),c.isEmpty(a)&&(p=l.getElementRule(c.name),p&&(p.removeEmpty?c.remove():p.paddEmpty&&(c.empty().append(new e("#text",3)).value="\xa0"))))}else{for(u=i;c&&c.firstChild===u&&c.lastChild===u&&(u=c,!o[c.name]);)c=c.parent;u===c&&(h=new e("#text",3),h.value="\xa0",i.replace(h))}}),r.allow_html_in_named_anchor||u.addAttributeFilter("id,name",function(e){for(var t=e.length,n,r,i,o;t--;)if(o=e[t],"a"===o.name&&o.firstChild&&!o.attr("href")){i=o.parent,n=o.lastChild;do r=n.prev,i.insert(n,o),n=r;while(n)}})}}),r(N,[m,p],function(e,t){var n=t.makeMap;return function(t){var r=[],i,o,a,s,l;return t=t||{},i=t.indent,o=n(t.indent_before||""),a=n(t.indent_after||""),s=e.getEncodeFunc(t.entity_encoding||"raw",t.entities),l="html"==t.element_format,{start:function(e,t,n){var c,u,d,f;if(i&&o[e]&&r.length>0&&(f=r[r.length-1],f.length>0&&"\n"!==f&&r.push("\n")),r.push("<",e),t)for(c=0,u=t.length;u>c;c++)d=t[c],r.push(" ",d.name,'="',s(d.value,!0),'"');r[r.length]=!n||l?">":" />",n&&i&&a[e]&&r.length>0&&(f=r[r.length-1],f.length>0&&"\n"!==f&&r.push("\n"))},end:function(e){var t;r.push(""),i&&a[e]&&r.length>0&&(t=r[r.length-1],t.length>0&&"\n"!==t&&r.push("\n"))},text:function(e,t){e.length>0&&(r[r.length]=t?e:s(e))},cdata:function(e){r.push("")},comment:function(e){r.push("")},pi:function(e,t){t?r.push(""):r.push(""),i&&r.push("\n")},doctype:function(e){r.push("",i?"\n":"")},reset:function(){r.length=0},getContent:function(){return r.join("").replace(/\n$/,"")}}}}),r(E,[N,x],function(e,t){return function(n,r){var i=this,o=new e(n);n=n||{},n.validate="validate"in n?n.validate:!0,i.schema=r=r||new t,i.writer=o,i.serialize=function(e){function t(e){var n=i[e.type],s,l,c,u,d,f,p,h,m;if(n)n(e);else{if(s=e.name,l=e.shortEnded,c=e.attributes,a&&c&&c.length>1){for(f=[],f.map={},m=r.getElementRule(e.name),p=0,h=m.attributesOrder.length;h>p;p++)u=m.attributesOrder[p],u in c.map&&(d=c.map[u],f.map[u]=d,f.push({name:u,value:d}));for(p=0,h=c.length;h>p;p++)u=c[p].name,u in f.map||(d=c.map[u],f.map[u]=d,f.push({name:u,value:d}));c=f}if(o.start(e.name,c,l),!l){if(e=e.firstChild)do t(e);while(e=e.next);o.end(s)}}}var i,a;return a=n.validate,i={3:function(e){o.text(e.value,e.raw)},8:function(e){o.comment(e.value)},7:function(e){o.pi(e.name,e.value)},10:function(e){o.doctype(e.value)},4:function(e){o.cdata(e.value)},11:function(e){if(e=e.firstChild)do t(e);while(e=e.next)}},o.reset(),1!=e.type||n.inner?i[11](e):t(e),o.getContent()}}}),r(k,[v,_,m,E,C,x,g,p],function(e,t,n,r,i,o,a,s){var l=s.each,c=s.trim,u=e.DOM;return function(e,i){var s,d,f;return i&&(s=i.dom,d=i.schema),s=s||u,d=d||new o(e),e.entity_encoding=e.entity_encoding||"named",e.remove_trailing_brs="remove_trailing_brs"in e?e.remove_trailing_brs:!0,f=new t(e,d),f.addAttributeFilter("src,href,style",function(t,n){for(var r=t.length,i,o,a="data-mce-"+n,l=e.url_converter,c=e.url_converter_scope,u;r--;)i=t[r],o=i.attributes.map[a],o!==u?(i.attr(n,o.length>0?o:null),i.attr(a,null)):(o=i.attributes.map[n],"style"===n?o=s.serializeStyle(s.parseStyle(o),i.name):l&&(o=l.call(c,o,n,i.name)),i.attr(n,o.length>0?o:null))}),f.addAttributeFilter("class",function(e){for(var t=e.length,n,r;t--;)n=e[t],r=n.attr("class").replace(/(?:^|\s)mce-item-\w+(?!\S)/g,""),n.attr("class",r.length>0?r:null)}),f.addAttributeFilter("data-mce-type",function(e,t,n){for(var r=e.length,i;r--;)i=e[r],"bookmark"!==i.attributes.map["data-mce-type"]||n.cleanup||i.remove()}),f.addAttributeFilter("data-mce-expando",function(e,t){for(var n=e.length;n--;)e[n].attr(t,null)}),f.addNodeFilter("noscript",function(e){for(var t=e.length,r;t--;)r=e[t].firstChild,r&&(r.value=n.decode(r.value))}),f.addNodeFilter("script,style",function(e,t){function n(e){return e.replace(/()/g,"\n").replace(/^[\r\n]*|[\r\n]*$/g,"").replace(/^\s*(()?|\s*\/\/\s*\]\]>(-->)?|\/\/\s*(-->)?|\]\]>|\/\*\s*-->\s*\*\/|\s*-->\s*)\s*$/g,"")}for(var r=e.length,i,o;r--;)if(i=e[r],o=i.firstChild?i.firstChild.value:"","script"===t){var a=(i.attr("type")||"text/javascript").replace(/^mce\-/,"");i.attr("type","text/javascript"===a?null:a),o.length>0&&(i.firstChild.value="// ")}else o.length>0&&(i.firstChild.value="")}),f.addNodeFilter("#comment",function(e){for(var t=e.length,n;t--;)n=e[t],0===n.value.indexOf("[CDATA[")?(n.name="#cdata",n.type=4,n.value=n.value.replace(/^\[CDATA\[|\]\]$/g,"")):0===n.value.indexOf("mce:protected ")&&(n.name="#text",n.type=3,n.raw=!0,n.value=unescape(n.value).substr(14))}),f.addNodeFilter("xml:namespace,input",function(e,t){for(var n=e.length,r;n--;)r=e[n],7===r.type?r.remove():1===r.type&&("input"!==t||"type"in r.attributes.map||r.attr("type","text"))}),e.fix_list_elements&&f.addNodeFilter("ul,ol",function(e){for(var t=e.length,n,r;t--;)n=e[t],r=n.parent,("ul"===r.name||"ol"===r.name)&&n.prev&&"li"===n.prev.name&&n.prev.append(n)}),f.addAttributeFilter("data-mce-src,data-mce-href,data-mce-style,data-mce-selected",function(e,t){for(var n=e.length;n--;)e[n].attr(t,null)}),{schema:d,addNodeFilter:f.addNodeFilter,addAttributeFilter:f.addAttributeFilter,serialize:function(t,n){var i=this,o,u,p,h,m;return a.ie&&s.select("script,style,select,map").length>0?(m=t.innerHTML,t=t.cloneNode(!1),s.setHTML(t,m)):t=t.cloneNode(!0),o=t.ownerDocument.implementation,o.createHTMLDocument&&(u=o.createHTMLDocument(""),l("BODY"==t.nodeName?t.childNodes:[t],function(e){u.body.appendChild(u.importNode(e,!0))}),t="BODY"!=t.nodeName?u.body.firstChild:u.body,p=s.doc,s.doc=u),n=n||{},n.format=n.format||"html",n.selection&&(n.forced_root_block=""),n.no_events||(n.node=t,i.onPreProcess(n)),h=new r(e,d),n.content=h.serialize(f.parse(c(n.getInner?t.innerHTML:s.getOuterHTML(t)),n)),n.cleanup||(n.content=n.content.replace(/\uFEFF/g,"")),n.no_events||i.onPostProcess(n),p&&(s.doc=p),n.node=null,n.content},addRules:function(e){d.addValidElements(e)},setRules:function(e){d.setValidElements(e)},onPreProcess:function(e){i&&i.fire("PreProcess",e)},onPostProcess:function(e){i&&i.fire("PostProcess",e)}}}}),r(S,[],function(){function e(e){function t(t,n){var r,i=0,o,a,s,l,c,u,d=-1,f;if(r=t.duplicate(),r.collapse(n),f=r.parentElement(),f.ownerDocument===e.dom.doc){for(;"false"===f.contentEditable;)f=f.parentNode;if(!f.hasChildNodes())return{node:f,inside:1};for(s=f.children,o=s.length-1;o>=i;)if(u=Math.floor((i+o)/2),l=s[u],r.moveToElementText(l),d=r.compareEndPoints(n?"StartToStart":"EndToEnd",t),d>0)o=u-1;else{if(!(0>d))return{node:l};i=u+1}if(0>d)for(l?r.collapse(!1):(r.moveToElementText(f),r.collapse(!0),l=f,a=!0),c=0;0!==r.compareEndPoints(n?"StartToStart":"StartToEnd",t)&&0!==r.move("character",1)&&f==r.parentElement();)c++;else for(r.collapse(!0),c=0;0!==r.compareEndPoints(n?"StartToStart":"StartToEnd",t)&&0!==r.move("character",-1)&&f==r.parentElement();)c++;return{node:l,position:d,offset:c,inside:a}}}function n(){function n(e){var n=t(o,e),r,i,s=0,l,c,u;if(r=n.node,i=n.offset,n.inside&&!r.hasChildNodes())return a[e?"setStart":"setEnd"](r,0),void 0;if(i===c)return a[e?"setStartBefore":"setEndAfter"](r),void 0;if(n.position<0){if(l=n.inside?r.firstChild:r.nextSibling,!l)return a[e?"setStartAfter":"setEndAfter"](r),void 0;if(!i)return 3==l.nodeType?a[e?"setStart":"setEnd"](l,0):a[e?"setStartBefore":"setEndBefore"](l),void 0;for(;l;){if(u=l.nodeValue,s+=u.length,s>=i){r=l,s-=i,s=u.length-s;break}l=l.nextSibling}}else{if(l=r.previousSibling,!l)return a[e?"setStartBefore":"setEndBefore"](r);if(!i)return 3==r.nodeType?a[e?"setStart":"setEnd"](l,r.nodeValue.length):a[e?"setStartAfter":"setEndAfter"](l),void 0;for(;l;){if(s+=l.nodeValue.length,s>=i){r=l,s-=i;break}l=l.previousSibling}}a[e?"setStart":"setEnd"](r,s)}var o=e.getRng(),a=i.createRng(),s,l,c,u,d;if(s=o.item?o.item(0):o.parentElement(),s.ownerDocument!=i.doc)return a;if(l=e.isCollapsed(),o.item)return a.setStart(s.parentNode,i.nodeIndex(s)),a.setEnd(a.startContainer,a.startOffset+1),a;try{n(!0),l||n()}catch(f){if(-2147024809!=f.number)throw f;d=r.getBookmark(2),c=o.duplicate(),c.collapse(!0),s=c.parentElement(),l||(c=o.duplicate(),c.collapse(!1),u=c.parentElement(),u.innerHTML=u.innerHTML),s.innerHTML=s.innerHTML,r.moveToBookmark(d),o=e.getRng(),n(!0),l||n()}return a}var r=this,i=e.dom,o=!1;this.getBookmark=function(n){function r(e){var t,n,r,o,a=[];for(t=e.parentNode,n=i.getRoot().parentNode;t!=n&&9!==t.nodeType;){for(r=t.children,o=r.length;o--;)if(e===r[o]){a.push(o);break}e=t,t=t.parentNode}return a}function o(e){var n;return n=t(a,e),n?{position:n.position,offset:n.offset,indexes:r(n.node),inside:n.inside}:void 0}var a=e.getRng(),s={};return 2===n&&(a.item?s.start={ctrl:!0,indexes:r(a.item(0))}:(s.start=o(!0),e.isCollapsed()||(s.end=o()))),s},this.moveToBookmark=function(e){function t(e){var t,n,r,o;for(t=i.getRoot(),n=e.length-1;n>=0;n--)o=t.children,r=e[n],r<=o.length-1&&(t=o[r]);return t}function n(n){var i=e[n?"start":"end"],a,s,l,c;i&&(a=i.position>0,s=o.createTextRange(),s.moveToElementText(t(i.indexes)),c=i.offset,c!==l?(s.collapse(i.inside||a),s.moveStart("character",a?-c:c)):s.collapse(n),r.setEndPoint(n?"StartToStart":"EndToStart",s),n&&r.collapse(!0)) +}var r,o=i.doc.body;e.start&&(e.start.ctrl?(r=o.createControlRange(),r.addElement(t(e.start.indexes)),r.select()):(r=o.createTextRange(),n(!0),n(),r.select()))},this.addRange=function(t){function n(e){var t,n,a,d,h;a=i.create("a"),t=e?s:c,n=e?l:u,d=r.duplicate(),(t==f||t==f.documentElement)&&(t=p,n=0),3==t.nodeType?(t.parentNode.insertBefore(a,t),d.moveToElementText(a),d.moveStart("character",n),i.remove(a),r.setEndPoint(e?"StartToStart":"EndToEnd",d)):(h=t.childNodes,h.length?(n>=h.length?i.insertAfter(a,h[h.length-1]):t.insertBefore(a,h[n]),d.moveToElementText(a)):t.canHaveHTML&&(t.innerHTML="",a=t.firstChild,d.moveToElementText(a),d.collapse(o)),r.setEndPoint(e?"StartToStart":"EndToEnd",d),i.remove(a))}var r,a,s,l,c,u,d,f=e.dom.doc,p=f.body,h,m;if(s=t.startContainer,l=t.startOffset,c=t.endContainer,u=t.endOffset,r=p.createTextRange(),s==c&&1==s.nodeType){if(l==u&&!s.hasChildNodes()){if(s.canHaveHTML)return d=s.previousSibling,d&&!d.hasChildNodes()&&i.isBlock(d)?d.innerHTML="":d=null,s.innerHTML="",r.moveToElementText(s.lastChild),r.select(),i.doc.selection.clear(),s.innerHTML="",d&&(d.innerHTML=""),void 0;l=i.nodeIndex(s),s=s.parentNode}if(l==u-1)try{if(m=s.childNodes[l],a=p.createControlRange(),a.addElement(m),a.select(),h=e.getRng(),h.item&&m===h.item(0))return}catch(g){}}n(!0),n(),r.select()},this.getRangeAt=n}return e}),r(T,[g],function(e){return{BACKSPACE:8,DELETE:46,DOWN:40,ENTER:13,LEFT:37,RIGHT:39,SPACEBAR:32,TAB:9,UP:38,modifierPressed:function(e){return e.shiftKey||e.ctrlKey||e.altKey},metaKeyPressed:function(t){return(e.mac?t.ctrlKey||t.metaKey:t.ctrlKey)&&!t.altKey}}}),r(R,[T,p,g],function(e,t,n){return function(r,i){function o(e){return i.settings.object_resizing===!1?!1:/TABLE|IMG|DIV/.test(e.nodeName)?"false"===e.getAttribute("data-mce-resize")?!1:!0:!1}function a(t){var n,r;n=t.screenX-k,r=t.screenY-S,L=n*N[2]+A,M=r*N[3]+B,L=5>L?5:L,M=5>M?5:M,(e.modifierPressed(t)||"IMG"==x.nodeName&&0!==N[2]*N[3])&&(L=Math.round(M/D),M=Math.round(L*D)),b.setStyles(w,{width:L,height:M}),N[2]<0&&w.clientWidth<=L&&b.setStyle(w,"left",T+(A-L)),N[3]<0&&w.clientHeight<=M&&b.setStyle(w,"top",R+(B-M)),H||(i.fire("ObjectResizeStart",{target:x,width:A,height:B}),H=!0)}function s(){function e(e,t){t&&(x.style[e]||!i.schema.isValid(x.nodeName.toLowerCase(),e)?b.setStyle(x,e,t):b.setAttrib(x,e,t))}H=!1,e("width",L),e("height",M),b.unbind(P,"mousemove",a),b.unbind(P,"mouseup",s),O!=P&&(b.unbind(O,"mousemove",a),b.unbind(O,"mouseup",s)),b.remove(w),I&&"TABLE"!=x.nodeName||l(x),i.fire("ObjectResized",{target:x,width:L,height:M}),i.nodeChanged()}function l(e,t,n){var r,l,u,d,f,p=i.getBody().offsetParent||i.getBody();r=b.getPos(e,p),T=r.x,R=r.y,f=e.getBoundingClientRect(),l=f.width||f.right-f.left,u=f.height||f.bottom-f.top,x!=e&&(m(),x=e,L=M=0),d=i.fire("ObjectSelected",{target:e}),o(e)&&!d.isDefaultPrevented()?C(_,function(e,r){function o(t){H=!0,k=t.screenX,S=t.screenY,A=x.clientWidth,B=x.clientHeight,D=B/A,N=e,w=x.cloneNode(!0),b.addClass(w,"mce-clonedresizable"),w.contentEditable=!1,w.unSelectabe=!0,b.setStyles(w,{left:T,top:R,margin:0}),w.removeAttribute("data-mce-selected"),i.getBody().appendChild(w),b.bind(P,"mousemove",a),b.bind(P,"mouseup",s),O!=P&&(b.bind(O,"mousemove",a),b.bind(O,"mouseup",s))}var c,d;return t?(r==t&&o(n),void 0):(c=b.get("mceResizeHandle"+r),c?b.show(c):(d=i.getBody(),c=b.add(d,"div",{id:"mceResizeHandle"+r,"data-mce-bogus":!0,"class":"mce-resizehandle",contentEditable:!1,unSelectabe:!0,style:"cursor:"+r+"-resize; margin:0; padding:0"}),b.bind(c,"mousedown",function(e){e.preventDefault(),o(e)})),b.setStyles(c,{left:l*e[0]+T-c.offsetWidth/2,top:u*e[1]+R-c.offsetHeight/2}),void 0)}):c(),x.setAttribute("data-mce-selected","1")}function c(){var e,t;x&&x.removeAttribute("data-mce-selected");for(e in _)t=b.get("mceResizeHandle"+e),t&&(b.unbind(t),b.remove(t))}function u(e){function t(e,t){do if(e===t)return!0;while(e=e.parentNode)}var n;return C(b.select("img[data-mce-selected],hr[data-mce-selected]"),function(e){e.removeAttribute("data-mce-selected")}),n="mousedown"==e.type?e.target:r.getNode(),n=b.getParent(n,I?"table":"table,img,hr"),n&&(g(),t(r.getStart(),n)&&t(r.getEnd(),n)&&(!I||n!=r.getStart()&&"IMG"!==r.getStart().nodeName))?(l(n),void 0):(c(),void 0)}function d(e,t,n){e&&e.attachEvent&&e.attachEvent("on"+t,n)}function f(e,t,n){e&&e.detachEvent&&e.detachEvent("on"+t,n)}function p(e){var t=e.srcElement,n,r,o,a,s,c,u;n=t.getBoundingClientRect(),c=E.clientX-n.left,u=E.clientY-n.top;for(r in _)if(o=_[r],a=t.offsetWidth*o[0],s=t.offsetHeight*o[1],Math.abs(a-c)<8&&Math.abs(s-u)<8){N=o;break}H=!0,i.getDoc().selection.empty(),l(t,r,E)}function h(e){var t=e.srcElement;if(t!=x){if(m(),0===t.id.indexOf("mceResizeHandle"))return e.returnValue=!1,void 0;("IMG"==t.nodeName||"TABLE"==t.nodeName)&&(c(),x=t,d(t,"resizestart",p))}}function m(){f(x,"resizestart",p)}function g(){try{i.getDoc().execCommand("enableObjectResizing",!1,!1)}catch(e){}}function v(e){var t;if(I){t=P.body.createControlRange();try{return t.addElement(e),t.select(),!0}catch(n){}}}function y(){x=w=null,I&&(m(),f(i.getBody(),"controlselect",h))}var b=i.dom,C=t.each,x,w,_,N,E,k,S,T,R,A,B,D,H,L,M,P=i.getDoc(),O=document,I=n.ie&&n.ie<11;_={n:[.5,0,0,-1],e:[1,.5,1,0],s:[.5,1,0,1],w:[0,.5,-1,0],nw:[0,0,-1,-1],ne:[1,0,1,-1],se:[1,1,1,1],sw:[0,1,-1,1]};var F=".mce-content-body";return i.contentStyles.push(F+" div.mce-resizehandle {"+"position: absolute;"+"border: 1px solid black;"+"background: #FFF;"+"width: 5px;"+"height: 5px;"+"z-index: 10000"+"}"+F+" .mce-resizehandle:hover {"+"background: #000"+"}"+F+" img[data-mce-selected], hr[data-mce-selected] {"+"outline: 1px solid black;"+"resize: none"+"}"+F+" .mce-clonedresizable {"+"position: absolute;"+(n.gecko?"":"outline: 1px dashed black;")+"opacity: .5;"+"filter: alpha(opacity=50);"+"z-index: 10000"+"}"),i.on("init",function(){I?(i.on("ObjectResized",function(e){"TABLE"!=e.target.nodeName&&(c(),v(e.target))}),d(i.getBody(),"controlselect",h),i.on("mousedown",function(e){E=e})):(g(),n.ie>=11&&i.on("mouseup mousedown",function(e){("IMG"==e.target.nodeName||"IMG"==i.selection.getNode().nodeName)&&(e.preventDefault(),i.selection.select(e.target))})),i.on("nodechange mousedown ResizeEditor",u),i.on("keydown keyup",function(e){x&&"TABLE"==x.nodeName&&u(e)})}),{controlSelect:v,destroy:y}}}),r(A,[f,S,R,g,p],function(e,n,r,i,o){function a(e,t,i,o){var a=this;a.dom=e,a.win=t,a.serializer=i,a.editor=o,a.controlSelection=new r(a,o),a.win.getSelection||(a.tridentSel=new n(a))}var s=o.each,l=o.grep,c=o.trim,u=i.ie,d=i.opera;return a.prototype={setCursorLocation:function(e,t){var n=this,r=n.dom.createRng();r.setStart(e,t),r.setEnd(e,t),n.setRng(r),n.collapse(!1)},getContent:function(e){var n=this,r=n.getRng(),i=n.dom.create("body"),o=n.getSel(),a,s,l;return e=e||{},a=s="",e.get=!0,e.format=e.format||"html",e.selection=!0,n.editor.fire("BeforeGetContent",e),"text"==e.format?n.isCollapsed()?"":r.text||(o.toString?o.toString():""):(r.cloneContents?(l=r.cloneContents(),l&&i.appendChild(l)):r.item!==t||r.htmlText!==t?(i.innerHTML="
    "+(r.item?r.item(0).outerHTML:r.htmlText),i.removeChild(i.firstChild)):i.innerHTML=r.toString(),/^\s/.test(i.innerHTML)&&(a=" "),/\s+$/.test(i.innerHTML)&&(s=" "),e.getInner=!0,e.content=n.isCollapsed()?"":a+n.serializer.serialize(i,e)+s,n.editor.fire("GetContent",e),e.content)},setContent:function(e,t){var n=this,r=n.getRng(),i,o=n.win.document,a,s;if(t=t||{format:"html"},t.set=!0,t.selection=!0,e=t.content=e,t.no_events||n.editor.fire("BeforeSetContent",t),e=t.content,r.insertNode){e+='_',r.startContainer==o&&r.endContainer==o?o.body.innerHTML=e:(r.deleteContents(),0===o.body.childNodes.length?o.body.innerHTML=e:r.createContextualFragment?r.insertNode(r.createContextualFragment(e)):(a=o.createDocumentFragment(),s=o.createElement("div"),a.appendChild(s),s.outerHTML=e,r.insertNode(a))),i=n.dom.get("__caret"),r=o.createRange(),r.setStartBefore(i),r.setEndBefore(i),n.setRng(r),n.dom.remove("__caret");try{n.setRng(r)}catch(l){}}else r.item&&(o.execCommand("Delete",!1,null),r=n.getRng()),/^\s+/.test(e)?(r.pasteHTML('_'+e),n.dom.remove("__mce_tmp")):r.pasteHTML(e);t.no_events||n.editor.fire("SetContent",t)},getStart:function(){var e=this,t=e.getRng(),n,r,i,o;if(t.duplicate||t.item){if(t.item)return t.item(0);for(i=t.duplicate(),i.collapse(1),n=i.parentElement(),n.ownerDocument!==e.dom.doc&&(n=e.dom.getRoot()),r=o=t.parentElement();o=o.parentNode;)if(o==n){n=r;break}return n}return n=t.startContainer,1==n.nodeType&&n.hasChildNodes()&&(n=n.childNodes[Math.min(n.childNodes.length-1,t.startOffset)]),n&&3==n.nodeType?n.parentNode:n},getEnd:function(){var e=this,t=e.getRng(),n,r;return t.duplicate||t.item?t.item?t.item(0):(t=t.duplicate(),t.collapse(0),n=t.parentElement(),n.ownerDocument!==e.dom.doc&&(n=e.dom.getRoot()),n&&"BODY"==n.nodeName?n.lastChild||n:n):(n=t.endContainer,r=t.endOffset,1==n.nodeType&&n.hasChildNodes()&&(n=n.childNodes[r>0?r-1:r]),n&&3==n.nodeType?n.parentNode:n)},getBookmark:function(e,t){function n(e,t){var n=0;return s(a.select(e),function(e,r){e==t&&(n=r)}),n}function r(e){function t(t){var n,r,i,o=t?"start":"end";n=e[o+"Container"],r=e[o+"Offset"],1==n.nodeType&&"TR"==n.nodeName&&(i=n.childNodes,n=i[Math.min(t?r:r-1,i.length-1)],n&&(r=t?0:n.childNodes.length,e["set"+(t?"Start":"End")](n,r)))}return t(!0),t(),e}function i(){function e(e,n){var i=e[n?"startContainer":"endContainer"],a=e[n?"startOffset":"endOffset"],s=[],l,c,u=0;if(3==i.nodeType){if(t)for(l=i.previousSibling;l&&3==l.nodeType;l=l.previousSibling)a+=l.nodeValue.length;s.push(a)}else c=i.childNodes,a>=c.length&&c.length&&(u=1,a=Math.max(0,c.length-1)),s.push(o.dom.nodeIndex(c[a],t)+u);for(;i&&i!=r;i=i.parentNode)s.push(o.dom.nodeIndex(i,t));return s}var n=o.getRng(!0),r=a.getRoot(),i={};return i.start=e(n,!0),o.isCollapsed()||(i.end=e(n)),i}var o=this,a=o.dom,l,c,u,d,f,p,h="",m;if(2==e)return p=o.getNode(),f=p.nodeName,"IMG"==f?{name:f,index:n(f,p)}:o.tridentSel?o.tridentSel.getBookmark(e):i();if(e)return{rng:o.getRng()};if(l=o.getRng(),u=a.uniqueId(),d=o.isCollapsed(),m="overflow:hidden;line-height:0px",l.duplicate||l.item){if(l.item)return p=l.item(0),f=p.nodeName,{name:f,index:n(f,p)};c=l.duplicate();try{l.collapse(),l.pasteHTML(''+h+""),d||(c.collapse(!1),l.moveToElementText(c.parentElement()),0===l.compareEndPoints("StartToEnd",c)&&c.move("character",-1),c.pasteHTML(''+h+""))}catch(g){return null}}else{if(p=o.getNode(),f=p.nodeName,"IMG"==f)return{name:f,index:n(f,p)};c=r(l.cloneRange()),d||(c.collapse(!1),c.insertNode(a.create("span",{"data-mce-type":"bookmark",id:u+"_end",style:m},h))),l=r(l),l.collapse(!0),l.insertNode(a.create("span",{"data-mce-type":"bookmark",id:u+"_start",style:m},h))}return o.moveToBookmark({id:u,keep:1}),{id:u}},moveToBookmark:function(e){function t(t){var n=e[t?"start":"end"],r,i,o,s;if(n){for(o=n[0],i=c,r=n.length-1;r>=1;r--){if(s=i.childNodes,n[r]>s.length-1)return;i=s[n[r]]}3===i.nodeType&&(o=Math.min(n[0],i.nodeValue.length)),1===i.nodeType&&(o=Math.min(n[0],i.childNodes.length)),t?a.setStart(i,o):a.setEnd(i,o)}return!0}function n(t){var n=o.get(e.id+"_"+t),r,i,a,c,u=e.keep;if(n&&(r=n.parentNode,"start"==t?(u?(r=n.firstChild,i=1):i=o.nodeIndex(n),f=p=r,h=m=i):(u?(r=n.firstChild,i=1):i=o.nodeIndex(n),p=r,m=i),!u)){for(c=n.previousSibling,a=n.nextSibling,s(l(n.childNodes),function(e){3==e.nodeType&&(e.nodeValue=e.nodeValue.replace(/\uFEFF/g,""))});n=o.get(e.id+"_"+t);)o.remove(n,1);c&&a&&c.nodeType==a.nodeType&&3==c.nodeType&&!d&&(i=c.nodeValue.length,c.appendData(a.nodeValue),o.remove(a),"start"==t?(f=p=c,h=m=i):(p=c,m=i))}}function r(e){return!o.isBlock(e)||e.innerHTML||u||(e.innerHTML='
    '),e}var i=this,o=i.dom,a,c,f,p,h,m;if(e)if(e.start){if(a=o.createRng(),c=o.getRoot(),i.tridentSel)return i.tridentSel.moveToBookmark(e);t(!0)&&t()&&i.setRng(a)}else e.id?(n("start"),n("end"),f&&(a=o.createRng(),a.setStart(r(f),h),a.setEnd(r(p),m),i.setRng(a))):e.name?i.select(o.select(e.name)[e.index]):e.rng&&i.setRng(e.rng)},select:function(t,n){function r(t,n){var r=t,i=new e(t,r);do{if(3==t.nodeType&&0!==c(t.nodeValue).length)return n?a.setStart(t,0):a.setEnd(t,t.nodeValue.length),void 0;if(l[t.nodeName])return n?a.setStartBefore(t):"BR"==t.nodeName?a.setEndBefore(t):a.setEndAfter(t),void 0}while(t=n?i.next():i.prev());"BODY"==r.nodeName&&(n?a.setStart(r,0):a.setEnd(r,r.childNodes.length))}var i=this,o=i.dom,a=o.createRng(),s,l;if(i.lastFocusBookmark=null,l=o.schema.getNonEmptyElements(),t){if(!n&&i.controlSelection.controlSelect(t))return;s=o.nodeIndex(t),a.setStart(t.parentNode,s),a.setEnd(t.parentNode,s+1),n&&(r(t,1),r(t)),i.setRng(a)}return t},isCollapsed:function(){var e=this,t=e.getRng(),n=e.getSel();return!t||t.item?!1:t.compareEndPoints?0===t.compareEndPoints("StartToEnd",t):!n||t.collapsed},collapse:function(e){var t=this,n=t.getRng(),r;n.item&&(r=n.item(0),n=t.win.document.body.createTextRange(),n.moveToElementText(r)),n.collapse(!!e),t.setRng(n)},getSel:function(){var e=this.win;return e.getSelection?e.getSelection():e.document.selection},getRng:function(e){var t=this,n,r,i,o=t.win.document,a;if(!e&&t.lastFocusBookmark){var s=t.lastFocusBookmark;return s.startContainer?(r=o.createRange(),r.setStart(s.startContainer,s.startOffset),r.setEnd(s.endContainer,s.endOffset)):r=s,r}if(e&&t.tridentSel)return t.tridentSel.getRangeAt(0);try{(n=t.getSel())&&(r=n.rangeCount>0?n.getRangeAt(0):n.createRange?n.createRange():o.createRange())}catch(l){}if(u&&r&&r.setStart){try{a=o.selection.createRange()}catch(l){}a&&a.item&&(i=a.item(0),r=o.createRange(),r.setStartBefore(i),r.setEndAfter(i))}return r||(r=o.createRange?o.createRange():o.body.createTextRange()),r.setStart&&9===r.startContainer.nodeType&&r.collapsed&&(i=t.dom.getRoot(),r.setStart(i,0),r.setEnd(i,0)),t.selectedRange&&t.explicitRange&&(0===r.compareBoundaryPoints(r.START_TO_START,t.selectedRange)&&0===r.compareBoundaryPoints(r.END_TO_END,t.selectedRange)?r=t.explicitRange:(t.selectedRange=null,t.explicitRange=null)),r},setRng:function(e,t){var n=this,r;if(e.select)try{e.select()}catch(i){}else if(n.tridentSel){if(e.cloneRange)try{return n.tridentSel.addRange(e),void 0}catch(i){}}else if(r=n.getSel()){n.explicitRange=e;try{r.removeAllRanges(),r.addRange(e)}catch(i){}t===!1&&r.extend&&(r.collapse(e.endContainer,e.endOffset),r.extend(e.startContainer,e.startOffset)),n.selectedRange=r.rangeCount>0?r.getRangeAt(0):null}},setNode:function(e){var t=this;return t.setContent(t.dom.getOuterHTML(e)),e},getNode:function(){function e(e,t){for(var n=e;e&&3===e.nodeType&&0===e.length;)e=t?e.nextSibling:e.previousSibling;return e||n}var t=this,n=t.getRng(),r,i=n.startContainer,o=n.endContainer,a=n.startOffset,s=n.endOffset;return n?n.setStart?(r=n.commonAncestorContainer,!n.collapsed&&(i==o&&2>s-a&&i.hasChildNodes()&&(r=i.childNodes[a]),3===i.nodeType&&3===o.nodeType&&(i=i.length===a?e(i.nextSibling,!0):i.parentNode,o=0===s?e(o.previousSibling,!1):o.parentNode,i&&i===o))?i:r&&3==r.nodeType?r.parentNode:r):n.item?n.item(0):n.parentElement():t.dom.getRoot()},getSelectedBlocks:function(t,n){var r=this,i=r.dom,o,a,s=[];if(a=i.getRoot(),t=i.getParent(t||r.getStart(),i.isBlock),n=i.getParent(n||r.getEnd(),i.isBlock),t&&t!=a&&s.push(t),t&&n&&t!=n){o=t;for(var l=new e(t,a);(o=l.next())&&o!=n;)i.isBlock(o)&&s.push(o)}return n&&t!=n&&n!=a&&s.push(n),s},isForward:function(){var e=this.dom,t=this.getSel(),n,r;return t&&t.anchorNode&&t.focusNode?(n=e.createRng(),n.setStart(t.anchorNode,t.anchorOffset),n.collapse(!0),r=e.createRng(),r.setStart(t.focusNode,t.focusOffset),r.collapse(!0),n.compareBoundaryPoints(n.START_TO_START,r)<=0):!0},normalize:function(){function t(t){function a(t,n){for(var r=new e(t,f.getParent(t.parentNode,f.isBlock)||p);t=r[n?"prev":"next"]();)if("BR"===t.nodeName)return!0}function s(e,t){return e.previousSibling&&e.previousSibling.nodeName==t}function l(t,n){var r,a;for(n=n||c,r=new e(n,f.getParent(n.parentNode,f.isBlock)||p);h=r[t?"prev":"next"]();){if(3===h.nodeType&&h.nodeValue.length>0)return c=h,u=t?h.nodeValue.length:0,i=!0,void 0;if(f.isBlock(h)||m[h.nodeName.toLowerCase()])return;a=h}o&&a&&(c=a,i=!0,u=0)}var c,u,d,f=n.dom,p=f.getRoot(),h,m,g;if(c=r[(t?"start":"end")+"Container"],u=r[(t?"start":"end")+"Offset"],m=f.schema.getNonEmptyElements(),9===c.nodeType&&(c=f.getRoot(),u=0),c===p){if(t&&(h=c.childNodes[u>0?u-1:0],h&&(g=h.nodeName.toLowerCase(),m[h.nodeName]||"TABLE"==h.nodeName)))return;if(c.hasChildNodes()&&(u=Math.min(!t&&u>0?u-1:u,c.childNodes.length-1),c=c.childNodes[u],u=0,c.hasChildNodes()&&!/TABLE/.test(c.nodeName))){h=c,d=new e(c,p);do{if(3===h.nodeType&&h.nodeValue.length>0){u=t?0:h.nodeValue.length,c=h,i=!0;break}if(m[h.nodeName.toLowerCase()]){u=f.nodeIndex(h),c=h.parentNode,"IMG"!=h.nodeName||t||u++,i=!0;break}}while(h=t?d.next():d.prev())}}o&&(3===c.nodeType&&0===u&&l(!0),1===c.nodeType&&(h=c.childNodes[u],!h||"BR"!==h.nodeName||s(h,"A")||a(h)||a(h,!0)||l(!0,c.childNodes[u]))),t&&!o&&3===c.nodeType&&u===c.nodeValue.length&&l(!1),i&&r["set"+(t?"Start":"End")](c,u)}var n=this,r,i,o;u||(r=n.getRng(),o=r.collapsed,t(!0),o||t(),i&&(o&&r.collapse(!0),n.setRng(r,n.isForward())))},selectorChanged:function(e,t){var n=this,r;return n.selectorChangedData||(n.selectorChangedData={},r={},n.editor.on("NodeChange",function(e){var t=e.element,i=n.dom,o=i.getParents(t,null,i.getRoot()),a={};s(n.selectorChangedData,function(e,t){s(o,function(n){return i.is(n,t)?(r[t]||(s(e,function(e){e(!0,{node:n,selector:t,parents:o})}),r[t]=e),a[t]=e,!1):void 0})}),s(r,function(e,n){a[n]||(delete r[n],s(e,function(e){e(!1,{node:t,selector:n,parents:o})}))})})),n.selectorChangedData[e]||(n.selectorChangedData[e]=[]),n.selectorChangedData[e].push(t),n},getScrollContainer:function(){for(var e,t=this.dom.getRoot();t&&"BODY"!=t.nodeName;){if(t.scrollHeight>t.clientHeight){e=t;break}t=t.parentNode}return e},scrollIntoView:function(e){function t(e){for(var t=0,n=0,r=e;r&&r.nodeType;)t+=r.offsetLeft||0,n+=r.offsetTop||0,r=r.offsetParent;return{x:t,y:n}}var n,r,i=this,o=i.dom,a=o.getRoot(),s,l;if("BODY"!=a.nodeName){var c=i.getScrollContainer();if(c)return n=t(e).y-t(c).y,l=c.clientHeight,s=c.scrollTop,(s>n||n+25>s+l)&&(c.scrollTop=s>n?n:n-l+25),void 0}r=o.getViewPort(i.editor.getWin()),n=o.getPos(e).y,s=r.y,l=r.h,(ns+l)&&i.editor.getWin().scrollTo(0,s>n?n:n-l+25)},destroy:function(){this.win=null,this.controlSelection.destroy()}},a}),r(B,[p],function(e){function t(e){this.walk=function(t,r){function i(e){var t;return t=e[0],3===t.nodeType&&t===l&&c>=t.nodeValue.length&&e.splice(0,1),t=e[e.length-1],0===d&&e.length>0&&t===u&&3===t.nodeType&&e.splice(e.length-1,1),e}function o(e,t,n){for(var r=[];e&&e!=n;e=e[t])r.push(e);return r}function a(e,t){do{if(e.parentNode==t)return e;e=e.parentNode}while(e)}function s(e,t,n){var a=n?"nextSibling":"previousSibling";for(m=e,g=m.parentNode;m&&m!=t;m=g)g=m.parentNode,v=o(m==e?m:m[a],a),v.length&&(n||v.reverse(),r(i(v)))}var l=t.startContainer,c=t.startOffset,u=t.endContainer,d=t.endOffset,f,p,h,m,g,v,y;if(y=e.select("td.mce-item-selected,th.mce-item-selected"),y.length>0)return n(y,function(e){r([e])}),void 0;if(1==l.nodeType&&l.hasChildNodes()&&(l=l.childNodes[c]),1==u.nodeType&&u.hasChildNodes()&&(u=u.childNodes[Math.min(d-1,u.childNodes.length-1)]),l==u)return r(i([l]));for(f=e.findCommonAncestor(l,u),m=l;m;m=m.parentNode){if(m===u)return s(l,f,!0);if(m===f)break}for(m=u;m;m=m.parentNode){if(m===l)return s(u,f);if(m===f)break}p=a(l,f)||l,h=a(u,f)||u,s(l,p,!0),v=o(p==l?p:p.nextSibling,"nextSibling",h==u?h.nextSibling:h),v.length&&r(i(v)),s(u,h)},this.split=function(e){function t(e,t){return e.splitText(t)}var n=e.startContainer,r=e.startOffset,i=e.endContainer,o=e.endOffset;return n==i&&3==n.nodeType?r>0&&rr?(o-=r,n=i=t(i,o).previousSibling,o=i.nodeValue.length,r=0):o=0):(3==n.nodeType&&r>0&&r0&&o=e;e++)r.addShortcut("ctrl+"+e,"",["FormatBlock",!1,"h"+e]);r.addShortcut("ctrl+7","",["FormatBlock",!1,"p"]),r.addShortcut("ctrl+8","",["FormatBlock",!1,"div"]),r.addShortcut("ctrl+9","",["FormatBlock",!1,"address"])}function c(e){return e?O[e]:O}function u(e,t){e&&("string"!=typeof e?et(e,function(e,t){u(t,e)}):(t=t.length?t:[t],et(t,function(e){e.deep===X&&(e.deep=!e.selector),e.split===X&&(e.split=!e.selector||e.inline),e.remove===X&&e.selector&&!e.inline&&(e.remove="none"),e.selector&&e.inline&&(e.mixed=!0,e.block_expand=!0),"string"==typeof e.classes&&(e.classes=e.classes.split(/\s+/))}),O[e]=t))}function d(e){var t;return r.dom.getParent(e,function(e){return t=r.dom.getStyle(e,"text-decoration"),t&&"none"!==t}),t}function f(e){var t;1===e.nodeType&&e.parentNode&&1===e.parentNode.nodeType&&(t=d(e.parentNode),r.dom.getStyle(e,"color")&&t?r.dom.setStyle(e,"text-decoration",t):r.dom.getStyle(e,"textdecoration")===t&&r.dom.setStyle(e,"text-decoration",null))}function p(t,n,o){function s(e,t){t=t||m,e&&(t.onformat&&t.onformat(e,t,n,o),et(t.styles,function(t,r){I.setStyle(e,r,E(t,n))}),et(t.attributes,function(t,r){I.setAttrib(e,r,E(t,n))}),et(t.classes,function(t){t=E(t,n),I.hasClass(e,t)||I.addClass(e,t)}))}function l(){function t(t,n){var r=new e(n);for(o=r.current();o;o=r.prev())if(o.childNodes.length>1||o==t||"BR"==o.tagName)return o}var n=r.selection.getRng(),i=n.startContainer,a=n.endContainer;if(i!=a&&0===n.endOffset){var s=t(i,a),l=3==s.nodeType?s.length:s.childNodes.length;n.setEnd(s,l)}return n}function u(e,t,n,r,i){var o=[],a=-1,s,l=-1,c=-1,u;return et(e.childNodes,function(e,t){return"UL"===e.nodeName||"OL"===e.nodeName?(a=t,s=e,!1):void 0}),et(e.childNodes,function(e,n){"SPAN"===e.nodeName&&"bookmark"==I.getAttrib(e,"data-mce-type")&&(e.id==t.id+"_start"?l=n:e.id==t.id+"_end"&&(c=n))}),0>=a||a>l&&c>a?(et(tt(e.childNodes),i),0):(u=I.clone(n,K),et(tt(e.childNodes),function(e,t){(a>l&&a>t||l>a&&t>a)&&(o.push(e),e.parentNode.removeChild(e))}),a>l?e.insertBefore(u,s):l>a&&e.insertBefore(u,s.nextSibling),r.push(u),et(o,function(e){u.appendChild(e)}),u)}function d(e,r,o){var l=[],c,d,f=!0;c=m.inline||m.block,d=I.create(c),s(d),W.walk(e,function(e){function p(e){var y,C,x,_,N;return N=f,y=e.nodeName.toLowerCase(),C=e.parentNode.nodeName.toLowerCase(),1===e.nodeType&&J(e)&&(N=f,f="true"===J(e),_=!0),w(y,"br")?(v=0,m.block&&I.remove(e),void 0):m.wrapper&&g(e,t,n)?(v=0,void 0):f&&!_&&m.block&&!m.wrapper&&i(y)&&z(C,c)?(e=I.rename(e,c),s(e),l.push(e),v=0,void 0):m.selector&&(et(h,function(t){"collapsed"in t&&t.collapsed!==b||I.is(e,t.selector)&&!a(e)&&(s(e,t),x=!0)}),!m.inline||x)?(v=0,void 0):(!f||_||!z(c,y)||!z(C,c)||!o&&3===e.nodeType&&1===e.nodeValue.length&&65279===e.nodeValue.charCodeAt(0)||a(e)||m.inline&&V(e)?"li"==y&&r?v=u(e,r,d,l,p):(v=0,et(tt(e.childNodes),p),_&&(f=N),v=0):(v||(v=I.clone(d,K),e.parentNode.insertBefore(v,e),l.push(v)),v.appendChild(e)),void 0)}var v;et(e,p)}),m.wrap_links===!1&&et(l,function(e){function t(e){var n,r,i;if("A"===e.nodeName){for(r=I.clone(d,K),l.push(r),i=tt(e.childNodes),n=0;n1||!V(e))&&0===o)return I.remove(e,1),void 0;if(m.inline||m.wrapper){if(m.exact||1!==o||(e=i(e)),et(h,function(t){et(I.select(t.inline,e),function(e){var r;if(t.wrap_links===!1){r=e.parentNode;do if("A"===r.nodeName)return;while(r=r.parentNode)}R(t,n,e,t.exact?e:null)})}),g(e.parentNode,t,n))return I.remove(e,1),e=0,G;m.merge_with_parents&&I.getParent(e.parentNode,function(r){return g(r,t,n)?(I.remove(e,1),e=0,G):void 0}),e&&m.merge_siblings!==!1&&(e=H(B(e),e),e=H(e,B(e,G)))}})}var h=c(t),m=h[0],v,y,b=!o&&F.isCollapsed();if(m)if(o)o.nodeType?(y=I.createRng(),y.setStartBefore(o),y.setEndAfter(o),d(T(y,h),null,!0)):d(o,null,!0);else if(b&&m.inline&&!I.select("td.mce-item-selected,th.mce-item-selected").length)M("apply",t,n);else{var C=r.selection.getNode();U||!h[0].defaultBlock||I.getParent(C,I.isBlock)||p(h[0].defaultBlock),r.selection.setRng(l()),v=F.getBookmark(),d(T(F.getRng(G),h),v),m.styles&&(m.styles.color||m.styles.textDecoration)&&(nt(C,f,"childNodes"),f(C)),F.moveToBookmark(v),P(F.getRng(G)),r.nodeChanged()}}function h(e,t,n){function i(e){var n,r,o,a,s;if(1===e.nodeType&&J(e)&&(a=b,b="true"===J(e),s=!0),n=tt(e.childNodes),b&&!s)for(r=0,o=p.length;o>r&&!R(p[r],t,e,e);r++);if(h.deep&&n.length){for(r=0,o=n.length;o>r;r++)i(n[r]);s&&(b=a)}}function a(n){var r;return et(o(n.parentNode).reverse(),function(n){var i;r||"_start"==n.id||"_end"==n.id||(i=g(n,e,t),i&&i.split!==!1&&(r=n))}),r}function s(e,n,r,i){var o,a,s,l,c,u;if(e){for(u=e.parentNode,o=n.parentNode;o&&o!=u;o=o.parentNode){for(a=I.clone(o,K),c=0;c=0;a--){if(s=t[a].selector,!s||t[a].defaultBlock)return G;for(i=r.length-1;i>=0;i--)if(I.is(r[i],s))return G}return K}function C(e,t,n){var i;return Y||(Y={},i={},r.on("NodeChange",function(e){var t=o(e.element),n={};et(Y,function(e,r){et(t,function(o){return g(o,r,{},e.similar)?(i[r]||(et(e,function(e){e(!0,{node:o,format:r,parents:t})}),i[r]=e),n[r]=e,!1):void 0})}),et(i,function(r,o){n[o]||(delete i[o],et(r,function(n){n(!1,{node:e.element,format:o,parents:t})}))})})),et(e.split(","),function(e){Y[e]||(Y[e]=[],Y[e].similar=n),Y[e].push(t)}),this}function x(e,t){return w(e,t.inline)?G:w(e,t.block)?G:t.selector?1==e.nodeType&&I.is(e,t.selector):void 0}function w(e,t){return e=e||"",t=t||"",e=""+(e.nodeName||e),t=""+(t.nodeName||t),e.toLowerCase()==t.toLowerCase()}function _(e,t){return N(I.getStyle(e,t),t)}function N(e,t){return("color"==t||"backgroundColor"==t)&&(e=I.toHex(e)),"fontWeight"==t&&700==e&&(e="bold"),"fontFamily"==t&&(e=e.replace(/[\'\"]/g,"").replace(/,\s+/g,",")),""+e}function E(e,t){return"string"!=typeof e?e=e(t):t&&(e=e.replace(/%(\w+)/g,function(e,n){return t[n]||e})),e}function k(e){return e&&3===e.nodeType&&/^([\t \r\n]+|)$/.test(e.nodeValue)}function S(e,t,n){var r=I.create(t,n);return e.parentNode.insertBefore(r,e),r.appendChild(e),r}function T(t,n,a){function s(e){function t(e){return"BR"==e.nodeName&&e.getAttribute("data-mce-bogus")&&!e.nextSibling +}var r,i,o,a,s;if(r=i=e?g:y,a=e?"previousSibling":"nextSibling",s=I.getRoot(),3==r.nodeType&&!k(r)&&(e?v>0:br?n:r,-1===n||a||n++):(n=o.indexOf(" ",t),r=o.indexOf("\xa0",t),n=-1!==n&&(-1===r||r>n)?n:r),n}var s,l,c,u;if(3===t.nodeType){if(c=o(t,n),-1!==c)return{container:t,offset:c};u=t}for(s=new e(t,I.getParent(t,V)||r.getBody());l=s[i?"prev":"next"]();)if(3===l.nodeType){if(u=l,c=o(l),-1!==c)return{container:l,offset:c}}else if(V(l))break;return u?(n=i?0:u.length,{container:u,offset:n}):void 0}function d(e,r){var i,a,s,l;for(3==e.nodeType&&0===e.nodeValue.length&&e[r]&&(e=e[r]),i=o(e),a=0;ap?p:v],3==g.nodeType&&(v=0)),1==y.nodeType&&y.hasChildNodes()&&(p=y.childNodes.length-1,y=y.childNodes[b>p?p:b-1],3==y.nodeType&&(b=y.nodeValue.length)),g=c(g),y=c(y),(D(g.parentNode)||D(g))&&(g=D(g)?g:g.parentNode,g=g.nextSibling||g,3==g.nodeType&&(v=0)),(D(y.parentNode)||D(y))&&(y=D(y)?y:y.parentNode,y=y.previousSibling||y,3==y.nodeType&&(b=y.length)),n[0].inline&&(t.collapsed&&(m=u(g,v,!0),m&&(g=m.container,v=m.offset),m=u(y,b),m&&(y=m.container,b=m.offset)),h=l(y,b),h.node)){for(;h.node&&0===h.offset&&h.node.previousSibling;)h=l(h.node.previousSibling);h.node&&h.offset>0&&3===h.node.nodeType&&" "===h.node.nodeValue.charAt(h.offset-1)&&h.offset>1&&(y=h.node,y.splitText(h.offset-1))}return(n[0].inline||n[0].block_expand)&&(n[0].inline&&3==g.nodeType&&0!==v||(g=s(!0)),n[0].inline&&3==y.nodeType&&b!==y.nodeValue.length||(y=s())),n[0].selector&&n[0].expand!==K&&!n[0].inline&&(g=d(g,"previousSibling"),y=d(y,"nextSibling")),(n[0].block||n[0].selector)&&(g=f(g,"previousSibling"),y=f(y,"nextSibling"),n[0].block&&(V(g)||(g=s(!0)),V(y)||(y=s()))),1==g.nodeType&&(v=q(g),g=g.parentNode),1==y.nodeType&&(b=q(y)+1,y=y.parentNode),{startContainer:g,startOffset:v,endContainer:y,endOffset:b}}function R(e,t,n,r){var i,o,a;if(!x(n,e))return K;if("all"!=e.remove)for(et(e.styles,function(e,i){e=N(E(e,t),i),"number"==typeof i&&(i=e,r=0),(!r||w(_(r,i),e))&&I.setStyle(n,i,""),a=1}),a&&""===I.getAttrib(n,"style")&&(n.removeAttribute("style"),n.removeAttribute("data-mce-style")),et(e.attributes,function(e,i){var o;if(e=E(e,t),"number"==typeof i&&(i=e,r=0),!r||w(I.getAttrib(r,i),e)){if("class"==i&&(e=I.getAttrib(n,i),e&&(o="",et(e.split(/\s+/),function(e){/mce\w+/.test(e)&&(o+=(o?" ":"")+e)}),o)))return I.setAttrib(n,i,o),void 0;"class"==i&&n.removeAttribute("className"),$.test(i)&&n.removeAttribute("data-mce-"+i),n.removeAttribute(i)}}),et(e.classes,function(e){e=E(e,t),(!r||I.hasClass(r,e))&&I.removeClass(n,e)}),o=I.getAttribs(n),i=0;ia?a:o]),3===i.nodeType&&n&&o>=i.nodeValue.length&&(i=new e(i,r.getBody()).next()||i),3!==i.nodeType||n||0!==o||(i=new e(i,r.getBody()).prev()||i),i}function M(t,n,o){function a(e){var t=I.create("span",{id:y,"data-mce-bogus":!0,style:b?"color:red":""});return e&&t.appendChild(r.getDoc().createTextNode(j)),t}function s(e,t){for(;e;){if(3===e.nodeType&&e.nodeValue!==j||e.childNodes.length>1)return!1;t&&1===e.nodeType&&t.push(e),e=e.firstChild}return!0}function l(e){for(;e;){if(e.id===y)return e;e=e.parentNode}}function u(t){var n;if(t)for(n=new e(t,t),t=n.current();t;t=n.next())if(3===t.nodeType)return t}function d(e,t){var n,r;if(e)r=F.getRng(!0),s(e)?(t!==!1&&(r.setStartBefore(e),r.setEndBefore(e)),I.remove(e)):(n=u(e),n.nodeValue.charAt(0)===j&&(n=n.deleteData(0,1)),I.remove(e,1)),F.setRng(r);else if(e=l(F.getStart()),!e)for(;e=I.get(y);)d(e,!1)}function f(){var e,t,r,i,s,d,f;e=F.getRng(!0),i=e.startOffset,d=e.startContainer,f=d.nodeValue,t=l(F.getStart()),t&&(r=u(t)),f&&i>0&&i=0;p--)u.appendChild(I.clone(f[p],!1)),u=u.firstChild;u.appendChild(I.doc.createTextNode(j)),u=u.firstChild;var v=I.getParent(d,i);v&&I.isEmpty(v)?d.parentNode.replaceChild(m,d):I.insertAfter(m,d),F.setCursorLocation(u,1),I.isEmpty(d)&&I.remove(d)}}function v(){var e;e=l(F.getStart()),e&&!I.isEmpty(e)&&nt(e,function(e){1!=e.nodeType||e.id===y||I.isEmpty(e)||I.setAttrib(e,"data-mce-bogus",null)},"childNodes")}var y="_mce_caret",b=r.settings.caret_debug;r._hasCaretEvents||(Z=function(){var e=[],t;if(s(l(F.getStart()),e))for(t=e.length;t--;)I.setAttrib(e[t],"data-mce-bogus","1")},Q=function(e){var t=e.keyCode;d(),(8==t||37==t||39==t)&&d(l(F.getStart())),v()},r.on("SetContent",function(e){e.selection&&v()}),r._hasCaretEvents=!0),"apply"==t?f():m()}function P(t){var n=t.startContainer,r=t.startOffset,i,o,a,s,l;if(3==n.nodeType&&r>=n.nodeValue.length&&(r=q(n),n=n.parentNode,i=!0),1==n.nodeType)for(s=n.childNodes,n=s[Math.min(r,s.length-1)],o=new e(n,I.getParent(n,I.isBlock)),(r>s.length-1||i)&&o.next(),a=o.current();a;a=o.next())if(3==a.nodeType&&!k(a))return l=I.create("a",null,j),a.parentNode.insertBefore(l,a),t.setStart(a,0),F.setRng(t),I.remove(l),void 0}var O={},I=r.dom,F=r.selection,W=new t(I),z=r.schema.isValidChild,V=I.isBlock,U=r.settings.forced_root_block,q=I.nodeIndex,j="\ufeff",$=/^(src|href|style)$/,K=!1,G=!0,Y,X,J=I.getContentEditable,Q,Z,et=n.each,tt=n.grep,nt=n.walk,rt=n.extend;rt(this,{get:c,register:u,apply:p,remove:h,toggle:m,match:v,matchAll:y,matchNode:g,canApply:b,formatChanged:C}),s(),l(),r.on("BeforeGetContent",function(){Z&&Z()}),r.on("mouseup keydown",function(e){Q&&Q(e)})}}),r(H,[g,p],function(e,t){var n=t.trim,r;return r=new RegExp(["]+data-mce-bogus[^>]+>[\u200b\ufeff]+<\\/span>","]+data-mce-bogus[^>]+><\\/div>",'\\s?data-mce-selected="[^"]+"'].join("|"),"gi"),function(t){function i(){return n(t.getContent({format:"raw",no_events:1}).replace(r,""))}function o(){a.typing=!1,a.add()}var a,s=0,l=[],c,u,d;return t.on("init",function(){a.add()}),t.on("BeforeExecCommand",function(e){var t=e.command;"Undo"!=t&&"Redo"!=t&&"mceRepaint"!=t&&a.beforeChange()}),t.on("ExecCommand",function(e){var t=e.command;"Undo"!=t&&"Redo"!=t&&"mceRepaint"!=t&&a.add()}),t.on("ObjectResizeStart",function(){a.beforeChange()}),t.on("SaveContent ObjectResized",o),t.dom.bind(t.dom.getRoot(),"dragend",o),t.dom.bind(t.getBody(),"focusout",function(){!t.removed&&a.typing&&o()}),t.on("KeyUp",function(n){var r=n.keyCode;(r>=33&&36>=r||r>=37&&40>=r||45==r||13==r||n.ctrlKey)&&(o(),t.nodeChanged()),(46==r||8==r||e.mac&&(91==r||93==r))&&t.nodeChanged(),u&&a.typing&&(t.isDirty()||(t.isNotDirty=!l[0]||i()==l[0].content,t.isNotDirty||t.fire("change",{level:l[0],lastLevel:null})),t.fire("TypingUndo"),u=!1,t.nodeChanged())}),t.on("KeyDown",function(e){var t=e.keyCode;return t>=33&&36>=t||t>=37&&40>=t||45==t?(a.typing&&o(),void 0):((16>t||t>20)&&224!=t&&91!=t&&!a.typing&&(a.beforeChange(),a.typing=!0,a.add(),u=!0),void 0)}),t.on("MouseDown",function(){a.typing&&o()}),t.addShortcut("ctrl+z","","Undo"),t.addShortcut("ctrl+y,ctrl+shift+z","","Redo"),t.on("AddUndo Undo Redo ClearUndos MouseUp",function(e){e.isDefaultPrevented()||t.nodeChanged()}),a={data:l,typing:!1,beforeChange:function(){d||(c=t.selection.getBookmark(2,!0))},add:function(e){var n,r=t.settings,o;if(e=e||{},e.content=i(),d||t.fire("BeforeAddUndo",{level:e}).isDefaultPrevented())return null;if(o=l[s],o&&o.content==e.content)return null;if(l[s]&&(l[s].beforeBookmark=c),r.custom_undo_redo_levels&&l.length>r.custom_undo_redo_levels){for(n=0;n0&&(t.fire("change",a),t.isNotDirty=!1),e},undo:function(){var e;return a.typing&&(a.add(),a.typing=!1),s>0&&(e=l[--s],0===s&&(t.isNotDirty=!0),t.setContent(e.content,{format:"raw"}),t.selection.moveToBookmark(e.beforeBookmark),t.fire("undo",{level:e})),e},redo:function(){var e;return s0||a.typing&&l[0]&&i()!=l[0].content},hasRedo:function(){return sR)&&(l=i.create("br"),t.parentNode.insertBefore(l,t)),a.setStartBefore(t),a.setEndBefore(t)):(a.setStartAfter(t),a.setEndAfter(t)):(a.setStart(t,0),a.setEnd(t,0));o.setRng(a),i.remove(l),o.scrollIntoView(t)}function h(e){var t=k,r,o,s;if(r=e||"TABLE"==L?i.create(e||P):T.cloneNode(!1),s=r,a.keep_styles!==!1)do if(/^(SPAN|STRONG|B|EM|I|FONT|STRIKE|U)$/.test(t.nodeName)){if("_mce_caret"==t.id)continue;o=t.cloneNode(!1),i.setAttrib(o,"id",""),r.hasChildNodes()?(o.appendChild(r.firstChild),r.appendChild(o)):(s=o,r.appendChild(o))}while(t=t.parentNode);return n||(s.innerHTML='
    '),r}function m(t){var n,r,i;if(3==k.nodeType&&(t?S>0:S0)return!0}function b(){var e,t,r;k&&3==k.nodeType&&S>=k.nodeValue.length&&(n||y()||(e=i.create("br"),_.insertNode(e),_.setStartAfter(e),_.setEndAfter(e),t=!0)),e=i.create("br"),_.insertNode(e),n&&"PRE"==L&&(!R||8>R)&&e.parentNode.insertBefore(i.doc.createTextNode("\r"),e),r=i.create("span",{}," "),e.parentNode.insertBefore(r,e),o.scrollIntoView(r),i.remove(r),t?(_.setStartBefore(e),_.setEndBefore(e)):(_.setStartAfter(e),_.setEndAfter(e)),o.setRng(_),s.add()}function C(e){do 3===e.nodeType&&(e.nodeValue=e.nodeValue.replace(/^[\r\n]+/,"")),e=e.firstChild;while(e)}function x(e){var t=i.getRoot(),n,r;for(n=e;n!==t&&"false"!==i.getContentEditable(n);)"true"===i.getContentEditable(n)&&(r=n),n=n.parentNode;return n!==t?r:t}function w(e){var t;n||(e.normalize(),t=e.lastChild,(!t||/^(left|right)$/gi.test(i.getStyle(t,"float",!0)))&&i.add(e,"br"))}var _=o.getRng(!0),N,E,k,S,T,R,A,B,D,H,L,M,P,O;if(!_.collapsed)return t.execCommand("Delete"),void 0;if(!r.isDefaultPrevented()&&(k=_.startContainer,S=_.startOffset,P=(a.force_p_newlines?"p":"")||a.forced_root_block,P=P?P.toUpperCase():"",R=i.doc.documentMode,A=r.shiftKey,1==k.nodeType&&k.hasChildNodes()&&(O=S>k.childNodes.length-1,k=k.childNodes[Math.min(S,k.childNodes.length-1)]||k,S=O&&3==k.nodeType?k.nodeValue.length:0),E=x(k))){if(s.beforeChange(),!i.isBlock(E)&&E!=i.getRoot())return(!P||A)&&b(),void 0;if((P&&!A||!P&&A)&&(k=g(k,S)),T=i.getParent(k,i.isBlock),H=T?i.getParent(T.parentNode,i.isBlock):null,L=T?T.nodeName.toUpperCase():"",M=H?H.nodeName.toUpperCase():"","LI"!=M||r.ctrlKey||(T=H,L=M),"LI"==L){if(!P&&A)return b(),void 0;if(i.isEmpty(T))return v(),void 0}if("PRE"==L&&a.br_in_pre!==!1){if(!A)return b(),void 0}else if(!P&&!A&&"LI"!=L||P&&A)return b(),void 0;P&&T===t.getBody()||(P=P||"P",m()?(B=/^(H[1-6]|PRE|FIGURE)$/.test(L)&&"HGROUP"!=M?h(P):h(),a.end_container_on_empty_block&&u(H)&&i.isEmpty(T)?B=i.split(H,T):i.insertAfter(B,T),p(B)):m(!0)?(B=T.parentNode.insertBefore(h(),T),d(B),p(T)):(N=_.cloneRange(),N.setEndAfter(T),D=N.extractContents(),C(D),B=D.firstChild,i.insertAfter(D,T),f(B),w(T),p(B)),i.setAttrib(B,"id",""),s.add())}}var i=t.dom,o=t.selection,a=t.settings,s=t.undoManager,l=t.schema,c=l.getNonEmptyElements();t.on("keydown",function(e){13==e.keyCode&&r(e)!==!1&&e.preventDefault()})}}),r(M,[],function(){return function(e){function t(){var t=i.getStart(),s=e.getBody(),l,c,u,d,f,p,h,m=-16777215,g,v,y,b,C;if(C=n.forced_root_block,t&&1===t.nodeType&&C){for(;t&&t!=s;){if(a[t.nodeName])return;t=t.parentNode}if(l=i.getRng(),l.setStart){c=l.startContainer,u=l.startOffset,d=l.endContainer,f=l.endOffset;try{v=e.getDoc().activeElement===s}catch(x){}}else l.item&&(t=l.item(0),l=e.getDoc().body.createTextRange(),l.moveToElementText(t)),v=l.parentElement().ownerDocument===e.getDoc(),y=l.duplicate(),y.collapse(!0),u=-1*y.move("character",m),y.collapsed||(y=l.duplicate(),y.collapse(!1),f=-1*y.move("character",m)-u);for(t=s.firstChild,b=s.nodeName.toLowerCase();t;)if((3===t.nodeType||1==t.nodeType&&!a[t.nodeName])&&o.isValidChild(b,C.toLowerCase())){if(3===t.nodeType&&0===t.nodeValue.length){h=t,t=t.nextSibling,r.remove(h);continue}p||(p=r.create(C),t.parentNode.insertBefore(p,t),g=!0),h=t,t=t.nextSibling,p.appendChild(h)}else p=null,t=t.nextSibling;if(g&&v){if(l.setStart)l.setStart(c,u),l.setEnd(d,f),i.setRng(l);else try{l=e.getDoc().body.createTextRange(),l.moveToElementText(s),l.collapse(!0),l.moveStart("character",u),f>0&&l.moveEnd("character",f),l.select()}catch(x){}e.nodeChanged()}}}var n=e.settings,r=e.dom,i=e.selection,o=e.schema,a=o.getBlockElements();n.forced_root_block&&e.on("NodeChange",t)}}),r(P,[E,g,p],function(e,n,r){var i=r.each,o=r.extend,a=r.map,s=r.inArray,l=r.explode,c=n.gecko,u=n.ie,d=!0,f=!1;return function(n){function r(e,t,n){var r;return e=e.toLowerCase(),(r=_.exec[e])?(r(e,t,n),d):f}function p(e){var t;return e=e.toLowerCase(),(t=_.state[e])?t(e):-1}function h(e){var t;return e=e.toLowerCase(),(t=_.value[e])?t(e):f}function m(e,t){t=t||"exec",i(e,function(e,n){i(n.toLowerCase().split(","),function(n){_[t][n]=e})})}function g(e,r,i){return r===t&&(r=f),i===t&&(i=null),n.getDoc().execCommand(e,r,i)}function v(e){return E.match(e)}function y(e,r){E.toggle(e,r?{value:r}:t),n.nodeChanged()}function b(e){k=w.getBookmark(e)}function C(){w.moveToBookmark(k)}var x=n.dom,w=n.selection,_={state:{},exec:{},value:{}},N=n.settings,E=n.formatter,k;o(this,{execCommand:r,queryCommandState:p,queryCommandValue:h,addCommands:m}),m({"mceResetDesignMode,mceBeginUndoLevel":function(){},"mceEndUndoLevel,mceAddUndoLevel":function(){n.undoManager.add()},"Cut,Copy,Paste":function(e){var t=n.getDoc(),r;try{g(e)}catch(i){r=d}(r||!t.queryCommandSupported(e))&&n.windowManager.alert("Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X/C/V keyboard shortcuts instead.")},unlink:function(e){w.isCollapsed()&&w.select(w.getNode()),g(e),w.collapse(f)},"JustifyLeft,JustifyCenter,JustifyRight,JustifyFull":function(e){var t=e.substring(7);"full"==t&&(t="justify"),i("left,center,right,justify".split(","),function(e){t!=e&&E.remove("align"+e)}),y("align"+t),r("mceRepaint")},"InsertUnorderedList,InsertOrderedList":function(e){var t,n;g(e),t=x.getParent(w.getNode(),"ol,ul"),t&&(n=t.parentNode,/^(H[1-6]|P|ADDRESS|PRE)$/.test(n.nodeName)&&(b(),x.split(n,t),C()))},"Bold,Italic,Underline,Strikethrough,Superscript,Subscript":function(e){y(e)},"ForeColor,HiliteColor,FontName":function(e,t,n){y(e,n)},FontSize:function(e,t,n){var r,i;n>=1&&7>=n&&(i=l(N.font_size_style_values),r=l(N.font_size_classes),n=r?r[n-1]||n:i[n-1]||n),y(e,n)},RemoveFormat:function(e){E.remove(e)},mceBlockQuote:function(){y("blockquote")},FormatBlock:function(e,t,n){return y(n||"p")},mceCleanup:function(){var e=w.getBookmark();n.setContent(n.getContent({cleanup:d}),{cleanup:d}),w.moveToBookmark(e)},mceRemoveNode:function(e,t,r){var i=r||w.getNode();i!=n.getBody()&&(b(),n.dom.remove(i,d),C())},mceSelectNodeDepth:function(e,t,r){var i=0;x.getParent(w.getNode(),function(e){return 1==e.nodeType&&i++==r?(w.select(e),f):void 0},n.getBody())},mceSelectNode:function(e,t,n){w.select(n)},mceInsertContent:function(t,r,i){function o(e){function t(e){return r[e]&&3==r[e].nodeType}var n,r,i;return n=w.getRng(!0),r=n.startContainer,i=n.startOffset,3==r.nodeType&&(i>0?e=e.replace(/^ /," "):t("previousSibling")||(e=e.replace(/^ /," ")),i|)$/," "):t("nextSibling")||(e=e.replace(/( | )(
    |)$/," "))),e}var a,s,l,c,d,f,p,h,m,g,v,y,b,C;/^ | $/.test(i)&&(i=o(i)),a=n.parser,s=new e({},n.schema),b='',f={content:i,format:"html",selection:!0},n.fire("BeforeSetContent",f),i=f.content,-1==i.indexOf("{$caret}")&&(i+="{$caret}"),i=i.replace(/\{\$caret\}/,b),w.isCollapsed()||n.getDoc().execCommand("Delete",!1,null),l=w.getNode();var _={context:l.nodeName.toLowerCase()};if(d=a.parse(i,_),v=d.lastChild,"mce_marker"==v.attr("id"))for(p=v,v=v.prev;v;v=v.walk(!0))if(3==v.type||!x.isBlock(v.name)){v.parent.insert(p,v,"br"===v.name);break}if(_.invalid){for(w.setContent(b),l=w.getNode(),c=n.getBody(),9==l.nodeType?l=v=c:v=l;v!==c;)l=v,v=v.parentNode;i=l==c?c.innerHTML:x.getOuterHTML(l),i=s.serialize(a.parse(i.replace(//i,function(){return s.serialize(d)}))),l==c?x.setHTML(c,i):x.setOuterHTML(l,i)}else i=s.serialize(d),v=l.firstChild,y=l.lastChild,!v||v===y&&"BR"===v.nodeName?x.setHTML(l,i):w.setContent(i);p=x.get("mce_marker"),h=x.getRect(p),m=x.getViewPort(n.getWin()),(h.y+h.h>m.y+m.h||h.ym.x+m.w||h.x")},mceToggleVisualAid:function(){n.hasVisual=!n.hasVisual,n.addVisual()},mceReplaceContent:function(e,t,r){n.execCommand("mceInsertContent",!1,r.replace(/\{\$selection\}/g,w.getContent({format:"text"})))},mceInsertLink:function(e,t,n){var r;"string"==typeof n&&(n={href:n}),r=x.getParent(w.getNode(),"a"),n.href=n.href.replace(" ","%20"),r&&n.href||E.remove("link"),n.href&&E.apply("link",n,r)},selectAll:function(){var e=x.getRoot(),t=x.createRng();w.getRng().setStart?(t.setStart(e,0),t.setEnd(e,e.childNodes.length),w.setRng(t)):g("SelectAll")},mceNewDocument:function(){n.setContent("")}}),m({"JustifyLeft,JustifyCenter,JustifyRight,JustifyFull":function(e){var t="align"+e.substring(7),n=w.isCollapsed()?[x.getParent(w.getNode(),x.isBlock)]:w.getSelectedBlocks(),r=a(n,function(e){return!!E.matchNode(e,t)});return-1!==s(r,d)},"Bold,Italic,Underline,Strikethrough,Superscript,Subscript":function(e){return v(e)},mceBlockQuote:function(){return v("blockquote")},Outdent:function(){var e;if(N.inline_styles){if((e=x.getParent(w.getStart(),x.isBlock))&&parseInt(e.style.paddingLeft,10)>0)return d;if((e=x.getParent(w.getEnd(),x.isBlock))&&parseInt(e.style.paddingLeft,10)>0)return d}return p("InsertUnorderedList")||p("InsertOrderedList")||!N.inline_styles&&!!x.getParent(w.getNode(),"BLOCKQUOTE")},"InsertUnorderedList,InsertOrderedList":function(e){var t=x.getParent(w.getNode(),"ul,ol");return t&&("insertunorderedlist"===e&&"UL"===t.tagName||"insertorderedlist"===e&&"OL"===t.tagName)}},"state"),m({"FontSize,FontName":function(e){var t=0,n;return(n=x.getParent(w.getNode(),"span"))&&(t="fontsize"==e?n.style.fontSize:n.style.fontFamily.replace(/, /g,",").replace(/[\'\"]/g,"").toLowerCase()),t}},"value"),m({Undo:function(){n.undoManager.undo()},Redo:function(){n.undoManager.redo()}})}}),r(O,[p],function(e){function t(e,i){var o=this,a,s;return e=r(e),i=o.settings=i||{},/^([\w\-]+):([^\/]{2})/i.test(e)||/^\s*#/.test(e)?(o.source=e,void 0):(0===e.indexOf("/")&&0!==e.indexOf("//")&&(e=(i.base_uri?i.base_uri.protocol||"http":"http")+"://mce_host"+e),/^[\w\-]*:?\/\//.test(e)||(s=i.base_uri?i.base_uri.path:new t(location.href).directory,e=(i.base_uri&&i.base_uri.protocol||"http")+"://mce_host"+o.toAbsPath(s,e)),e=e.replace(/@@/g,"(mce_at)"),e=/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@\/]*):?([^:@\/]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(e),n(["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],function(t,n){var r=e[n];r&&(r=r.replace(/\(mce_at\)/g,"@@")),o[t]=r}),a=i.base_uri,a&&(o.protocol||(o.protocol=a.protocol),o.userInfo||(o.userInfo=a.userInfo),o.port||"mce_host"!==o.host||(o.port=a.port),o.host&&"mce_host"!==o.host||(o.host=a.host),o.source=""),void 0)}var n=e.each,r=e.trim;return t.prototype={setPath:function(e){var t=this;e=/^(.*?)\/?(\w+)?$/.exec(e),t.path=e[0],t.directory=e[1],t.file=e[2],t.source="",t.getURI()},toRelative:function(e){var n=this,r;if("./"===e)return e;if(e=new t(e,{base_uri:n}),"mce_host"!=e.host&&n.host!=e.host&&e.host||n.port!=e.port||n.protocol!=e.protocol)return e.getURI();var i=n.getURI(),o=e.getURI();return i==o||"/"==i.charAt(i.length-1)&&i.substr(0,i.length-1)==o?i:(r=n.toRelPath(n.path,e.path),e.query&&(r+="?"+e.query),e.anchor&&(r+="#"+e.anchor),r)},toAbsolute:function(e,n){return e=new t(e,{base_uri:this}),e.getURI(this.host==e.host&&this.protocol==e.protocol?n:0)},toRelPath:function(e,t){var n,r=0,i="",o,a;if(e=e.substring(0,e.lastIndexOf("/")),e=e.split("/"),n=t.split("/"),e.length>=n.length)for(o=0,a=e.length;a>o;o++)if(o>=n.length||e[o]!=n[o]){r=o+1;break}if(e.lengtho;o++)if(o>=e.length||e[o]!=n[o]){r=o+1;break}if(1===r)return t;for(o=0,a=e.length-(r-1);a>o;o++)i+="../";for(o=r-1,a=n.length;a>o;o++)i+=o!=r-1?"/"+n[o]:n[o];return i},toAbsPath:function(e,t){var r,i=0,o=[],a,s;for(a=/\/$/.test(t)?"/":"",e=e.split("/"),t=t.split("/"),n(e,function(e){e&&o.push(e)}),e=o,r=t.length-1,o=[];r>=0;r--)0!==t[r].length&&"."!==t[r]&&(".."!==t[r]?i>0?i--:o.push(t[r]):i++);return r=e.length-i,s=0>=r?o.reverse().join("/"):e.slice(0,r).join("/")+"/"+o.reverse().join("/"),0!==s.indexOf("/")&&(s="/"+s),a&&s.lastIndexOf("/")!==s.length-1&&(s+=a),s},getURI:function(e){var t,n=this;return(!n.source||e)&&(t="",e||(n.protocol&&(t+=n.protocol+"://"),n.userInfo&&(t+=n.userInfo+"@"),n.host&&(t+=n.host),n.port&&(t+=":"+n.port)),n.path&&(t+=n.path),n.query&&(t+="?"+n.query),n.anchor&&(t+="#"+n.anchor),n.source=t),n.source}},t}),r(I,[p],function(e){function t(){}var n=e.each,r=e.extend,i,o;return t.extend=i=function(e){function t(){var e,t,n,r;if(!o&&(r=this,r.init&&r.init.apply(r,arguments),t=r.Mixins))for(e=t.length;e--;)n=t[e],n.init&&n.init.apply(r,arguments)}function a(){return this}function s(e,t){return function(){var n=this,r=n._super,i;return n._super=c[e],i=t.apply(n,arguments),n._super=r,i}}var l=this,c=l.prototype,u,d,f;o=!0,u=new l,o=!1,e.Mixins&&(n(e.Mixins,function(t){t=t;for(var n in t)"init"!==n&&(e[n]=t[n])}),c.Mixins&&(e.Mixins=c.Mixins.concat(e.Mixins))),e.Methods&&n(e.Methods.split(","),function(t){e[t]=a}),e.Properties&&n(e.Properties.split(","),function(t){var n="_"+t;e[t]=function(e){var t=this,r;return e!==r?(t[n]=e,t):t[n]}}),e.Statics&&n(e.Statics,function(e,n){t[n]=e}),e.Defaults&&c.Defaults&&(e.Defaults=r({},c.Defaults,e.Defaults));for(d in e)f=e[d],u[d]="function"==typeof f&&c[d]?s(d,f):f;return t.prototype=u,t.constructor=t,t.extend=i,t},t}),r(F,[I,p],function(e,t){function n(e){for(var t=[],n=e.length,r;n--;)r=e[n],r.__checked||(t.push(r),r.__checked=1);for(n=t.length;n--;)delete t[n].__checked;return t}var r=/^([\w\\*]+)?(?:#([\w\\]+))?(?:\.([\w\\\.]+))?(?:\[\@?([\w\\]+)([\^\$\*!~]?=)([\w\\]+)\])?(?:\:(.+))?/i,i=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,o=/^\s*|\s*$/g,a,s=e.extend({init:function(e){function t(e){return e?(e=e.toLowerCase(),function(t){return"*"===e||t.type===e}):void 0}function n(e){return e?function(t){return t._name===e}:void 0}function a(e){return e?(e=e.split("."),function(t){for(var n=e.length;n--;)if(!t.hasClass(e[n]))return!1;return!0}):void 0}function s(e,t,n){return e?function(r){var i=r[e]?r[e]():"";return t?"="===t?i===n:"*="===t?i.indexOf(n)>=0:"~="===t?(" "+i+" ").indexOf(" "+n+" ")>=0:"!="===t?i!=n:"^="===t?0===i.indexOf(n):"$="===t?i.substr(i.length-n.length)===n:!1:!!n}:void 0}function l(e){var t;return e?(e=/(?:not\((.+)\))|(.+)/i.exec(e),e[1]?(t=u(e[1],[]),function(e){return!d(e,t)}):(e=e[2],function(t,n,r){return"first"===e?0===n:"last"===e?n===r-1:"even"===e?0===n%2:"odd"===e?1===n%2:t[e]?t[e]():!1})):void 0}function c(e,i,c){function u(e){e&&i.push(e)}var d;return d=r.exec(e.replace(o,"")),u(t(d[1])),u(n(d[2])),u(a(d[3])),u(s(d[4],d[5],d[6])),u(l(d[7])),i.psuedo=!!d[7],i.direct=c,i}function u(e,t){var n=[],r,o,a;do if(i.exec(""),o=i.exec(e),o&&(e=o[3],n.push(o[1]),o[2])){r=o[3];break}while(o);for(r&&u(r,t),e=[],a=0;a"!=n[a]&&e.push(c(n[a],[],">"===n[a-1]));return t.push(e),t}var d=this.match;this._selectors=u(e,[])},match:function(e,n){var r,i,o,a,s,l,c,u,d,f,p,h,m;for(n=n||this._selectors,r=0,i=n.length;i>r;r++){for(s=n[r],a=s.length,m=e,h=0,o=a-1;o>=0;o--)for(u=s[o];m;){for(u.psuedo&&(p=m.parent().items(),d=t.inArray(m,p),f=p.length),l=0,c=u.length;c>l;l++)if(!u[l](m,d,f)){l=c+1;break}if(l===c){h++;break}if(o===a-1)break;m=m.parent()}if(h===a)return!0}return!1},find:function(e){function t(e,n,i){var o,a,s,l,c,u=n[i];for(o=0,a=e.length;a>o;o++){for(c=e[o],s=0,l=u.length;l>s;s++)if(!u[s](c,o,a)){s=l+1;break}if(s===l)i==n.length-1?r.push(c):c.items&&t(c.items(),n,i+1);else if(u.direct)return;c.items&&t(c.items(),n,i)}}var r=[],i,o,l=this._selectors;if(e.items){for(i=0,o=l.length;o>i;i++)t(e.items(),l[i],0);o>1&&(r=n(r))}return a||(a=s.Collection),new a(r)}});return s}),r(W,[p,F,I],function(e,t,n){var r,i,o=Array.prototype.push,a=Array.prototype.slice;return i={length:0,init:function(e){e&&this.add(e)},add:function(t){var n=this; +return e.isArray(t)?o.apply(n,t):t instanceof r?n.add(t.toArray()):o.call(n,t),n},set:function(e){var t=this,n=t.length,r;for(t.length=0,t.add(e),r=t.length;n>r;r++)delete t[r];return t},filter:function(e){var n=this,i,o,a=[],s,l;for("string"==typeof e?(e=new t(e),l=function(t){return e.match(t)}):l=e,i=0,o=n.length;o>i;i++)s=n[i],l(s)&&a.push(s);return new r(a)},slice:function(){return new r(a.apply(this,arguments))},eq:function(e){return-1===e?this.slice(e):this.slice(e,+e+1)},each:function(t){return e.each(this,t),this},toArray:function(){return e.toArray(this)},indexOf:function(e){for(var t=this,n=t.length;n--&&t[n]!==e;);return n},reverse:function(){return new r(e.toArray(this).reverse())},hasClass:function(e){return this[0]?this[0].hasClass(e):!1},prop:function(e,t){var n=this,r,i;return t!==r?(n.each(function(n){n[e]&&n[e](t)}),n):(i=n[0],i&&i[e]?i[e]():void 0)},exec:function(t){var n=this,r=e.toArray(arguments).slice(1);return n.each(function(e){e[t]&&e[t].apply(e,r)}),n},remove:function(){for(var e=this.length;e--;)this[e].remove();return this}},e.each("fire on off show hide addClass removeClass append prepend before after reflow".split(" "),function(t){i[t]=function(){var n=e.toArray(arguments);return this.each(function(e){t in e&&e[t].apply(e,n)}),this}}),e.each("text name disabled active selected checked visible parent value data".split(" "),function(e){i[e]=function(t){return this.prop(e,t)}}),r=n.extend(i),t.Collection=r,r}),r(z,[p,v],function(e,t){return{id:function(){return t.DOM.uniqueId()},createFragment:function(e){return t.DOM.createFragment(e)},getWindowSize:function(){return t.DOM.getViewPort()},getSize:function(e){return t.DOM.getSize(e)},getPos:function(e,n){return t.DOM.getPos(e,n)},getViewPort:function(e){return t.DOM.getViewPort(e)},get:function(e){return document.getElementById(e)},addClass:function(e,n){return t.DOM.addClass(e,n)},removeClass:function(e,n){return t.DOM.removeClass(e,n)},hasClass:function(e,n){return t.DOM.hasClass(e,n)},toggleClass:function(e,n,r){return t.DOM.toggleClass(e,n,r)},css:function(e,n,r){return t.DOM.setStyle(e,n,r)},on:function(e,n,r,i){return t.DOM.bind(e,n,r,i)},off:function(e,n,r){return t.DOM.unbind(e,n,r)},fire:function(e,n,r){return t.DOM.fire(e,n,r)},innerHtml:function(e,n){t.DOM.setHTML(e,n)}}}),r(V,[I,p,W,z],function(e,t,n,r){var i=t.makeMap("focusin focusout scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave wheel keydown keypress keyup contextmenu"," "),o={},a="onmousewheel"in document,s=!1,l=e.extend({Statics:{controlIdLookup:{}},classPrefix:"mce-",init:function(e){var n=this,i,o;if(n.settings=e=t.extend({},n.Defaults,e),n._id=r.id(),n._text=n._name="",n._width=n._height=0,n._aria={role:e.role},i=e.classes)for(i=i.split(" "),i.map={},o=i.length;o--;)i.map[i[o]]=!0;n._classes=i||[],n.visible(!0),t.each("title text width height name classes visible disabled active value".split(" "),function(t){var r=e[t],i;r!==i?n[t](r):n["_"+t]===i&&(n["_"+t]=!1)}),n.on("click",function(){return n.disabled()?!1:void 0}),e.classes&&t.each(e.classes.split(" "),function(e){n.addClass(e)}),n.settings=e,n._borderBox=n.parseBox(e.border),n._paddingBox=n.parseBox(e.padding),n._marginBox=n.parseBox(e.margin),e.hidden&&n.hide()},Properties:"parent,title,text,width,height,disabled,active,name,value",Methods:"renderHtml",getContainerElm:function(){return document.body},getParentCtrl:function(e){for(var t;e&&!(t=l.controlIdLookup[e.id]);)e=e.parentNode;return t},parseBox:function(e){var t,n=10;if(e)return"number"==typeof e?(e=e||0,{top:e,left:e,bottom:e,right:e}):(e=e.split(" "),t=e.length,1===t?e[1]=e[2]=e[3]=e[0]:2===t?(e[2]=e[0],e[3]=e[1]):3===t&&(e[3]=e[1]),{top:parseInt(e[0],n)||0,right:parseInt(e[1],n)||0,bottom:parseInt(e[2],n)||0,left:parseInt(e[3],n)||0})},borderBox:function(){return this._borderBox},paddingBox:function(){return this._paddingBox},marginBox:function(){return this._marginBox},measureBox:function(e,t){function n(t){var n=document.defaultView;return n?(t=t.replace(/[A-Z]/g,function(e){return"-"+e}),n.getComputedStyle(e,null).getPropertyValue(t)):e.currentStyle[t]}function r(e){var t=parseInt(n(e),10);return isNaN(t)?0:t}return{top:r(t+"TopWidth"),right:r(t+"RightWidth"),bottom:r(t+"BottomWidth"),left:r(t+"LeftWidth")}},initLayoutRect:function(){var e=this,t=e.settings,n,r,i=e.getEl(),o,a,s,l,c,u,d;n=e._borderBox=e._borderBox||e.measureBox(i,"border"),e._paddingBox=e._paddingBox||e.measureBox(i,"padding"),e._marginBox=e._marginBox||e.measureBox(i,"margin"),u=t.minWidth,d=t.minHeight,s=u||i.offsetWidth,l=d||i.offsetHeight,o=t.width,a=t.height,c=t.autoResize,c="undefined"!=typeof c?c:!o&&!a,o=o||s,a=a||l;var f=n.left+n.right,p=n.top+n.bottom,h=t.maxWidth||65535,m=t.maxHeight||65535;return e._layoutRect=r={x:t.x||0,y:t.y||0,w:o,h:a,deltaW:f,deltaH:p,contentW:o-f,contentH:a-p,innerW:o-f,innerH:a-p,startMinWidth:u||0,startMinHeight:d||0,minW:Math.min(s,h),minH:Math.min(l,m),maxW:h,maxH:m,autoResize:c,scrollW:0},e._lastLayoutRect={},r},layoutRect:function(e){var t=this,n=t._layoutRect,r,i,o,a,s,c;return n||(n=t.initLayoutRect()),e?(o=n.deltaW,a=n.deltaH,e.x!==s&&(n.x=e.x),e.y!==s&&(n.y=e.y),e.minW!==s&&(n.minW=e.minW),e.minH!==s&&(n.minH=e.minH),i=e.w,i!==s&&(i=in.maxW?n.maxW:i,n.w=i,n.innerW=i-o),i=e.h,i!==s&&(i=in.maxH?n.maxH:i,n.h=i,n.innerH=i-a),i=e.innerW,i!==s&&(i=in.maxW-o?n.maxW-o:i,n.innerW=i,n.w=i+o),i=e.innerH,i!==s&&(i=in.maxH-a?n.maxH-a:i,n.innerH=i,n.h=i+a),e.contentW!==s&&(n.contentW=e.contentW),e.contentH!==s&&(n.contentH=e.contentH),r=t._lastLayoutRect,(r.x!==n.x||r.y!==n.y||r.w!==n.w||r.h!==n.h)&&(c=l.repaintControls,c&&c.map&&!c.map[t._id]&&(c.push(t),c.map[t._id]=!0),r.x=n.x,r.y=n.y,r.w=n.w,r.h=n.h),t):n},repaint:function(){var e=this,t,n,r,i,o=0,a=0,s;t=e.getEl().style,r=e._layoutRect,s=e._lastRepaintRect||{},i=e._borderBox,o=i.left+i.right,a=i.top+i.bottom,r.x!==s.x&&(t.left=r.x+"px",s.x=r.x),r.y!==s.y&&(t.top=r.y+"px",s.y=r.y),r.w!==s.w&&(t.width=r.w-o+"px",s.w=r.w),r.h!==s.h&&(t.height=r.h-a+"px",s.h=r.h),e._hasBody&&r.innerW!==s.innerW&&(n=e.getEl("body").style,n.width=r.innerW+"px",s.innerW=r.innerW),e._hasBody&&r.innerH!==s.innerH&&(n=n||e.getEl("body").style,n.height=r.innerH+"px",s.innerH=r.innerH),e._lastRepaintRect=s,e.fire("repaint",{},!1)},on:function(e,t){function n(e){var t,n;return function(i){return t||r.parents().each(function(r){var i=r.settings.callbacks;return i&&(t=i[e])?(n=r,!1):void 0}),t.call(n,i)}}var r=this,o,a,s,l;if(t)for("string"==typeof t&&(t=n(t)),s=e.toLowerCase().split(" "),l=s.length;l--;)e=s[l],o=r._bindings,o||(o=r._bindings={}),a=o[e],a||(a=o[e]=[]),a.push(t),i[e]&&(r._nativeEvents?r._nativeEvents[e]=!0:r._nativeEvents={name:!0},r._rendered&&r.bindPendingEvents());return r},off:function(e,t){var n=this,r,i=n._bindings,o,a,s,l;if(i)if(e)for(s=e.toLowerCase().split(" "),r=s.length;r--;){if(e=s[r],o=i[e],!e){for(a in i)i[a].length=0;return n}if(o)if(t)for(l=o.length;l--;)o[l]===t&&o.splice(l,1);else o.length=0}else n._bindings=[];return n},fire:function(e,t,n){function r(){return!1}function i(){return!0}var o=this,a,s,l,c;if(e=e.toLowerCase(),t=t||{},t.type||(t.type=e),t.control||(t.control=o),t.preventDefault||(t.preventDefault=function(){t.isDefaultPrevented=i},t.stopPropagation=function(){t.isPropagationStopped=i},t.stopImmediatePropagation=function(){t.isImmediatePropagationStopped=i},t.isDefaultPrevented=r,t.isPropagationStopped=r,t.isImmediatePropagationStopped=r),o._bindings&&(l=o._bindings[e]))for(a=0,s=l.length;s>a&&(t.isImmediatePropagationStopped()||l[a].call(o,t)!==!1);a++);if(n!==!1)for(c=o.parent();c&&!t.isPropagationStopped();)c.fire(e,t,!1),c=c.parent();return t},parents:function(e){var t=this,r=new n;for(t=t.parent();t;t=t.parent())r.add(t);return e&&(r=r.filter(e)),r},next:function(){var e=this.parent().items();return e[e.indexOf(this)+1]},prev:function(){var e=this.parent().items();return e[e.indexOf(this)-1]},findCommonAncestor:function(e,t){for(var n;e;){for(n=t;n&&e!=n;)n=n.parent();if(e==n)break;e=e.parent()}return e},hasClass:function(e,t){var n=this._classes[t||"control"];return e=this.classPrefix+e,n&&!!n.map[e]},addClass:function(e,t){var n=this,r,i;return e=this.classPrefix+e,r=n._classes[t||"control"],r||(r=[],r.map={},n._classes[t||"control"]=r),r.map[e]||(r.map[e]=e,r.push(e),n._rendered&&(i=n.getEl(t),i&&(i.className=r.join(" ")))),n},removeClass:function(e,t){var n=this,r,i,o;if(e=this.classPrefix+e,r=n._classes[t||"control"],r&&r.map[e])for(delete r.map[e],i=r.length;i--;)r[i]===e&&r.splice(i,1);return n._rendered&&(o=n.getEl(t),o&&(o.className=r.join(" "))),n},toggleClass:function(e,t,n){var r=this;return t?r.addClass(e,n):r.removeClass(e,n),r},classes:function(e){var t=this._classes[e||"control"];return t?t.join(" "):""},innerHtml:function(e){return r.innerHtml(this.getEl(),e),this},getEl:function(e,t){var n,i=e?this._id+"-"+e:this._id;return n=o[i]=(t===!0?null:o[i])||r.get(i)},visible:function(e){var t=this,n;return"undefined"!=typeof e?(t._visible!==e&&(t._rendered&&(t.getEl().style.display=e?"":"none"),t._visible=e,n=t.parent(),n&&(n._lastRect=null),t.fire(e?"show":"hide")),t):t._visible},show:function(){return this.visible(!0)},hide:function(){return this.visible(!1)},focus:function(){try{this.getEl().focus()}catch(e){}return this},blur:function(){return this.getEl().blur(),this},aria:function(e,t){var n=this,r=n.getEl();return"undefined"==typeof t?n._aria[e]:(n._aria[e]=t,n._rendered&&("label"==e&&r.setAttribute("aria-labeledby",n._id),r.setAttribute("role"==e?e:"aria-"+e,t)),n)},encode:function(e,t){return t!==!1&&l.translate&&(e=l.translate(e)),(e||"").replace(/[&<>"]/g,function(e){return"&#"+e.charCodeAt(0)+";"})},before:function(e){var t=this,n=t.parent();return n&&n.insert(e,n.items().indexOf(t),!0),t},after:function(e){var t=this,n=t.parent();return n&&n.insert(e,n.items().indexOf(t)),t},remove:function(){var e=this,t=e.getEl(),n=e.parent(),i,a;if(e.items){var s=e.items().toArray();for(a=s.length;a--;)s[a].remove()}if(n&&n.items&&(i=[],n.items().each(function(t){t!==e&&i.push(t)}),n.items().set(i),n._lastRect=null),e._eventsRoot&&e._eventsRoot==e&&r.off(t),delete l.controlIdLookup[e._id],delete o[e._id],t&&t.parentNode){var c=t.getElementsByTagName("*");for(a=c.length;a--;)delete o[c[a].id];t.parentNode.removeChild(t)}return e},renderBefore:function(e){var t=this;return e.parentNode.insertBefore(r.createFragment(t.renderHtml()),e),t.postRender(),t},renderTo:function(e){var t=this;return e=e||t.getContainerElm(),e.appendChild(r.createFragment(t.renderHtml())),t.postRender(),t},postRender:function(){var e=this,t=e.settings,n,i,o,a,s;for(a in t)0===a.indexOf("on")&&e.on(a.substr(2),t[a]);if(e._eventsRoot){for(o=e.parent();!s&&o;o=o.parent())s=o._eventsRoot;if(s)for(a in s._nativeEvents)e._nativeEvents[a]=!0}e.bindPendingEvents(),t.style&&(n=e.getEl(),n&&(n.setAttribute("style",t.style),n.style.cssText=t.style)),e._visible||r.css(e.getEl(),"display","none"),e.settings.border&&(i=e.borderBox(),r.css(e.getEl(),{"border-top-width":i.top,"border-right-width":i.right,"border-bottom-width":i.bottom,"border-left-width":i.left})),l.controlIdLookup[e._id]=e;for(var c in e._aria)e.aria(c,e._aria[c]);e.fire("postrender",{},!1)},scrollIntoView:function(e){function t(e,t){var n,r,i=e;for(n=r=0;i&&i!=t&&i.nodeType;)n+=i.offsetLeft||0,r+=i.offsetTop||0,i=i.offsetParent;return{x:n,y:r}}var n=this.getEl(),r=n.parentNode,i,o,a,s,l,c,u=t(n,r);return i=u.x,o=u.y,a=n.offsetWidth,s=n.offsetHeight,l=r.clientWidth,c=r.clientHeight,"end"==e?(i-=l-a,o-=c-s):"center"==e&&(i-=l/2-a/2,o-=c/2-s/2),r.scrollLeft=i,r.scrollTop=o,this},bindPendingEvents:function(){function e(e){var t=o.getParentCtrl(e.target);t&&t.fire(e.type,e)}function t(){var e=d._lastHoverCtrl;e&&(e.fire("mouseleave",{target:e.getEl()}),e.parents().each(function(e){e.fire("mouseleave",{target:e.getEl()})}),d._lastHoverCtrl=null)}function n(e){var t=o.getParentCtrl(e.target),n=d._lastHoverCtrl,r=0,i,a,s;if(t!==n){if(d._lastHoverCtrl=t,a=t.parents().toArray().reverse(),a.push(t),n){for(s=n.parents().toArray().reverse(),s.push(n),r=0;r=r;i--)n=s[i],n.fire("mouseleave",{target:n.getEl()})}for(i=r;il;l++)d=u[l]._eventsRoot;for(d||(d=u[u.length-1]||o),o._eventsRoot=d,c=l,l=0;c>l;l++)u[l]._eventsRoot=d;for(p in f){if(!f)return!1;"wheel"!==p||s?("mouseenter"===p||"mouseleave"===p?d._hasMouseEnter||(r.on(d.getEl(),"mouseleave",t),r.on(d.getEl(),"mouseover",n),d._hasMouseEnter=1):d[p]||(r.on(d.getEl(),p,e),d[p]=!0),f[p]=!1):a?r.on(o.getEl(),"mousewheel",i):r.on(o.getEl(),"DOMMouseScroll",i)}}},reflow:function(){return this.repaint(),this}});return window.elementIdCache=o,l}),r(U,[],function(){var e={},t;return{add:function(t,n){e[t.toLowerCase()]=n},has:function(t){return!!e[t.toLowerCase()]},create:function(n,r){var i,o,a;if(!t){a=tinymce.ui;for(o in a)e[o.toLowerCase()]=a[o];t=!0}if("string"==typeof n?(r=r||{},r.type=n):(r=n,n=r.type),n=n.toLowerCase(),i=e[n],!i)throw new Error("Could not find control by type: "+n);return i=new i(r),i.type=n,i}}}),r(q,[V,W,F,U,p,z],function(e,t,n,r,i,o){var a={};return e.extend({layout:"",innerClass:"container-inner",init:function(e){var n=this;n._super(e),e=n.settings,n._fixed=e.fixed,n._items=new t,n.addClass("container"),n.addClass("container-body","body"),e.containerCls&&n.addClass(e.containerCls),n._layout=r.create((e.layout||n.layout)+"layout"),n.settings.items&&n.add(n.settings.items),n._hasBody=!0},items:function(){return this._items},find:function(e){return e=a[e]=a[e]||new n(e),e.find(this)},add:function(e){var t=this;return t.items().add(t.create(e)).parent(t),t},focus:function(){var e=this;return e.keyNav?e.keyNav.focusFirst():e._super(),e},replace:function(e,t){for(var n,r=this.items(),i=r.length;i--;)if(r[i]===e){r[i]=t;break}i>=0&&(n=t.getEl(),n&&n.parentNode.removeChild(n),n=e.getEl(),n&&n.parentNode.removeChild(n)),t.parent(this)},create:function(t){var n=this,o,a=[];return i.isArray(t)||(t=[t]),i.each(t,function(t){t&&(t instanceof e||("string"==typeof t&&(t={type:t}),o=i.extend({},n.settings.defaults,t),t.type=o.type=o.type||t.type||n.settings.defaultType||(o.defaults?o.defaults.type:null),t=r.create(o)),a.push(t))}),a},renderNew:function(){var e=this;return e.items().each(function(t,n){var r,i;t.parent(e),t._rendered||(r=e.getEl("body"),i=o.createFragment(t.renderHtml()),r.hasChildNodes()&&n<=r.childNodes.length-1?r.insertBefore(i,r.childNodes[n]):r.appendChild(i),t.postRender())}),e._layout.applyClasses(e),e._lastRect=null,e},append:function(e){return this.add(e).renderNew()},prepend:function(e){var t=this;return t.items().set(t.create(e).concat(t.items().toArray())),t.renderNew()},insert:function(e,t,n){var r=this,i,o,a;return e=r.create(e),i=r.items(),!n&&t=0&&t'+'
    '+(e.settings.html||"")+t.renderHtml(e)+"
    "+""},postRender:function(){var e=this,t;return e.items().exec("postRender"),e._super(),e._layout.postRender(e),e._rendered=!0,e.settings.style&&o.css(e.getEl(),e.settings.style),e.settings.border&&(t=e.borderBox(),o.css(e.getEl(),{"border-top-width":t.top,"border-right-width":t.right,"border-bottom-width":t.bottom,"border-left-width":t.left})),e},initLayoutRect:function(){var e=this,t=e._super();return e._layout.recalc(e),t},recalc:function(){var e=this,t=e._layoutRect,n=e._lastRect;return n&&n.w==t.w&&n.h==t.h?void 0:(e._layout.recalc(e),t=e.layoutRect(),e._lastRect={x:t.x,y:t.y,w:t.w,h:t.h},!0)},reflow:function(){var t,n;if(this.visible()){for(e.repaintControls=[],e.repaintControls.map={},n=this.recalc(),t=e.repaintControls.length;t--;)e.repaintControls[t].repaint();"flow"!==this.settings.layout&&"stack"!==this.settings.layout&&this.repaint(),e.repaintControls=[]}return this}})}),r(j,[z],function(e){function t(){var e=document,t,n,r,i,o,a,s,l,c=Math.max;return t=e.documentElement,n=e.body,r=c(t.scrollWidth,n.scrollWidth),i=c(t.clientWidth,n.clientWidth),o=c(t.offsetWidth,n.offsetWidth),a=c(t.scrollHeight,n.scrollHeight),s=c(t.clientHeight,n.clientHeight),l=c(t.offsetHeight,n.offsetHeight),{width:o>r?i:r,height:l>a?s:a}}return function(n,r){function i(){return a.getElementById(r.handle||n)}var o,a=document,s,l,c,u,d,f;r=r||{},l=function(n){var l=t(),p,h;n.preventDefault(),s=n.button,p=i(),d=n.screenX,f=n.screenY,h=window.getComputedStyle?window.getComputedStyle(p,null).getPropertyValue("cursor"):p.runtimeStyle.cursor,o=a.createElement("div"),e.css(o,{position:"absolute",top:0,left:0,width:l.width,height:l.height,zIndex:2147483647,opacity:1e-4,background:"red",cursor:h}),a.body.appendChild(o),e.on(a,"mousemove",u),e.on(a,"mouseup",c),r.start(n)},u=function(e){return e.button!==s?c(e):(e.deltaX=e.screenX-d,e.deltaY=e.screenY-f,e.preventDefault(),r.drag(e),void 0)},c=function(t){e.off(a,"mousemove",u),e.off(a,"mouseup",c),o.parentNode.removeChild(o),r.stop&&r.stop(t)},this.destroy=function(){e.off(i())},e.on(i(),"mousedown",l)}}),r($,[z,j],function(e,t){return{init:function(){var e=this;e.on("repaint",e.renderScroll)},renderScroll:function(){function n(){function t(t,a,s,l,c,u){var d,f,p,h,m,g,v,y,b;if(f=i.getEl("scroll"+t)){if(y=a.toLowerCase(),b=s.toLowerCase(),i.getEl("absend")&&e.css(i.getEl("absend"),y,i.layoutRect()[l]-1),!c)return e.css(f,"display","none"),void 0;e.css(f,"display","block"),d=i.getEl("body"),p=i.getEl("scroll"+t+"t"),h=d["client"+s]-2*o,h-=n&&r?f["client"+u]:0,m=d["scroll"+s],g=h/m,v={},v[y]=d["offset"+a]+o,v[b]=h,e.css(f,v),v={},v[y]=d["scroll"+a]*g,v[b]=h*g,e.css(p,v)}}var n,r,a;a=i.getEl("body"),n=a.scrollWidth>a.clientWidth,r=a.scrollHeight>a.clientHeight,t("h","Left","Width","contentW",n,"Height"),t("v","Top","Height","contentH",r,"Width")}function r(){function n(n,r,a,s,l){var c,u=i._id+"-scroll"+n,d=i.classPrefix;i.getEl().appendChild(e.createFragment('
    '+'
    '+"
    ")),i.draghelper=new t(u+"t",{start:function(){c=i.getEl("body")["scroll"+r],e.addClass(e.get(u),d+"active")},drag:function(e){var t,u,d,f,p=i.layoutRect();u=p.contentW>p.innerW,d=p.contentH>p.innerH,f=i.getEl("body")["client"+a]-2*o,f-=u&&d?i.getEl("scroll"+n)["client"+l]:0,t=f/i.getEl("body")["scroll"+a],i.getEl("body")["scroll"+r]=c+e["delta"+s]/t},stop:function(){e.removeClass(e.get(u),d+"active")}})}i.addClass("scroll"),n("v","Top","Height","Y","Width"),n("h","Left","Width","X","Height")}var i=this,o=2;i.settings.autoScroll&&(i._hasScroll||(i._hasScroll=!0,r(),i.on("wheel",function(e){var t=i.getEl("body");t.scrollLeft+=10*(e.deltaX||0),t.scrollTop+=10*e.deltaY,n()}),e.on(i.getEl("body"),"scroll",n)),n())}}}),r(K,[q,$],function(e,t){return e.extend({Defaults:{layout:"fit",containerCls:"panel"},Mixins:[t],renderHtml:function(){var e=this,t=e._layout,n=e.settings.html;return e.preRender(),t.preRender(e),"undefined"==typeof n?n='
    '+t.renderHtml(e)+"
    ":("function"==typeof n&&(n=n.call(e)),e._hasBody=!1),'
    '+(e._preBodyHtml||"")+n+"
    "}})}),r(G,[z],function(e){function t(t,n,r){var i,o,a,s,l,c,u,d,f;return f=e.getViewPort(),o=e.getPos(n),a=o.x,s=o.y,t._fixed&&(a-=f.x,s-=f.y),i=t.getEl(),l=i.offsetWidth,c=i.offsetHeight,u=n.offsetWidth,d=n.offsetHeight,r=(r||"").split(""),"b"===r[0]&&(s+=d),"r"===r[1]&&(a+=u),"c"===r[0]&&(s+=Math.round(d/2)),"c"===r[1]&&(a+=Math.round(u/2)),"b"===r[3]&&(s-=c),"r"===r[4]&&(a-=l),"c"===r[3]&&(s-=Math.round(c/2)),"c"===r[4]&&(a-=Math.round(l/2)),{x:a,y:s,w:l,h:c}}return{testMoveRel:function(n,r){for(var i=e.getViewPort(),o=0;o0&&a.x+a.w0&&a.y+a.hi.x&&a.x+a.wi.y&&a.y+a.he?0:e+n>t?(e=t-n,0>e?0:e):e}var i=this;if(i.settings.constrainToViewport){var o=e.getViewPort(window),a=i.layoutRect();t=r(t,o.w+o.x,a.w),n=r(n,o.h+o.y,a.h)}return i._rendered?i.layoutRect({x:t,y:n}).repaint():(i.settings.x=t,i.settings.y=n),i.fire("move",{x:t,y:n}),i}}}),r(Y,[z],function(e){return{resizeToContent:function(){this._layoutRect.autoResize=!0,this._lastRect=null,this.reflow()},resizeTo:function(t,n){if(1>=t||1>=n){var r=e.getWindowSize();t=1>=t?t*r.w:t,n=1>=n?n*r.h:n}return this._layoutRect.autoResize=!1,this.layoutRect({minW:t,minH:n,w:t,h:n}).reflow()},resizeBy:function(e,t){var n=this,r=n.layoutRect();return n.resizeTo(r.w+e,r.h+t)}}}),r(X,[K,G,Y,z],function(e,t,n,r){function i(e){var t;for(t=s.length;t--;)s[t]===e&&s.splice(t,1)}var o,a,s=[],l=[],c,u=e.extend({Mixins:[t,n],init:function(e){function t(){var e,t=u.zIndex||65535,n;if(l.length)for(e=0;en&&(e.fixed(!1).layoutRect({y:e._autoFixY}).repaint(),t(!1,e._autoFixY-n)):(e._autoFixY=e.layoutRect().y,e._autoFixY'),n=n.firstChild,d.getContainerElm().appendChild(n),setTimeout(function(){r.addClass(n,i+"in"),r.addClass(d.getEl(),i+"in")},0),c=!0),l.push(d),t()}}),d.on("close hide",function(e){if(e.control==d){for(var n=l.length;n--;)l[n]===d&&l.splice(n,1);t()}}),d.on("show",function(){d.parents().each(function(e){return e._fixed?(d.fixed(!0),!1):void 0})}),e.popover&&(d._preBodyHtml='
    ',d.addClass("popover").addClass("bottom").addClass("start"))},fixed:function(e){var t=this;if(t._fixed!=e){if(t._rendered){var n=r.getViewPort();e?t.layoutRect().y-=n.y:t.layoutRect().y+=n.y}t.toggleClass("fixed",e),t._fixed=e}return t},show:function(){var e=this,t,n=e._super();for(t=s.length;t--&&s[t]!==e;);return-1===t&&s.push(e),n},hide:function(){return i(this),this._super()},hideAll:function(){u.hideAll()},close:function(){var e=this;return e.fire("close"),e.remove()},remove:function(){i(this),this._super()}});return u.hideAll=function(){for(var e=s.length;e--;){var t=s[e];t.settings.autohide&&(t.fire("cancel",{},!1),t.hide(),s.splice(e,1))}},u}),r(J,[z],function(e){return function(t){function n(){if(!h)if(h=[],d.find)d.find("*").each(function(e){e.canFocus&&h.push(e.getEl())});else for(var e=d.getEl().getElementsByTagName("*"),t=0;ti?i=l.length-1:i>=l.length&&(i=0),o=l[i],o.focus(),m=o.id,t.actOnFocus&&s()}function u(){var e,r;for(r=i(t.root.getEl()),n(),e=h.length;e--;)if("toolbar"==r&&h[e].id===m)return h[e].focus(),void 0;h[0].focus()}var d=t.root,f=t.enableUpDown!==!1,p=t.enableLeftRight!==!1,h=t.items,m;return d.on("keydown",function(e){var n=37,r=39,u=38,d=40,h=27,m=14,g=13,v=32,y=9,b;switch(e.keyCode){case n:p&&(t.leftAction?t.leftAction():c(-1),b=!0);break;case r:p&&("menuitem"==i()&&"menu"==o()?a("haspopup")&&s():c(1),b=!0);break;case u:f&&(c(-1),b=!0);break;case d:f&&("menuitem"==i()&&"menubar"==o()?s():"button"==i()&&a("haspopup")?s():c(1),b=!0);break;case y:b=!0,e.shiftKey?c(-1):c(1);break;case h:b=!0,l();break;case m:case g:case v:b=s()}b&&(e.stopPropagation(),e.preventDefault())}),d.on("focusin",function(e){n(),m=e.target.id}),{moveFocus:c,focusFirst:u,cancel:l}}}),r(Q,[X,K,z,J,j],function(e,t,n,r,i){var o=e.extend({modal:!0,Defaults:{border:1,layout:"flex",containerCls:"panel",role:"dialog",callbacks:{submit:function(){this.fire("submit",{data:this.toJSON()})},close:function(){this.close()}}},init:function(e){var n=this;n._super(e),n.addClass("window"),n._fixed=!0,e.buttons&&(n.statusbar=new t({layout:"flex",border:"1 0 0 0",spacing:3,padding:10,align:"center",pack:"end",defaults:{type:"button"},items:e.buttons}),n.statusbar.addClass("foot"),n.statusbar.parent(n)),n.on("click",function(e){-1!=e.target.className.indexOf(n.classPrefix+"close")&&n.close()}),n.aria("label",e.title),n._fullscreen=!1},recalc:function(){var e=this,t=e.statusbar,r,i,o;e._fullscreen&&(e.layoutRect(n.getWindowSize()),e.layoutRect().contentH=e.layoutRect().innerH),e._super(),r=e.layoutRect(),e.settings.title&&!e._fullscreen&&(i=r.headerW,i>r.w&&(e.layoutRect({w:i}),o=!0)),t&&(t.layoutRect({w:e.layoutRect().innerW}).recalc(),i=t.layoutRect().minW+r.deltaW,i>r.w&&(e.layoutRect({w:i}),o=!0)),o&&e.recalc()},initLayoutRect:function(){var e=this,t=e._super(),r=0,i;e.settings.title&&!e._fullscreen&&(i=e.getEl("head"),t.headerW=i.offsetWidth,t.headerH=i.offsetHeight,r+=t.headerH),e.statusbar&&(r+=e.statusbar.layoutRect().h),t.deltaH+=r,t.minH+=r,t.h+=r;var o=n.getWindowSize();return t.x=Math.max(0,o.w/2-t.w/2),t.y=Math.max(0,o.h/2-t.h/2),t},renderHtml:function(){var e=this,t=e._layout,n=e._id,r=e.classPrefix,i=e.settings,o="",a="",s=i.html;return e.preRender(),t.preRender(e),i.title&&(o='
    '+'
    '+e.encode(i.title)+"
    "+''+'
    '+"
    "),i.url&&(s=''),"undefined"==typeof s&&(s=t.renderHtml(e)),e.statusbar&&(a=e.statusbar.renderHtml()),'
    '+o+'
    '+s+"
    "+a+"
    "},fullscreen:function(e){var t=this,r=document.documentElement,i,o=t.classPrefix,a;if(e!=t._fullscreen)if(n.on(window,"resize",function(){var e;if(t._fullscreen)if(i)t._timer||(t._timer=setTimeout(function(){var e=n.getWindowSize();t.moveTo(0,0).resizeTo(e.w,e.h),t._timer=0},50));else{e=(new Date).getTime();var r=n.getWindowSize();t.moveTo(0,0).resizeTo(r.w,r.h),(new Date).getTime()-e>50&&(i=!0)}}),a=t.layoutRect(),t._fullscreen=e,e){t._initial={x:a.x,y:a.y,w:a.w,h:a.h},t._borderBox=t.parseBox("0"),t.getEl("head").style.display="none",a.deltaH-=a.headerH+2,n.addClass(r,o+"fullscreen"),n.addClass(document.body,o+"fullscreen"),t.addClass("fullscreen");var s=n.getWindowSize();t.moveTo(0,0).resizeTo(s.w,s.h)}else t._borderBox=t.parseBox(t.settings.border),t.getEl("head").style.display="",a.deltaH+=a.headerH,n.removeClass(r,o+"fullscreen"),n.removeClass(document.body,o+"fullscreen"),t.removeClass("fullscreen"),t.moveTo(t._initial.x,t._initial.y).resizeTo(t._initial.w,t._initial.h);return t.reflow()},postRender:function(){var e=this,t=[],n,o,a;setTimeout(function(){e.addClass("in")},0),e.keyboardNavigation=new r({root:e,enableLeftRight:!1,enableUpDown:!1,items:t,onCancel:function(){e.close()}}),e.find("*").each(function(e){e.canFocus&&(o=o||e.settings.autofocus,n=n||e,"filepicker"==e.type?(t.push(e.getEl("inp")),e.getEl("open")&&t.push(e.getEl("open").firstChild)):t.push(e.getEl()))}),e.statusbar&&e.statusbar.find("*").each(function(e){e.canFocus&&(o=o||e.settings.autofocus,n=n||e,t.push(e.getEl()))}),e._super(),e.statusbar&&e.statusbar.postRender(),!o&&n&&n.focus(),this.dragHelper=new i(e._id+"-dragh",{start:function(){a={x:e.layoutRect().x,y:e.layoutRect().y}},drag:function(t){e.moveTo(a.x+t.deltaX,a.y+t.deltaY)}}),e.on("submit",function(t){t.isDefaultPrevented()||e.close()})},submit:function(){var e=this.getParentCtrl(document.activeElement);return e&&e.blur(),this.fire("submit",{data:this.toJSON()})},remove:function(){var e=this;e.dragHelper.destroy(),e._super(),e.statusbar&&this.statusbar.remove()}});return o}),r(Z,[Q],function(e){var t=e.extend({init:function(e){e={border:1,padding:20,layout:"flex",pack:"center",align:"center",containerCls:"panel",autoScroll:!0,buttons:{type:"button",text:"Ok",action:"ok"},items:{type:"label",multiline:!0,maxWidth:500,maxHeight:200}},this._super(e)},Statics:{OK:1,OK_CANCEL:2,YES_NO:3,YES_NO_CANCEL:4,msgBox:function(n){var r,i=n.callback||function(){};switch(n.buttons){case t.OK_CANCEL:r=[{type:"button",text:"Ok",subtype:"primary",onClick:function(e){e.control.parents()[1].close(),i(!0)}},{type:"button",text:"Cancel",onClick:function(e){e.control.parents()[1].close(),i(!1)}}];break;case t.YES_NO:r=[{type:"button",text:"Ok",subtype:"primary",onClick:function(e){e.control.parents()[1].close(),i(!0)}}];break;case t.YES_NO_CANCEL:r=[{type:"button",text:"Ok",subtype:"primary",onClick:function(e){e.control.parents()[1].close()}}];break;default:r=[{type:"button",text:"Ok",subtype:"primary",onClick:function(e){e.control.parents()[1].close()}}]}return new e({padding:20,x:n.x,y:n.y,minWidth:300,minHeight:100,layout:"flex",pack:"center",align:"center",buttons:r,title:n.title,items:{type:"label",multiline:!0,maxWidth:500,maxHeight:200,text:n.text},onClose:n.onClose}).renderTo(document.body).reflow()},alert:function(e,n){return"string"==typeof e&&(e={text:e}),e.callback=n,t.msgBox(e)},confirm:function(e,n){return"string"==typeof e&&(e={text:e}),e.callback=n,e.buttons=t.OK_CANCEL,t.msgBox(e)}}});return t}),r(et,[Q,Z],function(e,t){return function(n){function r(){return o.length?o[o.length-1]:void 0}var i=this,o=[];i.windows=o,i.open=function(t,r){var i;return n.editorManager.activeEditor=n,t.title=t.title||" ",t.url=t.url||t.file,t.url&&(t.width=parseInt(t.width||320,10),t.height=parseInt(t.height||240,10)),t.body&&(t.items={defaults:t.defaults,type:t.bodyType||"form",items:t.body}),t.url||t.buttons||(t.buttons=[{text:"Ok",subtype:"primary",onclick:function(){i.find("form")[0].submit(),i.close() +}},{text:"Cancel",onclick:function(){i.close()}}]),i=new e(t),o.push(i),i.on("close",function(){for(var e=o.length;e--;)o[e]===i&&o.splice(e,1);n.focus()}),t.data&&i.on("postRender",function(){this.find("*").each(function(e){var n=e.name();n in t.data&&e.value(t.data[n])})}),i.features=t||{},i.params=r||{},n.nodeChanged(),i.renderTo(document.body).reflow()},i.alert=function(e,n,r){t.alert(e,function(){n.call(r||this)})},i.confirm=function(e,n,r){t.confirm(e,function(e){n.call(r||this,e)})},i.close=function(){r()&&r().close()},i.getParams=function(){return r()?r().params:null},i.setParams=function(e){r()&&(r().params=e)}}}),r(tt,[T,B,C,m,g,p],function(e,t,n,r,i,o){return function(a){function s(e,t){try{a.getDoc().execCommand(e,!1,t)}catch(n){}}function l(){var e=a.getDoc().documentMode;return e?e:6}function c(e){return e.isDefaultPrevented()}function u(){function t(e){function t(){if(3==l.nodeType){if(e&&c==l.length)return!0;if(!e&&0===c)return!0}}var n,r,i,s,l,c,u;n=z.getRng();var d=[n.startContainer,n.startOffset,n.endContainer,n.endOffset];if(n.collapsed||(e=!0),l=n[(e?"start":"end")+"Container"],c=n[(e?"start":"end")+"Offset"],3==l.nodeType&&(r=W.getParent(n.startContainer,W.isBlock),e&&(r=W.getNext(r,W.isBlock)),!r||!t()&&n.collapsed||(i=W.create("em",{id:"__mceDel"}),O(o.grep(r.childNodes),function(e){i.appendChild(e)}),r.appendChild(i))),n=W.createRng(),n.setStart(d[0],d[1]),n.setEnd(d[2],d[3]),z.setRng(n),a.getDoc().execCommand(e?"ForwardDelete":"Delete",!1,null),i){for(s=z.getBookmark();u=W.get("__mceDel");)W.remove(u,!0);z.moveToBookmark(s)}}a.on("keydown",function(n){var r;r=n.keyCode==F,c(n)||!r&&n.keyCode!=I||e.modifierPressed(n)||(n.preventDefault(),t(r))}),a.addCommand("Delete",function(){t()})}function d(){function e(e){var t=W.create("body"),n=e.cloneContents();return t.appendChild(n),z.serializer.serialize(t,{format:"html"})}function t(t){var n=e(t),r=W.createRng();r.selectNode(a.getBody());var i=e(r);return n===i}a.on("keydown",function(e){var n=e.keyCode,r;if(!c(e)&&(n==F||n==I)){if(r=a.selection.isCollapsed(),r&&!W.isEmpty(a.getBody()))return;if($&&!r)return;if(!r&&!t(a.selection.getRng()))return;e.preventDefault(),a.setContent(""),a.selection.setCursorLocation(a.getBody(),0),a.nodeChanged()}})}function f(){a.on("keydown",function(t){!c(t)&&65==t.keyCode&&e.metaKeyPressed(t)&&(t.preventDefault(),a.execCommand("SelectAll"))})}function p(){a.settings.content_editable||(W.bind(a.getDoc(),"focusin",function(){z.setRng(z.getRng())}),W.bind(a.getDoc(),"mousedown",function(e){e.target==a.getDoc().documentElement&&(a.getWin().focus(),z.setRng(z.getRng()))}))}function h(){a.on("keydown",function(e){if(!c(e)&&e.keyCode===I&&z.isCollapsed()&&0===z.getRng(!0).startOffset){var t=z.getNode(),n=t.previousSibling;if("HR"==t.nodeName)return W.remove(t),e.preventDefault(),void 0;n&&n.nodeName&&"hr"===n.nodeName.toLowerCase()&&(W.remove(n),e.preventDefault())}})}function m(){window.Range.prototype.getClientRects||a.on("mousedown",function(e){if(!c(e)&&"HTML"===e.target.nodeName){var t=a.getBody();t.blur(),setTimeout(function(){t.focus()},0)}})}function g(){a.on("click",function(e){e=e.target,/^(IMG|HR)$/.test(e.nodeName)&&z.getSel().setBaseAndExtent(e,0,e,1),"A"==e.nodeName&&W.hasClass(e,"mce-item-anchor")&&z.select(e),a.nodeChanged()})}function v(){function e(){var e=W.getAttribs(z.getStart().cloneNode(!1));return function(){var t=z.getStart();t!==a.getBody()&&(W.setAttrib(t,"style",null),O(e,function(e){t.setAttributeNode(e.cloneNode(!0))}))}}function t(){return!z.isCollapsed()&&W.getParent(z.getStart(),W.isBlock)!=W.getParent(z.getEnd(),W.isBlock)}a.on("keypress",function(n){var r;return c(n)||8!=n.keyCode&&46!=n.keyCode||!t()?void 0:(r=e(),a.getDoc().execCommand("delete",!1,null),r(),n.preventDefault(),!1)}),W.bind(a.getDoc(),"cut",function(n){var r;!c(n)&&t()&&(r=e(),setTimeout(function(){r()},0))})}function y(){var e,n;a.on("selectionchange",function(){n&&(clearTimeout(n),n=0),n=window.setTimeout(function(){var n=z.getRng();e&&t.compareRanges(n,e)||(a.nodeChanged(),e=n)},50)})}function b(){document.body.setAttribute("role","application")}function C(){a.on("keydown",function(e){if(!c(e)&&e.keyCode===I&&z.isCollapsed()&&0===z.getRng(!0).startOffset){var t=z.getNode().previousSibling;if(t&&t.nodeName&&"table"===t.nodeName.toLowerCase())return e.preventDefault(),!1}})}function x(){l()>7||(s("RespectVisibilityInDesign",!0),a.contentStyles.push(".mceHideBrInPre pre br {display: none}"),W.addClass(a.getBody(),"mceHideBrInPre"),U.addNodeFilter("pre",function(e){for(var t=e.length,r,i,o,a;t--;)for(r=e[t].getAll("br"),i=r.length;i--;)o=r[i],a=o.prev,a&&3===a.type&&"\n"!=a.value.charAt(a.value-1)?a.value+="\n":o.parent.insert(new n("#text",3),o,!0).value="\n"}),q.addNodeFilter("pre",function(e){for(var t=e.length,n,r,i,o;t--;)for(n=e[t].getAll("br"),r=n.length;r--;)i=n[r],o=i.prev,o&&3==o.type&&(o.value=o.value.replace(/\r?\n$/,""))}))}function w(){W.bind(a.getBody(),"mouseup",function(){var e,t=z.getNode();"IMG"==t.nodeName&&((e=W.getStyle(t,"width"))&&(W.setAttrib(t,"width",e.replace(/[^0-9%]+/g,"")),W.setStyle(t,"width","")),(e=W.getStyle(t,"height"))&&(W.setAttrib(t,"height",e.replace(/[^0-9%]+/g,"")),W.setStyle(t,"height","")))})}function _(){a.on("keydown",function(t){var n,r,i,o,s,l,u,d;if(n=t.keyCode==F,!c(t)&&(n||t.keyCode==I)&&!e.modifierPressed(t)&&(r=z.getRng(),i=r.startContainer,o=r.startOffset,u=r.collapsed,3==i.nodeType&&i.nodeValue.length>0&&(0===o&&!u||u&&o===(n?0:1)))){if(l=i.previousSibling,l&&"IMG"==l.nodeName)return;d=a.schema.getNonEmptyElements(),t.preventDefault(),s=W.create("br",{id:"__tmp"}),i.parentNode.insertBefore(s,i),a.getDoc().execCommand(n?"ForwardDelete":"Delete",!1,null),i=z.getRng().startContainer,l=i.previousSibling,l&&1==l.nodeType&&!W.isBlock(l)&&W.isEmpty(l)&&!d[l.nodeName.toLowerCase()]&&W.remove(l),W.remove("__tmp")}})}function N(){a.on("keydown",function(t){var n,r,i,o,s;if(!c(t)&&t.keyCode==e.BACKSPACE&&(n=z.getRng(),r=n.startContainer,i=n.startOffset,o=W.getRoot(),s=r,n.collapsed&&0===i)){for(;s&&s.parentNode&&s.parentNode.firstChild==s&&s.parentNode!=o;)s=s.parentNode;"BLOCKQUOTE"===s.tagName&&(a.formatter.toggle("blockquote",null,s),n=W.createRng(),n.setStart(r,0),n.setEnd(r,0),z.setRng(n))}})}function E(){function e(){a._refreshContentEditable(),s("StyleWithCSS",!1),s("enableInlineTableEditing",!1),V.object_resizing||s("enableObjectResizing",!1)}V.readonly||a.on("BeforeExecCommand MouseDown",e)}function k(){function e(){O(W.select("a"),function(e){var t=e.parentNode,n=W.getRoot();if(t.lastChild===e){for(;t&&!W.isBlock(t);){if(t.parentNode.lastChild!==t||t===n)return;t=t.parentNode}W.add(t,"br",{"data-mce-bogus":1})}})}a.on("SetContent ExecCommand",function(t){("setcontent"==t.type||"mceInsertLink"===t.command)&&e()})}function S(){V.forced_root_block&&a.on("init",function(){s("DefaultParagraphSeparator",V.forced_root_block)})}function T(){a.on("Undo Redo SetContent",function(e){e.initial||a.execCommand("mceRepaint")})}function R(){a.on("keydown",function(e){var t;c(e)||e.keyCode!=I||(t=a.getDoc().selection.createRange(),t&&t.item&&(e.preventDefault(),a.undoManager.beforeChange(),W.remove(t.item(0)),a.undoManager.add()))})}function A(){var e;l()>=10&&(e="",O("p div h1 h2 h3 h4 h5 h6".split(" "),function(t,n){e+=(n>0?",":"")+t+":empty"}),a.contentStyles.push(e+"{padding-right: 1px !important}"))}function B(){l()<9&&(U.addNodeFilter("noscript",function(e){for(var t=e.length,n,r;t--;)n=e[t],r=n.firstChild,r&&n.attr("data-mce-innertext",r.value)}),q.addNodeFilter("noscript",function(e){for(var t=e.length,i,o,a;t--;)i=e[t],o=e[t].firstChild,o?o.value=r.decode(o.value):(a=i.attributes.map["data-mce-innertext"],a&&(i.attr("data-mce-innertext",null),o=new n("#text",3),o.value=a,o.raw=!0,i.append(o)))}))}function D(){function e(e,t){var n=i.createTextRange();try{n.moveToPoint(e,t)}catch(r){n=null}return n}function t(t){var r;t.button?(r=e(t.x,t.y),r&&(r.compareEndPoints("StartToStart",a)>0?r.setEndPoint("StartToStart",a):r.setEndPoint("EndToEnd",a),r.select())):n()}function n(){var e=r.selection.createRange();a&&!e.item&&0===e.compareEndPoints("StartToEnd",e)&&a.select(),W.unbind(r,"mouseup",n),W.unbind(r,"mousemove",t),a=o=0}var r=W.doc,i=r.body,o,a,s;r.documentElement.unselectable=!0,W.bind(r,"mousedown contextmenu",function(i){if("HTML"===i.target.nodeName){if(o&&n(),s=r.documentElement,s.scrollHeight>s.clientHeight)return;o=1,a=e(i.x,i.y),a&&(W.bind(r,"mouseup",n),W.bind(r,"mousemove",t),W.win.focus(),a.select())}})}function H(){a.on("keyup focusin",function(t){65==t.keyCode&&e.metaKeyPressed(t)||z.normalize()})}function L(){a.contentStyles.push("img:-moz-broken {-moz-force-broken-image-icon:1;min-width:24px;min-height:24px}")}function M(){a.inline||a.on("keydown",function(){document.activeElement==document.body&&a.getWin().focus()})}function P(){a.inline||(a.contentStyles.push("body {min-height: 150px}"),a.on("click",function(e){"HTML"==e.target.nodeName&&(a.execCommand("SelectAll"),a.selection.collapse(!0))}))}var O=o.each,I=e.BACKSPACE,F=e.DELETE,W=a.dom,z=a.selection,V=a.settings,U=a.parser,q=a.serializer,j=i.gecko,$=i.ie,K=i.webkit;C(),N(),d(),H(),K&&(_(),u(),p(),g(),S(),i.iOS?(y(),M()):f()),$&&i.ie<11&&(h(),b(),x(),w(),R(),A(),B(),D()),i.ie>=11&&P(),j&&(h(),m(),v(),E(),k(),T(),L())}}),r(nt,[p],function(e){function t(){return!1}function n(){return!0}var r="__bindings",i=e.makeMap("focusin focusout click dblclick mousedown mouseup mousemove mouseover beforepaste paste cut copy selectionchange mouseout mouseenter mouseleave keydown keypress keyup contextmenu dragend dragover draggesture dragdrop drop drag"," ");return{fire:function(e,i,o){var a=this,s,l,c,u,d;if(e=e.toLowerCase(),i=i||{},i.type=e,i.target||(i.target=a),i.preventDefault||(i.preventDefault=function(){i.isDefaultPrevented=n},i.stopPropagation=function(){i.isPropagationStopped=n},i.stopImmediatePropagation=function(){i.isImmediatePropagationStopped=n},i.isDefaultPrevented=t,i.isPropagationStopped=t,i.isImmediatePropagationStopped=t),a[r]&&(s=a[r][e]))for(l=0,c=s.length;c>l&&(s[l]=u=s[l],!i.isImmediatePropagationStopped());l++)if(u.call(a,i)===!1)return i.preventDefault(),i;if(o!==!1&&a.parent)for(d=a.parent();d&&!i.isPropagationStopped();)d.fire(e,i,!1),d=d.parent();return i},on:function(e,t){var n=this,o,a,s,l;if(t===!1&&(t=function(){return!1}),t)for(s=e.toLowerCase().split(" "),l=s.length;l--;)e=s[l],o=n[r],o||(o=n[r]={}),a=o[e],a||(a=o[e]=[],n.bindNative&&i[e]&&n.bindNative(e)),a.push(t);return n},off:function(e,t){var n=this,o,a=n[r],s,l,c,u;if(a)if(e)for(c=e.toLowerCase().split(" "),o=c.length;o--;){if(e=c[o],s=a[e],!e){for(l in a)a[e].length=0;return n}if(s){if(t)for(u=s.length;u--;)s[u]===t&&s.splice(u,1);else s.length=0;!s.length&&n.unbindNative&&i[e]&&(n.unbindNative(e),delete a[e])}}else{if(n.unbindNative)for(e in a)n.unbindNative(e);n[r]=[]}return n}}}),r(rt,[p,g],function(e,t){var n=e.each,r=e.explode,i={f9:120,f10:121,f11:122};return function(o){var a=this,s={};o.on("keyup keypress keydown",function(e){(e.altKey||e.ctrlKey||e.metaKey)&&n(s,function(n){var r=t.mac?e.ctrlKey||e.metaKey:e.ctrlKey;if(n.ctrl==r&&n.alt==e.altKey&&n.shift==e.shiftKey)return e.keyCode==n.keyCode||e.charCode&&e.charCode==n.charCode?(e.preventDefault(),"keydown"==e.type&&n.func.call(n.scope),!0):void 0})}),a.add=function(t,a,l,c){var u;return u=l,"string"==typeof l?l=function(){o.execCommand(u,!1,null)}:e.isArray(u)&&(l=function(){o.execCommand(u[0],u[1],u[2])}),n(r(t.toLowerCase()),function(e){var t={func:l,scope:c||o,desc:o.translate(a),alt:!1,ctrl:!1,shift:!1};n(r(e,"+"),function(e){switch(e){case"alt":case"ctrl":case"shift":t[e]=!0;break;default:t.charCode=e.charCodeAt(0),t.keyCode=i[e]||e.toUpperCase().charCodeAt(0)}}),s[(t.ctrl?"ctrl":"")+","+(t.alt?"alt":"")+","+(t.shift?"shift":"")+","+t.keyCode]=t}),!0}}}),r(it,[v,b,C,k,E,A,D,H,L,M,P,O,y,l,et,x,_,tt,g,p,nt,rt],function(e,n,r,i,o,a,s,l,c,u,d,f,p,h,m,g,v,y,b,C,x,w){function _(e,t){return"selectionchange"==t||"drop"==t?e.getDoc():!e.inline&&/^mouse|click|contextmenu/.test(t)?e.getDoc():e.getBody()}function N(e,t,r){var i=this,o,a;o=i.documentBaseUrl=r.documentBaseURL,a=r.baseURI,i.settings=t=T({id:e,theme:"modern",delta_width:0,delta_height:0,popup_css:"",plugins:"",document_base_url:o,add_form_submit_trigger:!0,submit_patch:!0,add_unload_trigger:!0,convert_urls:!0,relative_urls:!0,remove_script_host:!0,object_resizing:!0,doctype:"",visual:!0,font_size_style_values:"xx-small,x-small,small,medium,large,x-large,xx-large",font_size_legacy_values:"xx-small,small,medium,large,x-large,xx-large,300%",forced_root_block:"p",hidden_input:!0,padd_empty_editor:!0,render_ui:!0,indentation:"30px",inline_styles:!0,convert_fonts_to_spans:!0,indent:"simple",indent_before:"p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,ul,li,area,table,thead,tfoot,tbody,tr,section,article,hgroup,aside,figure,option,optgroup,datalist",indent_after:"p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,ul,li,area,table,thead,tfoot,tbody,tr,section,article,hgroup,aside,figure,option,optgroup,datalist",validate:!0,entity_encoding:"named",url_converter:i.convertURL,url_converter_scope:i,ie7_compat:!0},t),n.language=t.language||"en",n.languageLoad=t.language_load,n.baseURL=r.baseURL,i.id=t.id=e,i.isNotDirty=!0,i.plugins={},i.documentBaseURI=new f(t.document_base_url||o,{base_uri:a}),i.baseURI=a,i.contentCSS=[],i.contentStyles=[],i.shortcuts=new w(i),i.execCommands={},i.queryStateCommands={},i.queryValueCommands={},i.loadedCSS={},i.suffix=r.suffix,i.editorManager=r,i.inline=t.inline,i.execCallback("setup",i),r.fire("SetupEditor",i)}var E=e.DOM,k=n.ThemeManager,S=n.PluginManager,T=C.extend,R=C.each,A=C.explode,B=C.inArray,D=C.trim,H=C.resolve,L=h.Event,M=b.gecko,P=b.ie,O=b.opera;return N.prototype={render:function(){function e(){E.unbind(window,"ready",e),n.render()}function t(){var e=p.ScriptLoader;if(r.language&&"en"!=r.language&&(r.language_url=n.editorManager.baseURL+"/langs/"+r.language+".js"),r.language_url&&e.add(r.language_url),r.theme&&"function"!=typeof r.theme&&"-"!=r.theme.charAt(0)&&!k.urls[r.theme]){var t=r.theme_url;t=t?n.documentBaseURI.toAbsolute(t):"themes/"+r.theme+"/theme"+o+".js",k.load(r.theme,t)}C.isArray(r.plugins)&&(r.plugins=r.plugins.join(" ")),R(r.external_plugins,function(e,t){S.load(t,e),r.plugins+=" "+t}),R(r.plugins.split(/[ ,]/),function(e){if(e=D(e),e&&!S.urls[e])if("-"==e.charAt(0)){e=e.substr(1,e.length);var t=S.dependencies(e);R(t,function(e){var t={prefix:"plugins/",resource:e,suffix:"/plugin"+o+".js"};e=S.createUrl(t,e),S.load(e.resource,e)})}else S.load(e,{prefix:"plugins/",resource:e,suffix:"/plugin"+o+".js"})}),e.loadQueue(function(){n.removed||n.init()})}var n=this,r=n.settings,i=n.id,o=n.suffix;if(!L.domLoaded)return E.bind(window,"ready",e),void 0;if(n.getElement()&&b.contentEditable){r.inline?n.inline=!0:(n.orgVisibility=n.getElement().style.visibility,n.getElement().style.visibility="hidden");var a=n.getElement().form||E.getParent(i,"form");a&&(n.formElement=a,r.hidden_input&&!/TEXTAREA|INPUT/i.test(n.getElement().nodeName)&&E.insertAfter(E.create("input",{type:"hidden",name:i}),i),n.formEventDelegate=function(e){n.fire(e.type,e)},E.bind(a,"submit reset",n.formEventDelegate),n.on("reset",function(){n.setContent(n.startContent,{format:"raw"})}),!r.submit_patch||a.submit.nodeType||a.submit.length||a._mceOldSubmit||(a._mceOldSubmit=a.submit,a.submit=function(){return n.editorManager.triggerSave(),n.isNotDirty=!0,a._mceOldSubmit(a)})),n.windowManager=new m(n),"xml"==r.encoding&&n.on("GetContent",function(e){e.save&&(e.content=E.encode(e.content))}),r.add_form_submit_trigger&&n.on("submit",function(){n.initialized&&n.save()}),r.add_unload_trigger&&(n._beforeUnload=function(){!n.initialized||n.destroyed||n.isHidden()||n.save({format:"raw",no_events:!0,set_dirty:!1})},n.editorManager.on("BeforeUnload",n._beforeUnload)),t()}},init:function(){function e(n){var r=S.get(n),i,o;i=S.urls[n]||t.documentBaseUrl.replace(/\/$/,""),n=D(n),r&&-1===B(h,n)&&(R(S.dependencies(n),function(t){e(t)}),o=new r(t,i),t.plugins[n]=o,o.init&&(o.init(t,i),h.push(n)))}var t=this,n=t.settings,r=t.getElement(),i,o,a,s,l,c,u,d,f,p,h=[];if(t.editorManager.add(t),n.aria_label=n.aria_label||E.getAttrib(r,"aria-label",t.getLang("aria.rich_text_area")),n.theme&&("function"!=typeof n.theme?(n.theme=n.theme.replace(/-/,""),l=k.get(n.theme),t.theme=new l(t,k.urls[n.theme]),t.theme.init&&t.theme.init(t,k.urls[n.theme]||t.documentBaseUrl.replace(/\/$/,""))):t.theme=n.theme),R(n.plugins.replace(/\-/g,"").split(/[ ,]/),e),t.fire("BeforeRenderUI"),n.render_ui&&t.theme&&(t.orgDisplay=r.style.display,"function"!=typeof n.theme?(i=n.width||r.style.width||r.offsetWidth,o=n.height||r.style.height||r.offsetHeight,a=n.min_height||100,f=/^[0-9\.]+(|px)$/i,f.test(""+i)&&(i=Math.max(parseInt(i,10)+(l.deltaWidth||0),100)),f.test(""+o)&&(o=Math.max(parseInt(o,10)+(l.deltaHeight||0),a)),l=t.theme.renderUI({targetNode:r,width:i,height:o,deltaWidth:n.delta_width,deltaHeight:n.delta_height}),n.content_editable||(E.setStyles(l.sizeContainer||l.editorContainer,{wi2dth:i,h2eight:o}),o=(l.iframeHeight||o)+("number"==typeof o?l.deltaHeight||0:""),a>o&&(o=a))):(l=n.theme(t,r),l.editorContainer.nodeType&&(l.editorContainer=l.editorContainer.id=l.editorContainer.id||t.id+"_parent"),l.iframeContainer.nodeType&&(l.iframeContainer=l.iframeContainer.id=l.iframeContainer.id||t.id+"_iframecontainer"),o=l.iframeHeight||r.offsetHeight),t.editorContainer=l.editorContainer),n.content_css&&R(A(n.content_css),function(e){t.contentCSS.push(t.documentBaseURI.toAbsolute(e))}),n.content_style&&t.contentStyles.push(n.content_style),n.content_editable)return r=s=l=null,t.initContentBody();for(document.domain&&location.hostname!=document.domain&&(t.editorManager.relaxedDomain=document.domain),t.iframeHTML=n.doctype+"",n.document_base_url!=t.documentBaseUrl&&(t.iframeHTML+=''),!b.caretAfter&&n.ie7_compat&&(t.iframeHTML+=''),t.iframeHTML+='',p=0;p',t.loadedCSS[m]=!0}u=n.body_id||"tinymce",-1!=u.indexOf("=")&&(u=t.getParam("body_id","","hash"),u=u[t.id]||u),d=n.body_class||"",-1!=d.indexOf("=")&&(d=t.getParam("body_class","","hash"),d=d[t.id]||""),t.iframeHTML+='
    ",t.editorManager.relaxedDomain&&(P||O&&parseFloat(window.opera.version())<11)&&(c='javascript:(function(){document.open();document.domain="'+document.domain+'";'+'var ed = window.parent.tinymce.get("'+t.id+'");document.write(ed.iframeHTML);'+"document.close();ed.initContentBody();})()"),s=E.add(l.iframeContainer,"iframe",{id:t.id+"_ifr",src:c||'javascript:""',frameBorder:"0",allowTransparency:"true",title:t.editorManager.translate("Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help"),style:{width:"100%",height:o,display:"block"}}),t.contentAreaContainer=l.iframeContainer,l.editorContainer&&(E.get(l.editorContainer).style.display=t.orgDisplay),E.get(t.id).style.display="none",E.setAttrib(t.id,"aria-hidden",!0),t.editorManager.relaxedDomain&&c||t.initContentBody(),r=s=l=null},initContentBody:function(){var t=this,n=t.settings,o=E.get(t.id),f=t.getDoc(),p,h;n.inline||(t.getElement().style.visibility=t.orgVisibility),P&&t.editorManager.relaxedDomain||n.content_editable||(f.open(),f.write(t.iframeHTML),f.close(),t.editorManager.relaxedDomain&&(f.domain=t.editorManager.relaxedDomain)),n.content_editable&&(t.on("remove",function(){var e=this.getBody();E.removeClass(e,"mce-content-body"),E.removeClass(e,"mce-edit-focus"),E.setAttrib(e,"tabIndex",null),E.setAttrib(e,"contentEditable",null)}),E.addClass(o,"mce-content-body"),o.tabIndex=-1,t.contentDocument=f=n.content_document||document,t.contentWindow=n.content_window||window,t.bodyElement=o,n.content_document=n.content_window=null,n.root_name=o.nodeName.toLowerCase()),p=t.getBody(),p.disabled=!0,n.readonly||(p.contentEditable=t.getParam("content_editable_state",!0)),p.disabled=!1,t.schema=new g(n),t.dom=new e(f,{keep_values:!0,url_converter:t.convertURL,url_converter_scope:t,hex_colors:n.force_hex_style_colors,class_filter:n.class_filter,update_styles:!0,root_element:n.content_editable?t.id:null,collect:n.content_editable,schema:t.schema,onSetAttrib:function(e){t.fire("SetAttrib",e)}}),t.parser=new v(n,t.schema),t.parser.addAttributeFilter("src,href,style",function(e,n){for(var r=e.length,i,o=t.dom,a,s;r--;)i=e[r],a=i.attr(n),s="data-mce-"+n,i.attributes.map[s]||("style"===n?i.attr(s,o.serializeStyle(o.parseStyle(a),i.name)):i.attr(s,t.convertURL(a,n,i.name)))}),t.parser.addNodeFilter("script",function(e){for(var t=e.length,n;t--;)n=e[t],n.attr("type","mce-"+(n.attr("type")||"text/javascript"))}),t.parser.addNodeFilter("#cdata",function(e){for(var t=e.length,n;t--;)n=e[t],n.type=8,n.name="#comment",n.value="[CDATA["+n.value+"]]"}),t.parser.addNodeFilter("p,h1,h2,h3,h4,h5,h6,div",function(e){for(var n=e.length,i,o=t.schema.getNonEmptyElements();n--;)i=e[n],i.isEmpty(o)&&(i.empty().append(new r("br",1)).shortEnded=!0)}),t.serializer=new i(n,t),t.selection=new a(t.dom,t.getWin(),t.serializer,t),t.formatter=new s(t),t.undoManager=new l(t),t.forceBlocks=new u(t),t.enterKey=new c(t),t.editorCommands=new d(t),t.fire("PreInit"),n.browser_spellcheck||n.gecko_spellcheck||(f.body.spellcheck=!1,E.setAttrib(p,"spellcheck","false")),t.fire("PostRender"),t.quirks=y(t),n.directionality&&(p.dir=n.directionality),n.nowrap&&(p.style.whiteSpace="nowrap"),n.protect&&t.on("BeforeSetContent",function(e){R(n.protect,function(t){e.content=e.content.replace(t,function(e){return""})})}),t.on("SetContent",function(){t.addVisual(t.getBody())}),n.padd_empty_editor&&t.on("PostProcess",function(e){e.content=e.content.replace(/^(]*>( | |\s|\u00a0|)<\/p>[\r\n]*|
    [\r\n]*)$/,"")}),t.load({initial:!0,format:"html"}),t.startContent=t.getContent({format:"raw"}),t.initialized=!0,R(t._pendingNativeEvents,function(e){t.dom.bind(_(t,e),e,function(e){t.fire(e.type,e)})}),t.fire("init"),t.focus(!0),t.nodeChanged({initial:!0}),t.execCallback("init_instance_callback",t),t.contentStyles.length>0&&(h="",R(t.contentStyles,function(e){h+=e+"\r\n"}),t.dom.addStyle(h)),R(t.contentCSS,function(e){t.loadedCSS[e]||(t.dom.loadCSS(e),t.loadedCSS[e]=!0)}),n.auto_focus&&setTimeout(function(){var e=t.editorManager.get(n.auto_focus);e.selection.select(e.getBody(),1),e.selection.collapse(1),e.getBody().focus(),e.getWin().focus()},100),o=f=p=null},focus:function(e){var t,n=this,r=n.selection,i=n.settings.content_editable,o,a,s=n.getDoc(),l;e||(o=r.getRng(),o.item&&(a=o.item(0)),n._refreshContentEditable(),i||(b.opera||n.getBody().focus(),n.getWin().focus()),(M||i)&&(l=n.getBody(),l.setActive?l.setActive():l.focus(),i&&r.normalize()),a&&a.ownerDocument==s&&(o=s.body.createControlRange(),o.addElement(a),o.select())),n.editorManager.activeEditor!=n&&((t=n.editorManager.activeEditor)&&t.fire("deactivate",{relatedTarget:n}),n.fire("activate",{relatedTarget:t})),n.editorManager.activeEditor=n},execCallback:function(e){var t=this,n=t.settings[e],r;if(n)return t.callbackLookup&&(r=t.callbackLookup[e])&&(n=r.func,r=r.scope),"string"==typeof n&&(r=n.replace(/\.\w+$/,""),r=r?H(r):0,n=H(n),t.callbackLookup=t.callbackLookup||{},t.callbackLookup[e]={func:n,scope:r}),n.apply(r||t,Array.prototype.slice.call(arguments,1))},translate:function(e){var t=this.settings.language||"en",n=this.editorManager.i18n;return e?n.data[t+"."+e]||e.replace(/\{\#([^\}]+)\}/g,function(e,r){return n.data[t+"."+r]||"{#"+r+"}"}):""},getLang:function(e,n){return this.editorManager.i18n.data[(this.settings.language||"en")+"."+e]||(n!==t?n:"{#"+e+"}")},getParam:function(e,t,n){var r=e in this.settings?this.settings[e]:t,i;return"hash"===n?(i={},"string"==typeof r?R(r.indexOf("=")>0?r.split(/[;,](?![^=;,]*(?:[;,]|$))/):r.split(","),function(e){e=e.split("="),i[D(e[0])]=e.length>1?D(e[1]):D(e)}):i=r,i):r},nodeChanged:function(){var e=this,t=e.selection,n,r,i;e.initialized&&!e.settings.disable_nodechange&&(i=e.getBody(),n=t.getStart()||i,n=P&&n.ownerDocument!=e.getDoc()?e.getBody():n,"IMG"==n.nodeName&&t.isCollapsed()&&(n=n.parentNode),r=[],e.dom.getParent(n,function(e){return e===i?!0:(r.push(e),void 0)}),e.fire("NodeChange",{element:n,parents:r}))},addButton:function(e,t){var n=this;t.cmd&&(t.onclick=function(){n.execCommand(t.cmd)}),t.text||t.icon||(t.icon=e),n.buttons=n.buttons||{},t.tooltip=t.tooltip||t.title,n.buttons[e]=t},addMenuItem:function(e,t){var n=this;t.cmd&&(t.onclick=function(){n.execCommand(t.cmd)}),n.menuItems=n.menuItems||{},n.menuItems[e]=t},addCommand:function(e,t,n){this.execCommands[e]={func:t,scope:n||this}},addQueryStateHandler:function(e,t,n){this.queryStateCommands[e]={func:t,scope:n||this}},addQueryValueHandler:function(e,t,n){this.queryValueCommands[e]={func:t,scope:n||this}},addShortcut:function(e,t,n,r){this.shortcuts.add(e,t,n,r)},execCommand:function(e,t,n,r){var i=this,o=0,a;return/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint)$/.test(e)||r&&r.skip_focus||i.focus(),r=T({},r),r=i.fire("BeforeExecCommand",{command:e,ui:t,value:n}),r.isDefaultPrevented()?!1:(a=i.execCommands[e])&&a.func.call(a.scope,t,n)!==!0?(i.fire("ExecCommand",{command:e,ui:t,value:n}),!0):(R(i.plugins,function(r){return r.execCommand&&r.execCommand(e,t,n)?(i.fire("ExecCommand",{command:e,ui:t,value:n}),o=!0,!1):void 0}),o?o:i.theme&&i.theme.execCommand&&i.theme.execCommand(e,t,n)?(i.fire("ExecCommand",{command:e,ui:t,value:n}),!0):i.editorCommands.execCommand(e,t,n)?(i.fire("ExecCommand",{command:e,ui:t,value:n}),!0):(i.getDoc().execCommand(e,t,n),i.fire("ExecCommand",{command:e,ui:t,value:n}),void 0))},queryCommandState:function(e){var t=this,n,r;if(!t._isHidden()){if((n=t.queryStateCommands[e])&&(r=n.func.call(n.scope),r!==!0))return r;if(r=t.editorCommands.queryCommandState(e),-1!==r)return r;try{return t.getDoc().queryCommandState(e)}catch(i){}}},queryCommandValue:function(e){var n=this,r,i;if(!n._isHidden()){if((r=n.queryValueCommands[e])&&(i=r.func.call(r.scope),i!==!0))return i;if(i=n.editorCommands.queryCommandValue(e),i!==t)return i;try{return n.getDoc().queryCommandValue(e)}catch(o){}}},show:function(){var e=this;E.show(e.getContainer()),E.hide(e.id),e.load(),e.fire("show")},hide:function(){var e=this,t=e.getDoc();P&&t&&t.execCommand("SelectAll"),e.save(),E.hide(e.getContainer()),E.setStyle(e.id,"display",e.orgDisplay),e.fire("hide")},isHidden:function(){return!E.isHidden(this.id)},setProgressState:function(e,t){this.fire("ProgressState",{state:e,time:t})},load:function(e){var n=this,r=n.getElement(),i;return r?(e=e||{},e.load=!0,i=n.setContent(r.value!==t?r.value:r.innerHTML,e),e.element=r,e.no_events||n.fire("LoadContent",e),e.element=r=null,i):void 0},save:function(e){var t=this,n=t.getElement(),r,i;if(n&&t.initialized)return e=e||{},e.save=!0,e.element=n,r=e.content=t.getContent(e),e.no_events||t.fire("SaveContent",e),r=e.content,/TEXTAREA|INPUT/i.test(n.nodeName)?n.value=r:(n.innerHTML=r,(i=E.getParent(t.id,"form"))&&R(i.elements,function(e){return e.name==t.id?(e.value=r,!1):void 0})),e.element=n=null,e.set_dirty!==!1&&(t.isNotDirty=!0),r},setContent:function(e,t){var n=this,r=n.getBody(),i;return t=t||{},t.format=t.format||"html",t.set=!0,t.content=e,t.no_events||n.fire("BeforeSetContent",t),e=t.content,0===e.length||/^\s+$/.test(e)?(i=n.settings.forced_root_block,i&&n.schema.isValidChild(r.nodeName.toLowerCase(),i.toLowerCase())?e=P&&11>P?"<"+i+">":"<"+i+'>
    ":P||(e='
    '),r.innerHTML=e,n.fire("SetContent",t)):("raw"!==t.format&&(e=new o({},n.schema).serialize(n.parser.parse(e,{isRootContent:!0}))),t.content=D(e),n.dom.setHTML(r,t.content),t.no_events||n.fire("SetContent",t)),t.initial||(n.selection.select(r,!0),n.selection.collapse(!0)),t.content},getContent:function(e){var t=this,n,r=t.getBody();return e=e||{},e.format=e.format||"html",e.get=!0,e.getInner=!0,e.no_events||t.fire("BeforeGetContent",e),n="raw"==e.format?r.innerHTML:"text"==e.format?r.innerText||r.textContent:t.serializer.serialize(r,e),e.content="text"!=e.format?D(n):n,e.no_events||t.fire("GetContent",e),e.content},insertContent:function(e){this.execCommand("mceInsertContent",!1,e)},isDirty:function(){return!this.isNotDirty},getContainer:function(){var e=this;return e.container||(e.container=E.get(e.editorContainer||e.id+"_parent")),e.container},getContentAreaContainer:function(){return this.contentAreaContainer},getElement:function(){return E.get(this.settings.content_element||this.id)},getWin:function(){var e=this,t;return e.contentWindow||(t=E.get(e.id+"_ifr"),t&&(e.contentWindow=t.contentWindow)),e.contentWindow},getDoc:function(){var e=this,t;return e.contentDocument||(t=e.getWin(),t&&(e.contentDocument=t.document)),e.contentDocument},getBody:function(){return this.bodyElement||this.getDoc().body},convertURL:function(e,t,n){var r=this,i=r.settings;return i.urlconverter_callback?r.execCallback("urlconverter_callback",e,n,!0,t):!i.convert_urls||n&&"LINK"==n.nodeName||0===e.indexOf("file:")||0===e.length?e:i.relative_urls?r.documentBaseURI.toRelative(e):e=r.documentBaseURI.toAbsolute(e,i.remove_script_host)},addVisual:function(e){var n=this,r=n.settings,i=n.dom,o;e=e||n.getBody(),n.hasVisual===t&&(n.hasVisual=r.visual),R(i.select("table,a",e),function(e){var t;switch(e.nodeName){case"TABLE":return o=r.visual_table_class||"mce-item-table",t=i.getAttrib(e,"border"),t&&"0"!=t||(n.hasVisual?i.addClass(e,o):i.removeClass(e,o)),void 0;case"A":return i.getAttrib(e,"href",!1)||(t=i.getAttrib(e,"name")||e.id,o="mce-item-anchor",t&&(n.hasVisual?i.addClass(e,o):i.removeClass(e,o))),void 0}}),n.fire("VisualAid",{element:e,hasVisual:n.hasVisual})},remove:function(){var e=this,t=e.getContainer(),n=e.getDoc();e.removed||(e.removed=1,P&&n&&n.execCommand("SelectAll"),e.save(),E.setStyle(e.id,"display",e.orgDisplay),e.settings.content_editable||(L.unbind(e.getWin()),L.unbind(e.getDoc())),L.unbind(e.getBody()),L.unbind(t),e.fire("remove"),e.editorManager.remove(e),E.remove(t),e.destroy())},bindNative:function(e){var t=this;t.initialized?t.dom.bind(_(t,e),e,function(n){t.fire(e,n)}):t._pendingNativeEvents?t._pendingNativeEvents.push(e):t._pendingNativeEvents=[e]},unbindNative:function(e){var t=this;t.initialized&&t.dom.unbind(e)},destroy:function(e){var t=this,n;t.destroyed||(e&&M&&(L.unbind(t.getDoc()),L.unbind(t.getWin()),L.unbind(t.getBody())),e||(t.editorManager.off("beforeunload",t._beforeUnload),t.theme&&t.theme.destroy&&t.theme.destroy(),t.selection.destroy(),t.dom.destroy()),n=t.formElement,n&&(n._mceOldSubmit&&(n.submit=n._mceOldSubmit,n._mceOldSubmit=null),E.unbind(n,"submit reset",t.formEventDelegate)),t.contentAreaContainer=t.formElement=t.container=null,t.settings.content_element=t.bodyElement=t.contentDocument=t.contentWindow=null,t.selection&&(t.selection=t.selection.win=t.selection.dom=t.selection.dom.doc=null),t.destroyed=1)},_refreshContentEditable:function(){var e=this,t,n;e._isHidden()&&(t=e.getBody(),n=t.parentNode,n.removeChild(t),n.appendChild(t),t.focus())},_isHidden:function(){var e;return M?(e=this.selection.getSel(),!e||!e.rangeCount||0===e.rangeCount):0}},T(N.prototype,x),N}),r(ot,[],function(){var e={};return{add:function(t,n){for(var r in n)e[r]=n[r]},translate:function(t){if("undefined"==typeof t)return t;if("string"!=typeof t&&t.raw)return t.raw;if(t.push){var n=t.slice(1);t=(e[t[0]]||t[0]).replace(/\{([^\}]+)\}/g,function(e,t){return n[t]})}return e[t]||t},data:e}}),r(at,[v,g],function(e,t){function n(r){function i(){try{return document.activeElement}catch(e){return document.body}}function o(e){return e&&e.startContainer?{startContainer:e.startContainer,startOffset:e.startOffset,endContainer:e.endContainer,endOffset:e.endOffset}:e +}function a(e,t){var n;return t.startContainer?(n=e.getDoc().createRange(),n.setStart(t.startContainer,t.startOffset),n.setEnd(t.endContainer,t.endOffset)):n=t,n}function s(s){function l(t){return!!e.DOM.getParent(t,n.isEditorUIElement)}var c=s.editor,u,d;c.on("init",function(){"onbeforedeactivate"in document&&t.ie<11?c.dom.bind(c.getBody(),"beforedeactivate",function(){var e=c.getDoc().selection;try{u=e&&e.createRange?e.createRange():c.selection.getRng()}catch(t){}}):(c.inline||t.ie>10)&&(c.on("nodechange keyup",function(){var e,t=document.activeElement;for(t&&t.id==c.id+"_ifr"&&(t=c.getBody());t;){if(t==c.getBody()){e=!0;break}t=t.parentNode}e&&(u=c.selection.getRng())}),t.webkit&&(d=function(){var e=c.selection.getRng();e.collapsed||(u=e)},e.DOM.bind(document,"selectionchange",d),c.on("remove",function(){e.DOM.unbind(document,"selectionchange",d)})))}),c.on("mousedown",function(){c.selection.lastFocusBookmark=null}),c.on("focusin",function(){var e=r.focusedEditor;c.selection.lastFocusBookmark&&(c.selection.setRng(a(c,c.selection.lastFocusBookmark)),c.selection.lastFocusBookmark=null),e!=c&&(e&&e.fire("blur",{focusedEditor:c}),r.activeEditor=c,c.fire("focus",{blurredEditor:e}),c.focus(!1),r.focusedEditor=c)}),c.on("focusout",function(){c.selection.lastFocusBookmark=o(u),window.setTimeout(function(){var e=r.focusedEditor;e!=c&&(c.selection.lastFocusBookmark=null),l(i())||e!=c||(c.fire("blur",{focusedEditor:null}),r.focusedEditor=null,c.selection.lastFocusBookmark=null)},0)})}r.on("AddEditor",s)}return n.isEditorUIElement=function(e){return-1!==e.className.indexOf("mce-")},n}),r(st,[it,v,O,g,p,nt,ot,at],function(e,n,r,i,o,a,s,l){var c=n.DOM,u=o.explode,d=o.each,f=o.extend,p=0,h,m={majorVersion:"4",minorVersion:"0.6",releaseDate:"2013-09-12",editors:[],i18n:s,activeEditor:null,setup:function(){var e=this,t,n,i="",o;if(n=document.location.href.replace(/[\?#].*$/,"").replace(/[\/\\][^\/]+$/,""),/[\/\\]$/.test(n)||(n+="/"),o=window.tinymce||window.tinyMCEPreInit)t=o.base||o.baseURL,i=o.suffix;else for(var a=document.getElementsByTagName("script"),s=0;s0&&d(u(h),function(n){c.get(n)?(l=new e(n,t,a),s.push(l),l.render(!0)):d(document.forms,function(r){d(r.elements,function(r){r.name===n&&(n="mce_editor_"+p++,c.setAttrib(r,"id",n),l=new e(n,t,a),s.push(l),l.render(1))})})});break;case"textareas":case"specific_textareas":d(c.select("textarea"),function(r){t.editor_deselector&&i(r,t.editor_deselector)||(!t.editor_selector||i(r,t.editor_selector))&&(l=new e(n(r),t,a),s.push(l),l.render(!0))})}t.oninit&&(h=m=0,d(s,function(e){m++,e.initialized?h++:e.on("init",function(){h++,h==m&&r(t,"oninit")}),h==m&&r(t,"oninit")}))}var a=this,s=[],l;a.settings=t,c.bind(window,"ready",o)},get:function(e){return e===t?this.editors:this.editors[e]},add:function(e){var t=this,n=t.editors;return n[e.id]=e,n.push(e),t.activeEditor=e,t.fire("AddEditor",{editor:e}),h||(h=function(){t.fire("BeforeUnload")},c.bind(window,"beforeunload",h)),e},createEditor:function(t,n){return this.add(new e(t,n,this))},remove:function(e){var t=this,n,r=t.editors,i,o;{if(e){if("string"==typeof e)return e=e.selector||e,d(c.select(e),function(e){t.remove(r[e.id])}),void 0;if(i=e,!r[i.id])return null;for(delete r[i.id],n=0;n=0;n--)t.remove(r[n])}},execCommand:function(t,n,r){var i=this,o=i.get(r);switch(t){case"mceAddEditor":return i.get(r)||new e(r,i.settings,i).render(),!0;case"mceRemoveEditor":return o&&o.remove(),!0;case"mceToggleEditor":return o?(o.isHidden()?o.show():o.hide(),!0):(i.execCommand("mceAddEditor",0,r),!0)}return i.activeEditor?i.activeEditor.execCommand(t,n,r):!1},triggerSave:function(){d(this.editors,function(e){e.save()})},addI18n:function(e,t){s.add(e,t)},translate:function(e){return s.translate(e)}};return f(m,a),m.setup(),window.tinymce=window.tinyMCE=m,m}),r(lt,[st,p],function(e,t){var n=t.each,r=t.explode;e.on("AddEditor",function(e){var t=e.editor;t.on("preInit",function(){function e(e,t){n(t,function(t,n){t&&s.setStyle(e,n,t)}),s.rename(e,"span")}function i(e){s=t.dom,l.convert_fonts_to_spans&&n(s.select("font,u,strike",e.node),function(e){o[e.nodeName.toLowerCase()](s,e)})}var o,a,s,l=t.settings;l.inline_styles&&(a=r(l.font_size_legacy_values),o={font:function(t,n){e(n,{backgroundColor:n.style.backgroundColor,color:n.color,fontFamily:n.face,fontSize:a[parseInt(n.size,10)-1]})},u:function(t,n){e(n,{textDecoration:"underline"})},strike:function(t,n){e(n,{textDecoration:"line-through"})}},t.on("PreProcess SetContent",i))})})}),r(ct,[],function(){return{send:function(e){function t(){!e.async||4==n.readyState||r++>1e4?(e.success&&1e4>r&&200==n.status?e.success.call(e.success_scope,""+n.responseText,n,e):e.error&&e.error.call(e.error_scope,r>1e4?"TIMED_OUT":"GENERAL",n,e),n=null):setTimeout(t,10)}var n,r=0;if(e.scope=e.scope||this,e.success_scope=e.success_scope||e.scope,e.error_scope=e.error_scope||e.scope,e.async=e.async===!1?!1:!0,e.data=e.data||"",n=new XMLHttpRequest){if(n.overrideMimeType&&n.overrideMimeType(e.content_type),n.open(e.type||(e.data?"POST":"GET"),e.url,e.async),e.content_type&&n.setRequestHeader("Content-Type",e.content_type),n.setRequestHeader("X-Requested-With","XMLHttpRequest"),n.send(e.data),!e.async)return t();setTimeout(t,10)}}}}),r(ut,[],function(){function e(t,n){var r,i,o,a;if(n=n||'"',null===t)return"null";if(o=typeof t,"string"==o)return i="\bb t\nn\ff\rr\"\"''\\\\",n+t.replace(/([\u0080-\uFFFF\x00-\x1f\"\'\\])/g,function(e,t){return'"'===n&&"'"===e?e:(r=i.indexOf(t),r+1?"\\"+i.charAt(r+1):(e=t.charCodeAt().toString(16),"\\u"+"0000".substring(e.length)+e))})+n;if("object"==o){if(t.hasOwnProperty&&"[object Array]"===Object.prototype.toString.call(t)){for(r=0,i="[";r0?",":"")+e(t[r],n);return i+"]"}i="{";for(a in t)t.hasOwnProperty(a)&&(i+="function"!=typeof t[a]?(i.length>1?","+n:n)+a+n+":"+e(t[a],n):"");return i+"}"}return""+t}return{serialize:e,parse:function(e){try{return window[String.fromCharCode(101)+"val"]("("+e+")")}catch(t){}}}}),r(dt,[ut,ct,p],function(e,t,n){function r(e){this.settings=i({},e),this.count=0}var i=n.extend;return r.sendRPC=function(e){return(new r).send(e)},r.prototype={send:function(n){var r=n.error,o=n.success;n=i(this.settings,n),n.success=function(t,i){t=e.parse(t),"undefined"==typeof t&&(t={error:"JSON Parse error."}),t.error?r.call(n.error_scope||n.scope,t.error,i):o.call(n.success_scope||n.scope,t.result)},n.error=function(e,t){r&&r.call(n.error_scope||n.scope,e,t)},n.data=e.serialize({id:n.id||"c"+this.count++,method:n.method,params:n.params}),n.content_type="application/json",t.send(n)}},r}),r(ft,[v],function(e){return{callbacks:{},count:0,send:function(n){var r=this,i=e.DOM,o=n.count!==t?n.count:r.count,a="tinymce_jsonp_"+o;r.callbacks[o]=function(e){i.remove(a),delete r.callbacks[o],n.callback(e)},i.add(i.doc.body,"script",{id:a,src:n.url,type:"text/javascript"}),r.count++}}}),r(pt,[],function(){function e(){s=[];for(var e in a)s.push(e);i.length=s.length}function n(){function n(e){var n,r;return r=e!==t?u+e:i.indexOf(",",u),-1===r||r>i.length?null:(n=i.substring(u,r),u=r+1,n)}var r,i,s,u=0;if(a={},c){o.load(l),i=o.getAttribute(l)||"";do r=n(parseInt(n(),32)||0),null!==r&&(s=n(parseInt(n(),32)||0),a[r]=s);while(null!==r);e()}}function r(){var t,n="";if(c){for(var r in a)t=a[r],n+=(n?",":"")+r.length.toString(32)+","+r+","+t.length.toString(32)+","+t;o.setAttribute(l,n),o.save(l),e()}}var i,o,a,s,l,c;try{if(window.localStorage)return localStorage}catch(u){}return l="tinymce",o=document.documentElement,c=!!o.addBehavior,c&&o.addBehavior("#default#userData"),i={key:function(e){return s[e]},getItem:function(e){return e in a?a[e]:null},setItem:function(e,t){a[e]=""+t,r()},removeItem:function(e){delete a[e],r()},clear:function(){a={},r()}},n(),i}),r(ht,[v,l,y,b,p,g],function(e,t,n,r,i,o){var a=window.tinymce;return a.DOM=e.DOM,a.ScriptLoader=n.ScriptLoader,a.PluginManager=r.PluginManager,a.ThemeManager=r.ThemeManager,a.dom=a.dom||{},a.dom.Event=t.Event,i.each(i,function(e,t){a[t]=e}),i.each("isOpera isWebKit isIE isGecko isMac".split(" "),function(e){a[e]=o[e.substr(2).toLowerCase()]}),{}}),r(mt,[I,p],function(e,t){return e.extend({Defaults:{firstControlClass:"first",lastControlClass:"last"},init:function(e){this.settings=t.extend({},this.Defaults,e)},preRender:function(e){e.addClass(this.settings.containerClass,"body")},applyClasses:function(e){var t=this,n=t.settings,r,i,o;r=e.items().filter(":visible"),i=n.firstControlClass,o=n.lastControlClass,r.each(function(e){e.removeClass(i).removeClass(o),n.controlClass&&e.addClass(n.controlClass)}),r.eq(0).addClass(i),r.eq(-1).addClass(o)},renderHtml:function(e){var t=this,n=t.settings,r,i="";return r=e.items(),r.eq(0).addClass(n.firstControlClass),r.eq(-1).addClass(n.lastControlClass),r.each(function(e){n.controlClass&&e.addClass(n.controlClass),i+=e.renderHtml()}),i},recalc:function(){},postRender:function(){}})}),r(gt,[mt],function(e){return e.extend({Defaults:{containerClass:"abs-layout",controlClass:"abs-layout-item"},recalc:function(e){e.items().filter(":visible").each(function(e){var t=e.settings;e.layoutRect({x:t.x,y:t.y,w:t.w,h:t.h}),e.recalc&&e.recalc()})},renderHtml:function(e){return'
    '+this._super(e)}})}),r(vt,[V,G],function(e,t){return e.extend({Mixins:[t],Defaults:{classes:"widget tooltip tooltip-n"},text:function(e){var t=this;return"undefined"!=typeof e?(t._value=e,t._rendered&&(t.getEl().lastChild.innerHTML=t.encode(e)),t):t._value},renderHtml:function(){var e=this,t=e.classPrefix;return'"},repaint:function(){var e=this,t,n;t=e.getEl().style,n=e._layoutRect,t.left=n.x+"px",t.top=n.y+"px",t.zIndex=131070}})}),r(yt,[V,vt],function(e,t){var n,r=e.extend({init:function(e){var t=this;t._super(e),t.canFocus=!0,e.tooltip&&r.tooltips!==!1&&t.on("mouseenter mouseleave",function(n){var r=t.tooltip().moveTo(-65535);if(n.control==t&&"mouseenter"==n.type){var i=r.text(e.tooltip).show().testMoveRel(t.getEl(),["bc-tc","bc-tl","bc-tr"]);r.toggleClass("tooltip-n","bc-tc"==i),r.toggleClass("tooltip-nw","bc-tl"==i),r.toggleClass("tooltip-ne","bc-tr"==i),r.moveRel(t.getEl(),i)}else r.hide()}),t.aria("label",e.tooltip)},tooltip:function(){var e=this;return n||(n=new t({type:"tooltip"}),n.renderTo(e.getContainerElm())),n},active:function(e){var t=this,n;return e!==n&&(t.aria("pressed",e),t.toggleClass("active",e)),t._super(e)},disabled:function(e){var t=this,n;return e!==n&&(t.aria("disabled",e),t.toggleClass("disabled",e)),t._super(e)},postRender:function(){var e=this,t=e.settings;e._rendered=!0,e._super(),e.parent()||!t.width&&!t.height||(e.initLayoutRect(),e.repaint()),t.autofocus&&setTimeout(function(){e.focus()},0)},remove:function(){this._super(),n&&(n.remove(),n=null)}});return r}),r(bt,[yt],function(e){return e.extend({Defaults:{classes:"widget btn",role:"button"},init:function(e){var t=this,n;t.on("click mousedown",function(e){e.preventDefault()}),t._super(e),n=e.size,e.subtype&&t.addClass(e.subtype),n&&t.addClass("btn-"+n)},repaint:function(){var e=this.getEl().firstChild.style;e.width=e.height="100%",this._super()},renderHtml:function(){var e=this,t=e._id,n=e.classPrefix,r=e.settings.icon,i="";return e.settings.image&&(r="none",i=" style=\"background-image: url('"+e.settings.image+"')\""),r=e.settings.icon?n+"ico "+n+"i-"+r:"",'
    '+'"+"
    "}})}),r(Ct,[q],function(e){return e.extend({Defaults:{defaultType:"button",role:"toolbar"},renderHtml:function(){var e=this,t=e._layout;return e.addClass("btn-group"),e.preRender(),t.preRender(e),'
    '+'
    '+(e.settings.html||"")+t.renderHtml(e)+"
    "+"
    "}})}),r(xt,[yt],function(e){return e.extend({Defaults:{classes:"checkbox",role:"checkbox",checked:!1},init:function(e){var t=this;t._super(e),t.on("click mousedown",function(e){e.preventDefault()}),t.on("click",function(e){e.preventDefault(),t.disabled()||t.checked(!t.checked())}),t.checked(t.settings.checked)},checked:function(e){var t=this;return"undefined"!=typeof e?(e?t.addClass("checked"):t.removeClass("checked"),t._checked=e,t.aria("checked",e),t):t._checked},value:function(e){return this.checked(e)},renderHtml:function(){var e=this,t=e._id,n=e.classPrefix;return'
    '+''+''+e.encode(e._text)+""+"
    "}})}),r(wt,[bt,X],function(e,t){return e.extend({showPanel:function(){var e=this,n=e.settings;n.panel.popover=!0,n.panel.autohide=!0,e.active(!0),e.panel?e.panel.show():(e.panel=new t(n.panel).on("hide",function(){e.active(!1)}).parent(e).renderTo(e.getContainerElm()),e.panel.fire("show"),e.panel.reflow()),e.panel.moveRel(e.getEl(),n.popoverAlign||"bc-tc")},hidePanel:function(){var e=this;e.panel&&e.panel.hide()},postRender:function(){var e=this;return e.on("click",function(t){t.control===e&&(e.panel&&e.panel.visible()?e.hidePanel():e.showPanel())}),e._super()}})}),r(_t,[wt,v],function(e,t){var n=t.DOM;return e.extend({init:function(e){this._super(e),this.addClass("colorbutton")},color:function(e){return e?(this._color=e,this.getEl("preview").style.backgroundColor=e,this):this._color},renderHtml:function(){var e=this,t=e._id,n=e.classPrefix,r=e.settings.icon?n+"ico "+n+"i-"+e.settings.icon:"",i=e.settings.image?" style=\"background-image: url('"+e.settings.image+"')\"":"";return'
    '+'"+'"+"
    "},postRender:function(){var e=this,t=e.settings.onclick;return e.on("click",function(r){r.control!=e||n.getParent(r.target,"."+e.classPrefix+"open")||(r.stopImmediatePropagation(),t.call(e,r))}),delete e.settings.onclick,e._super()}})}),r(Nt,[yt,z],function(e,t){return e.extend({init:function(e){var n=this;n._super(e),n.addClass("combobox"),n.on("click",function(e){for(var t=e.target;t;)t.id&&-1!=t.id.indexOf("-open")&&n.fire("action"),t=t.parentNode}),n.on("keydown",function(e){"INPUT"==e.target.nodeName&&13==e.keyCode&&n.parents().reverse().each(function(t){return e.preventDefault(),n.fire("change"),t.submit?(t.submit(),!1):void 0})}),e.placeholder&&(n.addClass("placeholder"),n.on("focusin",function(){n._hasOnChange||(t.on(n.getEl("inp"),"change",function(){n.fire("change")}),n._hasOnChange=!0),n.hasClass("placeholder")&&(n.getEl("inp").value="",n.removeClass("placeholder"))}),n.on("focusout",function(){0===n.value().length&&(n.getEl("inp").value=e.placeholder,n.addClass("placeholder"))}))},value:function(e){var t=this;return"undefined"!=typeof e?(t._value=e,t.removeClass("placeholder"),t._rendered&&(t.getEl("inp").value=e),t):t._rendered?(e=t.getEl("inp").value,e!=t.settings.placeholder?e:""):t._value},disabled:function(e){var t=this;t._super(e),t._rendered&&(t.getEl("inp").disabled=e)},focus:function(){this.getEl("inp").focus()},repaint:function(){var e=this,n=e.getEl(),r=e.getEl("open"),i=e.layoutRect(),o,a;o=r?i.w-r.offsetWidth-10:i.w-10;var s=document;return s.all&&(!s.documentMode||s.documentMode<=8)&&(a=e.layoutRect().h-2+"px"),t.css(n.firstChild,{width:o,lineHeight:a}),e._super(),e},postRender:function(){var e=this;return t.on(this.getEl("inp"),"change",function(){e.fire("change")}),e._super()},remove:function(){t.off(this.getEl("inp")),this._super()},renderHtml:function(){var e=this,t=e._id,n=e.settings,r=e.classPrefix,i=n.value||n.placeholder||"",o,a,s="";return o=n.icon?r+"ico "+r+"i-"+n.icon:"",a=e._text,(o||a)&&(s='
    '+'"+"
    ",e.addClass("has-open")),'
    '+''+s+"
    "}})}),r(Et,[V,J],function(e,t){return e.extend({Defaults:{delimiter:"\xbb"},init:function(e){var t=this;t._super(e),t.addClass("path"),t.canFocus=!0,t.on("click",function(e){var n,r=e.target;(n=r.getAttribute("data-index"))&&t.fire("select",{value:t.data()[n],index:n})})},focus:function(){var e=this;return e.keyNav=new t({root:e,enableLeftRight:!0}),e.keyNav.focusFirst(),e},data:function(e){var t=this;return"undefined"!=typeof e?(t._data=e,t.update(),t):t._data},update:function(){this.innerHtml(this._getPathHtml())},postRender:function(){var e=this;e._super(),e.data(e.settings.data)},renderHtml:function(){var e=this;return'
    '+e._getPathHtml()+"
    "},_getPathHtml:function(){var e=this,t=e._data||[],n,r,i="",o=e.classPrefix;for(n=0,r=t.length;r>n;n++)i+=(n>0?'":"")+'
    '+t[n].name+"
    ";return i||(i='
     
    '),i}})}),r(kt,[Et,st],function(e,t){return e.extend({postRender:function(){function e(e){return 1===e.nodeType&&("BR"==e.nodeName||!!e.getAttribute("data-mce-bogus"))}var n=this,r=t.activeEditor;return n.on("select",function(t){var n=[],i,o=r.getBody();for(r.focus(),i=r.selection.getStart();i&&i!=o;)e(i)||n.push(i),i=i.parentNode;r.selection.select(n[n.length-1-t.index]),r.nodeChanged()}),r.on("nodeChange",function(t){for(var i=[],o=t.parents,a=o.length;a--;)if(1==o[a].nodeType&&!e(o[a])){var s=r.fire("ResolveName",{name:o[a].nodeName.toLowerCase(),target:o[a]});i.push({name:s.name})}n.data(i)}),n._super()}})}),r(St,[q],function(e){return e.extend({Defaults:{layout:"flex",align:"center",defaults:{flex:1}},renderHtml:function(){var e=this,t=e._layout,n=e.classPrefix;return e.addClass("formitem"),t.preRender(e),'
    '+(e.settings.title?'
    '+e.settings.title+"
    ":"")+'
    '+(e.settings.html||"")+t.renderHtml(e)+"
    "+"
    "}})}),r(Tt,[q,St],function(e,t){return e.extend({Defaults:{containerCls:"form",layout:"flex",direction:"column",align:"stretch",flex:1,padding:20,labelGap:30,spacing:10},preRender:function(){var e=this,n=e.items();n.each(function(n){var r,i=n.settings.label;i&&(r=new t({layout:"flex",autoResize:"overflow",defaults:{flex:1},items:[{type:"label",text:i,flex:0,forId:n._id}]}),r.type="formitem","undefined"==typeof n.settings.flex&&(n.settings.flex=1),e.replace(n,r),r.add(n))})},recalcLabels:function(){var e=this,t=0,n=[],r,i;if(e.settings.labelGapCalc!==!1)for(e.items().filter("formitem").each(function(e){var r=e.items()[0],i=r.getEl().clientWidth;t=i>t?i:t,n.push(r)}),i=e.settings.labelGap||0,r=n.length;r--;)n[r].settings.minWidth=t+i},visible:function(e){var t=this._super(e);return e===!0&&this._rendered&&this.recalcLabels(),t},submit:function(){var e=this.getParentCtrl(document.activeElement);return e&&e.blur(),this.fire("submit",{data:this.toJSON()})},postRender:function(){var e=this;e._super(),e.recalcLabels(),e.fromJSON(e.settings.data)}})}),r(Rt,[Tt],function(e){return e.extend({Defaults:{containerCls:"fieldset",layout:"flex",direction:"column",align:"stretch",flex:1,padding:"25 15 5 15",labelGap:30,spacing:10,border:1},renderHtml:function(){var e=this,t=e._layout,n=e.classPrefix;return e.preRender(),t.preRender(e),'
    '+(e.settings.title?''+e.settings.title+"":"")+'
    '+(e.settings.html||"")+t.renderHtml(e)+"
    "+"
    "}})}),r(At,[Nt],function(e){return e.extend({init:function(e){var t=this,n=tinymce.activeEditor,r;e.spellcheck=!1,r=n.settings.file_browser_callback,r&&(e.icon="browse",e.onaction=function(){r(t.getEl("inp").id,t.getEl("inp").value,e.filetype,window)}),t._super(e)}})}),r(Bt,[gt],function(e){return e.extend({recalc:function(e){var t=e.layoutRect(),n=e.paddingBox();e.items().filter(":visible").each(function(e){e.layoutRect({x:n.left,y:n.top,w:t.innerW-n.right-n.left,h:t.innerH-n.top-n.bottom}),e.recalc&&e.recalc()})}})}),r(Dt,[gt],function(e){return e.extend({recalc:function(e){var t,n,r,i,o,a,s,l,c,u,d,f,p,h,m,g,v=[],y,b,C,x,w,_,N,E,k,S,T,R,A,B,D,H,L,M,P,O,I,F,W,z,V=Math.max,U=Math.min;for(r=e.items().filter(":visible"),i=e.layoutRect(),o=e._paddingBox,a=e.settings,f=a.direction,s=a.align,l=a.pack,c=a.spacing||0,("row-reversed"==f||"column-reverse"==f)&&(r=r.set(r.toArray().reverse()),f=f.split("-")[0]),"column"==f?(k="y",N="h",E="minH",S="maxH",R="innerH",T="top",A="bottom",B="deltaH",D="contentH",I="left",M="w",H="x",L="innerW",P="minW",O="maxW",F="right",W="deltaW",z="contentW"):(k="x",N="w",E="minW",S="maxW",R="innerW",T="left",A="right",B="deltaW",D="contentW",I="top",M="h",H="y",L="innerH",P="minH",O="maxH",F="bottom",W="deltaH",z="contentH"),d=i[R]-o[T]-o[T],_=u=0,t=0,n=r.length;n>t;t++)p=r[t],h=p.layoutRect(),m=p.settings,g=m.flex,d-=n-1>t?c:0,g>0&&(u+=g,h[S]&&v.push(p),h.flex=g),d-=h[E],y=o[I]+h[P]+o[F],y>_&&(_=y);if(x={},x[E]=0>d?i[E]-d+i[B]:i[R]-d+i[B],x[P]=_+i[W],x[D]=i[R]-d,x[z]=_,x.minW=U(x.minW,i.maxW),x.minH=U(x.minH,i.maxH),x.minW=V(x.minW,i.startMinWidth),x.minH=V(x.minH,i.startMinHeight),!i.autoResize||x.minW==i.minW&&x.minH==i.minH){for(C=d/u,t=0,n=v.length;n>t;t++)p=v[t],h=p.layoutRect(),b=h[S],y=h[E]+Math.ceil(h.flex*C),y>b?(d-=h[S]-h[E],u-=h.flex,h.flex=0,h.maxFlexSize=b):h.maxFlexSize=0;for(C=d/u,w=o[T],x={},0===u&&("end"==l?w=d+o[T]:"center"==l?(w=Math.round(i[R]/2-(i[R]-d)/2)+o[T],0>w&&(w=o[T])):"justify"==l&&(w=o[T],c=Math.floor(d/(r.length-1)))),x[H]=o[I],t=0,n=r.length;n>t;t++)p=r[t],h=p.layoutRect(),y=h.maxFlexSize||h[E],"center"===s?x[H]=Math.round(i[L]/2-h[M]/2):"stretch"===s?(x[M]=V(h[P]||0,i[L]-o[I]-o[F]),x[H]=o[I]):"end"===s&&(x[H]=i[L]-h[M]-o.top),h.flex>0&&(y+=Math.ceil(h.flex*C)),x[N]=y,x[k]=w,p.layoutRect(x),p.recalc&&p.recalc(),w+=y+c}else if(x.w=x.minW,x.h=x.minH,e.layoutRect(x),this.recalc(e),null===e._lastRect){var q=e.parent();q&&(q._lastRect=null,q.recalc())}}})}),r(Ht,[mt],function(e){return e.extend({Defaults:{containerClass:"flow-layout",controlClass:"flow-layout-item",endClass:"break"},recalc:function(e){e.items().filter(":visible").each(function(e){e.recalc&&e.recalc()})}})}),r(Lt,[V,yt,X,p,st,g],function(e,t,n,r,i,o){function a(e){function t(t){function n(e){return e.replace(/%(\w+)/g,"")}var r,i,o=e.dom,a="",l,c;return c=e.settings.preview_styles,c===!1?"":(c||(c="font-family font-size font-weight text-decoration text-transform color background-color border border-radius"),(t=e.formatter.get(t))?(t=t[0],r=t.block||t.inline||"span",i=o.create(r),s(t.styles,function(e,t){e=n(e),e&&o.setStyle(i,t,e)}),s(t.attributes,function(e,t){e=n(e),e&&o.setAttrib(i,t,e)}),s(t.classes,function(e){e=n(e),o.hasClass(i,e)||o.addClass(i,e)}),e.fire("PreviewFormats"),o.setStyles(i,{position:"absolute",left:-65535}),e.getBody().appendChild(i),l=o.getStyle(e.getBody(),"fontSize",!0),l=/px$/.test(l)?parseInt(l,10):0,s(c.split(" "),function(t){var n=o.getStyle(i,t,!0);if(!("background-color"==t&&/transparent|rgba\s*\([^)]+,\s*0\)/.test(n)&&(n=o.getStyle(e.getBody(),t,!0),"#ffffff"==o.toHex(n).toLowerCase())||"color"==t&&"#000000"==o.toHex(n).toLowerCase())){if("font-size"==t&&/em|%$/.test(n)){if(0===l)return;n=parseFloat(n,10)/(/%$/.test(n)?100:1),n=n*l+"px"}"border"==t&&n&&(a+="padding:0 2px;"),a+=t+":"+n+";"}}),e.fire("AfterPreviewFormats"),o.remove(i),a):void 0)}function r(t,n){return function(){var r=this;e.on("nodeChange",function(i){var o=e.formatter,a=null;s(i.parents,function(e){return s(t,function(t){return n?o.matchNode(e,n,{value:t.value})&&(a=t.value):o.matchNode(e,t.value)&&(a=t.value),a?!1:void 0}),a?!1:void 0}),r.value(a)})}}function i(e){e=e.split(";");for(var t=e.length;t--;)e[t]=e[t].split("=");return e}function o(){function n(e){var t=[];if(e)return s(e,function(e){var o={text:e.title,icon:e.icon};if(e.items)o.menu=n(e.items);else{var a=e.format||"custom"+r++;e.format||(e.name=a,i.push(e)),o.format=a}t.push(o)}),t}var r=0,i=[],o=[{title:"Headers",items:[{title:"Header 1",format:"h1"},{title:"Header 2",format:"h2"},{title:"Header 3",format:"h3"},{title:"Header 4",format:"h4"},{title:"Header 5",format:"h5"},{title:"Header 6",format:"h6"}]},{title:"Inline",items:[{title:"Bold",icon:"bold",format:"bold"},{title:"Italic",icon:"italic",format:"italic"},{title:"Underline",icon:"underline",format:"underline"},{title:"Strikethrough",icon:"strikethrough",format:"strikethrough"},{title:"Superscript",icon:"superscript",format:"superscript"},{title:"Subscript",icon:"subscript",format:"subscript"},{title:"Code",icon:"code",format:"code"}]},{title:"Blocks",items:[{title:"Paragraph",format:"p"},{title:"Blockquote",format:"blockquote"},{title:"Div",format:"div"},{title:"Pre",format:"pre"}]},{title:"Alignment",items:[{title:"Left",icon:"alignleft",format:"alignleft"},{title:"Center",icon:"aligncenter",format:"aligncenter"},{title:"Right",icon:"alignright",format:"alignright"},{title:"Justify",icon:"alignjustify",format:"alignjustify"}]}];e.on("init",function(){s(i,function(t){e.formatter.register(t.name,t)})});var a=n(e.settings.style_formats||o);return a={type:"menu",items:a,onPostRender:function(t){e.fire("renderFormatsMenu",{control:t.control})},itemDefaults:{preview:!0,textStyle:function(){return this.settings.format?t(this.settings.format):void 0},onPostRender:function(){var t=this,n=this.settings.format;n&&t.parent().on("show",function(){t.disabled(!e.formatter.canApply(n)),t.active(e.formatter.match(n))})},onclick:function(){this.settings.format&&f(this.settings.format)}}}}function a(){return e.undoManager?e.undoManager.hasUndo():!1}function l(){return e.undoManager?e.undoManager.hasRedo():!1}function c(){var t=this;t.disabled(!a()),e.on("Undo Redo AddUndo TypingUndo",function(){t.disabled(!a())})}function u(){var t=this;t.disabled(!l()),e.on("Undo Redo AddUndo TypingUndo",function(){t.disabled(!l())})}function d(){var t=this;e.on("VisualAid",function(e){t.active(e.hasVisual)}),t.active(e.hasVisual)}function f(t){t.control&&(t=t.control.value()),t&&e.execCommand("mceToggleFormat",!1,t)}var p;p=o(),s({bold:"Bold",italic:"Italic",underline:"Underline",strikethrough:"Strikethrough",subscript:"Subscript",superscript:"Superscript"},function(t,n){e.addButton(n,{tooltip:t,onPostRender:function(){var t=this;e.formatter?e.formatter.formatChanged(n,function(e){t.active(e)}):e.on("init",function(){e.formatter.formatChanged(n,function(e){t.active(e)})})},onclick:function(){f(n)}})}),s({outdent:["Decrease indent","Outdent"],indent:["Increase indent","Indent"],cut:["Cut","Cut"],copy:["Copy","Copy"],paste:["Paste","Paste"],help:["Help","mceHelp"],selectall:["Select all","SelectAll"],hr:["Insert horizontal rule","InsertHorizontalRule"],removeformat:["Clear formatting","RemoveFormat"],visualaid:["Visual aids","mceToggleVisualAid"],newdocument:["New document","mceNewDocument"]},function(t,n){e.addButton(n,{tooltip:t[0],cmd:t[1]})}),s({blockquote:["Toggle blockquote","mceBlockQuote"],numlist:["Numbered list","InsertOrderedList"],bullist:["Bullet list","InsertUnorderedList"],subscript:["Subscript","Subscript"],superscript:["Superscript","Superscript"],alignleft:["Align left","JustifyLeft"],aligncenter:["Align center","JustifyCenter"],alignright:["Align right","JustifyRight"],alignjustify:["Justify","JustifyFull"]},function(t,n){e.addButton(n,{tooltip:t[0],cmd:t[1],onPostRender:function(){var t=this;e.formatter?e.formatter.formatChanged(n,function(e){t.active(e)}):e.on("init",function(){e.formatter.formatChanged(n,function(e){t.active(e)})})}})}),e.addButton("undo",{tooltip:"Undo",onPostRender:c,cmd:"undo"}),e.addButton("redo",{tooltip:"Redo",onPostRender:u,cmd:"redo"}),e.addMenuItem("newdocument",{text:"New document",shortcut:"Ctrl+N",icon:"newdocument",cmd:"mceNewDocument"}),e.addMenuItem("undo",{text:"Undo",icon:"undo",shortcut:"Ctrl+Z",onPostRender:c,cmd:"undo"}),e.addMenuItem("redo",{text:"Redo",icon:"redo",shortcut:"Ctrl+Y",onPostRender:u,cmd:"redo"}),e.addMenuItem("visualaid",{text:"Visual aids",selectable:!0,onPostRender:d,cmd:"mceToggleVisualAid"}),s({cut:["Cut","Cut","Ctrl+X"],copy:["Copy","Copy","Ctrl+C"],paste:["Paste","Paste","Ctrl+V"],selectall:["Select all","SelectAll","Ctrl+A"],bold:["Bold","Bold","Ctrl+B"],italic:["Italic","Italic","Ctrl+I"],underline:["Underline","Underline"],strikethrough:["Strikethrough","Strikethrough"],subscript:["Subscript","Subscript"],superscript:["Superscript","Superscript"],removeformat:["Clear formatting","RemoveFormat"]},function(t,n){e.addMenuItem(n,{text:t[0],icon:n,shortcut:t[2],cmd:t[1]})}),e.on("mousedown",function(){n.hideAll()}),e.addButton("styleselect",{type:"menubutton",text:"Formats",menu:p}),e.addButton("formatselect",function(){var n=[],o=i(e.settings.block_formats||"Paragraph=p;Address=address;Pre=pre;Header 1=h1;Header 2=h2;Header 3=h3;Header 4=h4;Header 5=h5;Header 6=h6");return s(o,function(e){n.push({text:e[0],value:e[1],textStyle:function(){return t(e[1])}})}),{type:"listbox",text:{raw:o[0][0]},values:n,fixedWidth:!0,onselect:f,onPostRender:r(n)}}),e.addButton("fontselect",function(){var t="Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats",n=[],o=i(e.settings.font_formats||t);return s(o,function(e){n.push({text:{raw:e[0]},value:e[1],textStyle:-1==e[1].indexOf("dings")?"font-family:"+e[1]:""})}),{type:"listbox",text:"Font Family",tooltip:"Font Family",values:n,fixedWidth:!0,onPostRender:r(n,"fontname"),onselect:function(t){t.control.settings.value&&e.execCommand("FontName",!1,t.control.settings.value)}}}),e.addButton("fontsizeselect",function(){var t=[],n="8pt 10pt 12pt 14pt 18pt 24pt 36pt",i=e.settings.fontsize_formats||n; +return s(i.split(" "),function(e){t.push({text:e,value:e})}),{type:"listbox",text:"Font Sizes",tooltip:"Font Sizes",values:t,fixedWidth:!0,onPostRender:r(t,"fontsize"),onclick:function(t){t.control.settings.value&&e.execCommand("FontSize",!1,t.control.settings.value)}}}),e.addMenuItem("formats",{text:"Formats",menu:p})}var s=r.each;i.on("AddEditor",function(e){a(e.editor)}),e.translate=function(e){return i.translate(e)},t.tooltips=!o.iOS}),r(Mt,[gt],function(e){return e.extend({recalc:function(e){var t=e.settings,n,r,i,o,a,s,l,c,u,d,f,p,h,m,g,v,y,b,C,x,w,_,N=[],E=[],k,S,T,R,A,B;for(t=e.settings,i=e.items().filter(":visible"),o=e.layoutRect(),r=t.columns||Math.ceil(Math.sqrt(i.length)),n=Math.ceil(i.length/r),y=t.spacingH||t.spacing||0,b=t.spacingV||t.spacing||0,C=t.alignH||t.align,x=t.alignV||t.align,g=e._paddingBox,C&&"string"==typeof C&&(C=[C]),x&&"string"==typeof x&&(x=[x]),d=0;r>d;d++)N.push(0);for(f=0;n>f;f++)E.push(0);for(f=0;n>f;f++)for(d=0;r>d&&(u=i[f*r+d],u);d++)c=u.layoutRect(),k=c.minW,S=c.minH,N[d]=k>N[d]?k:N[d],E[f]=S>E[f]?S:E[f];for(A=o.innerW-g.left-g.right,w=0,d=0;r>d;d++)w+=N[d]+(d>0?y:0),A-=(d>0?y:0)+N[d];for(B=o.innerH-g.top-g.bottom,_=0,f=0;n>f;f++)_+=E[f]+(f>0?b:0),B-=(f>0?b:0)+E[f];if(w+=g.left+g.right,_+=g.top+g.bottom,l={},l.minW=w+(o.w-o.innerW),l.minH=_+(o.h-o.innerH),l.contentW=l.minW-o.deltaW,l.contentH=l.minH-o.deltaH,l.minW=Math.min(l.minW,o.maxW),l.minH=Math.min(l.minH,o.maxH),l.minW=Math.max(l.minW,o.startMinWidth),l.minH=Math.max(l.minH,o.startMinHeight),!o.autoResize||l.minW==o.minW&&l.minH==o.minH){o.autoResize&&(l=e.layoutRect(l),l.contentW=l.minW-o.deltaW,l.contentH=l.minH-o.deltaH);var D;D="start"==t.packV?0:B>0?Math.floor(B/n):0;var H=0,L=t.flexWidths;if(L)for(d=0;dd;d++)N[d]+=L?Math.ceil(L[d]*M):M;for(h=g.top,f=0;n>f;f++){for(p=g.left,s=E[f]+D,d=0;r>d&&(u=i[f*r+d],u);d++)m=u.settings,c=u.layoutRect(),a=N[d],T=R=0,c.x=p,c.y=h,v=m.alignH||(C?C[d]||C[0]:null),"center"==v?c.x=p+a/2-c.w/2:"right"==v?c.x=p+a-c.w:"stretch"==v&&(c.w=a),v=m.alignV||(x?x[d]||x[0]:null),"center"==v?c.y=h+s/2-c.h/2:"bottom"==v?c.y=h+s-c.h:"stretch"==v&&(c.h=s),u.layoutRect(c),p+=a+y,u.recalc&&u.recalc();h+=s+b}}else if(l.w=l.minW,l.h=l.minH,e.layoutRect(l),this.recalc(e),null===e._lastRect){var P=e.parent();P&&(P._lastRect=null,P.recalc())}}})}),r(Pt,[yt],function(e){return e.extend({renderHtml:function(){var e=this;return e.addClass("iframe"),e.canFocus=!1,''},src:function(e){this.getEl().src=e},html:function(e,t){var n=this,r=this.getEl().contentWindow.document.body;return r?(r.innerHTML=e,t&&t()):setTimeout(function(){n.html(e)},0),this}})}),r(Ot,[yt],function(e){return e.extend({init:function(e){var t=this;t._super(e),t.addClass("widget"),t.addClass("label"),t.canFocus=!1,e.multiline&&t.addClass("autoscroll"),e.strong&&t.addClass("strong")},initLayoutRect:function(){var e=this,t=e._super();return e.settings.multiline&&(e.getEl().offsetWidth>t.maxW&&(t.minW=t.maxW,e.addClass("multiline")),e.getEl().style.width=t.minW+"px",t.startMinH=t.h=t.minH=Math.min(t.maxH,e.getEl().offsetHeight)),t},disabled:function(e){var t=this,n;return e!==n&&(t.toggleClass("label-disabled",e),t._rendered&&(t.getEl()[0].className=t.classes())),t._super(e)},repaint:function(){var e=this;return e.settings.multiline||(e.getEl().style.lineHeight=e.layoutRect().h+"px"),e._super()},text:function(e){var t=this;return t._rendered&&e&&this.innerHtml(t.encode(e)),t._super(e)},renderHtml:function(){var e=this,t=e.settings.forId;return'"}})}),r(It,[q,J],function(e,t){return e.extend({Defaults:{role:"toolbar",layout:"flow"},init:function(e){var t=this;t._super(e),t.addClass("toolbar")},postRender:function(){var e=this;return e.items().addClass("toolbar-item"),e.keyNav=new t({root:e,enableLeftRight:!0}),e._super()}})}),r(Ft,[It],function(e){return e.extend({Defaults:{role:"menubar",containerCls:"menubar",defaults:{type:"menubutton"}}})}),r(Wt,[bt,U,Ft],function(e,t,n){function r(e,t){for(;e;){if(t===e)return!0;e=e.parentNode}return!1}var i=e.extend({init:function(e){var t=this;t._renderOpen=!0,t._super(e),t.addClass("menubtn"),e.fixedWidth&&t.addClass("fixed-width"),t.aria("haspopup",!0),t.hasPopup=!0},showMenu:function(){var e=this,n=e.settings,r;return e.menu&&e.menu.visible()?e.hideMenu():(e.menu||(r=n.menu||[],r.length?r={type:"menu",items:r}:r.type=r.type||"menu",e.menu=t.create(r).parent(e).renderTo(e.getContainerElm()),e.fire("createmenu"),e.menu.reflow(),e.menu.on("cancel",function(t){t.control===e.menu&&e.focus()}),e.menu.on("show hide",function(t){t.control==e.menu&&e.activeMenu("show"==t.type)}).fire("show"),e.aria("expanded",!0)),e.menu.show(),e.menu.layoutRect({w:e.layoutRect().w}),e.menu.moveRel(e.getEl(),["bl-tl","tl-bl"]),void 0)},hideMenu:function(){var e=this;e.menu&&(e.menu.items().each(function(e){e.hideMenu&&e.hideMenu()}),e.menu.hide(),e.aria("expanded",!1))},activeMenu:function(e){this.toggleClass("active",e)},renderHtml:function(){var e=this,t=e._id,r=e.classPrefix,i=e.settings.icon?r+"ico "+r+"i-"+e.settings.icon:"";return e.aria("role",e.parent()instanceof n?"menuitem":"button"),'
    '+'"+"
    "},postRender:function(){var e=this;return e.on("click",function(t){t.control===e&&r(t.target,e.getEl())&&(e.showMenu(),t.keyboard&&e.menu.items()[0].focus())}),e.on("mouseenter",function(t){var n=t.control,r=e.parent(),o;n&&r&&n instanceof i&&n.parent()==r&&(r.items().filter("MenuButton").each(function(e){e.hideMenu&&e!=n&&(e.menu&&e.menu.visible()&&(o=!0),e.hideMenu())}),o&&(n.focus(),n.showMenu()))}),e._super()},text:function(e){var t=this,n,r;if(t._rendered)for(r=t.getEl("open").getElementsByTagName("span"),n=0;n'+("-"!==i?' ":"")+("-"!==i?''+i+"":"")+(n.shortcut?'
    '+n.shortcut+"
    ":"")+(n.menu?'
    ':"")+""},postRender:function(){var e=this,t=e.settings,n=t.textStyle;if("function"==typeof n&&(n=n.call(this)),n){var r=e.getEl("text");r&&r.setAttribute("style",n)}return e._super()},remove:function(){this._super(),this.menu&&this.menu.remove()}})}),r(Ut,[X,J,Vt,p],function(e,t,n,r){var i=e.extend({Defaults:{defaultType:"menuitem",border:1,layout:"stack",role:"menu"},init:function(e){var i=this;if(e.autohide=!0,e.constrainToViewport=!0,e.itemDefaults)for(var o=e.items,a=o.length;a--;)o[a]=r.extend({},e.itemDefaults,o[a]);i._super(e),i.addClass("menu"),i.keyNav=new t({root:i,enableUpDown:!0,enableLeftRight:!0,leftAction:function(){i.parent()instanceof n&&i.keyNav.cancel()},onCancel:function(){i.fire("cancel",{},!1),i.hide()}})},repaint:function(){return this.toggleClass("menu-align",!0),this._super(),this.getEl().style.height="",this.getEl("body").style.height="",this},cancel:function(){var e=this;e.hideAll(),e.fire("cancel"),e.fire("select")},hideAll:function(){var e=this;return this.find("menuitem").exec("hideMenu"),e._super()},preRender:function(){var e=this;return e.items().each(function(t){var n=t.settings;return n.icon||n.selectable?(e._hasIcons=!0,!1):void 0}),e._super()}});return i}),r(qt,[xt],function(e){return e.extend({Defaults:{classes:"radio",role:"radio"}})}),r(jt,[yt,j],function(e,t){return e.extend({renderHtml:function(){var e=this,t=e.classPrefix;return e.addClass("resizehandle"),"both"==e.settings.direction&&e.addClass("resizehandle-both"),e.canFocus=!1,'
    '+''+"
    "},postRender:function(){var e=this;e._super(),e.resizeDragHelper=new t(this._id,{start:function(){e.fire("ResizeStart")},drag:function(t){"both"!=e.settings.direction&&(t.deltaX=0),e.fire("Resize",t)},end:function(){e.fire("ResizeEnd")}})},remove:function(){return this.resizeDragHelper&&this.resizeDragHelper.destroy(),this._super()}})}),r($t,[yt],function(e){return e.extend({renderHtml:function(){var e=this;return e.addClass("spacer"),e.canFocus=!1,'
    '}})}),r(Kt,[Wt,v],function(e,t){var n=t.DOM;return e.extend({Defaults:{classes:"widget btn splitbtn",role:"splitbutton"},repaint:function(){var e=this,t=e.getEl(),r=e.layoutRect(),i,o,a;return e._super(),i=t.firstChild,o=t.lastChild,n.css(i,{width:r.w-o.offsetWidth,height:r.h-2}),n.css(o,{height:r.h-2}),a=i.firstChild.style,a.width=a.height="100%",a=o.firstChild.style,a.width=a.height="100%",e},activeMenu:function(e){var t=this;n.toggleClass(t.getEl().lastChild,t.classPrefix+"active",e)},renderHtml:function(){var e=this,t=e._id,n=e.classPrefix,r=e.settings.icon?n+"ico "+n+"i-"+e.settings.icon:"";return'
    '+'"+'"+"
    "},postRender:function(){var e=this,t=e.settings.onclick;return e.on("click",function(e){e.control!=this||n.getParent(e.target,"."+this.classPrefix+"open")||(e.stopImmediatePropagation(),t.call(this,e))}),delete e.settings.onclick,e._super()}})}),r(Gt,[Ht],function(e){return e.extend({Defaults:{containerClass:"stack-layout",controlClass:"stack-layout-item",endClass:"break"}})}),r(Yt,[K,z],function(e,t){"use stict";return e.extend({lastIdx:0,Defaults:{layout:"absolute",defaults:{type:"panel"}},activateTab:function(e){this.activeTabId&&t.removeClass(this.getEl(this.activeTabId),this.classPrefix+"active"),this.activeTabId="t"+e,t.addClass(this.getEl("t"+e),this.classPrefix+"active"),e!=this.lastIdx&&(this.items()[this.lastIdx].hide(),this.lastIdx=e),this.items()[e].show().fire("showtab"),this.reflow()},renderHtml:function(){var e=this,t=e._layout,n="",r=e.classPrefix;return e.preRender(),t.preRender(e),e.items().each(function(t,i){n+='
    '+e.encode(t.settings.title)+"
    "}),'
    '+'
    '+n+"
    "+'
    '+t.renderHtml(e)+"
    "+"
    "},postRender:function(){var e=this;e._super(),e.settings.activeTab=e.settings.activeTab||0,e.activateTab(e.settings.activeTab),this.on("click",function(t){var n=t.target.parentNode;if(t.target.parentNode.id==e._id+"-head")for(var r=n.childNodes.length;r--;)n.childNodes[r]==t.target&&e.activateTab(r)})},initLayoutRect:function(){var e=this,t,n,r;n=r=0,e.items().each(function(t,i){n=Math.max(n,t.layoutRect().minW),r=Math.max(r,t.layoutRect().minH),e.settings.activeTab!=i&&t.hide()}),e.items().each(function(e){e.settings.x=0,e.settings.y=0,e.settings.w=n,e.settings.h=r,e.layoutRect({x:0,y:0,w:n,h:r})});var i=e.getEl("head").offsetHeight;return e.settings.minWidth=n,e.settings.minHeight=r+i,t=e._super(),t.deltaH+=e.getEl("head").offsetHeight,t.innerH=t.h-t.deltaH,t}})}),r(Xt,[yt,z],function(e,t){return e.extend({init:function(e){var t=this;t._super(e),t._value=e.value||"",t.addClass("textbox"),e.multiline?t.addClass("multiline"):t.on("keydown",function(e){13==e.keyCode&&t.parents().reverse().each(function(t){return e.preventDefault(),t.submit?(t.submit(),!1):void 0})})},value:function(e){var t=this;return"undefined"!=typeof e?(t._value=e,t._rendered&&(t.getEl().value=e),t):t._rendered?t.getEl().value:t._value},repaint:function(){var e=this,t,n,r,i=0,o=0,a;t=e.getEl().style,n=e._layoutRect,a=e._lastRepaintRect||{};var s=document;return!e.settings.multiline&&s.all&&(!s.documentMode||s.documentMode<=8)&&(t.lineHeight=n.h-o+"px"),r=e._borderBox,i=r.left+r.right+8,o=r.top+r.bottom+(e.settings.multiline?8:0),n.x!==a.x&&(t.left=n.x+"px",a.x=n.x),n.y!==a.y&&(t.top=n.y+"px",a.y=n.y),n.w!==a.w&&(t.width=n.w-i+"px",a.w=n.w),n.h!==a.h&&(t.height=n.h-o+"px",a.h=n.h),e._lastRepaintRect=a,e.fire("repaint",{},!1),e},renderHtml:function(){var e=this,t=e._id,n=e.settings,r=e.encode(e._value,!1),i="";return"spellcheck"in n&&(i+=' spellcheck="'+n.spellcheck+'"'),n.maxLength&&(i+=' maxlength="'+n.maxLength+'"'),n.size&&(i+=' size="'+n.size+'"'),n.subtype&&(i+=' type="'+n.subtype+'"'),n.multiline?'":'"},postRender:function(){var e=this;return t.on(e.getEl(),"change",function(t){e.fire("change",t)}),e._super()},remove:function(){t.off(this.getEl()),this._super()}})}),r(Jt,[z],function(e){return function(t){var n=this,r;n.show=function(i){return n.hide(),r=!0,window.setTimeout(function(){r&&t.appendChild(e.createFragment('
    '))},i||0),n},n.hide=function(){var e=t.lastChild;return e&&-1!=e.className.indexOf("throbber")&&e.parentNode.removeChild(e),r=!1,n}}}),a([l,c,u,d,f,p,h,m,g,v,y,b,C,x,w,_,N,E,k,S,T,R,A,B,D,H,L,M,P,O,I,F,W,z,V,U,q,j,$,K,G,Y,X,J,Q,Z,et,tt,nt,rt,it,ot,at,st,lt,ct,ut,dt,ft,pt,ht,mt,gt,vt,yt,bt,Ct,xt,wt,_t,Nt,Et,kt,St,Tt,Rt,At,Bt,Dt,Ht,Lt,Mt,Pt,Ot,It,Ft,Wt,zt,Vt,Ut,qt,jt,$t,Kt,Gt,Yt,Xt,Jt])}(this); \ No newline at end of file