From 0361cd1ff242b42ea6ee1347e09e133de01f4b6d Mon Sep 17 00:00:00 2001 From: franck Date: Wed, 28 Aug 2013 17:52:32 +0200 Subject: [PATCH 1/2] Removed InternalEvent, simplified SecurityContext --- composer.lock | 235 ++++++++--------- core/lib/Thelia/Action/BaseAction.php | 77 +++--- core/lib/Thelia/Action/Category.php | 249 +++++------------- core/lib/Thelia/Action/Customer.php | 6 +- core/lib/Thelia/Cart/CartTrait.php | 19 +- core/lib/Thelia/Config/Resources/action.xml | 10 +- core/lib/Thelia/Config/Resources/config.xml | 2 - .../Controller/Admin/BaseAdminController.php | 11 + .../Controller/Admin/CategoryController.php | 106 +++++++- .../Controller/Admin/SessionController.php | 4 +- core/lib/Thelia/Controller/BaseController.php | 39 +-- .../Controller/Front/CustomerController.php | 13 +- core/lib/Thelia/Core/Event/ActionEvent.php | 47 +--- core/lib/Thelia/Core/Event/CartItemEvent.php | 2 +- .../CategoryChangePositionEvent.php} | 68 +++-- ...ernalEvent.php => CategoryCreateEvent.php} | 64 ++++- .../CartEvent.php => CategoryDeleteEvent.php} | 33 ++- ....php => CategoryToggleVisibilityEvent.php} | 30 ++- .../Event/{Internal => }/CustomerEvent.php | 5 +- core/lib/Thelia/Core/Event/TheliaEvents.php | 24 +- .../Thelia/Core/Security/SecurityContext.php | 177 ++++++------- core/lib/Thelia/Core/Template/Loop/Auth.php | 3 - .../Smarty/Plugins/DataAccessFunctions.php | 7 +- .../Core/Template/Smarty/Plugins/Security.php | 5 - core/lib/Thelia/Model/CartItem.php | 2 +- core/lib/Thelia/Model/Customer.php | 2 +- 26 files changed, 630 insertions(+), 610 deletions(-) rename core/lib/Thelia/Core/{Context.php => Event/CategoryChangePositionEvent.php} (64%) mode change 100755 => 100644 rename core/lib/Thelia/Core/Event/{Internal/InternalEvent.php => CategoryCreateEvent.php} (62%) mode change 100755 => 100644 rename core/lib/Thelia/Core/Event/{Internal/CartEvent.php => CategoryDeleteEvent.php} (76%) mode change 100755 => 100644 rename core/lib/Thelia/Core/Event/{CategoryEvent.php => CategoryToggleVisibilityEvent.php} (81%) mode change 100755 => 100644 rename core/lib/Thelia/Core/Event/{Internal => }/CustomerEvent.php (95%) diff --git a/composer.lock b/composer.lock index d84eeb977..efa62a9f2 100755 --- a/composer.lock +++ b/composer.lock @@ -11,12 +11,12 @@ "source": { "type": "git", "url": "https://github.com/ezyang/htmlpurifier.git", - "reference": "19eee1489965d9bc6eded80f847ced2382127261" + "reference": "fac747bdbdba6aeaba4bed91ef49b2378c1798e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/19eee1489965d9bc6eded80f847ced2382127261", - "reference": "19eee1489965d9bc6eded80f847ced2382127261", + "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/fac747bdbdba6aeaba4bed91ef49b2378c1798e4", + "reference": "fac747bdbdba6aeaba4bed91ef49b2378c1798e4", "shasum": "" }, "require": { @@ -47,7 +47,7 @@ "keywords": [ "html" ], - "time": "2013-07-27 04:54:53" + "time": "2013-08-18 02:27:26" }, { "name": "imagine/imagine", @@ -55,12 +55,12 @@ "source": { "type": "git", "url": "https://github.com/avalanche123/Imagine.git", - "reference": "v0.5.0" + "reference": "f64ec666baaa800edcbf237db41121a569230709" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/avalanche123/Imagine/zipball/v0.5.0", - "reference": "v0.5.0", + "url": "https://api.github.com/repos/avalanche123/Imagine/zipball/f64ec666baaa800edcbf237db41121a569230709", + "reference": "f64ec666baaa800edcbf237db41121a569230709", "shasum": "" }, "require": { @@ -217,12 +217,12 @@ "source": { "type": "git", "url": "https://github.com/leafo/lessphp.git", - "reference": "v0.4.0" + "reference": "51f3f06f0fe78a722dabfd14578444bdd078d9de" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/leafo/lessphp/zipball/v0.4.0", - "reference": "v0.4.0", + "url": "https://api.github.com/repos/leafo/lessphp/zipball/51f3f06f0fe78a722dabfd14578444bdd078d9de", + "reference": "51f3f06f0fe78a722dabfd14578444bdd078d9de", "shasum": "" }, "type": "library", @@ -258,26 +258,26 @@ "source": { "type": "git", "url": "https://github.com/propelorm/Propel2.git", - "reference": "2.0.0-alpha1" + "reference": "3b9ea45a6e1b9fb3903cb910a31fbbac4a66c184" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/propelorm/Propel2/zipball/2.0.0-alpha1", - "reference": "2.0.0-alpha1", + "url": "https://api.github.com/repos/propelorm/Propel2/zipball/3b9ea45a6e1b9fb3903cb910a31fbbac4a66c184", + "reference": "3b9ea45a6e1b9fb3903cb910a31fbbac4a66c184", "shasum": "" }, "require": { "php": ">=5.4", - "psr/log": ">=1.0,<2.0", - "symfony/console": ">=2.2,<3.0", - "symfony/filesystem": ">=2.2,<3.0", - "symfony/finder": ">=2.2,<3.0", - "symfony/validator": ">=2.2,<3.0", - "symfony/yaml": ">=2.2,<3.0" + "psr/log": "~1.0", + "symfony/console": "~2.2", + "symfony/filesystem": "~2.2", + "symfony/finder": "~2.2", + "symfony/validator": "~2.2", + "symfony/yaml": "~2.2" }, "require-dev": { - "behat/behat": ">=2.4,<3.0", - "monolog/monolog": ">=1.3,<2.0", + "behat/behat": "~2.4", + "monolog/monolog": "~1.3", "phpunit/phpunit": "3.7.*" }, "suggest": { @@ -356,12 +356,12 @@ "source": { "type": "git", "url": "https://github.com/krichprollsch/phpCssEmbed.git", - "reference": "v1.0.2" + "reference": "406c6d5b846cafa9186f9944a6210d0e6fed154b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/krichprollsch/phpCssEmbed/zipball/v1.0.2", - "reference": "v1.0.2", + "url": "https://api.github.com/repos/krichprollsch/phpCssEmbed/zipball/406c6d5b846cafa9186f9944a6210d0e6fed154b", + "reference": "406c6d5b846cafa9186f9944a6210d0e6fed154b", "shasum": "" }, "require": { @@ -540,17 +540,17 @@ }, { "name": "symfony/class-loader", - "version": "v2.2.5", + "version": "v2.2.6", "target-dir": "Symfony/Component/ClassLoader", "source": { "type": "git", "url": "https://github.com/symfony/ClassLoader.git", - "reference": "v2.2.5" + "reference": "827c54ee9827f6de5afe53324cdbe47f017c0cba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/ClassLoader/zipball/v2.2.5", - "reference": "v2.2.5", + "url": "https://api.github.com/repos/symfony/ClassLoader/zipball/827c54ee9827f6de5afe53324cdbe47f017c0cba", + "reference": "827c54ee9827f6de5afe53324cdbe47f017c0cba", "shasum": "" }, "require": { @@ -586,21 +586,21 @@ ], "description": "Symfony ClassLoader Component", "homepage": "http://symfony.com", - "time": "2013-05-06 20:02:13" + "time": "2013-08-09 07:16:43" }, { "name": "symfony/config", - "version": "v2.2.5", + "version": "v2.2.6", "target-dir": "Symfony/Component/Config", "source": { "type": "git", "url": "https://github.com/symfony/Config.git", - "reference": "v2.2.5" + "reference": "4ab8ad0c0f4bb52b0e7fb12d63b81892fb7f697a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Config/zipball/v2.2.5", - "reference": "v2.2.5", + "url": "https://api.github.com/repos/symfony/Config/zipball/4ab8ad0c0f4bb52b0e7fb12d63b81892fb7f697a", + "reference": "4ab8ad0c0f4bb52b0e7fb12d63b81892fb7f697a", "shasum": "" }, "require": { @@ -637,17 +637,17 @@ }, { "name": "symfony/console", - "version": "v2.2.5", + "version": "v2.2.6", "target-dir": "Symfony/Component/Console", "source": { "type": "git", "url": "https://github.com/symfony/Console.git", - "reference": "v2.2.5" + "reference": "b9ed9d61ff84296c9ace5ac333c15e6f35062eeb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Console/zipball/v2.2.5", - "reference": "v2.2.5", + "url": "https://api.github.com/repos/symfony/Console/zipball/b9ed9d61ff84296c9ace5ac333c15e6f35062eeb", + "reference": "b9ed9d61ff84296c9ace5ac333c15e6f35062eeb", "shasum": "" }, "require": { @@ -680,21 +680,21 @@ ], "description": "Symfony Console Component", "homepage": "http://symfony.com", - "time": "2013-07-08 14:34:53" + "time": "2013-08-17 16:29:09" }, { "name": "symfony/dependency-injection", - "version": "v2.2.5", + "version": "v2.2.6", "target-dir": "Symfony/Component/DependencyInjection", "source": { "type": "git", "url": "https://github.com/symfony/DependencyInjection.git", - "reference": "v2.2.5" + "reference": "434b31fe8548e0354d5f93b455d8927481ddfc6f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/v2.2.5", - "reference": "v2.2.5", + "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/434b31fe8548e0354d5f93b455d8927481ddfc6f", + "reference": "434b31fe8548e0354d5f93b455d8927481ddfc6f", "shasum": "" }, "require": { @@ -739,17 +739,17 @@ }, { "name": "symfony/event-dispatcher", - "version": "v2.2.5", + "version": "v2.2.6", "target-dir": "Symfony/Component/EventDispatcher", "source": { "type": "git", "url": "https://github.com/symfony/EventDispatcher.git", - "reference": "v2.2.5" + "reference": "45c43ffa186a0473c71a947981e43e025cd93c87" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/v2.2.5", - "reference": "v2.2.5", + "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/45c43ffa186a0473c71a947981e43e025cd93c87", + "reference": "45c43ffa186a0473c71a947981e43e025cd93c87", "shasum": "" }, "require": { @@ -793,17 +793,17 @@ }, { "name": "symfony/filesystem", - "version": "v2.2.5", + "version": "v2.2.6", "target-dir": "Symfony/Component/Filesystem", "source": { "type": "git", "url": "https://github.com/symfony/Filesystem.git", - "reference": "v2.2.5" + "reference": "fa16b9ab446b84371a63ab391133ff58134edff1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Filesystem/zipball/v2.2.5", - "reference": "v2.2.5", + "url": "https://api.github.com/repos/symfony/Filesystem/zipball/fa16b9ab446b84371a63ab391133ff58134edff1", + "reference": "fa16b9ab446b84371a63ab391133ff58134edff1", "shasum": "" }, "require": { @@ -840,17 +840,17 @@ }, { "name": "symfony/finder", - "version": "v2.3.3", + "version": "v2.3.4", "target-dir": "Symfony/Component/Finder", "source": { "type": "git", "url": "https://github.com/symfony/Finder.git", - "reference": "v2.3.3" + "reference": "4a0fee5b86f5bbd9dfdc11ec124eba2915737ce1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Finder/zipball/v2.3.3", - "reference": "v2.3.3", + "url": "https://api.github.com/repos/symfony/Finder/zipball/4a0fee5b86f5bbd9dfdc11ec124eba2915737ce1", + "reference": "4a0fee5b86f5bbd9dfdc11ec124eba2915737ce1", "shasum": "" }, "require": { @@ -883,21 +883,21 @@ ], "description": "Symfony Finder Component", "homepage": "http://symfony.com", - "time": "2013-07-21 12:12:18" + "time": "2013-08-13 20:18:00" }, { "name": "symfony/form", - "version": "v2.2.5", + "version": "v2.2.6", "target-dir": "Symfony/Component/Form", "source": { "type": "git", "url": "https://github.com/symfony/Form.git", - "reference": "v2.2.5" + "reference": "33e3fcb6ca3cefe43ab22dcb8bee5ea039033a88" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Form/zipball/v2.2.5", - "reference": "v2.2.5", + "url": "https://api.github.com/repos/symfony/Form/zipball/33e3fcb6ca3cefe43ab22dcb8bee5ea039033a88", + "reference": "33e3fcb6ca3cefe43ab22dcb8bee5ea039033a88", "shasum": "" }, "require": { @@ -942,21 +942,21 @@ ], "description": "Symfony Form Component", "homepage": "http://symfony.com", - "time": "2013-08-02 13:12:51" + "time": "2013-08-25 11:59:08" }, { "name": "symfony/http-foundation", - "version": "v2.2.5", + "version": "v2.2.6", "target-dir": "Symfony/Component/HttpFoundation", "source": { "type": "git", "url": "https://github.com/symfony/HttpFoundation.git", - "reference": "v2.2.5" + "reference": "9402ff009d4f1ee63e83e8f2262993a7c2a3beea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/v2.2.5", - "reference": "v2.2.5", + "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/9402ff009d4f1ee63e83e8f2262993a7c2a3beea", + "reference": "9402ff009d4f1ee63e83e8f2262993a7c2a3beea", "shasum": "" }, "require": { @@ -992,21 +992,21 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "http://symfony.com", - "time": "2013-08-07 14:00:53" + "time": "2013-08-25 18:21:55" }, { "name": "symfony/http-kernel", - "version": "v2.2.5", + "version": "v2.2.6", "target-dir": "Symfony/Component/HttpKernel", "source": { "type": "git", "url": "https://github.com/symfony/HttpKernel.git", - "reference": "v2.2.5" + "reference": "080dea28df16aed1fbc7aeb08a1dcb10d7ab5299" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/v2.2.5", - "reference": "v2.2.5", + "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/080dea28df16aed1fbc7aeb08a1dcb10d7ab5299", + "reference": "080dea28df16aed1fbc7aeb08a1dcb10d7ab5299", "shasum": "" }, "require": { @@ -1062,25 +1062,24 @@ ], "description": "Symfony HttpKernel Component", "homepage": "http://symfony.com", - "time": "2013-08-07 15:57:43" + "time": "2013-08-26 19:27:24" }, { "name": "symfony/icu", - "version": "v1.2.0", + "version": "v1.0.0", "target-dir": "Symfony/Component/Icu", "source": { "type": "git", "url": "https://github.com/symfony/Icu.git", - "reference": "v1.2.0" + "reference": "v1.0.0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Icu/zipball/v1.2.0", - "reference": "v1.2.0", + "url": "https://api.github.com/repos/symfony/Icu/zipball/v1.0.0", + "reference": "v1.0.0", "shasum": "" }, "require": { - "lib-icu": ">=4.4", "php": ">=5.3.3", "symfony/intl": ">=2.3,<3.0" }, @@ -1110,21 +1109,21 @@ "icu", "intl" ], - "time": "2013-06-03 18:32:58" + "time": "2013-06-03 18:32:07" }, { "name": "symfony/intl", - "version": "v2.3.3", + "version": "v2.3.4", "target-dir": "Symfony/Component/Intl", "source": { "type": "git", "url": "https://github.com/symfony/Intl.git", - "reference": "v2.3.3" + "reference": "ebbcf7e3dab5185b4b24c961431e302a0ffb66ec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Intl/zipball/v2.3.3", - "reference": "v2.3.3", + "url": "https://api.github.com/repos/symfony/Intl/zipball/ebbcf7e3dab5185b4b24c961431e302a0ffb66ec", + "reference": "ebbcf7e3dab5185b4b24c961431e302a0ffb66ec", "shasum": "" }, "require": { @@ -1187,21 +1186,21 @@ "l10n", "localization" ], - "time": "2013-08-01 12:40:45" + "time": "2013-08-24 14:32:55" }, { "name": "symfony/locale", - "version": "v2.3.3", + "version": "v2.3.4", "target-dir": "Symfony/Component/Locale", "source": { "type": "git", "url": "https://github.com/symfony/Locale.git", - "reference": "v2.3.3" + "reference": "490825116712881a351b9a13ad6dddd4a39b8bb0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Locale/zipball/v2.3.3", - "reference": "v2.3.3", + "url": "https://api.github.com/repos/symfony/Locale/zipball/490825116712881a351b9a13ad6dddd4a39b8bb0", + "reference": "490825116712881a351b9a13ad6dddd4a39b8bb0", "shasum": "" }, "require": { @@ -1239,17 +1238,17 @@ }, { "name": "symfony/options-resolver", - "version": "v2.2.5", + "version": "v2.2.6", "target-dir": "Symfony/Component/OptionsResolver", "source": { "type": "git", "url": "https://github.com/symfony/OptionsResolver.git", - "reference": "v2.2.5" + "reference": "b36671093db40feacce2d489298f0782a0a61cfd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/OptionsResolver/zipball/v2.2.5", - "reference": "v2.2.5", + "url": "https://api.github.com/repos/symfony/OptionsResolver/zipball/b36671093db40feacce2d489298f0782a0a61cfd", + "reference": "b36671093db40feacce2d489298f0782a0a61cfd", "shasum": "" }, "require": { @@ -1291,17 +1290,17 @@ }, { "name": "symfony/process", - "version": "v2.3.3", + "version": "v2.3.4", "target-dir": "Symfony/Component/Process", "source": { "type": "git", "url": "https://github.com/symfony/Process.git", - "reference": "v2.3.3" + "reference": "1e91553e1cedd0b8fb1da6ea4f89b02e21713d5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Process/zipball/v2.3.3", - "reference": "v2.3.3", + "url": "https://api.github.com/repos/symfony/Process/zipball/1e91553e1cedd0b8fb1da6ea4f89b02e21713d5b", + "reference": "1e91553e1cedd0b8fb1da6ea4f89b02e21713d5b", "shasum": "" }, "require": { @@ -1334,21 +1333,21 @@ ], "description": "Symfony Process Component", "homepage": "http://symfony.com", - "time": "2013-08-02 21:51:01" + "time": "2013-08-22 06:42:25" }, { "name": "symfony/property-access", - "version": "v2.2.5", + "version": "v2.2.6", "target-dir": "Symfony/Component/PropertyAccess", "source": { "type": "git", "url": "https://github.com/symfony/PropertyAccess.git", - "reference": "v2.2.5" + "reference": "2452dd5d49c1602876d9eeb4de15425d5f9a6342" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/PropertyAccess/zipball/v2.2.5", - "reference": "v2.2.5", + "url": "https://api.github.com/repos/symfony/PropertyAccess/zipball/2452dd5d49c1602876d9eeb4de15425d5f9a6342", + "reference": "2452dd5d49c1602876d9eeb4de15425d5f9a6342", "shasum": "" }, "require": { @@ -1392,21 +1391,21 @@ "property path", "reflection" ], - "time": "2013-07-28 18:26:16" + "time": "2013-08-22 04:15:06" }, { "name": "symfony/routing", - "version": "v2.2.5", + "version": "v2.2.6", "target-dir": "Symfony/Component/Routing", "source": { "type": "git", "url": "https://github.com/symfony/Routing.git", - "reference": "v2.2.5" + "reference": "2704242137edc19cc61e71027a7a04eef28f42c6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Routing/zipball/v2.2.5", - "reference": "v2.2.5", + "url": "https://api.github.com/repos/symfony/Routing/zipball/2704242137edc19cc61e71027a7a04eef28f42c6", + "reference": "2704242137edc19cc61e71027a7a04eef28f42c6", "shasum": "" }, "require": { @@ -1450,21 +1449,21 @@ ], "description": "Symfony Routing Component", "homepage": "http://symfony.com", - "time": "2013-07-30 11:22:46" + "time": "2013-08-23 14:06:02" }, { "name": "symfony/translation", - "version": "v2.2.5", + "version": "v2.2.6", "target-dir": "Symfony/Component/Translation", "source": { "type": "git", "url": "https://github.com/symfony/Translation.git", - "reference": "v2.2.5" + "reference": "37a11fe823c28f9235548d253b215f07cec9a0de" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Translation/zipball/v2.2.5", - "reference": "v2.2.5", + "url": "https://api.github.com/repos/symfony/Translation/zipball/37a11fe823c28f9235548d253b215f07cec9a0de", + "reference": "37a11fe823c28f9235548d253b215f07cec9a0de", "shasum": "" }, "require": { @@ -1505,7 +1504,7 @@ ], "description": "Symfony Translation Component", "homepage": "http://symfony.com", - "time": "2013-07-28 18:26:16" + "time": "2013-08-24 12:29:44" }, { "name": "symfony/validator", @@ -1514,12 +1513,12 @@ "source": { "type": "git", "url": "https://github.com/symfony/Validator.git", - "reference": "55808a75bf373a8edb6400239268d315f0a326c7" + "reference": "8f6f6be47fb8e1179cd225b1f949630e26221e42" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Validator/zipball/55808a75bf373a8edb6400239268d315f0a326c7", - "reference": "55808a75bf373a8edb6400239268d315f0a326c7", + "url": "https://api.github.com/repos/symfony/Validator/zipball/8f6f6be47fb8e1179cd225b1f949630e26221e42", + "reference": "8f6f6be47fb8e1179cd225b1f949630e26221e42", "shasum": "" }, "require": { @@ -1566,21 +1565,21 @@ ], "description": "Symfony Validator Component", "homepage": "http://symfony.com", - "time": "2013-08-13 20:18:00" + "time": "2013-08-24 15:26:22" }, { "name": "symfony/yaml", - "version": "v2.2.5", + "version": "v2.2.6", "target-dir": "Symfony/Component/Yaml", "source": { "type": "git", "url": "https://github.com/symfony/Yaml.git", - "reference": "v2.2.5" + "reference": "d135717c1a42cb566cc09433658e7e8dbbe30b0a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/v2.2.5", - "reference": "v2.2.5", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/d135717c1a42cb566cc09433658e7e8dbbe30b0a", + "reference": "d135717c1a42cb566cc09433658e7e8dbbe30b0a", "shasum": "" }, "require": { @@ -1613,7 +1612,7 @@ ], "description": "Symfony Yaml Component", "homepage": "http://symfony.com", - "time": "2013-07-11 09:28:01" + "time": "2013-08-24 06:36:00" } ], "packages-dev": [ diff --git a/core/lib/Thelia/Action/BaseAction.php b/core/lib/Thelia/Action/BaseAction.php index bef57b30d..ab8f4abb8 100755 --- a/core/lib/Thelia/Action/BaseAction.php +++ b/core/lib/Thelia/Action/BaseAction.php @@ -40,52 +40,6 @@ class BaseAction $this->container = $container; } - /** - * Validate a BaseForm - * - * @param BaseForm $aBaseForm the form - * @param string $expectedMethod the expected method, POST or GET, or null for any of them - * @throws FormValidationException is the form contains error, or the method is not the right one - * @return \Symfony\Component\Form\Form Form the symfony form object - */ - protected function validateForm(BaseForm $aBaseForm, $expectedMethod = null) - { - $form = $aBaseForm->getForm(); - - if ($expectedMethod == null || $aBaseForm->getRequest()->isMethod($expectedMethod)) { - - $form->bind($aBaseForm->getRequest()); - - if ($form->isValid()) { - return $form; - } else { - throw new FormValidationException("Missing or invalid data"); - } - } else { - throw new FormValidationException(sprintf("Wrong form method, %s expected.", $expectedMethod)); - } - } - - /** - * Propagate a form error in the action event - * - * @param BaseForm $aBaseForm the form - * @param string $error_message an error message that may be displayed to the customer - * @param ActionEvent $event the action event - */ - protected function propagateFormError(BaseForm $aBaseForm, $error_message, ActionEvent $event) - { - // The form has an error - $aBaseForm->setError(true); - $aBaseForm->setErrorMessage($error_message); - - // Store the form in the parser context - $event->setErrorForm($aBaseForm); - - // Stop event propagation - $event->stopPropagation(); - } - /** * Return the event dispatcher, * @@ -96,4 +50,33 @@ class BaseAction return $this->container->get('event_dispatcher'); } -} + /** + * Check current user authorisations. + * + * @param mixed $roles a single role or an array of roles. + * @param mixed $permissions a single permission or an array of permissions. + * + * @throws AuthenticationException if permissions are not granted to the current user. + */ + protected function checkAuth($roles, $permissions) { + + if (! $this->getSecurityContext()->isGranted( + is_array($roles) ? $roles : array($roles), + is_array($permissions) ? $permissions : array($permissions)) ) { + + Tlog::getInstance()->addAlert("Authorization roles:", $roles, " permissions:", $permissions, " refused."); + + throw new AuthorizationException("Sorry, you're not allowed to perform this action"); + } + } + + /** + * Return the security context + * + * @return Thelia\Core\Security\SecurityContext + */ + protected function getSecurityContext() + { + return $this->container->get('thelia.securityContext'); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Action/Category.php b/core/lib/Thelia/Action/Category.php index 6e5b7ba00..d411d2a51 100755 --- a/core/lib/Thelia/Action/Category.php +++ b/core/lib/Thelia/Action/Category.php @@ -24,134 +24,46 @@ namespace Thelia\Action; use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Thelia\Core\Event\ActionEvent; use Thelia\Core\Event\TheliaEvents; use Thelia\Model\Category as CategoryModel; -use Thelia\Form\CategoryCreationForm; -use Thelia\Core\Event\CategoryEvent; -use Thelia\Tools\Redirect; use Thelia\Model\CategoryQuery; -use Thelia\Model\AdminLog; -use Thelia\Form\CategoryDeletionForm; -use Thelia\Action\Exception\FormValidationException; use Propel\Runtime\ActiveQuery\Criteria; use Propel\Runtime\Propel; use Thelia\Model\Map\CategoryTableMap; use Propel\Runtime\Exception\PropelException; +use Thelia\Core\Event\CategoryCreateEvent; +use Thelia\Core\Event\CategoryDeleteEvent; +use Thelia\Core\Event\CategoryToggleVisibilityEvent; +use Thelia\Core\Event\CategoryChangePositionEvent; + class Category extends BaseAction implements EventSubscriberInterface { - public function create(ActionEvent $event) + public function create(CategoryCreateEvent $event) { - $this->checkAuth("ADMIN", "admin.category.create"); - $request = $event->getRequest(); + $category = new CategoryModel(); - try { - $categoryCreationForm = new CategoryCreationForm($request); + $event->getDispatcher()->dispatch(TheliaEvents::BEFORE_CREATECATEGORY, $event); - $form = $this->validateForm($categoryCreationForm, "POST"); + $category->create( + $event->getTitle(), + $event->getParent(), + $event->getLocale() + ); - $data = $form->getData(); + $event->setCreatedCategory($category); - $category = new CategoryModel(); - - $event->getDispatcher()->dispatch(TheliaEvents::BEFORE_CREATECATEGORY, $event); - - $category->create( - $data["title"], - $data["parent"], - $data["locale"] - ); - - AdminLog::append(sprintf("Category %s (ID %s) created", $category->getTitle(), $category->getId()), $request, $request->getSession()->getAdminUser()); - - $categoryEvent = new CategoryEvent($category); - - $event->getDispatcher()->dispatch(TheliaEvents::AFTER_CREATECATEGORY, $categoryEvent); - - // Substitute _ID_ in the URL with the ID of the created category - $successUrl = str_replace('_ID_', $category->getId(), $categoryCreationForm->getSuccessUrl()); - - // Redirect to the success URL - $this->redirect($successUrl); - - } catch (PropelException $e) { - Tlog::getInstance()->error(sprintf('error during creating category with message "%s"', $e->getMessage())); - - $message = "Failed to create this category, please try again."; - } - - // The form has errors, propagate it. - $this->propagateFormError($categoryCreationForm, $message, $event); + $event->getDispatcher()->dispatch(TheliaEvents::AFTER_CREATECATEGORY, $event); } - public function modify(ActionEvent $event) + public function modify(CategoryChangeEvent $event) { + $this->checkAuth("ADMIN", "admin.category.change"); - $this->checkAuth("ADMIN", "admin.category.delete"); - - $request = $event->getRequest(); - - $customerModification = new CustomerModification($request); - - $form = $customerModification->getForm(); - - if ($request->isMethod("post")) { - - $form->bind($request); - - if ($form->isValid()) { - $data = $form->getData(); - - $customer = CustomerQuery::create()->findPk(1); - try { - $customerEvent = new CustomerEvent($customer); - $event->getDispatcher()->dispatch(TheliaEvents::BEFORE_CHANGECUSTOMER, $customerEvent); - - $data = $form->getData(); - - $customer->createOrUpdate( - $data["title"], - $data["firstname"], - $data["lastname"], - $data["address1"], - $data["address2"], - $data["address3"], - $data["phone"], - $data["cellphone"], - $data["zipcode"], - $data["country"] - ); - - $customerEvent->customer = $customer; - $event->getDispatcher()->dispatch(TheliaEvents::AFTER_CHANGECUSTOMER, $customerEvent); - - // Update the logged-in user, and redirect to the success URL (exits) - // We don-t send the login event, as the customer si already logged. - $this->processSuccessfullLogin($event, $customer, $customerModification); - } catch (PropelException $e) { - - Tlog::getInstance()->error(sprintf('error during modifying customer on action/modifyCustomer with message "%s"', $e->getMessage())); - - $message = "Failed to change your account, please try again."; - } - } else { - $message = "Missing or invalid data"; - } - } else { - $message = "Wrong form method !"; - } - - // The form has an error - $customerModification->setError(true); - $customerModification->setErrorMessage($message); - - // Dispatch the errored form - $event->setErrorForm($customerModification); - + // TODO !! } /** @@ -159,50 +71,22 @@ class Category extends BaseAction implements EventSubscriberInterface * * @param ActionEvent $event */ - public function delete(ActionEvent $event) + public function delete(CategoryDeleteEvent $event) { - $this->checkAuth("ADMIN", "admin.category.delete"); - $request = $event->getRequest(); + $category = CategoryQuery::create()->findPk($event->getId()); - try { - $categoryDeletionForm = new CategoryDeletionForm($request); + if ($category !== null) { - $form = $this->validateForm($categoryDeletionForm, "POST"); + $event->setDeletedCategory($category); - $data = $form->getData(); - - $category = CategoryQuery::create()->findPk($data['id']); - - $categoryEvent = new CategoryEvent($category); - - $event->getDispatcher()->dispatch(TheliaEvents::BEFORE_DELETECATEGORY, $categoryEvent); + $event->getDispatcher()->dispatch(TheliaEvents::BEFORE_DELETECATEGORY, $event); $category->delete(); - AdminLog::append(sprintf("Category %s (ID %s) deleted", $category->getTitle(), $category->getId()), $request, $request->getSession()->getAdminUser()); - - $categoryEvent->category = $category; - - $event->getDispatcher()->dispatch(TheliaEvents::AFTER_DELETECATEGORY, $categoryEvent); - - // Substitute _ID_ in the URL with the ID of the created category - $successUrl = str_replace('_ID_', $category->getParent(), $categoryDeletionForm->getSuccessUrl()); - - // Redirect to the success URL - Redirect::exec($successUrl); - } catch (PropelException $e) { - - \Thelia\Log\Tlog::getInstance()->error(sprintf('error during deleting category ID=%s on action/modifyCustomer with message "%s"', $data['id'], $e->getMessage())); - - $message = "Failed to change your account, please try again."; - } catch (FormValidationException $e) { - - $message = $e->getMessage(); + $event->getDispatcher()->dispatch(TheliaEvents::AFTER_DELETECATEGORY, $event); } - - $this->propagateFormError($categoryDeletionForm, $message, $event); } /** @@ -210,63 +94,55 @@ class Category extends BaseAction implements EventSubscriberInterface * * @param ActionEvent $event */ - public function toggleVisibility(ActionEvent $event) + public function toggleVisibility(CategoryToggleVisibilityEvent $event) { - $this->checkAuth("ADMIN", "admin.category.edit"); - $request = $event->getRequest(); - - $category = CategoryQuery::create()->findPk($request->get('category_id', 0)); + $category = CategoryQuery::create()->findPk($event->getId()); if ($category !== null) { + $event->setCategory($category); + $event->getDispatcher()->dispatch(TheliaEvents::BEFORE_CHANGECATEGORY, $event); + $category->setVisible($category->getVisible() ? false : true); $category->save(); - $categoryEvent = new CategoryEvent($category); - - $event->getDispatcher()->dispatch(TheliaEvents::AFTER_CHANGECATEGORY, $categoryEvent); + $event->setCategory($category); + $event->getDispatcher()->dispatch(TheliaEvents::AFTER_CHANGECATEGORY, $event); } } /** - * Move category up + * Changes category position, selecting absolute ou relative change. * - * @param ActionEvent $event + * @param CategoryChangePositionEvent $event */ - public function changePositionUp(ActionEvent $event) + public function changePosition(CategoryChangePositionEvent $event) { - return $this->exchangePosition($event, 'up'); - } + $this->checkAuth("ADMIN", "admin.category.edit"); - /** - * Move category down - * - * @param ActionEvent $event - */ - public function changePositionDown(ActionEvent $event) - { - return $this->exchangePosition($event, 'down'); + if ($event->getMode() == CategoryChangePositionEvent::POSITION_ABSOLUTE) + return $this->changeAbsolutePosition($event); + else + return $this->exchangePosition($event); } /** * Move up or down a category * - * @param ActionEvent $event - * @param string $direction up to move up, down to move down + * @param CategoryChangePositionEvent $event */ - protected function exchangePosition(ActionEvent $event, $direction) + protected function exchangePosition(CategoryChangePositionEvent $event) { - $this->checkAuth("ADMIN", "admin.category.edit"); - - $request = $event->getRequest(); - - $category = CategoryQuery::create()->findPk($request->get('category_id', 0)); + $category = CategoryQuery::create()->findPk($event->getId()); if ($category !== null) { + $event->setCategory($category); + $event->getDispatcher()->dispatch(TheliaEvents::BEFORE_CHANGECATEGORY, $event); + // The current position of the category $my_position = $category->getPosition(); @@ -275,10 +151,10 @@ class Category extends BaseAction implements EventSubscriberInterface ->filterByParent($category->getParent()); // Up or down ? - if ($direction == 'up') { + if ($event->getMode() == CategoryChangePositionEvent::POSITION_UP) { // Find the category immediately before me $search->filterByPosition(array('max' => $my_position-1))->orderByPosition(Criteria::DESC); - } elseif ($direction == 'down') { + } elseif ($event->getMode() == CategoryChangePositionEvent::POSITION_DOWN) { // Find the category immediately after me $search->filterByPosition(array('min' => $my_position+1))->orderByPosition(Criteria::ASC); } else @@ -304,26 +180,30 @@ class Category extends BaseAction implements EventSubscriberInterface $cnx->rollback(); } } + + $event->setCategory($category); + $event->getDispatcher()->dispatch(TheliaEvents::AFTER_CHANGECATEGORY, $event); } } /** * Changes category position * - * @param ActionEvent $event + * @param CategoryChangePositionEvent $event */ - public function changePosition(ActionEvent $event) + protected function changeAbsolutePosition(CategoryChangePositionEvent $event) { $this->checkAuth("ADMIN", "admin.category.edit"); - $request = $event->getRequest(); - - $category = CategoryQuery::create()->findPk($request->get('category_id', 0)); + $category = CategoryQuery::create()->findPk($event->getId()); if ($category !== null) { + $event->setCategory($category); + $event->getDispatcher()->dispatch(TheliaEvents::BEFORE_CHANGECATEGORY, $event); + // The required position - $new_position = $request->get('position', null); + $new_position = $event->getPosition(); // The current position $current_position = $category->getPosition(); @@ -363,6 +243,9 @@ class Category extends BaseAction implements EventSubscriberInterface $cnx->rollback(); } } + + $event->setCategory($category); + $event->getDispatcher()->dispatch(TheliaEvents::AFTER_CHANGECATEGORY, $event); } } @@ -389,12 +272,14 @@ class Category extends BaseAction implements EventSubscriberInterface public static function getSubscribedEvents() { return array( - "action.createCategory" => array("create", 128), - "action.modifyCategory" => array("modify", 128), - "action.deleteCategory" => array("delete", 128), + TheliaEvents::CATEGORY_CREATE => array("create", 128), + TheliaEvents::CATEGORY_MODIFY => array("modify", 128), + TheliaEvents::CATEGORY_DELETE => array("delete", 128), - "action.toggleCategoryVisibility" => array("toggleVisibility", 128), - "action.changeCategoryPositionUp" => array("changePositionUp", 128), + TheliaEvents::CATEGORY_TOGGLE_VISIBILITY => array("toggleVisibility", 128), + TheliaEvents::CATEGORY_CHANGE_POSITION => array("changePosition", 128), + + "action.changeCategoryPositionU" => array("changePositionUp", 128), "action.changeCategoryPositionDown" => array("changePositionDown", 128), "action.changeCategoryPosition" => array("changePosition", 128), ); diff --git a/core/lib/Thelia/Action/Customer.php b/core/lib/Thelia/Action/Customer.php index 785ee8f48..4c7a71d5e 100755 --- a/core/lib/Thelia/Action/Customer.php +++ b/core/lib/Thelia/Action/Customer.php @@ -96,7 +96,7 @@ class Customer extends BaseAction implements EventSubscriberInterface { $event->getDispatcher()->dispatch(TheliaEvents::CUSTOMER_LOGOUT, $event); - $this->getFrontSecurityContext()->clear(); + $this->getSecurityContext()->clearCustomerUser(); } public function changePassword(ActionEvent $event) @@ -127,8 +127,8 @@ class Customer extends BaseAction implements EventSubscriberInterface public static function getSubscribedEvents() { return array( - "action.createCustomer" => array("create", 128), - "action.modifyCustomer" => array("modify", 128), + TheliaEvents::CUSTOMER_CREATEACCOUNT => array("create", 128), + TheliaEvents::CUSTOMER_UPDATEACCOUNT => array("modify", 128), ); } } diff --git a/core/lib/Thelia/Cart/CartTrait.php b/core/lib/Thelia/Cart/CartTrait.php index ed4f70374..901263a32 100755 --- a/core/lib/Thelia/Cart/CartTrait.php +++ b/core/lib/Thelia/Cart/CartTrait.php @@ -28,8 +28,8 @@ use Thelia\Model\ConfigQuery; use Thelia\Model\Customer; use Symfony\Component\HttpFoundation\Request; use Thelia\Core\HttpFoundation\Session\Session; -use Thelia\Core\Event\Internal\CartEvent; use Thelia\Core\Event\TheliaEvents; +use Thelia\Core\Event\CartEvent; trait CartTrait { @@ -42,8 +42,9 @@ trait CartTrait */ public function getCart(Request $request) { + $session = $request->getSession(); - if (null !== $cart = $request->getSession()->getCart()) { + if (null !== $cart = $session->getCart()) { return $cart; } @@ -55,26 +56,26 @@ trait CartTrait if ($cart) { //le panier existe en base - $customer = $request->getSession()->getCustomerUser(); + $customer = $session->getCustomerUser(); if ($customer) { if ($cart->getCustomerId() != $customer->getId()) { //le customer du panier n'est pas le mm que celui connecté, il faut cloner le panier sans le customer_id - $cart = $this->duplicateCart($cart, $request->getSession(), $customer); + $cart = $this->duplicateCart($cart, $session, $customer); } } else { if ($cart->getCustomerId() != null) { //il faut dupliquer le panier sans le customer_id - $cart = $this->duplicateCart($cart, $request->getSession()); + $cart = $this->duplicateCart($cart, $session); } } } else { - $cart = $this->createCart($request->getSession()); + $cart = $this->createCart($session); } } else { //le cookie de panier n'existe pas, il va falloir le créer et faire un enregistrement en base. - $cart = $this->createCart($request->getSession()); + $cart = $this->createCart($session); } return $cart; @@ -116,7 +117,7 @@ trait CartTrait $cartEvent = new CartEvent($newCart); $this->getDispatcher()->dispatch(TheliaEvents::CART_DUPLICATE, $cartEvent); - return $cartEvent->cart; + return $cartEvent->getCart(); } protected function generateCookie() @@ -131,4 +132,4 @@ trait CartTrait return $id; } -} +} \ No newline at end of file diff --git a/core/lib/Thelia/Config/Resources/action.xml b/core/lib/Thelia/Config/Resources/action.xml index f773b4cd7..2bd31ce3e 100755 --- a/core/lib/Thelia/Config/Resources/action.xml +++ b/core/lib/Thelia/Config/Resources/action.xml @@ -22,16 +22,16 @@ - - - - - + + + + + diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index 60105ad32..45c763830 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -85,8 +85,6 @@ - - diff --git a/core/lib/Thelia/Controller/Admin/BaseAdminController.php b/core/lib/Thelia/Controller/Admin/BaseAdminController.php index 67cecd302..271ce3c05 100755 --- a/core/lib/Thelia/Controller/Admin/BaseAdminController.php +++ b/core/lib/Thelia/Controller/Admin/BaseAdminController.php @@ -30,11 +30,22 @@ use Symfony\Component\HttpKernel\HttpKernelInterface; use Thelia\Core\Security\Exception\AuthenticationException; use Thelia\Tools\URL; use Thelia\Tools\Redirect; +use Thelia\Core\Security\SecurityContext; +use Thelia\Model\AdminLog; class BaseAdminController extends BaseController { const TEMPLATE_404 = "404"; + /** + * Helper to append a message to the admin log. + * + * @param unknown $message + */ + public function adminLogAppend($message) { + AdminLog::append($message, $this->getRequest(), $this->getSecurityContext()->getAdminUser()); + } + public function processTemplateAction($template) { try { diff --git a/core/lib/Thelia/Controller/Admin/CategoryController.php b/core/lib/Thelia/Controller/Admin/CategoryController.php index 0c92d24dc..fda94191c 100755 --- a/core/lib/Thelia/Controller/Admin/CategoryController.php +++ b/core/lib/Thelia/Controller/Admin/CategoryController.php @@ -25,12 +25,52 @@ namespace Thelia\Controller\Admin; use Thelia\Core\Security\Exception\AuthenticationException; use Thelia\Core\Security\Exception\AuthorizationException; +use Thelia\Log\Tlog; +use Thelia\Core\Event\TheliaEvents; +use Thelia\Core\Event\CategoryCreateEvent; +use Thelia\Form\CategoryCreationForm; +use Thelia\Core\Event\CategoryDeleteEvent; +use Thelia\Core\Event\CategoryToggleVisibilityEvent; +use Thelia\Core\Event\CategoryChangePositionEvent; +use Thelia\Form\CategoryDeletionForm; class CategoryController extends BaseAdminController { protected function createNewCategory($args) { - $this->dispatchEvent("createCategory"); + try { + $categoryCreationForm = new CategoryCreationForm($this->getRequest()); + + $form = $this->validateForm($categoryCreationForm, "POST"); + + $data = $form->getData(); + + $categoryCreateEvent = new CategoryCreateEvent( + $data["title"], + $data["parent"], + $data["locale"] + ); + + $this->dispatch(TheliaEvents::CATEGORY_CREATE, $categoryCreateEvent); + + $category = $categoryCreateEvent->getCreatedCategory(); + + $this->adminLogAppend(sprintf("Category %s (ID %s) created", $category->getTitle(), $category->getId())); + + // Substitute _ID_ in the URL with the ID of the created category + $successUrl = str_replace('_ID_', $category->getId(), $categoryCreationForm->getSuccessUrl()); + + // Redirect to the success URL + $this->redirect($successUrl); + } + catch (FormValidationException $e) { + $categoryCreationForm->setErrorMessage($e->getMessage()); + $this->getParserContext()->setErrorForm($categoryCreationForm); + } + catch (Exception $e) { + Tlog::getInstance()->error(sprintf("Failed to create category: %s", $e->getMessage())); + $this->getParserContext()->setGeneralError($e->getMessage()); + } // At this point, the form has error, and should be redisplayed. return $this->render('categories', $args); @@ -45,9 +85,35 @@ class CategoryController extends BaseAdminController protected function deleteCategory($args) { - $this->dispatchEvent("deleteCategory"); + try { + $categoryDeletionForm = new CategoryDeletionForm($this->getRequest()); - // Something was wrong, category was not deleted. Display parent category list + $data = $this->validateForm($categoryDeletionForm, "POST")->getData(); +var_dump($data); + $categoryDeleteEvent = new CategoryDeleteEvent($data['category_id']); + + $this->dispatch(TheliaEvents::CATEGORY_DELETE, $categoryDeleteEvent); + + $category = $categoryDeleteEvent->getDeletedCategory(); + + $this->adminLogAppend(sprintf("Category %s (ID %s) deleted", $category->getTitle(), $category->getId())); + + // Substitute _ID_ in the URL with the ID of the created category + $successUrl = str_replace('_ID_', $categoryDeleteEvent->getDeletedCategory()->getId(), $categoryDeletionForm->getSuccessUrl()); + + // Redirect to the success URL + $this->redirect($successUrl); + } + catch (FormValidationException $e) { + $categoryDeletionForm->setErrorMessage($e->getMessage()); + $this->getParserContext()->setErrorForm($categoryDeletionForm); + } + catch (Exception $e) { + Tlog::getInstance()->error(sprintf("Failed to delete category: %s", $e->getMessage())); + $this->getParserContext()->setGeneralError($e->getMessage()); + } + + // At this point, something was wrong, category was not deleted. Display parent category list return $this->render('categories', $args); } @@ -60,28 +126,48 @@ class CategoryController extends BaseAdminController protected function visibilityToggle($args) { - $this->dispatchEvent("toggleCategoryVisibility"); + $event = new CategoryToggleVisibilityEvent($this->getRequest()->get('category_id', 0)); + + $this->dispatch(TheliaEvents::CATEGORY_TOGGLE_VISIBILITY, $event); return $this->nullResponse(); } protected function changePosition($args) { - $this->dispatchEvent("changeCategoryPosition"); + $request = $this->getRequest(); + + $event = new CategoryChangePositionEvent( + $request->get('category_id', 0), + CategoryChangePositionEvent::POSITION_ABSOLUTE, + $request->get('position', null) + ); + + $this->dispatch(TheliaEvents::CATEGORY_CHANGE_POSITION, $event); return $this->render('categories', $args); } protected function positionDown($args) { - $this->dispatchEvent("changeCategoryPositionDown"); + $event = new CategoryChangePositionEvent( + $this->getRequest()->get('category_id', 0), + CategoryChangePositionEvent::POSITION_DOWN + ); + + $this->dispatch(TheliaEvents::CATEGORY_CHANGE_POSITION, $event); return $this->render('categories', $args); } protected function positionUp($args) { - $this->dispatchEvent("changeCategoryPositionUp"); + $event = new CategoryChangePositionEvent( + $this->getRequest()->get('category_id', 0), + CategoryChangePositionEvent::POSITION_UP + ); + + $this->dispatch(TheliaEvents::CATEGORY_CHANGE_POSITION, $event); return $this->render('categories', $args); } @@ -138,9 +224,11 @@ class CategoryController extends BaseAdminController return $this->positionDown($args); } - } catch (AuthorizationException $ex) { + } + catch (AuthorizationException $ex) { return $this->errorPage($ex->getMessage()); - } catch (AuthenticationException $ex) { + } + catch (AuthenticationException $ex) { return $this->errorPage($ex->getMessage()); } diff --git a/core/lib/Thelia/Controller/Admin/SessionController.php b/core/lib/Thelia/Controller/Admin/SessionController.php index 5299253e0..39dbc1205 100755 --- a/core/lib/Thelia/Controller/Admin/SessionController.php +++ b/core/lib/Thelia/Controller/Admin/SessionController.php @@ -43,7 +43,7 @@ class SessionController extends BaseAdminController { $this->dispatch(TheliaEvents::ADMIN_LOGOUT); - $this->getSecurityContext()->clear(); + $this->getSecurityContext()->clearAdminUser(); // Go back to login page. return Redirect::exec(URL::absoluteUrl('/admin/login')); // FIXME - should be a parameter @@ -61,7 +61,7 @@ class SessionController extends BaseAdminController $user = $authenticator->getAuthentifiedUser(); // Success -> store user in security context - $this->getSecurityContext()->setUser($user); + $this->getSecurityContext()->setAdminUser($user); // Log authentication success AdminLog::append("Authentication successful", $request, $user); diff --git a/core/lib/Thelia/Controller/BaseController.php b/core/lib/Thelia/Controller/BaseController.php index 5c6e3eb5e..1a610768d 100755 --- a/core/lib/Thelia/Controller/BaseController.php +++ b/core/lib/Thelia/Controller/BaseController.php @@ -34,6 +34,7 @@ use Symfony\Component\EventDispatcher\EventDispatcher; use Thelia\Core\Factory\ActionEventFactory; use Thelia\Form\BaseForm; use Thelia\Form\Exception\FormValidationException; +use Symfony\Component\EventDispatcher\Event; /** * @@ -56,34 +57,12 @@ class BaseController extends ContainerAware } /** - * Create an action event + * Dispatch a Thelia event * - * @param string $action - * @return EventDispatcher + * @param string $eventName a TheliaEvent name, as defined in TheliaEvents class + * @param Event $event the event */ - protected function dispatchEvent($action) - { - // Create the - $eventFactory = new ActionEventFactory($this->getRequest(), $action, $this->container->getParameter("thelia.actionEvent")); - - $actionEvent = $eventFactory->createActionEvent(); - - $this->dispatch("action.$action", $actionEvent); - - if ($actionEvent->hasErrorForm()) { - $this->getParserContext()->setErrorForm($actionEvent->getErrorForm()); - } - - return $actionEvent; - } - - /** - * Dispatch a Thelia event to modules - * - * @param string $eventName a TheliaEvent name, as defined in TheliaEvents class - * @param ActionEvent $event the event - */ - protected function dispatch($eventName, ActionEvent $event = null) + protected function dispatch($eventName, Event $event = null) { $this->getDispatcher()->dispatch($eventName, $event); } @@ -113,13 +92,9 @@ class BaseController extends ContainerAware * * @return \Thelia\Core\Security\SecurityContext */ - protected function getSecurityContext($context = false) + protected function getSecurityContext() { - $securityContext = $this->container->get('thelia.securityContext'); - - $securityContext->setContext($context === false ? SecurityContext::CONTEXT_BACK_OFFICE : $context); - - return $securityContext; + return $this->container->get('thelia.securityContext'); } /** diff --git a/core/lib/Thelia/Controller/Front/CustomerController.php b/core/lib/Thelia/Controller/Front/CustomerController.php index 07f9eb4c8..698c69d70 100755 --- a/core/lib/Thelia/Controller/Front/CustomerController.php +++ b/core/lib/Thelia/Controller/Front/CustomerController.php @@ -36,6 +36,7 @@ use Thelia\Form\CustomerModification; use Thelia\Form\Exception\FormValidationException; use Thelia\Model\Customer; use Thelia\Core\Event\TheliaEvents; +use Thelia\Core\Event\CustomerEvent; class CustomerController extends BaseFrontController { @@ -76,7 +77,7 @@ class CustomerController extends BaseFrontController try { - $customer = $this->getSecurityContext(SecurityContext::CONTEXT_FRONT_OFFICE)->getUser(); + $customer = $this->getSecurityContext()->getCustomerUser(); $form = $this->validateForm($customerModification, "post"); @@ -116,9 +117,7 @@ class CustomerController extends BaseFrontController try { $customer = $authenticator->getAuthentifiedUser(); - $customerLoginEvent = new CustomerLoginEvent($customer); - - $this->processLogin($customer, $customerLoginEvent); + $this->processLogin($customer); $this->redirectSuccess(); } catch (ValidatorException $e) { @@ -132,11 +131,11 @@ class CustomerController extends BaseFrontController } } - public function processLogin(Customer $customer,$event = null) + public function processLogin(Customer $customer) { - $this->getSecurityContext(SecurityContext::CONTEXT_FRONT_OFFICE)->setUser($customer); + $this->getSecurityContext()->setCustomerUser($customer); - if($event) $this->dispatch(TheliaEvents::CUSTOMER_LOGIN, $event); + if($event) $this->dispatch(TheliaEvents::CUSTOMER_LOGIN, new CustomerLoginEvent($customer)); } /** diff --git a/core/lib/Thelia/Core/Event/ActionEvent.php b/core/lib/Thelia/Core/Event/ActionEvent.php index c5c188235..5040be7f5 100755 --- a/core/lib/Thelia/Core/Event/ActionEvent.php +++ b/core/lib/Thelia/Core/Event/ActionEvent.php @@ -35,27 +35,8 @@ use Thelia\Form\BaseForm; */ abstract class ActionEvent extends Event { - - /** - * - * @var Symfony\Component\HttpFoundation\Request - */ - protected $request; - - protected $errorForm = null; - protected $parameters = array(); - /** - * - * @param \Symfony\Component\HttpFoundation\Request $request - * @param string $action - */ - public function __construct(Request $request) - { - $this->request = $request; - } - public function __set($name, $value) { $this->parameters[$name] = $value; @@ -69,30 +50,4 @@ abstract class ActionEvent extends Event return null; } - - /** - * - * @return \Symfony\Component\HttpFoundation\Request - */ - public function getRequest() - { - return $this->request; - } - - public function setErrorForm(BaseForm $form) - { - $this->errorForm = $form; - - if ($form != null) $this->stopPropagation(); - } - - public function getErrorForm() - { - return $this->errorForm; - } - - public function hasErrorForm() - { - return $this->errorForm != null ? true : false; - } -} +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/CartItemEvent.php b/core/lib/Thelia/Core/Event/CartItemEvent.php index 59deffb37..6718b63ff 100755 --- a/core/lib/Thelia/Core/Event/CartItemEvent.php +++ b/core/lib/Thelia/Core/Event/CartItemEvent.php @@ -25,7 +25,7 @@ namespace Thelia\Core\Event; use Thelia\Model\CartItem; -class CartItemEvent extends InternalEvent +class CartItemEvent extends ActionEvent { protected $cartItem; diff --git a/core/lib/Thelia/Core/Context.php b/core/lib/Thelia/Core/Event/CategoryChangePositionEvent.php old mode 100755 new mode 100644 similarity index 64% rename from core/lib/Thelia/Core/Context.php rename to core/lib/Thelia/Core/Event/CategoryChangePositionEvent.php index 6fa5a638b..141fc8182 --- a/core/lib/Thelia/Core/Context.php +++ b/core/lib/Thelia/Core/Event/CategoryChangePositionEvent.php @@ -21,34 +21,64 @@ /* */ /*************************************************************************************/ -namespace Thelia\Core; +namespace Thelia\Core\Event; +use Thelia\Model\Category; -class Context +class CategoryChangePositionEvent extends ActionEvent { - const CONTEXT_FRONT_OFFICE = 'front'; - const CONTEXT_BACK_OFFICE = 'admin'; + const POSITION_UP = 1; + const POSITION_DOWN = 2; + const POSITION_ABSOLUTE = 3; - protected $defineContext = array( - self::CONTEXT_BACK_OFFICE, - self::CONTEXT_FRONT_OFFICE - ); + protected $id; + protected $mode; + protected $position; + protected $category; - protected $currentContext = self::CONTEXT_FRONT_OFFICE; - - public function isValidContext($context) + public function __construct($id, $mode, $position = null) { - return in_array($context, $this->defineContext); + $this->id = $id; + $this->mode = $mode; + $this->position = $position; } - public function setContext($context) + public function getId() { - if ($this->isValidContext($context)) { - $this->currentContext = $context; - } + return $this->id; } - public function getContext() + public function setId($id) { - return $this->currentContext; + $this->id = $id; } -} + + public function getMode() + { + return $this->mode; + } + + public function setMode($mode) + { + $this->mode = $mode; + } + + public function getPosition() + { + return $this->position; + } + + public function setPosition($position) + { + $this->position = $position; + } + + public function getCategory() + { + return $this->category; + } + + public function setCategory($category) + { + $this->category = $category; + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/Internal/InternalEvent.php b/core/lib/Thelia/Core/Event/CategoryCreateEvent.php old mode 100755 new mode 100644 similarity index 62% rename from core/lib/Thelia/Core/Event/Internal/InternalEvent.php rename to core/lib/Thelia/Core/Event/CategoryCreateEvent.php index 49273769f..558b04277 --- a/core/lib/Thelia/Core/Event/Internal/InternalEvent.php +++ b/core/lib/Thelia/Core/Event/CategoryCreateEvent.php @@ -21,16 +21,62 @@ /* */ /*************************************************************************************/ -namespace Thelia\Core\Event\Internal; +namespace Thelia\Core\Event; -use Symfony\Component\EventDispatcher\Event; +use Thelia\Model\Category; -/** - * Base class used for internal event like creating new Customer, adding item to cart, etc - * - * Class InternalEvent - * @package Thelia\Core\Event - */ -abstract class InternalEvent extends Event +class CategoryCreateEvent extends ActionEvent { + protected $title; + protected $parent; + protected $locale; + protected $created_category; + + public function __construct($title, $parent, $locale) + { + $this->title = $title; + $this->parent = $parent; + $this->locale = $locale; + } + + public function getTitle() + { + return $this->title; + } + + public function setTitle($title) + { + $this->title = $title; + } + + public function getParent() + { + return $this->parent; + } + + public function setParent($parent) + { + $this->parent = $parent; + } + + public function getLocale() + { + return $this->locale; + } + + public function setLocale($locale) + { + $this->locale = $locale; + } + + public function getCreatedCategory() + { + return $this->created_category; + } + + public function setCreatedCategory(Category $created_category) + { + $this->created_category = $created_category; +var_dump($this->created_category); + } } diff --git a/core/lib/Thelia/Core/Event/Internal/CartEvent.php b/core/lib/Thelia/Core/Event/CategoryDeleteEvent.php old mode 100755 new mode 100644 similarity index 76% rename from core/lib/Thelia/Core/Event/Internal/CartEvent.php rename to core/lib/Thelia/Core/Event/CategoryDeleteEvent.php index 7d35bea55..c53cb7e10 --- a/core/lib/Thelia/Core/Event/Internal/CartEvent.php +++ b/core/lib/Thelia/Core/Event/CategoryDeleteEvent.php @@ -21,17 +21,36 @@ /* */ /*************************************************************************************/ -namespace Thelia\Core\Event\Internal; +namespace Thelia\Core\Event; +use Thelia\Model\Category; -use Thelia\Model\Cart; - -class CartEvent extends InternalEvent +class CategoryDeleteEvent extends ActionEvent { - public $cart; + protected $id; + protected $deleted_category; - public function __construct(Cart $cart) + public function __construct($id) { - $this->cart = $cart; + $this->id = $id; } + public function getId() + { + return $this->id; + } + + public function setId($id) + { + $this->id = $id; + } + + public function getDeletedCategory() + { + return $this->deleted_category; + } + + public function setDeletedCategory(Category $deleted_category) + { + $this->deleted_category = $deleted_category; + } } diff --git a/core/lib/Thelia/Core/Event/CategoryEvent.php b/core/lib/Thelia/Core/Event/CategoryToggleVisibilityEvent.php old mode 100755 new mode 100644 similarity index 81% rename from core/lib/Thelia/Core/Event/CategoryEvent.php rename to core/lib/Thelia/Core/Event/CategoryToggleVisibilityEvent.php index 44986e8b9..b7237924e --- a/core/lib/Thelia/Core/Event/CategoryEvent.php +++ b/core/lib/Thelia/Core/Event/CategoryToggleVisibilityEvent.php @@ -22,15 +22,35 @@ /*************************************************************************************/ namespace Thelia\Core\Event; - use Thelia\Model\Category; -class CategoryEvent extends InternalEvent +class CategoryToggleVisibilityEvent extends ActionEvent { - public $category; + protected $id; + protected $category; - public function __construct(Category $category) + public function __construct($id) + { + $this->id = $id; + } + + public function getId() + { + return $this->id; + } + + public function setId($id) + { + $this->id = $id; + } + + public function getCategory() + { + return $this->category; + } + + public function setCategory(Category $category) { $this->category = $category; } -} +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/Internal/CustomerEvent.php b/core/lib/Thelia/Core/Event/CustomerEvent.php similarity index 95% rename from core/lib/Thelia/Core/Event/Internal/CustomerEvent.php rename to core/lib/Thelia/Core/Event/CustomerEvent.php index 46c9278cb..656f023c9 100755 --- a/core/lib/Thelia/Core/Event/Internal/CustomerEvent.php +++ b/core/lib/Thelia/Core/Event/CustomerEvent.php @@ -21,11 +21,12 @@ /* */ /*************************************************************************************/ -namespace Thelia\Core\Event\Internal; +namespace Thelia\Core\Event; use Thelia\Model\Customer; +use Thelia\Core\Event\ActionEvent; -class CustomerEvent extends InternalEvent +class CustomerEvent extends ActionEvent { public $customer; diff --git a/core/lib/Thelia/Core/Event/TheliaEvents.php b/core/lib/Thelia/Core/Event/TheliaEvents.php index 81fc34097..2dd85905d 100755 --- a/core/lib/Thelia/Core/Event/TheliaEvents.php +++ b/core/lib/Thelia/Core/Event/TheliaEvents.php @@ -94,11 +94,29 @@ final class TheliaEvents */ const AFTER_CHANGECUSTOMER = "action.after_changecustomer"; + /** * Sent once the category creation form has been successfully validated, and before category insertion in the database. */ const BEFORE_CREATECATEGORY = "action.before_createcategory"; + /** + * Create, change or delete a category + */ + const CATEGORY_CREATE = "action.createCategory"; + const CATEGORY_MODIFY = "action.modifyCategory"; + const CATEGORY_DELETE = "action.deleteCategory"; + + /** + * Toggle category visibility + */ + const CATEGORY_TOGGLE_VISIBILITY = "action.toggleCategoryVisibility"; + + /** + * Change category position + */ + const CATEGORY_CHANGE_POSITION = "action.changeCategoryPosition"; + /** * Sent just after a successful insert of a new category in the database. */ @@ -113,6 +131,11 @@ final class TheliaEvents */ const AFTER_DELETECATEGORY = "action.after_deletecategory"; + /** + * Sent just before a successful change of a category in the database. + */ + const BEFORE_CHANGECATEGORY = "action.before_changecategory"; + /** * Sent just after a successful change of a category in the database. */ @@ -154,5 +177,4 @@ final class TheliaEvents * Sent on cimage cache clear request */ const IMAGE_CLEAR_CACHE = "action.clearImageCache"; - } diff --git a/core/lib/Thelia/Core/Security/SecurityContext.php b/core/lib/Thelia/Core/Security/SecurityContext.php index 9df25de9e..c09945f61 100755 --- a/core/lib/Thelia/Core/Security/SecurityContext.php +++ b/core/lib/Thelia/Core/Security/SecurityContext.php @@ -33,36 +33,11 @@ use Thelia\Core\HttpFoundation\Request; */ class SecurityContext { - const CONTEXT_FRONT_OFFICE = 'front'; - const CONTEXT_BACK_OFFICE = 'admin'; - private $request; - private $context; public function __construct(Request $request) { $this->request = $request; - - $this->context = null; - } - - public function setContext($context) - { - if ($context !== self::CONTEXT_FRONT_OFFICE && $context !== self::CONTEXT_BACK_OFFICE) { - throw new \InvalidArgumentException(sprintf("Invalid or empty context identifier '%s'", $context)); - } - - $this->context = $context; - - return $this; - } - - public function getContext($exception_if_context_undefined = false) - { - if (null === $this->context && $exception_if_context_undefined === true) - throw new \LogicException("No context defined. Please use setContext() first."); - - return $this->context; } private function getSession() @@ -76,28 +51,47 @@ class SecurityContext } /** - * Gets the currently authenticated user in the current context, or null if none is defined + * Gets the currently authenticated user in the admin, or null if none is defined * * @return UserInterface|null A UserInterface instance or null if no user is available */ - public function getUser() + public function getAdminUser() { - $context = $this->getContext(true); - - if ($context === self::CONTEXT_FRONT_OFFICE) - $user = $this->getSession()->getCustomerUser(); - else if ($context == self::CONTEXT_BACK_OFFICE) - $user = $this->getSession()->getAdminUser(); - else - $user = null; - - return $user; + return $this->getSession()->getAdminUser(); } - final public function isAuthenticated() + /** + * Gets the currently authenticated customer, or null if none is defined + * + * @return UserInterface|null A UserInterface instance or null if no user is available + */ + public function getCustomerUser() { - if (null !== $this->getUser()) { - return true; + return $this->getSession()->getCustomerUser(); + } + + /** + * Check if a user has at least one of the required roles + * + * @param UserInterface $user the user + * @param array $roles the roles + * @return boolean true if the user has the required role, false otherwise + */ + final public function hasRequiredRole($user, array $roles) { + + if ($user != null) { + // Check if user's roles matches required roles + $userRoles = $user->getRoles(); + + $roleFound = false; + + foreach ($userRoles as $role) { + if (in_array($role, $roles)) { + $roleFound = true; + + return true; + } + } } return false; @@ -110,85 +104,88 @@ class SecurityContext */ final public function isGranted(array $roles, array $permissions) { - if ($this->isAuthenticated() === true) { + // Find a user which matches the required roles. + $user = $this->getCustomerUser(); - $user = $this->getUser(); + if (! $this->hasRequiredRole($user, $roles)) { + $user = $this->getAdminUser(); - // Check if user's roles matches required roles - $userRoles = $user->getRoles(); + if (! $this->hasRequiredRole($user, $roles)) { + $user = null; + } + } - $roleFound = false; + if ($user != null) { - foreach ($userRoles as $role) { - if (in_array($role, $roles)) { - $roleFound = true; - - break; - } + if (empty($permissions)) { + return true; } - if ($roleFound) { + // Get permissions from profile + // $userPermissions = $user->getPermissions(); FIXME - if (empty($permissions)) { - return true; - } + // TODO: Finalize permissions system !; - // Get permissions from profile - // $userPermissions = $user->getPermissions(); FIXME + $userPermissions = array('*'); // FIXME ! - // TODO: Finalize permissions system !; + $permissionsFound = true; - $userPermissions = array('*'); // FIXME ! + // User have all permissions ? + if (in_array('*', $userPermissions)) + return true; - $permissionsFound = true; + // Check that user's permissions matches required permissions + foreach ($permissions as $permission) { + if (! in_array($permission, $userPermissions)) { + $permissionsFound = false; - // User have all permissions ? - if (in_array('*', $userPermissions)) - return true; - - // Check that user's permissions matches required permissions - foreach ($permissions as $permission) { - if (! in_array($permission, $userPermissions)) { - $permissionsFound = false; - - break; - } - } - - return $permissionsFound; + break; + } } + + return $permissionsFound; } return false; } /** - * Sets the authenticated user. + * Sets the authenticated admin user. * * @param UserInterface $user A UserInterface, or null if no further user should be stored */ - public function setUser(UserInterface $user) + public function setAdminUser(UserInterface $user) { - $context = $this->getContext(true); - $user->eraseCredentials(); - if ($context === self::CONTEXT_FRONT_OFFICE) - $this->getSession()->setCustomerUser($user); - else if ($context == self::CONTEXT_BACK_OFFICE) - $this->getSession()->setAdminUser($user); + $this->getSession()->setAdminUser($user); } /** - * Clear the user from the security context + * Sets the authenticated customer user. + * + * @param UserInterface $user A UserInterface, or null if no further user should be stored */ - public function clear() + public function setCustomerUser(UserInterface $user) { - $context = $this->getContext(true); + $user->eraseCredentials(); - if ($context === self::CONTEXT_FRONT_OFFICE) - $this->getSession()->clearCustomerUser(); - else if ($context == self::CONTEXT_BACK_OFFICE) - $this->getSession()->clearAdminUser(); + $this->getSession()->setCustomerUser($user); } -} + + /** + * Clear the customer from the security context + */ + public function clearCustomerUser() + { + $this->getSession()->clearCustomerUser(); + } + + /** + * Clear the admin from the security context + */ + public function clearAdminUser() + { + $this->getSession()->clearAdminUser(); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Template/Loop/Auth.php b/core/lib/Thelia/Core/Template/Loop/Auth.php index b645a0f95..ff9f3cfd3 100755 --- a/core/lib/Thelia/Core/Template/Loop/Auth.php +++ b/core/lib/Thelia/Core/Template/Loop/Auth.php @@ -68,15 +68,12 @@ class Auth extends BaseLoop */ public function exec(&$pagination) { - $context = $this->getContext(); $roles = $this->_explode($this->getRoles()); $permissions = $this->_explode($this->getPermissions()); $loopResult = new LoopResult(); try { - $this->securityContext->setContext($context); - if (true === $this->securityContext->isGranted($roles, $permissions == null ? array() : $permissions)) { // Create an empty row: loop is no longer empty :) diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php index d9f08bbdf..ee65f34b3 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php @@ -52,7 +52,7 @@ class DataAccessFunctions extends AbstractSmartyPlugin */ public function adminDataAccess($params, &$smarty) { - return $this->userDataAccess("Admin User", SecurityContext::CONTEXT_BACK_OFFICE, $params); + return $this->userDataAccess("Admin User", $this->securityContext->getAdminUser(), $params); } /** @@ -64,7 +64,7 @@ class DataAccessFunctions extends AbstractSmartyPlugin */ public function customerDataAccess($params, &$smarty) { - return $this->userDataAccess("Customer User", SecurityContext::CONTEXT_FRONT_OFFICE, $params); + return $this->userDataAccess("Customer User", $this->securityContext->getCustomerUser(), $params); } /** @@ -75,12 +75,11 @@ class DataAccessFunctions extends AbstractSmartyPlugin * @return string the value of the requested attribute * @throws InvalidArgumentException if the object does not have the requested attribute. */ - protected function userDataAccess($objectLabel, $context, $params) + protected function userDataAccess($objectLabel, $user, $params) { $attribute = $this->getNormalizedParam($params, array('attribute', 'attrib', 'attr')); if (! empty($attribute)) { - $user = $this->securityContext->setContext($context)->getUser(); if (null != $user) { $getter = sprintf("get%s", ucfirst($attribute)); diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/Security.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/Security.php index eb19d97f5..24d2c29ee 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/Security.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/Security.php @@ -46,11 +46,6 @@ class Security extends AbstractSmartyPlugin */ public function checkAuthFunction($params, &$smarty) { - // Context: 'front' or 'admin' - $context = $this->getNormalizedParam($params, 'context'); - - $this->securityContext->setContext($context); - $roles = $this->_explode($this->getParam($params, 'roles')); $permissions = $this->_explode($this->getParam($params, 'permissions')); diff --git a/core/lib/Thelia/Model/CartItem.php b/core/lib/Thelia/Model/CartItem.php index 39408763e..fbfbee32c 100755 --- a/core/lib/Thelia/Model/CartItem.php +++ b/core/lib/Thelia/Model/CartItem.php @@ -4,10 +4,10 @@ namespace Thelia\Model; use Propel\Runtime\Connection\ConnectionInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; -use Thelia\Core\Event\Internal\CartEvent; use Thelia\Core\Event\TheliaEvents; use Thelia\Model\Base\CartItem as BaseCartItem; use Thelia\Model\ConfigQuery; +use Thelia\Core\Event\CartEvent; class CartItem extends BaseCartItem { diff --git a/core/lib/Thelia/Model/Customer.php b/core/lib/Thelia/Model/Customer.php index a6a4927b2..d7418a4ea 100755 --- a/core/lib/Thelia/Model/Customer.php +++ b/core/lib/Thelia/Model/Customer.php @@ -3,7 +3,6 @@ namespace Thelia\Model; use Symfony\Component\Config\Definition\Exception\Exception; -use Thelia\Core\Event\Internal\CustomerEvent; use Thelia\Model\Base\Customer as BaseCustomer; use Thelia\Model\Exception\InvalidArgumentException; @@ -17,6 +16,7 @@ use Propel\Runtime\Connection\ConnectionInterface; use Propel\Runtime\Propel; use Thelia\Model\Map\CustomerTableMap; use Thelia\Core\Security\Role\Role; +use Thelia\Core\Event\CustomerEvent; /** * Skeleton subclass for representing a row from the 'customer' table. From cce270fdcc225912f16221ce711a2c2e1ea24dfc Mon Sep 17 00:00:00 2001 From: franck Date: Wed, 28 Aug 2013 19:47:31 +0200 Subject: [PATCH 2/2] Factorized ModelCriterialTools calls in loops --- .../Controller/Admin/CategoryController.php | 6 +- .../Thelia/Core/Template/Element/BaseLoop.php | 23 +++++ .../Thelia/Core/Template/Loop/Attribute.php | 3 +- .../Template/Loop/AttributeAvailability.php | 8 +- .../Template/Loop/AttributeCombination.php | 11 +-- .../Thelia/Core/Template/Loop/Category.php | 9 +- .../Core/Template/Loop/CategoryPath.php | 13 ++- .../lib/Thelia/Core/Template/Loop/Content.php | 8 +- .../lib/Thelia/Core/Template/Loop/Country.php | 8 +- .../Thelia/Core/Template/Loop/Currency.php | 8 +- .../lib/Thelia/Core/Template/Loop/Feature.php | 8 +- .../Template/Loop/FeatureAvailability.php | 8 +- .../Core/Template/Loop/FeatureValue.php | 9 +- core/lib/Thelia/Core/Template/Loop/Folder.php | 8 +- core/lib/Thelia/Core/Template/Loop/Image.php | 13 +-- .../lib/Thelia/Core/Template/Loop/Product.php | 8 +- core/lib/Thelia/Core/Template/Loop/Title.php | 8 +- core/lib/Thelia/Model/Category.php | 6 +- .../Thelia/Model/Tools/ModelCriteriaTools.php | 86 +++++++++++-------- .../css/bootstrap-editable.css | 78 ++++++++--------- templates/admin/default/assets/css/admin.less | 6 -- templates/admin/default/categories.html | 2 +- .../default/includes/category_breadcrumb.html | 4 +- .../default/includes/inner-form-toolbar.html | 2 +- 24 files changed, 150 insertions(+), 193 deletions(-) diff --git a/core/lib/Thelia/Controller/Admin/CategoryController.php b/core/lib/Thelia/Controller/Admin/CategoryController.php index fda94191c..4e798d683 100755 --- a/core/lib/Thelia/Controller/Admin/CategoryController.php +++ b/core/lib/Thelia/Controller/Admin/CategoryController.php @@ -89,7 +89,7 @@ class CategoryController extends BaseAdminController $categoryDeletionForm = new CategoryDeletionForm($this->getRequest()); $data = $this->validateForm($categoryDeletionForm, "POST")->getData(); -var_dump($data); + $categoryDeleteEvent = new CategoryDeleteEvent($data['category_id']); $this->dispatch(TheliaEvents::CATEGORY_DELETE, $categoryDeleteEvent); @@ -151,8 +151,8 @@ var_dump($data); protected function positionDown($args) { $event = new CategoryChangePositionEvent( - $this->getRequest()->get('category_id', 0), - CategoryChangePositionEvent::POSITION_DOWN + $this->getRequest()->get('category_id', 0), + CategoryChangePositionEvent::POSITION_DOWN ); $this->dispatch(TheliaEvents::CATEGORY_CHANGE_POSITION, $event); diff --git a/core/lib/Thelia/Core/Template/Element/BaseLoop.php b/core/lib/Thelia/Core/Template/Element/BaseLoop.php index 72f782309..8861022e9 100755 --- a/core/lib/Thelia/Core/Template/Element/BaseLoop.php +++ b/core/lib/Thelia/Core/Template/Element/BaseLoop.php @@ -28,6 +28,7 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Thelia\Core\Template\Loop\Argument\Argument; use Propel\Runtime\ActiveQuery\ModelCriteria; use Thelia\Core\Security\SecurityContext; +use Thelia\Model\Tools\ModelCriteriaTools; /** * @@ -234,6 +235,28 @@ abstract class BaseLoop } } + /** + * Setup ModelCriteria for proper i18n processing + * + * @param ModelCriteria $search the Propel Criteria to configure + * @param array $columns the i18n columns + * @param string $foreignTable the specified table (default to criteria table) + * @param string $foreignKey the foreign key in this table (default to criteria table) + */ + protected function configureI18nProcessing(ModelCriteria $search, $columns = array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), $foreignTable = null, $foreignKey = 'ID') { + + /* manage translations */ + ModelCriteriaTools::getI18n( + $this->getBackend_context(), + $this->getLang(), + $search, + $this->request->getSession()->getLocale(), + $columns, + $foreignTable, + $foreignKey + ); + } + /** * * this function have to be implement in your own loop class. diff --git a/core/lib/Thelia/Core/Template/Loop/Attribute.php b/core/lib/Thelia/Core/Template/Loop/Attribute.php index 41721350b..0608732a4 100755 --- a/core/lib/Thelia/Core/Template/Loop/Attribute.php +++ b/core/lib/Thelia/Core/Template/Loop/Attribute.php @@ -34,7 +34,6 @@ use Thelia\Core\Template\Loop\Argument\Argument; use Thelia\Log\Tlog; use Thelia\Model\Base\LangQuery; -use Thelia\Model\Tools\ModelCriteriaTools; use Thelia\Model\Base\CategoryQuery; use Thelia\Model\Base\ProductCategoryQuery; @@ -92,7 +91,7 @@ class Attribute extends BaseLoop $lang = $this->getLang(); /* manage translations */ - ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale()); + $this->configureI18nProcessing($search); $id = $this->getId(); diff --git a/core/lib/Thelia/Core/Template/Loop/AttributeAvailability.php b/core/lib/Thelia/Core/Template/Loop/AttributeAvailability.php index be42f5dab..0664c7d56 100755 --- a/core/lib/Thelia/Core/Template/Loop/AttributeAvailability.php +++ b/core/lib/Thelia/Core/Template/Loop/AttributeAvailability.php @@ -33,8 +33,6 @@ use Thelia\Core\Template\Loop\Argument\ArgumentCollection; use Thelia\Core\Template\Loop\Argument\Argument; use Thelia\Log\Tlog; -use Thelia\Model\Tools\ModelCriteriaTools; - use Thelia\Model\Base\AttributeAvQuery; use Thelia\Model\ConfigQuery; use Thelia\Type\TypeCollection; @@ -79,12 +77,8 @@ class AttributeAvailability extends BaseLoop { $search = AttributeAvQuery::create(); - $backendContext = $this->getBackend_context(); - - $lang = $this->getLang(); - /* manage translations */ - ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale()); + $this->configureI18nProcessing($search); $id = $this->getId(); diff --git a/core/lib/Thelia/Core/Template/Loop/AttributeCombination.php b/core/lib/Thelia/Core/Template/Loop/AttributeCombination.php index 833f1abb3..556a5a1fd 100755 --- a/core/lib/Thelia/Core/Template/Loop/AttributeCombination.php +++ b/core/lib/Thelia/Core/Template/Loop/AttributeCombination.php @@ -33,8 +33,6 @@ use Thelia\Core\Template\Loop\Argument\ArgumentCollection; use Thelia\Core\Template\Loop\Argument\Argument; use Thelia\Log\Tlog; -use Thelia\Model\Tools\ModelCriteriaTools; - use Thelia\Model\Base\AttributeCombinationQuery; use Thelia\Model\Map\AttributeAvTableMap; use Thelia\Model\Map\AttributeTableMap; @@ -59,6 +57,7 @@ class AttributeCombination extends BaseLoop { return new ArgumentCollection( Argument::createIntTypeArgument('product_sale_elements', null, true), + Argument::createIntTypeArgument('lang'), new Argument( 'order', new TypeCollection( @@ -79,20 +78,16 @@ class AttributeCombination extends BaseLoop $search = AttributeCombinationQuery::create(); /* manage attribute translations */ - ModelCriteriaTools::getFrontEndI18n( + $this->configureI18nProcessing( $search, - ConfigQuery::read("default_lang_without_translation", 1), - $this->request->getSession()->getLocale(), array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), AttributeTableMap::TABLE_NAME, 'ATTRIBUTE_ID' ); /* manage attributeAv translations */ - ModelCriteriaTools::getFrontEndI18n( + $this->configureI18nProcessing( $search, - ConfigQuery::read("default_lang_without_translation", 1), - $this->request->getSession()->getLocale(), array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), AttributeAvTableMap::TABLE_NAME, 'ATTRIBUTE_AV_ID' diff --git a/core/lib/Thelia/Core/Template/Loop/Category.php b/core/lib/Thelia/Core/Template/Loop/Category.php index 9b497bb1a..e01ce3df4 100755 --- a/core/lib/Thelia/Core/Template/Loop/Category.php +++ b/core/lib/Thelia/Core/Template/Loop/Category.php @@ -32,8 +32,6 @@ use Thelia\Core\Template\Loop\Argument\ArgumentCollection; use Thelia\Core\Template\Loop\Argument\Argument; use Thelia\Log\Tlog; -use Thelia\Model\Tools\ModelCriteriaTools; - use Thelia\Model\CategoryQuery; use Thelia\Model\ConfigQuery; use Thelia\Type\TypeCollection; @@ -98,12 +96,8 @@ class Category extends BaseLoop { $search = CategoryQuery::create(); - $backendContext = $this->getBackend_context(); - - $lang = $this->getLang(); - /* manage translations */ - ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale()); + $this->configureI18nProcessing($search); $id = $this->getId(); @@ -169,7 +163,6 @@ class Category extends BaseLoop $loopResult = new LoopResult(); foreach ($categories as $category) { - /* * no cause pagination lost : * if ($this->getNotEmpty() && $category->countAllProducts() == 0) continue; diff --git a/core/lib/Thelia/Core/Template/Loop/CategoryPath.php b/core/lib/Thelia/Core/Template/Loop/CategoryPath.php index d6c0cd02c..30238c26d 100755 --- a/core/lib/Thelia/Core/Template/Loop/CategoryPath.php +++ b/core/lib/Thelia/Core/Template/Loop/CategoryPath.php @@ -65,7 +65,8 @@ class CategoryPath extends BaseLoop Argument::createIntTypeArgument('category', null, true), Argument::createIntTypeArgument('depth'), Argument::createIntTypeArgument('level'), - Argument::createBooleanOrBothTypeArgument('visible', true, false) + Argument::createBooleanOrBothTypeArgument('visible', true, false), + Argument::createIntTypeArgument('lang') ); } @@ -80,6 +81,9 @@ class CategoryPath extends BaseLoop $visible = $this->getVisible(); $search = CategoryQuery::create(); + + $this->configureI18nProcessing($search, array('TITLE')); + $search->filterById($id); if ($visible != BooleanOrBothType::ANY) $search->filterByVisible($visible); @@ -95,7 +99,7 @@ class CategoryPath extends BaseLoop $loopResultRow = new LoopResultRow(); $loopResultRow - ->set("TITLE",$category->getTitle()) + ->set("TITLE",$category->getVirtualColumn('i18n_TITLE')) ->set("URL", $category->getUrl()) ->set("ID", $category->getId()) ; @@ -114,8 +118,11 @@ class CategoryPath extends BaseLoop $ids[] = $parent; $search = CategoryQuery::create(); + + $this->configureI18nProcessing($search, array('TITLE')); + $search->filterById($parent); - if ($visible == true) $search->filterByVisible($visible); + if ($visible != BooleanOrBothType::ANY) $search->filterByVisible($visible); } } } while ($category != null && $parent > 0); diff --git a/core/lib/Thelia/Core/Template/Loop/Content.php b/core/lib/Thelia/Core/Template/Loop/Content.php index 6632a184c..701206ea8 100755 --- a/core/lib/Thelia/Core/Template/Loop/Content.php +++ b/core/lib/Thelia/Core/Template/Loop/Content.php @@ -31,8 +31,6 @@ use Thelia\Core\Template\Element\LoopResultRow; use Thelia\Core\Template\Loop\Argument\ArgumentCollection; use Thelia\Core\Template\Loop\Argument\Argument; -use Thelia\Model\Tools\ModelCriteriaTools; - use Thelia\Model\FolderQuery; use Thelia\Model\Map\ContentTableMap; use Thelia\Model\ContentFolderQuery; @@ -88,12 +86,8 @@ class Content extends BaseLoop { $search = ContentQuery::create(); - $backendContext = $this->getBackend_context(); - - $lang = $this->getLang(); - /* manage translations */ - ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale()); + $this->configureI18nProcessing($search); $id = $this->getId(); diff --git a/core/lib/Thelia/Core/Template/Loop/Country.php b/core/lib/Thelia/Core/Template/Loop/Country.php index c6f7d16de..d93d94cb4 100755 --- a/core/lib/Thelia/Core/Template/Loop/Country.php +++ b/core/lib/Thelia/Core/Template/Loop/Country.php @@ -31,8 +31,6 @@ use Thelia\Core\Template\Element\LoopResultRow; use Thelia\Core\Template\Loop\Argument\ArgumentCollection; use Thelia\Core\Template\Loop\Argument\Argument; -use Thelia\Model\Tools\ModelCriteriaTools; - use Thelia\Model\CountryQuery; use Thelia\Model\ConfigQuery; @@ -70,12 +68,8 @@ class Country extends BaseLoop { $search = CountryQuery::create(); - $backendContext = $this->getBackend_context(); - - $lang = $this->getLang(); - /* manage translations */ - ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale()); + $this->configureI18nProcessing($search); $id = $this->getId(); diff --git a/core/lib/Thelia/Core/Template/Loop/Currency.php b/core/lib/Thelia/Core/Template/Loop/Currency.php index d833ff8ae..b793b86fd 100755 --- a/core/lib/Thelia/Core/Template/Loop/Currency.php +++ b/core/lib/Thelia/Core/Template/Loop/Currency.php @@ -31,8 +31,6 @@ use Thelia\Core\Template\Element\LoopResultRow; use Thelia\Core\Template\Loop\Argument\ArgumentCollection; use Thelia\Core\Template\Loop\Argument\Argument; -use Thelia\Model\Tools\ModelCriteriaTools; - use Thelia\Model\CurrencyQuery; use Thelia\Model\ConfigQuery; @@ -69,12 +67,8 @@ class Currency extends BaseLoop { $search = CurrencyQuery::create(); - $backendContext = $this->getBackend_context(); - - $lang = $this->getLang(); - /* manage translations */ - ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale(), array('NAME')); + $this->configureI18nProcessing($search, array('NAME')); $id = $this->getId(); diff --git a/core/lib/Thelia/Core/Template/Loop/Feature.php b/core/lib/Thelia/Core/Template/Loop/Feature.php index 85d037080..e2de85dbc 100755 --- a/core/lib/Thelia/Core/Template/Loop/Feature.php +++ b/core/lib/Thelia/Core/Template/Loop/Feature.php @@ -31,8 +31,6 @@ use Thelia\Core\Template\Element\LoopResultRow; use Thelia\Core\Template\Loop\Argument\ArgumentCollection; use Thelia\Core\Template\Loop\Argument\Argument; -use Thelia\Model\Tools\ModelCriteriaTools; - use Thelia\Model\Base\CategoryQuery; use Thelia\Model\Base\ProductCategoryQuery; use Thelia\Model\Base\FeatureQuery; @@ -84,12 +82,8 @@ class Feature extends BaseLoop { $search = FeatureQuery::create(); - $backendContext = $this->getBackend_context(); - - $lang = $this->getLang(); - /* manage translations */ - ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale()); + $this->configureI18nProcessing($search); $id = $this->getId(); diff --git a/core/lib/Thelia/Core/Template/Loop/FeatureAvailability.php b/core/lib/Thelia/Core/Template/Loop/FeatureAvailability.php index ce6f8767a..c04d70031 100755 --- a/core/lib/Thelia/Core/Template/Loop/FeatureAvailability.php +++ b/core/lib/Thelia/Core/Template/Loop/FeatureAvailability.php @@ -31,8 +31,6 @@ use Thelia\Core\Template\Element\LoopResultRow; use Thelia\Core\Template\Loop\Argument\ArgumentCollection; use Thelia\Core\Template\Loop\Argument\Argument; -use Thelia\Model\Tools\ModelCriteriaTools; - use Thelia\Model\Base\FeatureAvQuery; use Thelia\Model\ConfigQuery; use Thelia\Type\TypeCollection; @@ -77,12 +75,8 @@ class FeatureAvailability extends BaseLoop { $search = FeatureAvQuery::create(); - $backendContext = $this->getBackend_context(); - - $lang = $this->getLang(); - /* manage translations */ - ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale()); + $this->configureI18nProcessing($search); $id = $this->getId(); diff --git a/core/lib/Thelia/Core/Template/Loop/FeatureValue.php b/core/lib/Thelia/Core/Template/Loop/FeatureValue.php index 8a29d7c74..42d50c57b 100755 --- a/core/lib/Thelia/Core/Template/Loop/FeatureValue.php +++ b/core/lib/Thelia/Core/Template/Loop/FeatureValue.php @@ -33,8 +33,6 @@ use Thelia\Core\Template\Loop\Argument\ArgumentCollection; use Thelia\Core\Template\Loop\Argument\Argument; use Thelia\Log\Tlog; -use Thelia\Model\Tools\ModelCriteriaTools; - use Thelia\Model\Base\FeatureProductQuery; use Thelia\Model\ConfigQuery; use Thelia\Model\Map\FeatureAvTableMap; @@ -70,7 +68,8 @@ class FeatureValue extends BaseLoop new Type\EnumListType(array('alpha', 'alpha_reverse', 'manual', 'manual_reverse')) ), 'manual' - ) + ), + Argument::createIntTypeArgument('lang') ); } @@ -84,10 +83,8 @@ class FeatureValue extends BaseLoop $search = FeatureProductQuery::create(); /* manage featureAv translations */ - ModelCriteriaTools::getFrontEndI18n( + $this->configureI18nProcessing( $search, - ConfigQuery::read("default_lang_without_translation", 1), - $this->request->getSession()->getLocale(), array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), FeatureAvTableMap::TABLE_NAME, 'FEATURE_AV_ID' diff --git a/core/lib/Thelia/Core/Template/Loop/Folder.php b/core/lib/Thelia/Core/Template/Loop/Folder.php index c95b0dc42..327ce76d4 100755 --- a/core/lib/Thelia/Core/Template/Loop/Folder.php +++ b/core/lib/Thelia/Core/Template/Loop/Folder.php @@ -32,8 +32,6 @@ use Thelia\Core\Template\Loop\Argument\ArgumentCollection; use Thelia\Core\Template\Loop\Argument\Argument; use Thelia\Log\Tlog; -use Thelia\Model\Tools\ModelCriteriaTools; - use Thelia\Model\FolderQuery; use Thelia\Model\ConfigQuery; use Thelia\Type\TypeCollection; @@ -80,12 +78,8 @@ class Folder extends BaseLoop { $search = FolderQuery::create(); - $backendContext = $this->getBackend_context(); - - $lang = $this->getLang(); - /* manage translations */ - ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale()); + $this->configureI18nProcessing($search); $id = $this->getId(); diff --git a/core/lib/Thelia/Core/Template/Loop/Image.php b/core/lib/Thelia/Core/Template/Loop/Image.php index a1e866cb2..638905dc2 100755 --- a/core/lib/Thelia/Core/Template/Loop/Image.php +++ b/core/lib/Thelia/Core/Template/Loop/Image.php @@ -207,16 +207,8 @@ class Image extends BaseLoop } - /** - * \Criteria::INNER_JOIN in second parameter for joinWithI18n exclude query without translation. - * - * @todo : verify here if we want results for row without translations. - */ - - $search->joinWithI18n( - $this->request->getSession()->getLocale(), - (ConfigQuery::read("default_lang_without_translation", 1)) ? Criteria::LEFT_JOIN : Criteria::INNER_JOIN - ); + /* manage translations */ + $this->configureI18nProcessing($search); $results = $this->search($search, $pagination); @@ -295,6 +287,7 @@ class Image extends BaseLoop ), 'manual' ), + Argument::createIntTypeArgument('lang'), Argument::createIntTypeArgument('width'), Argument::createIntTypeArgument('height'), diff --git a/core/lib/Thelia/Core/Template/Loop/Product.php b/core/lib/Thelia/Core/Template/Loop/Product.php index 10112ef28..1570acca8 100755 --- a/core/lib/Thelia/Core/Template/Loop/Product.php +++ b/core/lib/Thelia/Core/Template/Loop/Product.php @@ -33,8 +33,6 @@ use Thelia\Core\Template\Loop\Argument\ArgumentCollection; use Thelia\Core\Template\Loop\Argument\Argument; use Thelia\Log\Tlog; -use Thelia\Model\Tools\ModelCriteriaTools; - use Thelia\Model\CategoryQuery; use Thelia\Model\Map\FeatureProductTableMap; use Thelia\Model\Map\ProductPriceTableMap; @@ -138,12 +136,8 @@ class Product extends BaseLoop { $search = ProductQuery::create(); - $backendContext = $this->getBackend_context(); - - $lang = $this->getLang(); - /* manage translations */ - ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale()); + $this->configureI18nProcessing($search); $attributeNonStrictMatch = $this->getAttribute_non_strict_match(); $isPSELeftJoinList = array(); diff --git a/core/lib/Thelia/Core/Template/Loop/Title.php b/core/lib/Thelia/Core/Template/Loop/Title.php index caa5e7d87..c53be086a 100755 --- a/core/lib/Thelia/Core/Template/Loop/Title.php +++ b/core/lib/Thelia/Core/Template/Loop/Title.php @@ -31,8 +31,6 @@ use Thelia\Core\Template\Element\LoopResultRow; use Thelia\Core\Template\Loop\Argument\ArgumentCollection; use Thelia\Core\Template\Loop\Argument\Argument; -use Thelia\Model\Tools\ModelCriteriaTools; - use Thelia\Model\CustomerTitleQuery; use Thelia\Model\ConfigQuery; @@ -67,12 +65,8 @@ class Title extends BaseLoop { $search = CustomerTitleQuery::create(); - $backendContext = $this->getBackend_context(); - - $lang = $this->getLang(); - /* manage translations */ - ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale(), array('SHORT', 'LONG')); + $this->configureI18nProcessing($search, array('SHORT', 'LONG')); $id = $this->getId(); diff --git a/core/lib/Thelia/Model/Category.php b/core/lib/Thelia/Model/Category.php index 88e7cfc10..2ffd375dd 100755 --- a/core/lib/Thelia/Model/Category.php +++ b/core/lib/Thelia/Model/Category.php @@ -48,7 +48,7 @@ class Category extends BaseCategory ->findOne() ; - return $last->getPosition() + 1; + return $last != null ? $last->getPosition() + 1 : 1; } /** @@ -74,6 +74,4 @@ class Category extends BaseCategory return $countProduct; } - - -} +} \ No newline at end of file diff --git a/core/lib/Thelia/Model/Tools/ModelCriteriaTools.php b/core/lib/Thelia/Model/Tools/ModelCriteriaTools.php index e9323ebfa..3913b2890 100755 --- a/core/lib/Thelia/Model/Tools/ModelCriteriaTools.php +++ b/core/lib/Thelia/Model/Tools/ModelCriteriaTools.php @@ -6,6 +6,7 @@ use Propel\Runtime\ActiveQuery\Criteria; use Propel\Runtime\ActiveQuery\Join; use Propel\Runtime\ActiveQuery\ModelCriteria; use Thelia\Model\Base\LangQuery; +use Thelia\Model\ConfigQuery; /** * Class ModelCriteriaTools @@ -17,13 +18,12 @@ class ModelCriteriaTools { /** * @param ModelCriteria $search - * @param $defaultLangWithoutTranslation - * @param $askedLocale + * @param $requestedLocale * @param array $columns * @param null $foreignTable * @param string $foreignKey */ - public static function getFrontEndI18n(ModelCriteria &$search, $defaultLangWithoutTranslation, $askedLocale, $columns = array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), $foreignTable = null, $foreignKey = 'ID') + public static function getFrontEndI18n(ModelCriteria &$search, $requestedLocale, $columns, $foreignTable, $foreignKey) { if($foreignTable === null) { $foreignTable = $search->getTableMap()->getName(); @@ -32,21 +32,24 @@ class ModelCriteriaTools $aliasPrefix = $foreignTable . '_'; } - $askedLocaleI18nAlias = 'asked_locale_i18n'; + $defaultLangWithoutTranslation = ConfigQuery::read("default_lang_without_translation", 1); + + $requestedLocaleI18nAlias = 'requested_locale_i18n'; $defaultLocaleI18nAlias = 'default_locale_i18n'; - if($defaultLangWithoutTranslation == 0) { - $askedLocaleJoin = new Join(); - $askedLocaleJoin->addExplicitCondition($search->getTableMap()->getName(), $foreignKey, null, $foreignTable . '_i18n', 'ID', $askedLocaleI18nAlias); - $askedLocaleJoin->setJoinType(Criteria::INNER_JOIN); + if (!$defaultLangWithoutTranslation == 0) { - $search->addJoinObject($askedLocaleJoin, $askedLocaleI18nAlias) - ->addJoinCondition($askedLocaleI18nAlias ,'`' . $askedLocaleI18nAlias . '`.LOCALE = ?', $askedLocale, null, \PDO::PARAM_STR); + $requestedLocaleJoin = new Join(); + $requestedLocaleJoin->addExplicitCondition($search->getTableMap()->getName(), $foreignKey, null, $foreignTable . '_i18n', 'ID', $requestedLocaleI18nAlias); + $requestedLocaleJoin->setJoinType(Criteria::INNER_JOIN); - $search->withColumn('NOT ISNULL(`' . $askedLocaleI18nAlias . '`.`ID`)', $aliasPrefix . 'IS_TRANSLATED'); + $search->addJoinObject($requestedLocaleJoin, $requestedLocaleI18nAlias) + ->addJoinCondition($requestedLocaleI18nAlias ,'`' . $requestedLocaleI18nAlias . '`.LOCALE = ?', $requestedLocale, null, \PDO::PARAM_STR); + + $search->withColumn('NOT ISNULL(`' . $requestedLocaleI18nAlias . '`.`ID`)', $aliasPrefix . 'IS_TRANSLATED'); foreach($columns as $column) { - $search->withColumn('`' . $askedLocaleI18nAlias . '`.`' . $column . '`', $aliasPrefix . 'i18n_' . $column); + $search->withColumn('`' . $requestedLocaleI18nAlias . '`.`' . $column . '`', $aliasPrefix . 'i18n_' . $column); } } else { $defaultLocale = LangQuery::create()->findOneById($defaultLangWithoutTranslation)->getLocale(); @@ -58,24 +61,24 @@ class ModelCriteriaTools $search->addJoinObject($defaultLocaleJoin, $defaultLocaleI18nAlias) ->addJoinCondition($defaultLocaleI18nAlias ,'`' . $defaultLocaleI18nAlias . '`.LOCALE = ?', $defaultLocale, null, \PDO::PARAM_STR); - $askedLocaleJoin = new Join(); - $askedLocaleJoin->addExplicitCondition($search->getTableMap()->getName(), $foreignKey, null, $foreignTable . '_i18n', 'ID', $askedLocaleI18nAlias); - $askedLocaleJoin->setJoinType(Criteria::LEFT_JOIN); + $requestedLocaleJoin = new Join(); + $requestedLocaleJoin->addExplicitCondition($search->getTableMap()->getName(), $foreignKey, null, $foreignTable . '_i18n', 'ID', $requestedLocaleI18nAlias); + $requestedLocaleJoin->setJoinType(Criteria::LEFT_JOIN); - $search->addJoinObject($askedLocaleJoin, $askedLocaleI18nAlias) - ->addJoinCondition($askedLocaleI18nAlias ,'`' . $askedLocaleI18nAlias . '`.LOCALE = ?', $askedLocale, null, \PDO::PARAM_STR); + $search->addJoinObject($requestedLocaleJoin, $requestedLocaleI18nAlias) + ->addJoinCondition($requestedLocaleI18nAlias ,'`' . $requestedLocaleI18nAlias . '`.LOCALE = ?', $requestedLocale, null, \PDO::PARAM_STR); - $search->withColumn('NOT ISNULL(`' . $askedLocaleI18nAlias . '`.`ID`)', $aliasPrefix . 'IS_TRANSLATED'); + $search->withColumn('NOT ISNULL(`' . $requestedLocaleI18nAlias . '`.`ID`)', $aliasPrefix . 'IS_TRANSLATED'); - $search->where('NOT ISNULL(`' . $askedLocaleI18nAlias . '`.ID)')->_or()->where('NOT ISNULL(`' . $defaultLocaleI18nAlias . '`.ID)'); + $search->where('NOT ISNULL(`' . $requestedLocaleI18nAlias . '`.ID)')->_or()->where('NOT ISNULL(`' . $defaultLocaleI18nAlias . '`.ID)'); foreach($columns as $column) { - $search->withColumn('CASE WHEN NOT ISNULL(`' . $askedLocaleI18nAlias . '`.ID) THEN `' . $askedLocaleI18nAlias . '`.`' . $column . '` ELSE `' . $defaultLocaleI18nAlias . '`.`' . $column . '` END', $aliasPrefix . 'i18n_' . $column); + $search->withColumn('CASE WHEN NOT ISNULL(`' . $requestedLocaleI18nAlias . '`.ID) THEN `' . $requestedLocaleI18nAlias . '`.`' . $column . '` ELSE `' . $defaultLocaleI18nAlias . '`.`' . $column . '` END', $aliasPrefix . 'i18n_' . $column); } } } - public static function getBackEndI18n(ModelCriteria &$search, $askedLocale, $columns = array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), $foreignTable = null, $foreignKey = 'ID') + public static function getBackEndI18n(ModelCriteria &$search, $requestedLocale, $columns, $foreignTable, $foreignKey) { if($foreignTable === null) { $foreignTable = $search->getTableMap()->getName(); @@ -84,35 +87,44 @@ class ModelCriteriaTools $aliasPrefix = $foreignTable . '_'; } - $askedLocaleI18nAlias = 'asked_locale_i18n'; + $requestedLocaleI18nAlias = 'requested_locale_i18n'; - $askedLocaleJoin = new Join(); - $askedLocaleJoin->addExplicitCondition($search->getTableMap()->getName(), $foreignKey, null, $foreignTable . '_i18n', 'ID', $askedLocaleI18nAlias); - $askedLocaleJoin->setJoinType(Criteria::LEFT_JOIN); + $requestedLocaleJoin = new Join(); + $requestedLocaleJoin->addExplicitCondition($search->getTableMap()->getName(), $foreignKey, null, $foreignTable . '_i18n', 'ID', $requestedLocaleI18nAlias); + $requestedLocaleJoin->setJoinType(Criteria::LEFT_JOIN); - $search->addJoinObject($askedLocaleJoin, $askedLocaleI18nAlias) - ->addJoinCondition($askedLocaleI18nAlias ,'`' . $askedLocaleI18nAlias . '`.LOCALE = ?', $askedLocale, null, \PDO::PARAM_STR); + $search->addJoinObject($requestedLocaleJoin, $requestedLocaleI18nAlias) + ->addJoinCondition($requestedLocaleI18nAlias ,'`' . $requestedLocaleI18nAlias . '`.LOCALE = ?', $requestedLocale, null, \PDO::PARAM_STR); - $search->withColumn('NOT ISNULL(`' . $askedLocaleI18nAlias . '`.`ID`)', $aliasPrefix . 'IS_TRANSLATED'); + $search->withColumn('NOT ISNULL(`' . $requestedLocaleI18nAlias . '`.`ID`)', $aliasPrefix . 'IS_TRANSLATED'); foreach($columns as $column) { - $search->withColumn('`' . $askedLocaleI18nAlias . '`.`' . $column . '`', $aliasPrefix . 'i18n_' . $column); + $search->withColumn('`' . $requestedLocaleI18nAlias . '`.`' . $column . '`', $aliasPrefix . 'i18n_' . $column); } } - public static function getI18n($backendContext, $lang, ModelCriteria &$search, $defaultLangWithoutTranslation, $currentLocale, $columns = array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), $foreignTable = null, $foreignKey = 'ID') + public static function getI18n($backendContext, $requestedLangId, ModelCriteria &$search, $currentLocale, $columns, $foreignTable, $foreignKey) { - if($lang !== null) { - $localeSearch = LangQuery::create()->findOneById($lang); - if($localeSearch === null) { - throw new \InvalidArgumentException('Incorrect lang argument given in attribute loop'); + // If a lang has been requested, find the related Lang object, and get the locale + if ($requestedLangId !== null) { + $localeSearch = LangQuery::create()->findOneById($requestedLangId); + + if ($localeSearch === null) { + throw new \InvalidArgumentException(sprintf('Incorrect lang argument given in attribute loop: lang ID %d not found', $requestedLangId)); } + + $locale = $localeSearch->getLocale(); + } + else { + // Use the currently defined locale + $locale = $currentLocale; } - if($backendContext) { - self::getBackEndI18n($search, $lang === null ? $currentLocale : $localeSearch->getLocale(), $columns, $foreignTable, $foreignKey); + // Call the proper method depending on the context: front or back + if ($backendContext) { + self::getBackEndI18n($search, $locale, $columns, $foreignTable, $foreignKey); } else { - self::getFrontEndI18n($search, $defaultLangWithoutTranslation, $lang === null ? $currentLocale : $localeSearch->getLocale(), $columns, $foreignTable, $foreignKey); + self::getFrontEndI18n($search, $locale, $columns, $foreignTable, $foreignKey); } } } diff --git a/templates/admin/default/assets/bootstrap-editable/css/bootstrap-editable.css b/templates/admin/default/assets/bootstrap-editable/css/bootstrap-editable.css index 2d9cc4eae..16de488fa 100755 --- a/templates/admin/default/assets/bootstrap-editable/css/bootstrap-editable.css +++ b/templates/admin/default/assets/bootstrap-editable/css/bootstrap-editable.css @@ -1,4 +1,4 @@ -/*! X-editable - v1.4.6 +/*! X-editable - v1.4.6 * In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery * http://github.com/vitalets/x-editable * Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */ @@ -18,45 +18,45 @@ vertical-align: top; margin-left: 7px; /* inline-block emulation for IE7*/ - zoom: 1; + zoom: 1; *display: inline; } .editable-buttons.editable-buttons-bottom { - display: block; + display: block; margin-top: 7px; margin-left: 0; } .editable-input { - vertical-align: top; + vertical-align: top; display: inline-block; /* should be inline to take effect of parent's white-space: nowrap */ width: auto; /* bootstrap-responsive has width: 100% that breakes layout */ white-space: normal; /* reset white-space decalred in parent*/ /* display-inline emulation for IE7*/ - zoom: 1; - *display: inline; + zoom: 1; + *display: inline; } .editable-buttons .editable-cancel { - margin-left: 7px; + margin-left: 7px; } /*for jquery-ui buttons need set height to look more pretty*/ .editable-buttons button.ui-button-icon-only { - height: 24px; + height: 24px; width: 30px; } .editableform-loading { - background: url('../img/loading.gif') center center no-repeat; + background: url('../img/loading.gif') center center no-repeat; height: 25px; - width: auto; - min-width: 25px; + width: auto; + min-width: 25px; } .editable-inline .editableform-loading { - background-position: left 5px; + background-position: left 5px; } .editable-error-block { @@ -68,17 +68,17 @@ /*add padding for jquery ui*/ .editable-error-block.ui-state-error { - padding: 3px; -} + padding: 3px; +} .editable-error { - color: red; + color: red; } /* ---- For specific types ---- */ .editableform .editable-date { - padding: 0; + padding: 0; margin: 0; float: left; } @@ -86,25 +86,25 @@ /* move datepicker icon to center of add-on button. See https://github.com/vitalets/x-editable/issues/183 */ .editable-inline .add-on .icon-th { margin-top: 3px; - margin-left: 1px; + margin-left: 1px; } /* checklist vertical alignment */ -.editable-checklist label input[type="checkbox"], +.editable-checklist label input[type="checkbox"], .editable-checklist label span { vertical-align: middle; margin: 0; } .editable-checklist label { - white-space: nowrap; + white-space: nowrap; } /* set exact width of textarea to fit buttons toolbar */ .editable-wysihtml5 { - width: 566px; - height: 250px; + width: 566px; + height: 250px; } /* clear button shown as link in date inputs */ @@ -119,16 +119,16 @@ .editable-clear-x { background: url('../img/clear.png') center center no-repeat; display: block; - width: 13px; + width: 13px; height: 13px; position: absolute; opacity: 0.6; z-index: 100; - + top: 50%; right: 6px; margin-top: -6px; - + } .editable-clear-x:hover { @@ -140,49 +140,49 @@ } .editable-container.editable-popup { max-width: none !important; /* without this rule poshytip/tooltip does not stretch */ -} +} .editable-container.popover { width: auto; /* without this rule popover does not stretch */ } .editable-container.editable-inline { - display: inline-block; + display: inline-block; vertical-align: middle; width: auto; /* inline-block emulation for IE7*/ - zoom: 1; - *display: inline; + zoom: 1; + *display: inline; } .editable-container.ui-widget { font-size: inherit; /* jqueryui widget font 1.1em too big, overwrite it */ z-index: 9990; /* should be less than select2 dropdown z-index to close dropdown first when click */ } -.editable-click, -a.editable-click, +.editable-click, +a.editable-click, a.editable-click:hover { text-decoration: none; - border-bottom: dashed 1px #0088cc; + border-bottom: dotted 1px #0088cc; } -.editable-click.editable-disabled, -a.editable-click.editable-disabled, +.editable-click.editable-disabled, +a.editable-click.editable-disabled, a.editable-click.editable-disabled:hover { - color: #585858; + color: #585858; cursor: default; border-bottom: none; } .editable-empty, .editable-empty:hover, .editable-empty:focus{ - font-style: italic; - color: #DD1144; + font-style: italic; + color: #DD1144; /* border-bottom: none; */ text-decoration: none; } .editable-unsaved { - font-weight: bold; + font-weight: bold; } .editable-unsaved:after { @@ -194,12 +194,12 @@ a.editable-click.editable-disabled:hover { -moz-transition: background-color 1400ms ease-out; -o-transition: background-color 1400ms ease-out; -ms-transition: background-color 1400ms ease-out; - transition: background-color 1400ms ease-out; + transition: background-color 1400ms ease-out; } /*see https://github.com/vitalets/x-editable/issues/139 */ .form-horizontal .editable -{ +{ padding-top: 5px; display:inline-block; } diff --git a/templates/admin/default/assets/css/admin.less b/templates/admin/default/assets/css/admin.less index 0f1d499ce..9d9f2c482 100755 --- a/templates/admin/default/assets/css/admin.less +++ b/templates/admin/default/assets/css/admin.less @@ -717,10 +717,4 @@ label { // Center the alert box (20px bottom margin) in the table cell padding: 20px 20px 0 20px; } -} - -// -- Editable tweaks --------------------------------------------------------- - -.editable-click, a.editable-click, a.editable-click:hover { - border-bottom: 1px dotted #0088CC; } \ No newline at end of file diff --git a/templates/admin/default/categories.html b/templates/admin/default/categories.html index e37018e02..7bf76988c 100755 --- a/templates/admin/default/categories.html +++ b/templates/admin/default/categories.html @@ -241,7 +241,7 @@ $(function() { $.ajax({ url : "{url path='admin/catalog/category'}", data : { - id : $(this).data('id'), + category_id : $(this).data('id'), action : 'visibilityToggle' } }); diff --git a/templates/admin/default/includes/category_breadcrumb.html b/templates/admin/default/includes/category_breadcrumb.html index 0870a4c2e..cf03c4082 100755 --- a/templates/admin/default/includes/category_breadcrumb.html +++ b/templates/admin/default/includes/category_breadcrumb.html @@ -12,11 +12,11 @@ {if $action == 'edit'} {intl l='Editing %cat' cat="{$TITLE}"} {else} - {$TITLE} {intl l="(edit)"} + {$TITLE} {intl l="(edit)"} {/if} {else} -
  • {$TITLE} /
  • +
  • {$TITLE} /
  • {/if} {/loop} {/ifloop} diff --git a/templates/admin/default/includes/inner-form-toolbar.html b/templates/admin/default/includes/inner-form-toolbar.html index 8d6f65cc8..4d5570f6c 100755 --- a/templates/admin/default/includes/inner-form-toolbar.html +++ b/templates/admin/default/includes/inner-form-toolbar.html @@ -12,7 +12,7 @@