# By Manuel Raynaud (79) and others
# Via gmorel (21) and others
* 'master' of https://github.com/thelia/thelia: (268 commits)
  unit testing for tax engine calculator
  tax in loops
  remove test
  Working - Add Symfony2 routing ability to Thelia router
  finish simple list customer page in backoffice
  Working - Fix #category-rule replaced by parser when writing jawascript
  debug bar
  mock getTotalAmoutn in order class
  tax engine
  escae output only if it's not an object
  tax faker
  insert 19.6 tva
  create admin customer view and add output info in customer loop
  update format smarty plugin
  tax engine model
  tax engine model
  WIP - Coupon : add rule input ajax controller
  create customer admin controller and index controller
  clean some code
  fix phpdoc
  ...
This commit is contained in:
gmorel
2013-09-09 17:47:32 +02:00
3437 changed files with 66617 additions and 22090 deletions

3
.gitignore vendored
View File

@@ -22,3 +22,6 @@ web/cache/*
web/.htaccess
phpdoc*.log
php-cs
xhprof
phpunit.phar
.DS_Store

View File

@@ -12,3 +12,4 @@ before_script:
- composer install --prefer-dist --dev
- sh -c "mysql -u$DB_USER -e 'SET FOREIGN_KEY_CHECKS = 0; DROP DATABASE IF EXISTS thelia;SET FOREIGN_KEY_CHECKS = 1;'; fi"
- php Thelia thelia:install --db_host=localhost --db_username=$DB_USER --db_name=thelia
- php install/faker.php

View File

@@ -9,9 +9,8 @@
},
"require":{
"php": ">=5.4",
"ezyang/htmlpurifier": "dev-master",
"ircmaxell/password-compat": "dev-master",
"propel/propel": "2.0.0-alpha1",
"propel/propel": "dev-master",
"psr/log" : "1.0",
"symfony/class-loader": "2.2.*",
"symfony/config" : "2.2.*",
@@ -27,7 +26,7 @@
"symfony-cmf/routing": "1.0.0",
"symfony/form": "2.2.*",
"symfony/validator": "2.3.*@dev",
"symfony/validator": "2.3.*",
"smarty/smarty": "v3.1.14",
"kriswallsmith/assetic": "1.2.*@dev",
@@ -36,11 +35,14 @@
"simplepie/simplepie": "dev-master",
"imagine/imagine": "dev-master"
"imagine/imagine": "dev-master",
"symfony/serializer": "dev-master",
"symfony/icu": "1.0"
},
"require-dev" : {
"phpunit/phpunit": "3.7.*",
"fzaninotto/faker": "dev-master"
"fzaninotto/faker": "dev-master",
"maximebf/debugbar": "1.*"
},
"minimum-stability": "stable",
"config" : {

351
composer.lock generated
View File

@@ -3,64 +3,21 @@
"This file locks the dependencies of your project to a known state",
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
],
"hash": "458aeccc06b7394d7653a9063b6fd981",
"hash": "ba2f3e0943f00c7c3bf0c086bc611b0f",
"packages": [
{
"name": "ezyang/htmlpurifier",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/ezyang/htmlpurifier.git",
"reference": "19eee1489965d9bc6eded80f847ced2382127261"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/19eee1489965d9bc6eded80f847ced2382127261",
"reference": "19eee1489965d9bc6eded80f847ced2382127261",
"shasum": ""
},
"require": {
"php": ">=5.2"
},
"type": "library",
"autoload": {
"psr-0": {
"HTMLPurifier": "library/"
},
"files": [
"library/HTMLPurifier.composer.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL"
],
"authors": [
{
"name": "Edward Z. Yang",
"email": "admin@htmlpurifier.org",
"homepage": "http://ezyang.com"
}
],
"description": "Standards compliant HTML filter written in PHP",
"homepage": "http://htmlpurifier.org/",
"keywords": [
"html"
],
"time": "2013-07-27 04:54:53"
},
{
"name": "imagine/imagine",
"version": "dev-master",
"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 +174,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",
@@ -254,30 +211,30 @@
},
{
"name": "propel/propel",
"version": "2.0.0-alpha1",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/propelorm/Propel2.git",
"reference": "2.0.0-alpha1"
"reference": "58a25ded43c3d04313cad2b738342d307988b1b5"
},
"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/58a25ded43c3d04313cad2b738342d307988b1b5",
"reference": "58a25ded43c3d04313cad2b738342d307988b1b5",
"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": {
@@ -310,7 +267,7 @@
"orm",
"persistence"
],
"time": "2013-06-05 06:46:14"
"time": "2013-09-01 13:29:51"
},
{
"name": "psr/log",
@@ -356,12 +313,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": {
@@ -397,12 +354,12 @@
"source": {
"type": "git",
"url": "https://github.com/simplepie/simplepie.git",
"reference": "f5436d69a8efa9d4ab3a9abc65d17317eb24b7f4"
"reference": "f97c8ef9be655c35e6fecdb608bdf5af05a4374a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/simplepie/simplepie/zipball/f5436d69a8efa9d4ab3a9abc65d17317eb24b7f4",
"reference": "f5436d69a8efa9d4ab3a9abc65d17317eb24b7f4",
"url": "https://api.github.com/repos/simplepie/simplepie/zipball/f97c8ef9be655c35e6fecdb608bdf5af05a4374a",
"reference": "f97c8ef9be655c35e6fecdb608bdf5af05a4374a",
"shasum": ""
},
"require": {
@@ -443,7 +400,7 @@
"feeds",
"rss"
],
"time": "2013-04-29 06:13:26"
"time": "2013-08-31 01:38:46"
},
{
"name": "smarty/smarty",
@@ -540,17 +497,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 +543,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 +594,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 +637,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 +696,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 +750,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 +797,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 +840,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 +899,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 +949,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,27 +1019,26 @@
],
"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": "cac3fdfb111adbe590155f491594636d45129783"
},
"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/cac3fdfb111adbe590155f491594636d45129783",
"reference": "cac3fdfb111adbe590155f491594636d45129783",
"shasum": ""
},
"require": {
"lib-icu": ">=4.4",
"php": ">=5.3.3",
"symfony/intl": ">=2.3,<3.0"
"symfony/intl": "~2.3"
},
"type": "library",
"autoload": {
@@ -1110,21 +1066,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 +1143,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 +1195,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 +1247,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 +1290,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 +1348,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 +1406,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,21 +1461,21 @@
],
"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",
"version": "2.3.x-dev",
"version": "v2.3.4",
"target-dir": "Symfony/Component/Validator",
"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 +1522,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 +1569,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": [
@@ -1623,12 +1579,12 @@
"source": {
"type": "git",
"url": "https://github.com/fzaninotto/Faker.git",
"reference": "feb6492762a77db946bc13cc44a20a01546be0e6"
"reference": "77a4e394d99a67e7fb611e8b402c2da4b80fa4f8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/fzaninotto/Faker/zipball/feb6492762a77db946bc13cc44a20a01546be0e6",
"reference": "feb6492762a77db946bc13cc44a20a01546be0e6",
"url": "https://api.github.com/repos/fzaninotto/Faker/zipball/77a4e394d99a67e7fb611e8b402c2da4b80fa4f8",
"reference": "77a4e394d99a67e7fb611e8b402c2da4b80fa4f8",
"shasum": ""
},
"require": {
@@ -1661,7 +1617,56 @@
"faker",
"fixtures"
],
"time": "2013-08-12 10:05:47"
"time": "2013-08-29 19:11:59"
},
{
"name": "maximebf/debugbar",
"version": "1.5.1",
"source": {
"type": "git",
"url": "https://github.com/maximebf/php-debugbar.git",
"reference": "37dccc40da52bf9f85571c30cf302da696db0d05"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/37dccc40da52bf9f85571c30cf302da696db0d05",
"reference": "37dccc40da52bf9f85571c30cf302da696db0d05",
"shasum": ""
},
"require": {
"php": ">=5.3.0",
"psr/log": "~1.0"
},
"require-dev": {
"php": ">=5.3.0"
},
"suggest": {
"kriswallsmith/assetic": "The best way to manage assets",
"monolog/monolog": "Log using Monolog"
},
"type": "library",
"autoload": {
"psr-0": {
"DebugBar": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Maxime Bouroumeau-Fuseau",
"email": "maxime.bouroumeau@gmail.com",
"homepage": "http://maximebf.com"
}
],
"description": "Debug bar in the browser for php application",
"homepage": "https://github.com/maximebf/php-debugbar",
"keywords": [
"debug"
],
"time": "2013-08-17 02:02:49"
},
{
"name": "phpunit/php-code-coverage",
@@ -2036,10 +2041,8 @@
],
"minimum-stability": "stable",
"stability-flags": {
"ezyang/htmlpurifier": 20,
"ircmaxell/password-compat": 20,
"propel/propel": 15,
"symfony/validator": 20,
"propel/propel": 20,
"kriswallsmith/assetic": 20,
"leafo/lessphp": 20,
"ptachoire/cssembed": 20,

View File

@@ -0,0 +1,108 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Action;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Thelia\Core\Event\AddressCreateOrUpdateEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Model\Address as AddressModel;
/**
* Class Address
* @package Thelia\Action
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class Address extends BaseAction implements EventSubscriberInterface
{
public function create(AddressCreateOrUpdateEvent $event)
{
$address = new AddressModel();
$address->setCustomer($event->getCustomer());
$this->createOrUpdate($address, $event);
}
public function update(AddressCreateOrUpdateEvent $event)
{
$addressModel = $event->getAddress();
$this->createOrUpdate($addressModel, $event);
}
protected function createOrUpdate(AddressModel $addressModel, AddressCreateOrUpdateEvent $event)
{
$addressModel->setDispatcher($this->getDispatcher());
if ($addressModel->isNew()) {
$addressModel->setLabel($event->getLabel());
}
$addressModel
->setTitleId($event->getTitle())
->setFirstname($event->getFirstname())
->setLastname($event->getLastname())
->setAddress1($event->getAddress1())
->setAddress2($event->getAddress2())
->setAddress3($event->getAddress3())
->setZipcode($event->getZipcode())
->setCity($event->getCity())
->setCountryId($event->getCountry())
->setCellphone($event->getCellphone())
->setPhone($event->getPhone())
->setCompany($event->getCompany())
->save()
;
$event->setAddress($addressModel);
}
/**
* Returns an array of event names this subscriber wants to listen to.
*
* The array keys are event names and the value can be:
*
* * The method name to call (priority defaults to 0)
* * An array composed of the method name to call and the priority
* * An array of arrays composed of the method names to call and respective
* priorities, or 0 if unset
*
* For instance:
*
* * array('eventName' => 'methodName')
* * array('eventName' => array('methodName', $priority))
* * array('eventName' => array(array('methodName1', $priority), array('methodName2'))
*
* @return array The event names to listen to
*
* @api
*/
public static function getSubscribedEvents()
{
return array(
TheliaEvents::ADDRESS_CREATE => array("create", 128),
TheliaEvents::ADDRESS_UPDATE => array("update", 128)
);
}
}

49
core/lib/Thelia/Action/BaseAction.php Normal file → Executable file
View File

@@ -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,
*
@@ -95,5 +49,4 @@ class BaseAction
{
return $this->container->get('event_dispatcher');
}
}
}

View File

@@ -41,6 +41,7 @@ use Thelia\Model\ConfigQuery;
*
* Class Cart
* @package Thelia\Action
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class Cart extends BaseAction implements EventSubscriberInterface
{
@@ -142,7 +143,7 @@ class Cart extends BaseAction implements EventSubscriberInterface
return array(
"action.addArticle" => array("addItem", 128),
"action.deleteArticle" => array("deleteItem", 128),
"action.changeArticle" => array("changeItem", 128),
"action.updateArticle" => array("changeItem", 128),
);
}

268
core/lib/Thelia/Action/Category.php Normal file → Executable file
View File

@@ -24,134 +24,39 @@
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)
{
$category = new CategoryModel();
$this->checkAuth("ADMIN", "admin.category.create");
$category
->setDispatcher($this->getDispatcher())
->create(
$event->getTitle(),
$event->getParent(),
$event->getLocale()
);
$request = $event->getRequest();
try {
$categoryCreationForm = new CategoryCreationForm($request);
$form = $this->validateForm($categoryCreationForm, "POST");
$data = $form->getData();
$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->setCategory($category);
}
public function modify(ActionEvent $event)
public function update(CategoryChangeEvent $event)
{
$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);
}
/**
@@ -159,50 +64,14 @@ class Category extends BaseAction implements EventSubscriberInterface
*
* @param ActionEvent $event
*/
public function delete(ActionEvent $event)
public function delete(CategoryDeleteEvent $event)
{
$category = CategoryQuery::create()->findPk($event->getCategoryId());
$this->checkAuth("ADMIN", "admin.category.delete");
if ($category !== null) {
$request = $event->getRequest();
try {
$categoryDeletionForm = new CategoryDeletionForm($request);
$form = $this->validateForm($categoryDeletionForm, "POST");
$data = $form->getData();
$category = CategoryQuery::create()->findPk($data['id']);
$categoryEvent = new CategoryEvent($category);
$event->getDispatcher()->dispatch(TheliaEvents::BEFORE_DELETECATEGORY, $categoryEvent);
$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();
$category->setDispatcher($this->getDispatcher())->delete();
}
$this->propagateFormError($categoryDeletionForm, $message, $event);
}
/**
@@ -210,60 +79,41 @@ 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->getCategoryId());
if ($category !== null) {
$category->setVisible($category->getVisible() ? false : true);
$category->save();
$categoryEvent = new CategoryEvent($category);
$event->getDispatcher()->dispatch(TheliaEvents::AFTER_CHANGECATEGORY, $categoryEvent);
$category
->setDispatcher($this->getDispatcher())
->setVisible($category->getVisible() ? false : true)
->save()
;
}
}
/**
* 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');
}
/**
* 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->getCategoryId());
if ($category !== null) {
@@ -275,10 +125,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
@@ -295,7 +145,11 @@ class Category extends BaseAction implements EventSubscriberInterface
$cnx->beginTransaction();
try {
$category->setPosition($result->getPosition())->save();
$category
->setDispatcher($this->getDispatcher())
->setPosition($result->getPosition())
->save()
;
$result->setPosition($my_position)->save();
@@ -310,20 +164,16 @@ class Category extends BaseAction implements EventSubscriberInterface
/**
* 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->getCategoryId());
if ($category !== null) {
// The required position
$new_position = $request->get('position', null);
$new_position = $event->getPosition();
// The current position
$current_position = $category->getPosition();
@@ -356,7 +206,11 @@ class Category extends BaseAction implements EventSubscriberInterface
$result->setPosition($result->getPosition() + $delta)->save($cnx);
}
$category->setPosition($new_position)->save($cnx);
$category
->setDispatcher($this->getDispatcher())
->setPosition($new_position)
->save($cnx)
;
$cnx->commit();
} catch (Exception $e) {
@@ -389,14 +243,16 @@ 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_UPDATE => array("update", 128),
TheliaEvents::CATEGORY_DELETE => array("delete", 128),
"action.toggleCategoryVisibility" => array("toggleVisibility", 128),
"action.changeCategoryPositionUp" => array("changePositionUp", 128),
"action.changeCategoryPositionDown" => array("changePositionDown", 128),
"action.changeCategoryPosition" => array("changePosition", 128),
TheliaEvents::CATEGORY_TOGGLE_VISIBILITY => array("toggleVisibility", 128),
TheliaEvents::CATEGORY_CHANGE_POSITION => array("changePosition", 128),
"action.updateCategoryPositionU" => array("changePositionUp", 128),
"action.updateCategoryPositionDown" => array("changePositionDown", 128),
"action.updateCategoryPosition" => array("changePosition", 128),
);
}
}

View File

@@ -0,0 +1,155 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Action;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Thelia\Model\ConfigQuery;
use Thelia\Model\Config as ConfigModel;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\Event\ConfigUpdateEvent;
use Thelia\Core\Event\ConfigCreateEvent;
use Thelia\Core\Event\ConfigDeleteEvent;
class Config extends BaseAction implements EventSubscriberInterface
{
/**
* Create a new configuration entry
*
* @param ConfigCreateEvent $event
*/
public function create(ConfigCreateEvent $event)
{
$config = new ConfigModel();
$config
->setDispatcher($this->getDispatcher())
->setName($event->getEventName())
->setValue($event->getValue())
->setLocale($event->getLocale())
->setTitle($event->getTitle())
->setHidden($event->getHidden())
->setSecured($event->getSecured())
->save()
;
$event->setConfig($config);
}
/**
* Change a configuration entry value
*
* @param ConfigUpdateEvent $event
*/
public function setValue(ConfigUpdateEvent $event)
{
$search = ConfigQuery::create();
if (null !== $config = $search->findOneById($event->getConfigId())) {
if ($event->getValue() !== $config->getValue()) {
$config
->setDispatcher($this->getDispatcher())
->setValue($event->getValue())
->save()
;
$event->setConfig($config);
}
}
}
/**
* Change a configuration entry
*
* @param ConfigUpdateEvent $event
*/
public function modify(ConfigUpdateEvent $event)
{
$search = ConfigQuery::create();
if (null !== $config = ConfigQuery::create()->findOneById($event->getConfigId())) {
$config
->setDispatcher($this->getDispatcher())
->setName($event->getEventName())
->setValue($event->getValue())
->setHidden($event->getHidden())
->setSecured($event->getSecured())
->setLocale($event->getLocale())
->setTitle($event->getTitle())
->setDescription($event->getDescription())
->setChapo($event->getChapo())
->setPostscriptum($event->getPostscriptum())
->save();
$event->setConfig($config);
}
}
/**
* Delete a configuration entry
*
* @param ConfigDeleteEvent $event
*/
public function delete(ConfigDeleteEvent $event)
{
if (null !== ($config = ConfigQuery::create()->findOneById($event->getConfigId()))) {
if (! $config->getSecured()) {
$config
->setDispatcher($this->getDispatcher())
->delete()
;
$event->setConfig($config);
}
}
}
/**
* {@inheritDoc}
*/
public static function getSubscribedEvents()
{
return array(
TheliaEvents::CONFIG_CREATE => array("create", 128),
TheliaEvents::CONFIG_SETVALUE => array("setValue", 128),
TheliaEvents::CONFIG_UPDATE => array("modify", 128),
TheliaEvents::CONFIG_DELETE => array("delete", 128),
);
}
}

180
core/lib/Thelia/Action/Coupon.php Executable file
View File

@@ -0,0 +1,180 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Action;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Thelia\Core\Event\Coupon\CouponCreateOrUpdateEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Model\Coupon as CouponModel;
use Propel\Runtime\ActiveQuery\Criteria;
use Propel\Runtime\Propel;
use Thelia\Model\Map\CategoryTableMap;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* Process Coupon Events
*
* @package Coupon
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class Coupon extends BaseAction implements EventSubscriberInterface
{
/**
* Occurring when a Coupon is about to be created
*
* @param CouponCreateOrUpdateEvent $event Event creation or update Event
*/
public function create(CouponCreateOrUpdateEvent $event)
{
$coupon = new CouponModel();
$this->createOrUpdate($coupon, $event);
}
/**
* Occurring when a Coupon is about to be updated
*
* @param CouponCreateOrUpdateEvent $event Event creation or update Event
*/
public function update(CouponCreateOrUpdateEvent $event)
{
$coupon = $event->getCoupon();
$this->createOrUpdate($coupon, $event);
}
/**
* Occurring when a Coupon rule is about to be created
*
* @param CouponCreateOrUpdateEvent $event Event creation or update Event
*/
public function createRule(CouponCreateOrUpdateEvent $event)
{
$coupon = $event->getCoupon();
$this->createOrUpdate($coupon, $event);
}
/**
* Occurring when a Coupon rule is about to be updated
*
* @param CouponCreateOrUpdateEvent $event Event creation or update Event
*/
public function updateRule(CouponCreateOrUpdateEvent $event)
{
$coupon = $event->getCoupon();
$this->createOrUpdate($coupon, $event);
}
/**
* Occurring when a Coupon rule is about to be deleted
*
* @param CouponCreateOrUpdateEvent $event Event creation or update Event
*/
public function deleteRule(CouponCreateOrUpdateEvent $event)
{
$coupon = $event->getCoupon();
$this->createOrUpdate($coupon, $event);
}
/**
* Occurring when a Coupon rule is about to be consumed
*
* @param CouponCreateOrUpdateEvent $event Event creation or update Event
*/
public function consume(CouponCreateOrUpdateEvent $event)
{
// @todo implements
}
/**
* Call the Model and delegate the create or delete action
* Feed the Event with the updated model
*
* @param CouponModel $coupon Model to save
* @param CouponCreateOrUpdateEvent $event Event containing data
*/
protected function createOrUpdate(CouponModel $coupon, CouponCreateOrUpdateEvent $event)
{
$coupon->setDispatcher($this->getDispatcher());
$coupon->createOrUpdate(
$event->getCode(),
$event->getTitle(),
$event->getAmount(),
$event->getEffect(),
$event->getShortDescription(),
$event->getDescription(),
$event->isEnabled(),
$event->getExpirationDate(),
$event->isAvailableOnSpecialOffers(),
$event->isCumulative(),
$event->getMaxUsage(),
$event->getRules(),
$event->getLocale()
);
$event->setCoupon($coupon);
}
/**
* Returns an array of event names this subscriber listens to.
*
* The array keys are event names and the value can be:
*
* * The method name to call (priority defaults to 0)
* * An array composed of the method name to call and the priority
* * An array of arrays composed of the method names to call and respective
* priorities, or 0 if unset
*
* For instance:
*
* * array('eventName' => 'methodName')
* * array('eventName' => array('methodName', $priority))
* * array('eventName' => array(array('methodName1', $priority), array('methodName2'))
*
* @return array The event names to listen to
*
* @api
*/
public static function getSubscribedEvents()
{
return array(
TheliaEvents::COUPON_CREATE => array("create", 128),
TheliaEvents::COUPON_UPDATE => array("update", 128),
TheliaEvents::COUPON_DISABLE => array("disable", 128),
TheliaEvents::COUPON_ENABLE => array("enable", 128),
TheliaEvents::COUPON_CONSUME => array("consume", 128),
TheliaEvents::COUPON_RULE_CREATE => array("createRule", 128),
TheliaEvents::COUPON_RULE_UPDATE => array("updateRule", 128),
TheliaEvents::COUPON_RULE_DELETE => array("deleteRule", 128)
);
}
}

View File

@@ -0,0 +1,202 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Action;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Thelia\Model\CurrencyQuery;
use Thelia\Model\Currency as CurrencyModel;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\Event\CurrencyUpdateEvent;
use Thelia\Core\Event\CurrencyCreateEvent;
use Thelia\Core\Event\CurrencyDeleteEvent;
use Thelia\Model\ConfigQuery;
use Thelia\Core\Event\CurrencyUpdatePositionEvent;
class Currency extends BaseAction implements EventSubscriberInterface
{
/**
* Create a new currencyuration entry
*
* @param CurrencyCreateEvent $event
*/
public function create(CurrencyCreateEvent $event)
{
$currency = new CurrencyModel();
$currency
->setDispatcher($this->getDispatcher())
->setLocale($event->getLocale())
->setName($event->getCurrencyName())
->setSymbol($event->getSymbol())
->setRate($event->getRate())
->setCode(strtoupper($event->getCode()))
->save()
;
$event->setCurrency($currency);
}
/**
* Change a currency
*
* @param CurrencyUpdateEvent $event
*/
public function update(CurrencyUpdateEvent $event)
{
$search = CurrencyQuery::create();
if (null !== $currency = CurrencyQuery::create()->findOneById($event->getCurrencyId())) {
$currency
->setDispatcher($this->getDispatcher())
->setLocale($event->getLocale())
->setName($event->getCurrencyName())
->setSymbol($event->getSymbol())
->setRate($event->getRate())
->setCode(strtoupper($event->getCode()))
->save();
$event->setCurrency($currency);
}
}
/**
* Set the default currency
*
* @param CurrencyUpdateEvent $event
*/
public function setDefault(CurrencyUpdateEvent $event)
{
$search = CurrencyQuery::create();
if (null !== $currency = CurrencyQuery::create()->findOneById($event->getCurrencyId())) {
if ($currency->getByDefault() != $event->getIsDefault()) {
// Reset default status
CurrencyQuery::create()->filterByByDefault(true)->update(array('ByDefault' => false));
$currency
->setDispatcher($this->getDispatcher())
->setByDefault($event->getIsDefault())
->save()
;
}
$event->setCurrency($currency);
}
}
/**
* Delete a currencyuration entry
*
* @param CurrencyDeleteEvent $event
*/
public function delete(CurrencyDeleteEvent $event)
{
if (null !== ($currency = CurrencyQuery::create()->findOneById($event->getCurrencyId()))) {
$currency
->setDispatcher($this->getDispatcher())
->delete()
;
$event->setCurrency($currency);
}
}
public function updateRates() {
$rates_url = ConfigQuery::read('currency_rate_update_url', 'http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml');
$rate_data = @file_get_contents($rates_url);
if ($rate_data && $sxe = new \SimpleXMLElement($rate_data)) {
foreach ($sxe->Cube[0]->Cube[0]->Cube as $last)
{
$code = strtoupper($last["currency"]);
$rate = floatval($last['rate']);
if (null !== $currency = CurrencyQuery::create()->findOneByCode($code)) {
$currency
->setDispatcher($this->getDispatcher())
->setRate($rate)
->save()
;
}
}
}
else {
throw new \RuntimeException(sprintf("Failed to get currency rates data from URL %s", $rates_url));
}
}
/**
* Changes position, selecting absolute ou relative change.
*
* @param CategoryChangePositionEvent $event
*/
public function updatePosition(CurrencyUpdatePositionEvent $event)
{
if (null !== $currency = CurrencyQuery::create()->findOneById($event->getObjectId())) {
$currency->setDispatcher($this->getDispatcher());
$mode = $event->getMode();
if ($mode == CurrencyUpdatePositionEvent::POSITION_ABSOLUTE)
return $currency->changeAbsolutePosition($event->getPosition());
else if ($mode == CurrencyUpdatePositionEvent::POSITION_UP)
return $currency->movePositionUp();
else if ($mode == CurrencyUpdatePositionEvent::POSITION_DOWN)
return $currency->movePositionDown();
}
}
/**
* {@inheritDoc}
*/
public static function getSubscribedEvents()
{
return array(
TheliaEvents::CURRENCY_CREATE => array("create", 128),
TheliaEvents::CURRENCY_UPDATE => array("update", 128),
TheliaEvents::CURRENCY_DELETE => array("delete", 128),
TheliaEvents::CURRENCY_SET_DEFAULT => array("setDefault", 128),
TheliaEvents::CURRENCY_UPDATE_RATES => array("updateRates", 128),
TheliaEvents::CURRENCY_UPDATE_POSITION => array("updatePosition", 128)
);
}
}

View File

@@ -38,7 +38,16 @@ use Symfony\Component\Validator\Exception\ValidatorException;
use Thelia\Core\Security\Exception\AuthenticationException;
use Thelia\Core\Security\Exception\UsernameNotFoundException;
use Propel\Runtime\Exception\PropelException;
use Thelia\Core\Event\CustomerLoginEvent;
/**
*
* customer class where all actions are managed
*
* Class Customer
* @package Thelia\Action
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class Customer extends BaseAction implements EventSubscriberInterface
{
@@ -46,7 +55,6 @@ class Customer extends BaseAction implements EventSubscriberInterface
{
$customer = new CustomerModel();
$customer->setDispatcher($this->getDispatcher());
$this->createOrUpdateCustomer($customer, $event);
@@ -56,7 +64,6 @@ class Customer extends BaseAction implements EventSubscriberInterface
{
$customer = $event->getCustomer();
$customer->setDispatcher($this->getDispatcher());
$this->createOrUpdateCustomer($customer, $event);
@@ -64,6 +71,8 @@ class Customer extends BaseAction implements EventSubscriberInterface
private function createOrUpdateCustomer(CustomerModel $customer, CustomerCreateOrUpdateEvent $event)
{
$customer->setDispatcher($this->getDispatcher());
$customer->createOrUpdate(
$event->getTitle(),
$event->getFirstname(),
@@ -87,6 +96,12 @@ class Customer extends BaseAction implements EventSubscriberInterface
$event->setCustomer($customer);
}
public function login(CustomerLoginEvent $event)
{
$this->getSecurityContext()->setCustomerUser($event->getCustomer());
}
/**
* Perform user logout. The user is redirected to the provided view, if any.
*
@@ -94,9 +109,7 @@ class Customer extends BaseAction implements EventSubscriberInterface
*/
public function logout(ActionEvent $event)
{
$event->getDispatcher()->dispatch(TheliaEvents::CUSTOMER_LOGOUT, $event);
$this->getFrontSecurityContext()->clear();
$this->getSecurityContext()->clearCustomerUser();
}
public function changePassword(ActionEvent $event)
@@ -104,6 +117,16 @@ class Customer extends BaseAction implements EventSubscriberInterface
// TODO
}
/**
* Return the security context
*
* @return Thelia\Core\Security\SecurityContext
*/
protected function getSecurityContext()
{
return $this->container->get('thelia.securityContext');
}
/**
* Returns an array of event names this subscriber wants to listen to.
*
@@ -127,8 +150,10 @@ 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),
TheliaEvents::CUSTOMER_LOGOUT => array("logout", 128),
TheliaEvents::CUSTOMER_LOGIN => array("login" , 128),
);
}
}

8
core/lib/Thelia/Action/Image.php Normal file → Executable file
View File

@@ -269,8 +269,8 @@ class Image extends BaseAction implements EventSubscriberInterface
$event->setCacheFilepath($cacheFilePath);
$event->setCacheOriginalFilepath($originalImagePathInCache);
$event->setFileUrl(URL::absoluteUrl($processed_image_url, null, URL::PATH_TO_FILE));
$event->setOriginalFileUrl(URL::absoluteUrl($original_image_url, null, URL::PATH_TO_FILE));
$event->setFileUrl(URL::getInstance()->absoluteUrl($processed_image_url, null, URL::PATH_TO_FILE));
$event->setOriginalFileUrl(URL::getInstance()->absoluteUrl($original_image_url, null, URL::PATH_TO_FILE));
}
/**
@@ -382,7 +382,7 @@ class Image extends BaseAction implements EventSubscriberInterface
{
$path = $this->getCachePathFromWebRoot($subdir);
return URL::absoluteUrl(sprintf("%s/%s", $path, $safe_filename), null, URL::PATH_TO_FILE);
return URL::getInstance()->absoluteUrl(sprintf("%s/%s", $path, $safe_filename), null, URL::PATH_TO_FILE);
}
/**
@@ -494,4 +494,4 @@ class Image extends BaseAction implements EventSubscriberInterface
TheliaEvents::IMAGE_CLEAR_CACHE => array("clearCache", 128),
);
}
}
}

View File

@@ -0,0 +1,125 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Action;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Thelia\Model\MessageQuery;
use Thelia\Model\Message as MessageModel;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\Event\MessageUpdateEvent;
use Thelia\Core\Event\MessageCreateEvent;
use Thelia\Core\Event\MessageDeleteEvent;
class Message extends BaseAction implements EventSubscriberInterface
{
/**
* Create a new messageuration entry
*
* @param MessageCreateEvent $event
*/
public function create(MessageCreateEvent $event)
{
$message = new MessageModel();
$message
->setDispatcher($this->getDispatcher())
->setName($event->getMessageName())
->setLocale($event->getLocale())
->setTitle($event->getTitle())
->setSecured($event->getSecured())
->save()
;
$event->setMessage($message);
}
/**
* Change a message
*
* @param MessageUpdateEvent $event
*/
public function modify(MessageUpdateEvent $event)
{
$search = MessageQuery::create();
if (null !== $message = MessageQuery::create()->findOneById($event->getMessageId())) {
$message
->setDispatcher($this->getDispatcher())
->setName($event->getMessageName())
->setSecured($event->getSecured())
->setLocale($event->getLocale())
->setTitle($event->getTitle())
->setSubject($event->getSubject())
->setHtmlMessage($event->getHtmlMessage())
->setTextMessage($event->getTextMessage())
->save();
$event->setMessage($message);
}
}
/**
* Delete a messageuration entry
*
* @param MessageDeleteEvent $event
*/
public function delete(MessageDeleteEvent $event)
{
if (null !== ($message = MessageQuery::create()->findOneById($event->getMessageId()))) {
$message
->setDispatcher($this->getDispatcher())
->delete()
;
$event->setMessage($message);
}
}
/**
* {@inheritDoc}
*/
public static function getSubscribedEvents()
{
return array(
TheliaEvents::MESSAGE_CREATE => array("create", 128),
TheliaEvents::MESSAGE_UPDATE => array("modify", 128),
TheliaEvents::MESSAGE_DELETE => array("delete", 128),
);
}
}

View File

@@ -0,0 +1,85 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Action;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\KernelEvents;
use Thelia\Model\ConfigQuery;
/**
*
* Class PageNotFound
* @package Thelia\Action
* @author Etienne Roudeix <eroudeix@openstudio.fr>
*/
class PageNotFound extends BaseAction implements EventSubscriberInterface
{
public function display404(GetResponseForExceptionEvent $event)
{
if($event->getException() instanceof NotFoundHttpException) {
$parser = $this->container->get("thelia.parser");
// Define the template thant shoud be used
$parser->setTemplate(ConfigQuery::getActiveTemplate());
//$event->getRequest()->attributes->set('_view', ConfigQuery::getPageNotFoundView());
$response = new Response($parser->render(ConfigQuery::getPageNotFoundView()), 404);
$event->setResponse($response);
}
}
/**
* Returns an array of event names this subscriber wants to listen to.
*
* The array keys are event names and the value can be:
*
* * The method name to call (priority defaults to 0)
* * An array composed of the method name to call and the priority
* * An array of arrays composed of the method names to call and respective
* priorities, or 0 if unset
*
* For instance:
*
* * array('eventName' => 'methodName')
* * array('eventName' => array('methodName', $priority))
* * array('eventName' => array(array('methodName1', $priority), array('methodName2'))
*
* @return array The event names to listen to
*
* @api
*/
public static function getSubscribedEvents()
{
return array(
KernelEvents::EXCEPTION => array("display404", 128),
);
}
}

View File

@@ -0,0 +1,157 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Action;
use Thelia\Core\Event\BaseChangePositionEvent;
trait PositionManagementTrait {
const POSITION_UP
/**
* Changes object position, selecting absolute ou relative change.
*
* @param BaseChangePositionEvent $event
*/
public function changePosition(BaseChangePositionEvent $event)
{
if ($event->getMode() == BaseChangePositionEvent::POSITION_ABSOLUTE)
return $this->changeAbsolutePosition($event);
else
return $this->exchangePosition($event);
}
/**
* Move up or down a object
*
* @param BaseChangePositionEvent $event
*/
protected function exchangePosition(BaseChangePositionEvent $event)
{
$object = CategoryQuery::create()->findPk($event->getCategoryId());
if ($object !== null) {
// The current position of the object
$my_position = $object->getPosition();
// Find object to exchange position with
$search = CategoryQuery::create()
->filterByParent($object->getParent());
// Up or down ?
if ($event->getMode() == BaseChangePositionEvent::POSITION_UP) {
// Find the object immediately before me
$search->filterByPosition(array('max' => $my_position-1))->orderByPosition(Criteria::DESC);
} elseif ($event->getMode() == BaseChangePositionEvent::POSITION_DOWN) {
// Find the object immediately after me
$search->filterByPosition(array('min' => $my_position+1))->orderByPosition(Criteria::ASC);
} else
return;
$result = $search->findOne();
// If we found the proper object, exchange their positions
if ($result) {
$cnx = Propel::getWriteConnection(CategoryTableMap::DATABASE_NAME);
$cnx->beginTransaction();
try {
$object
->setDispatcher($this->getDispatcher())
->setPosition($result->getPosition())
->save()
;
$result->setPosition($my_position)->save();
$cnx->commit();
} catch (Exception $e) {
$cnx->rollback();
}
}
}
}
/**
* Changes object position
*
* @param BaseChangePositionEvent $event
*/
protected function changeAbsolutePosition(BaseChangePositionEvent $event)
{
$object = CategoryQuery::create()->findPk($event->getCategoryId());
if ($object !== null) {
// The required position
$new_position = $event->getPosition();
// The current position
$current_position = $object->getPosition();
if ($new_position != null && $new_position > 0 && $new_position != $current_position) {
// Find categories to offset
$search = CategoryQuery::create()->filterByParent($object->getParent());
if ($new_position > $current_position) {
// The new position is after the current position -> we will offset + 1 all categories located between us and the new position
$search->filterByPosition(array('min' => 1+$current_position, 'max' => $new_position));
$delta = -1;
} else {
// The new position is brefore the current position -> we will offset - 1 all categories located between us and the new position
$search->filterByPosition(array('min' => $new_position, 'max' => $current_position - 1));
$delta = 1;
}
$results = $search->find();
$cnx = Propel::getWriteConnection(CategoryTableMap::DATABASE_NAME);
$cnx->beginTransaction();
try {
foreach ($results as $result) {
$result->setPosition($result->getPosition() + $delta)->save($cnx);
}
$object
->setDispatcher($this->getDispatcher())
->setPosition($new_position)
->save($cnx)
;
$cnx->commit();
} catch (Exception $e) {
$cnx->rollback();
}
}
}
}
}

26
core/lib/Thelia/Cart/CartTrait.php Normal file → Executable file
View File

@@ -28,9 +28,16 @@ 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;
/**
* managed cart
*
* Trait CartTrait
* @package Thelia\Cart
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
trait CartTrait
{
/**
@@ -42,8 +49,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 +63,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 +124,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 +139,4 @@ trait CartTrait
return $id;
}
}
}

7
core/lib/Thelia/Command/BaseModuleGenerate.php Normal file → Executable file
View File

@@ -22,6 +22,13 @@
/*************************************************************************************/
namespace Thelia\Command;
/**
* base class for module commands
*
* Class BaseModuleGenerate
* @package Thelia\Command
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
abstract class BaseModuleGenerate extends ContainerAwareCommand
{
protected $module;

View File

@@ -24,19 +24,35 @@
namespace Thelia\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Filesystem\Exception\IOException;
use Thelia\Command\ContainerAwareCommand;
/**
* clear the cache
*
* Class CacheClear
* @package Thelia\Command
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*
*/
class CacheClear extends ContainerAwareCommand
{
protected function configure()
{
$this
->setName("cache:clear")
->setDescription("Invalidate all caches");
->setDescription("Invalidate all caches")
->addOption(
"without-assets",
null,
InputOption::VALUE_NONE,
"remove cache assets"
)
;
}
protected function execute(InputInterface $input, OutputInterface $output)
@@ -44,20 +60,28 @@ class CacheClear extends ContainerAwareCommand
$cacheDir = $this->getContainer()->getParameter("kernel.cache_dir");
if (!is_writable($cacheDir)) {
throw new \RuntimeException(sprintf('Unable to write in the "%s" directory', $cacheDir));
}
$output->writeln(sprintf("Clearing cache in <info>%s</info> directory", $cacheDir));
$fs = new Filesystem();
try {
$fs->remove($cacheDir);
$output->writeln("<info>cache cleared successfully</info>");
} catch (IOException $e) {
$output->writeln(sprintf("error during clearing cache : %s", $e->getMessage()));
$this->clearCache($cacheDir, $output);
if(!$input->getOption("without-assets")) {
$this->clearCache(THELIA_WEB_DIR . "/assets", $output);
}
}
protected function clearCache($dir, OutputInterface $output)
{
if (!is_writable($dir)) {
throw new \RuntimeException(sprintf('Unable to write in the "%s" directory', $dir));
}
$output->writeln(sprintf("Clearing cache in <info>%s</info> directory", $dir));
$fs = new Filesystem();
try {
$fs->remove($dir);
$output->writeln(sprintf("<info>%s cache dir cleared successfully</info>", $dir));
} catch (IOException $e) {
$output->writeln(sprintf("error during clearing cache : %s", $e->getMessage()));
}
}
}

6
core/lib/Thelia/Command/ClearImageCache.php Normal file → Executable file
View File

@@ -1,5 +1,4 @@
<?php
use Thelia\Core\Event\TheliaEvents;
/*************************************************************************************/
/* */
/* Thelia */
@@ -24,15 +23,14 @@ use Thelia\Core\Event\TheliaEvents;
namespace Thelia\Command;
use Thelia\Command\ContainerAwareCommand;
use Thelia\Core\Event\TheliaEvents;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Thelia\Core\Event\ImageEvent;
use Thelia\Core\HttpFoundation\Request;
use Symfony\Component\Console\Input\InputArgument;
use Thelia\Core\Event\TheliaEvents;
class ClearImageCache extends ContainerAwareCommand
@@ -67,4 +65,4 @@ class ClearImageCache extends ContainerAwareCommand
$output->writeln(sprintf("Failed to clear image cache: %s", $ex->getMessage()));
}
}
}
}

View File

@@ -0,0 +1,147 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Thelia\Command\ContainerAwareCommand;
use Thelia\Model\Admin;
class CreateAdminUser extends ContainerAwareCommand
{
/**
* Configure the command
*/
protected function configure()
{
$this
->setName("thelia:create-admin")
->setDescription("Create a new adminsitration user")
->setHelp("The <info>thelia:create-admin</info> command create a new administration user.")
->addOption(
'login_name',
null,
InputOption::VALUE_OPTIONAL,
'Admin login name',
null
)
->addOption(
'first_name',
null,
InputOption::VALUE_OPTIONAL,
'User first name',
null
)
->addOption(
"last_name",
null,
InputOption::VALUE_OPTIONAL,
'User last name',
null
)
->addOption(
'password',
null,
InputOption::VALUE_OPTIONAL,
'Password',
null
)
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$output->writeln('Please enter the admin user information:');
$admin = $this->getAdminInfo($input, $output); // new Admin();
$admin->save();
$output->writeln(array(
"",
"<info>User ".$admin->getLogin()." successfully created.</info>",
""
));
}
protected function enterData($dialog, $output, $label, $error_message)
{
return $dialog->askAndValidate(
$output,
$this->decorateInfo($label),
function ($answer) {
$answer = trim($answer);
if (empty($answer)) {
throw new \RuntimeException("This information is mandatory.");
}
return $answer;
}
);
}
/**
* Ask to user all needed information
*
* @param InputInterface $input
* @param OutputInterface $output
* @return array
*/
protected function getAdminInfo(InputInterface $input, OutputInterface $output)
{
$dialog = $this->getHelperSet()->get('dialog');
$admin = new Admin();
$admin->setLogin($input->getOption("login_name") ?: $this->enterData($dialog, $output, "Admin login name : ", "Please enter a login name."));
$admin->setFirstname($input->getOption("first_name") ?: $this->enterData($dialog, $output, "User first name : ", "Please enter user first name."));
$admin->setLastname($input->getOption("last_name") ?: $this->enterData($dialog, $output, "User last name : ", "Please enter user last name."));
do {
$password = $input->getOption("password") ?: $this->enterData($dialog, $output, "Password : ", "Please enter a password.");
$password_again = $input->getOption("password") ?: $this->enterData($dialog, $output, "Password (again): ", "Please enter the password again.");
if (! empty($password) && $password == $password_again) {
$admin->setPassword($password);
break;
}
$output->writeln("Passwords are different, please try again.");
}
while (true);
return $admin;
}
protected function decorateInfo($text)
{
return sprintf("<info>%s</info>", $text);
}
}

View File

@@ -28,7 +28,15 @@ use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Filesystem\Filesystem;
use Thelia\Command\ContainerAwareCommand;
use Thelia\Install\Database;
/**
* try to install a new instance of Thelia
*
* Class Install
* @package Thelia\Command
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class Install extends ContainerAwareCommand
{
/**
@@ -90,14 +98,16 @@ class Install extends ContainerAwareCommand
$connectionInfo = $this->getConnectionInfo($input, $output);
}
$this->createDatabase($connection, $connectionInfo["dbName"]);
$database = new Database($connection);
$database->createDatabase($connectionInfo["dbName"]);
$output->writeln(array(
"",
"<info>Creating Thelia database, please wait</info>",
""
));
$this->insertSql($connection, $connectionInfo["dbName"]);
$database->insertSql($connectionInfo["dbName"]);
$output->writeln(array(
"",
@@ -196,65 +206,6 @@ class Install extends ContainerAwareCommand
}
/**
* Insert all sql needed in database
*
* @param \PDO $connection
* @param $dbName
*/
protected function insertSql(\PDO $connection, $dbName)
{
$connection->query(sprintf("use %s", $dbName));
$sql = array();
$sql = array_merge(
$sql,
$this->prepareSql(file_get_contents(THELIA_ROOT . "/install/thelia.sql")),
$this->prepareSql(file_get_contents(THELIA_ROOT . "/install/insert.sql"))
);
for ($i = 0; $i < count($sql); $i ++) {
$connection->query($sql[$i]);
}
}
/**
* Separate each sql instruction in an array
*
* @param $sql
* @return array
*/
protected function prepareSql($sql)
{
$sql = str_replace(";',", "-CODE-", $sql);
$query = array();
$tab = explode(";", $sql);
for ($i=0; $i<count($tab); $i++) {
$queryTemp = str_replace("-CODE-", ";',", $tab[$i]);
$queryTemp = str_replace("|", ";", $queryTemp);
$query[] = $queryTemp;
}
return $query;
}
/**
* create database if not exists
*
* @param \PDO $connection
* @param $dbName
*/
protected function createDatabase(\PDO $connection, $dbName)
{
$connection->query(
sprintf(
"CREATE DATABASE IF NOT EXISTS %s CHARACTER SET utf8",
$dbName
)
);
}
/**
* test database access
*

7
core/lib/Thelia/Command/ModuleGenerateCommand.php Normal file → Executable file
View File

@@ -27,6 +27,13 @@ use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Filesystem\Filesystem;
/**
* generate a new Module
*
* Class ModuleGenerateCommand
* @package Thelia\Command
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class ModuleGenerateCommand extends BaseModuleGenerate
{
protected function configure()

7
core/lib/Thelia/Command/ModuleGenerateModelCommand.php Normal file → Executable file
View File

@@ -31,6 +31,13 @@ use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Filesystem\Filesystem;
/**
* generate class model for a specific module
*
* Class ModuleGenerateModelCommand
* @package Thelia\Command
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class ModuleGenerateModelCommand extends BaseModuleGenerate
{
protected function configure()

7
core/lib/Thelia/Command/ModuleGenerateSqlCommand.php Normal file → Executable file
View File

@@ -30,6 +30,13 @@ use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Filesystem\Filesystem;
/**
* generate sql for a specific module
*
* Class ModuleGenerateSqlCommand
* @package Thelia\Command
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class ModuleGenerateSqlCommand extends BaseModuleGenerate
{
public function configure()

0
core/lib/Thelia/Command/Output/TheliaConsoleOutput.php Normal file → Executable file
View File

View File

@@ -0,0 +1,70 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Command;
use Propel\Runtime\Propel;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Thelia\Install\Database;
/**
* Class ReloadDatabasesCommand
* @package Thelia\Command
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class ReloadDatabaseCommand extends BaseModuleGenerate
{
public function configure()
{
$this
->setName("thelia:dev:reloadDB")
->setDescription("erase current database and create new one")
/* ->addOption(
"load-fixtures",
null,
InputOption::VALUE_NONE,
"load fixtures in databases"
)*/
;
}
public function execute(InputInterface $input, OutputInterface $output)
{
$connection = Propel::getConnection(\Thelia\Model\Map\ProductTableMap::DATABASE_NAME);
$connection = $connection->getWrappedConnection();
$database = new Database($connection);
$output->writeln(array(
'',
'<info>starting reloaded database, please wait</info>'
));
$database->insertSql();
$output->writeln(array(
'',
'<info>Database reloaded with success</info>',
''
));
}
}

2
core/lib/Thelia/Command/Skeleton/Module/Class.php Normal file → Executable file
View File

@@ -25,7 +25,7 @@ namespace %%NAMESPACE%%;
use Thelia\Module\BaseModule;
class Class extends BaseModule
class %%CLASSNAME%% extends BaseModule
{
/**
* YOU HAVE TO IMPLEMENT HERE ABSTRACT METHODD FROM BaseModule Class

0
core/lib/Thelia/Command/Skeleton/Module/config.xml Normal file → Executable file
View File

0
core/lib/Thelia/Command/Skeleton/Module/plugin.xml Normal file → Executable file
View File

0
core/lib/Thelia/Command/Skeleton/Module/schema.xml Normal file → Executable file
View File

View File

@@ -22,14 +22,44 @@
<tag name="kernel.event_subscriber"/>
</service>
<service id="thelia.action.category" class="Thelia\Action\Category">
<service id="thelia.action.address" class="Thelia\Action\Address">
<argument type="service" id="service_container"/>
<tag name="kernel.event_subscriber"/>
</service>
<service id="thelia.action.image" class="Thelia\Action\Image">
<argument type="service" id="service_container"/>
<tag name="kernel.event_subscriber"/>
</service>
<service id="thelia.action.category" class="Thelia\Action\Image">
<service id="thelia.action.category" class="Thelia\Action\Category">
<argument type="service" id="service_container"/>
<tag name="kernel.event_subscriber"/>
<tag name="kernel.event_subscriber"/>
</service>
<service id="thelia.action.config" class="Thelia\Action\Config">
<argument type="service" id="service_container"/>
<tag name="kernel.event_subscriber"/>
</service>
<service id="thelia.action.message" class="Thelia\Action\Message">
<argument type="service" id="service_container"/>
<tag name="kernel.event_subscriber"/>
</service>
<service id="thelia.action.coupon" class="Thelia\Action\Coupon">
<argument type="service" id="service_container"/>
<tag name="kernel.event_subscriber"/>
</service>
<service id="thelia.action.currency" class="Thelia\Action\Currency">
<argument type="service" id="service_container"/>
<tag name="kernel.event_subscriber"/>
</service>
<service id="thelia.action.pageNotFound" class="Thelia\Action\PageNotFound">
<argument type="service" id="service_container"/>
<tag name="kernel.event_subscriber"/>
</service>
</services>

View File

@@ -7,25 +7,35 @@
<loops>
<loop class="Thelia\Core\Template\Loop\Accessory" name="accessory"/>
<loop class="Thelia\Core\Template\Loop\Address" name="address"/>
<loop class="Thelia\Core\Template\Loop\AssociatedContent" name="associated_content"/>
<loop class="Thelia\Core\Template\Loop\Attribute" name="attribute"/>
<loop class="Thelia\Core\Template\Loop\AttributeAvailability" name="attribute_availability"/>
<loop class="Thelia\Core\Template\Loop\AttributeCombination" name="attribute_combination"/>
<loop class="Thelia\Core\Template\Loop\Auth" name="auth"/>
<loop class="Thelia\Core\Template\Loop\Category" name="category"/>
<loop class="Thelia\Core\Template\Loop\Content" name="content"/>
<loop class="Thelia\Core\Template\Loop\Country" name="country"/>
<loop class="Thelia\Core\Template\Loop\Currency" name="currency"/>
<loop class="Thelia\Core\Template\Loop\Customer" name="customer"/>
<loop class="Thelia\Core\Template\Loop\Feature" name="feature"/>
<loop class="Thelia\Core\Template\Loop\FeatureAvailable" name="feature_available"/>
<loop class="Thelia\Core\Template\Loop\FeatureAvailability" name="feature_availability"/>
<loop class="Thelia\Core\Template\Loop\FeatureValue" name="feature_value"/>
<loop class="Thelia\Core\Template\Loop\Folder" name="folder"/>
<loop class="Thelia\Core\Template\Loop\Order" name="order"/>
<loop class="Thelia\Core\Template\Loop\OrderStatus" name="order-status"/>
<loop class="Thelia\Core\Template\Loop\CategoryPath" name="category-path"/>
<loop class="Thelia\Core\Template\Loop\Product" name="product"/>
<loop class="Thelia\Core\Template\Loop\ProductSaleElements" name="product_sale_elements"/>
<loop class="Thelia\Core\Template\Loop\Feed" name="feed"/>
<loop class="Thelia\Core\Template\Loop\Title" name="title"/>
<loop class="Thelia\Core\Template\Loop\Lang" name="lang"/>
<loop class="Thelia\Core\Template\Loop\CategoryTree" name="category-tree"/>
<loop class="Thelia\Core\Template\Loop\Cart" name="cart"/>
<loop class="Thelia\Core\Template\Loop\Image" name="image"/>
<loop class="Thelia\Core\Template\Loop\Config" name="config"/>
<loop class="Thelia\Core\Template\Loop\Coupon" name="coupon"/>
<loop class="Thelia\Core\Template\Loop\Message" name="message"/>
<loop class="Thelia\Core\Template\Loop\Delivery" name="delivery"/>
</loops>
<forms>
@@ -35,10 +45,27 @@
<form name="thelia.customer.login" class="Thelia\Form\CustomerLogin"/>
<form name="thelia.admin.login" class="Thelia\Form\AdminLogin"/>
<form name="thelia.address.create" class="Thelia\Form\AddressCreateForm" />
<form name="thelia.address.update" class="Thelia\Form\AddressUpdateForm" />
<form name="thelia.admin.category.creation" class="Thelia\Form\CategoryCreationForm"/>
<form name="thelia.admin.category.deletion" class="Thelia\Form\CategoryDeletionForm"/>
<form name="thelia.admin.category.deletion" class="Thelia\Form\CategoryModificationForm"/>
<form name="thelia.admin.product.creation" class="Thelia\Form\ProductCreationForm"/>
<form name="thelia.admin.product.deletion" class="Thelia\Form\ProductModificationForm"/>
<form name="thelia.cart.add" class="Thelia\Form\CartAdd"/>
<form name="thelia.admin.config.creation" class="Thelia\Form\ConfigCreationForm"/>
<form name="thelia.admin.config.modification" class="Thelia\Form\ConfigModificationForm"/>
<form name="thelia.admin.message.creation" class="Thelia\Form\MessageCreationForm"/>
<form name="thelia.admin.message.modification" class="Thelia\Form\MessageModificationForm"/>
<form name="thelia.admin.currency.creation" class="Thelia\Form\CurrencyCreationForm"/>
<form name="thelia.admin.currency.modification" class="Thelia\Form\CurrencyModificationForm"/>
<form name="thelia.admin.coupon.creation" class="Thelia\Form\CouponCreationForm"/>
</forms>
@@ -49,10 +76,18 @@
<command class="Thelia\Command\ModuleGenerateCommand"/>
<command class="Thelia\Command\ModuleGenerateModelCommand"/>
<command class="Thelia\Command\ModuleGenerateSqlCommand"/>
<command class="Thelia\Command\CreateAdminUser"/>
<command class="Thelia\Command\ReloadDatabaseCommand"/>
</commands>
<services>
<!-- URL maganement -->
<service id="thelia.url.manager" class="Thelia\Tools\URL">
<argument type="service" id="service_container" />
</service>
<service id="event_dispatcher" class="Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher">
<argument type="service" id="service_container" />
</service>
@@ -69,7 +104,7 @@
<!-- Translation and internationalisation -->
<service id="thelia.translator" class="Thelia\Core\Translation\Translator">
<argument type="string" id="en_US"></argument>
<argument type="string" id="en_UK"></argument>
</service>
<!-- Security context for front and back office -->
@@ -78,8 +113,6 @@
<argument type="service" id="request" />
</service>
<service id="thelia.envContext" class="Thelia\Core\Context"/>
<!-- Parser context -->
<service id="thelia.parser.context" class="Thelia\Core\Template\ParserContext" scope="request">
@@ -102,12 +135,18 @@
<service id="smarty.plugin.assetic" class="Thelia\Core\Template\Smarty\Plugins\Assetic" >
<tag name="thelia.parser.register_plugin"/>
<argument>%kernel.environment%</argument>
</service>
<service id="smarty.plugin.theliasyntax" class="Thelia\Core\Template\Smarty\Plugins\TheliaSyntax" >
<tag name="thelia.parser.register_plugin"/>
</service>
<service id="smarty.plugin.format" class="Thelia\Core\Template\Smarty\Plugins\Format" scope="request">
<argument type="service" id="request"/>
<tag name="thelia.parser.register_plugin"/>
</service>
<service id="smarty.plugin.thelialoop" class="Thelia\Core\Template\Smarty\Plugins\TheliaLoop" scope="request">
<tag name="thelia.parser.register_plugin"/>
@@ -145,17 +184,24 @@
<argument type="service" id="request"/>
</service>
<service id="smarty.plugin.security" class="Thelia\Core\Template\Smarty\Plugins\Security" scope="request">
<service id="smarty.plugin.security" class="Thelia\Core\Template\Smarty\Plugins\Security" scope="request">
<tag name="thelia.parser.register_plugin"/>
<argument type="service" id="thelia.securityContext" />
</service>
<service id="smarty.plugin.dataAccess" class="Thelia\Core\Template\Smarty\Plugins\DataAccessFunctions" scope="request">
<service id="smarty.plugin.dataAccess" class="Thelia\Core\Template\Smarty\Plugins\DataAccessFunctions" scope="request">
<tag name="thelia.parser.register_plugin"/>
<argument type="service" id="request" />
<argument type="service" id="thelia.securityContext" />
<argument type="service" id="thelia.parser.context"/>
</service>
<service id="smarty.plugin.adminUtilities" class="Thelia\Core\Template\Smarty\Plugins\AdminUtilities" scope="request">
<tag name="thelia.parser.register_plugin"/>
<argument type="service" id="thelia.securityContext" />
</service>
<service id="http_kernel" class="Thelia\Core\TheliaHttpKernel">
<argument type="service" id="event_dispatcher" />
<argument type="service" id="service_container" />
@@ -167,6 +213,36 @@
<service id="service_container" synthetic="true" />
<service id="kernel" synthetic="true" />
<!-- Coupon module -->
<service id="thelia.adapter" class="Thelia\Coupon\CouponBaseAdapter">
<argument type="service" id="service_container" />
</service>
<service id="thelia.coupon.manager" class="Thelia\Coupon\CouponManager">
<argument type="service" id="thelia.adapter" />
</service>
<service id="thelia.constraint.factory" class="Thelia\Constraint\ConstraintFactory">
<argument type="service" id="service_container" />
</service>
<service id="thelia.constraint.rule.available_for_x_articles" class="Thelia\Constraint\Rule\AvailableForXArticlesManager">
<argument type="service" id="thelia.translator" />
<tag name="thelia.coupon.addRule"/>
</service>
<service id="thelia.constraint.rule.available_for_total_amount" class="Thelia\Constraint\Rule\AvailableForTotalAmountManager">
<argument type="service" id="thelia.translator" />
<tag name="thelia.coupon.addRule"/>
</service>
<service id="thelia.coupon.type.remove_x_amount" class="Thelia\Coupon\Type\RemoveXAmount">
<argument type="service" id="thelia.translator" />
<tag name="thelia.coupon.addCoupon"/>
</service>
<service id="thelia.coupon.type.remove_x_percent" class="Thelia\Coupon\Type\RemoveXPercent">
<argument type="service" id="thelia.translator" />
<tag name="thelia.coupon.addCoupon"/>
</service>
</services>
</config>

View File

@@ -56,6 +56,17 @@
<tag name="router.register" priority="0"/>
</service>
<service id="router.install" class="%router.class%">
<argument type="service" id="router.xmlLoader"/>
<argument>install.xml</argument>
<argument type="collection">
<argument key="cache_dir">%kernel.cache_dir%</argument>
<argument key="debug">%kernel.debug%</argument>
</argument>
<argument type="service" id="request.context"/>
<tag name="router.register" priority="-1"/>
</service>
<service id="router.front" class="%router.class%">
<argument type="service" id="router.xmlLoader"/>
<argument>front.xml</argument>
@@ -64,6 +75,10 @@
<argument key="debug">%kernel.debug%</argument>
</argument>
<argument type="service" id="request.context"/>
<tag name="router.register" priority="254"/>
</service>
<service id="router.rewrite" class="Thelia\Core\Routing\RewritingRouter">
<tag name="router.register" priority="255"/>
</service>

View File

@@ -25,20 +25,185 @@
</route>
<!-- Route to the catalog controller (process category browsing) -->
<!-- Route to the catalog controller -->
<route id="admin.catalog" path="/admin/catalog">
<default key="_controller">Thelia\Controller\Admin\CategoryController::indexAction</default>
<default key="_controller">Thelia\Controller\Admin\CategoryController::defaultAction</default>
</route>
<route id="admin.category" path="/admin/catalog/category">
<default key="_controller">Thelia\Controller\Admin\CategoryController::processAction</default>
<!-- Customer rule management -->
<route id="admin.customers" path="/admin/customers">
<default key="_controller">Thelia\Controller\Admin\CustomerController::indexAction</default>
</route>
<!-- end Customer rule management -->
<!-- Categories management -->
<route id="admin.categories.default" path="/admin/categories">
<default key="_controller">Thelia\Controller\Admin\CategoryController::defaultAction</default>
</route>
<route id="admin.categories.create" path="/admin/categories/create">
<default key="_controller">Thelia\Controller\Admin\CategoryController::createAction</default>
</route>
<route id="admin.categories.update" path="/admin/categories/update">
<default key="_controller">Thelia\Controller\Admin\CategoryController::changeAction</default>
</route>
<route id="admin.categories.save" path="/admin/categories/save">
<default key="_controller">Thelia\Controller\Admin\CategoryController::saveChangeAction</default>
</route>
<route id="admin.categories.set-default" path="/admin/categories/toggle-online">
<default key="_controller">Thelia\Controller\Admin\CategoryController::toggleOnlineAction</default>
</route>
<route id="admin.categories.delete" path="/admin/categories/delete">
<default key="_controller">Thelia\Controller\Admin\CategoryController::deleteAction</default>
</route>
<route id="admin.categories.update-position" path="/admin/categories/update-position">
<default key="_controller">Thelia\Controller\Admin\CategoryController::updatePositionAction</default>
</route>
<route id="admin.category.ajax" path="/admin/catalog/category/parent/{parentId}.{_format}" methods="GET">
<default key="_controller">Thelia\Controller\Admin\CategoryController::getByParentIdAction</default>
<requirement key="_format">xml|json</requirement>
</route>
<!-- Route to the Coupon controller (process Coupon browsing) -->
<route id="admin.coupon.list" path="/admin/coupon">
<default key="_controller">Thelia\Controller\Admin\CouponController::browseAction</default>
</route>
<route id="admin.coupon.create" path="/admin/coupon/create">
<default key="_controller">Thelia\Controller\Admin\CouponController::createAction</default>
</route>
<route id="admin.coupon.update" path="/admin/coupon/update/{couponId}">
<default key="_controller">Thelia\Controller\Admin\CouponController::updateAction</default>
</route>
<route id="admin.coupon.read" path="/admin/coupon/read/{couponId}">
<default key="_controller">Thelia\Controller\Admin\CouponController::readAction</default>
</route>
<route id="admin.coupon.rule.input" path="/admin/coupon/rule/{ruleId}">
<default key="_controller">Thelia\Controller\Admin\CouponController::getRuleInputAction</default>
</route>
<!-- Routes to the Config (system variables) controller -->
<route id="admin.configuration.variables.default" path="/admin/configuration/variables">
<default key="_controller">Thelia\Controller\Admin\ConfigController::defaultAction</default>
</route>
<route id="admin.configuration.variables.update-values" path="/admin/configuration/variables/update-values">
<default key="_controller">Thelia\Controller\Admin\ConfigController::changeValuesAction</default>
</route>
<route id="admin.configuration.variables.create" path="/admin/configuration/variables/create">
<default key="_controller">Thelia\Controller\Admin\ConfigController::createAction</default>
</route>
<route id="admin.configuration.variables.update" path="/admin/configuration/variables/update">
<default key="_controller">Thelia\Controller\Admin\ConfigController::changeAction</default>
</route>
<route id="admin.configuration.variables.save" path="/admin/configuration/variables/save">
<default key="_controller">Thelia\Controller\Admin\ConfigController::saveChangeAction</default>
</route>
<route id="admin.configuration.variables.delete" path="/admin/configuration/variables/delete">
<default key="_controller">Thelia\Controller\Admin\ConfigController::deleteAction</default>
</route>
<!-- Routes to the Messages controller -->
<route id="admin.configuration.messages.default" path="/admin/configuration/messages">
<default key="_controller">Thelia\Controller\Admin\MessageController::defaultAction</default>
</route>
<route id="admin.configuration.messages.create" path="/admin/configuration/messages/create">
<default key="_controller">Thelia\Controller\Admin\MessageController::createAction</default>
</route>
<route id="admin.configuration.messages.update" path="/admin/configuration/messages/update">
<default key="_controller">Thelia\Controller\Admin\MessageController::changeAction</default>
</route>
<route id="admin.configuration.messages.save" path="/admin/configuration/messages/save">
<default key="_controller">Thelia\Controller\Admin\MessageController::saveChangeAction</default>
</route>
<route id="admin.configuration.messages.delete" path="/admin/configuration/messages/delete">
<default key="_controller">Thelia\Controller\Admin\MessageController::deleteAction</default>
</route>
<!-- Routes to the Currencies controller -->
<route id="admin.configuration.currencies.default" path="/admin/configuration/currencies">
<default key="_controller">Thelia\Controller\Admin\CurrencyController::defaultAction</default>
</route>
<route id="admin.configuration.currencies.create" path="/admin/configuration/currencies/create">
<default key="_controller">Thelia\Controller\Admin\CurrencyController::createAction</default>
</route>
<route id="admin.configuration.currencies.update" path="/admin/configuration/currencies/update">
<default key="_controller">Thelia\Controller\Admin\CurrencyController::changeAction</default>
</route>
<route id="admin.configuration.currencies.save" path="/admin/configuration/currencies/save">
<default key="_controller">Thelia\Controller\Admin\CurrencyController::saveChangeAction</default>
</route>
<route id="admin.configuration.currencies.set-default" path="/admin/configuration/currencies/set-default">
<default key="_controller">Thelia\Controller\Admin\CurrencyController::setDefaultAction</default>
</route>
<route id="admin.configuration.currencies.update-position" path="/admin/configuration/currencies/update-position">
<default key="_controller">Thelia\Controller\Admin\CurrencyController::updatePositionAction</default>
</route>
<route id="admin.configuration.currencies.update-rates" path="/admin/configuration/currencies/update-rates">
<default key="_controller">Thelia\Controller\Admin\CurrencyController::updateRatesAction</default>
</route>
<route id="admin.configuration.currencies.delete" path="/admin/configuration/currencies/delete">
<default key="_controller">Thelia\Controller\Admin\CurrencyController::deleteAction</default>
</route>
<route id="admin.configuration.currencies.update-position" path="/admin/configuration/currencies/update-position">
<default key="_controller">Thelia\Controller\Admin\CurrencyController::updatePositionAction</default>
</route>
<!-- attribute and feature routes management -->
<route id="admin.configuration.attribute" path="/admin/configuration/product_attributes">
<default key="_controller">Thelia\Controller\Admin\AttributeController::defaultAction</default>
</route>
<route id="admin.configuration.attribute.edit" path="/admin/configuration/product_attributes/update">
<default key="_controller">Thelia\Controller\Admin\AttributeController::updateAction</default>
</route>
<!-- end attribute and feature routes management -->
<!-- The default route, to display a template -->
<route id="admin.processTemplate" path="/admin/{template}">
<default key="_controller">Thelia\Controller\Admin\AdminController::processTemplateAction</default>
<requirement key="template">.*</requirement>
</route>
</routes>

35
core/lib/Thelia/Config/Resources/routing/front.xml Normal file → Executable file
View File

@@ -9,6 +9,7 @@
<default key="_view">index</default>
</route>
<!-- Customer routes -->
<route id="customer.create.process" path="/customer/create" methods="post">
<default key="_controller">Thelia\Controller\Front\CustomerController::createAction</default>
<default key="_view">connexion</default>
@@ -18,16 +19,38 @@
<default key="_controller">Thelia\Controller\Front\CustomerController::updateAction</default>
</route>
<route id="customler.login.process" path="/customer/login" methods="post">
<route id="customer.login.process" path="/customer/login" methods="post">
<default key="_controller">Thelia\Controller\Front\CustomerController::loginAction</default>
</route>
<route id="customer.logout.process" path="/customer/logout">
<default key="_controller">Thelia\Controller\Front\CustomerController::logoutAction</default>
</route>
<!-- end customer routes -->
<!-- customer address routes -->
<route id="address.create" path="/address/create" >
<default key="_controller">Thelia\Controller\Front\AddressController::createAction</default>
<default key="_view">address</default>
</route>
<route id="address.edit" path="/address/edit/{address_id}">
<default key="_controller">Thelia\Controller\Front\DefaultController::noAction</default>
<default key="_view">address_edit</default>
</route>
<route id="address.update" path="/address/update" >
<default key="_controller">Thelia\Controller\Front\AddressController::updateAction</default>
</route>
<!-- end customer address routes -->
<!-- cart routes -->
<route id="cart.add.process" path="/cart/add">
<default key="_controller">Thelia\Controller\Front\CartController::addItem</default>
<default key="_view">cart</default>
</route>
<route id="cart.change.process" path="/cart/delete/{cart_item}">
<route id="cart.delete.process" path="/cart/delete/{cart_item}">
<default key="_controller">Thelia\Controller\Front\CartController::deleteItem</default>
<default key="_view">cart</default>
</route>
@@ -36,4 +59,12 @@
<default key="_controller">Thelia\Controller\Front\CartController::changeItem</default>
<default key="_view">cart</default>
</route>
<!-- order management process -->
<route id="order.delivery.add" path="/delivery/choose/{delivery_id}">
<default key="_controller">Thelia\Controller\Front\DeliveryController::select</default>
<requirement key="delivery_id">\d+</requirement>
</route>
<!-- end order management process -->
</routes>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
<route id="home" path="/install" >
<default key="_controller">Thelia\Controller\Install\InstallController::index</default>
</route>
<route id="home" path="/install/step/2" >
<default key="_controller">Thelia\Controller\Install\InstallController::checkPermission</default>
</route>
</routes>

View File

@@ -0,0 +1,162 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Constraint;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Thelia\Constraint\Rule\AvailableForTotalAmountManager;
use Thelia\Constraint\Rule\CouponRuleInterface;
use Thelia\Constraint\Rule\SerializableRule;
use Thelia\Coupon\CouponAdapterInterface;
use Thelia\Coupon\CouponRuleCollection;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* Manage how Constraint could interact
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class ConstraintFactory
{
/** @var ContainerInterface Service Container */
protected $container = null;
/** @var CouponAdapterInterface Provide necessary value from Thelia*/
protected $adapter;
/** @var array CouponRuleCollection to process*/
protected $rules = null;
/**
* Constructor
*
* @param ContainerInterface $container Service container
*/
function __construct(ContainerInterface $container)
{
$this->container = $container;
$this->adapter = $container->get('thelia.adapter');
}
/**
* Serialize a collection of rules
*
* @param CouponRuleCollection $collection A collection of rules
*
* @return string A ready to be stored Rule collection
*/
public function serializeCouponRuleCollection(CouponRuleCollection $collection)
{
$serializableRules = array();
$rules = $collection->getRules();
if ($rules !== null) {
/** @var $rule CouponRuleInterface */
foreach ($rules as $rule) {
$serializableRules[] = $rule->getSerializableRule();
}
}
return base64_encode(json_encode($serializableRules));
}
/**
* Unserialize a collection of rules
*
* @param string $serializedRules Serialized Rules
*
* @return CouponRuleCollection Rules ready to be processed
*/
public function unserializeCouponRuleCollection($serializedRules)
{
$unserializedRules = json_decode(base64_decode($serializedRules));
$collection = new CouponRuleCollection();
if (!empty($serializedRules) && !empty($unserializedRules)) {
/** @var SerializableRule $rule */
foreach ($unserializedRules as $rule) {
if ($this->container->has($rule->ruleServiceId)) {
/** @var CouponRuleInterface $couponRule */
$couponRule = $this->build(
$rule->ruleServiceId,
(array) $rule->operators,
(array) $rule->values
);
$collection->add(clone $couponRule);
}
}
}
return $collection;
}
/**
* Build a Coupon Rule from form
*
* @param string $ruleServiceId Rule class name
* @param array $operators Rule Operator (<, >, = )
* @param array $values Values setting this Rule
*
* @throws \InvalidArgumentException
* @return CouponRuleInterface Ready to use Rule or false
*/
public function build($ruleServiceId, array $operators, array $values)
{
if (!$this->container->has($ruleServiceId)) {
return false;
}
/** @var CouponRuleInterface $rule */
$rule = $this->container->get($ruleServiceId);
$rule->setValidatorsFromForm($operators, $values);
return $rule;
}
/**
* Get Coupon Rule inputs from serviceId
*
* @param string $ruleServiceId Rule class name
*
* @return array Ready to be drawn rule inputs
*/
public function getInputs($ruleServiceId)
{
if (!$this->container->has($ruleServiceId)) {
return false;
}
/** @var CouponRuleInterface $rule */
$rule = $this->container->get($ruleServiceId);
return $rule->getValidators();
}
}

View File

@@ -0,0 +1,133 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Constraint;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Thelia\Constraint\Rule\AvailableForTotalAmountManager;
use Thelia\Constraint\Rule\CouponRuleInterface;
use Thelia\Constraint\Rule\Operators;
use Thelia\Coupon\CouponRuleCollection;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* Validate Constraints
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class ConstraintValidator
{
/**
* Check if a Customer meets SerializableRule
*
* @param CouponRuleCollection $rules Rules to check against the Customer
*
* @return bool
*/
public function test(CouponRuleCollection $rules)
{
$isMatching = true;
/** @var CouponRuleInterface $rule */
foreach ($rules->getRules() as $rule) {
if (!$rule->isMatching()) {
$isMatching = false;
}
}
return $isMatching;
}
/**
* Do variable comparison
*
* @param mixed $v1 Variable 1
* @param string $o Operator
*
* @param mixed $v2 Variable 2
* @throws \Exception
* @return bool
*/
public function variableOpComparison($v1, $o, $v2) {
if ($o == Operators::DIFFERENT) {
return ($v1 != $v2);
} // could put this elsewhere...
// $operators = str_split($o);
// foreach($o as $operator) {
switch ($o) { // return will exit switch, foreach loop, function
case Operators::SUPERIOR : // >
if ($v1 > $v2) {
return true;
} else {
continue;
} break;
case Operators::SUPERIOR_OR_EQUAL : // >=
if ($v1 >= $v2) {
return true;
} else {
continue;
} break;
case Operators::INFERIOR : // <
if ($v1 < $v2) {
return true;
} else {
continue;
} break;
case Operators::INFERIOR_OR_EQUAL : // <=
if ($v1 <= $v2) {
return true;
} else {
continue;
} break;
case Operators::EQUAL : // ==
if ($v1 == $v2) {
return true;
} else {
continue;
} break;
case Operators::IN:
if (in_array($v1, $v2)) { // in
return true;
} else {
continue;
} break;
case Operators::OUT:
if (!in_array($v1, $v2)) { // not in
return true;
} else {
continue;
} break;
default: throw new \Exception('Unrecognized operator ' . $o);
}
// }
return false;
}
}

View File

@@ -0,0 +1,178 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Constraint\Rule;
use Thelia\Constraint\Validator\CustomerParam;
use Thelia\Constraint\Validator\RuleValidator;
use Thelia\Coupon\CouponAdapterInterface;
use Thelia\Exception\InvalidRuleException;
use Thelia\Exception\InvalidRuleOperatorException;
use Thelia\Exception\InvalidRuleValueException;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class AvailableForCustomer extends CouponRuleAbstract
{
/** Rule 1st parameter : customer id */
CONST PARAM1 = 'customerId';
/** @var array Available Operators (Operators::CONST) */
protected $availableOperators = array(
Operators::EQUAL,
);
/** @var RuleValidator Customer Validator */
protected $customerValidator = null;
/**
* Check if backoffice inputs are relevant or not
*
* @throws InvalidRuleOperatorException if Operator is not allowed
* @throws InvalidRuleValueException if Value is not allowed
* @return bool
*/
public function checkBackOfficeInput()
{
if (!isset($this->validators)
|| empty($this->validators)
||!isset($this->validators[self::PARAM1])
||!isset($this->validators[self::PARAM1])
) {
throw new InvalidRuleValueException(get_class(), self::PARAM1);
}
/** @var RuleValidator $ruleValidator */
$ruleValidator = $this->validators[self::PARAM1];
/** @var CustomerParam $customer */
$customer = $ruleValidator->getParam();
if (!$customer instanceof CustomerParam) {
throw new InvalidRuleValueException(get_class(), self::PARAM1);
}
$this->checkBackOfficeInputsOperators();
return $this->isCustomerValid($customer->getInteger());
}
/**
* Generate current Rule param to be validated from adapter
*
* @return $this
*/
protected function setParametersToValidate()
{
$this->paramsToValidate = array(
self::PARAM1 => $this->adapter->getCustomer()->getId()
);
return $this;
}
/**
* Check if Checkout inputs are relevant or not
*
* @throws \Thelia\Exception\InvalidRuleValueException
* @return bool
*/
public function checkCheckoutInput()
{
if (!isset($this->paramsToValidate)
|| empty($this->paramsToValidate)
||!isset($this->paramsToValidate[self::PARAM1])
) {
throw new InvalidRuleValueException(get_class(), self::PARAM1);
}
$customerId = $this->paramsToValidate[self::PARAM1];
return $this->isCustomerValid($customerId);
}
/**
* Check if a Customer is valid
*
* @param int $customerId Customer to check
*
* @throws InvalidRuleValueException if Value is not allowed
* @return bool
*/
protected function isCustomerValid($customerId)
{
$customerValidator = $this->customerValidator;
try {
$customerValidator->getParam()->compareTo($customerId);
} catch(\InvalidArgumentException $e) {
throw new InvalidRuleValueException(get_class(), self::PARAM1);
}
return true;
}
/**
* Get I18n name
*
* @return string
*/
public function getName()
{
return $this->adapter
->getTranslator()
->trans('Customer', null, 'constraint');
}
/**
* Get I18n tooltip
*
* @return string
*/
public function getToolTip()
{
/** @var CustomerParam $param */
$param = $this->customerValidator->getParam();
$toolTip = $this->adapter
->getTranslator()
->trans(
'If customer is %fistname% %lastname% (%email%)',
array(
'%fistname%' => $param->getFirstName(),
'%lastname%' => $param->getLastName(),
'%email%' => $param->getEmail(),
),
'constraint'
);
return $toolTip;
}
}

View File

@@ -0,0 +1,59 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Constraint\Rule;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class AvailableForDate extends AvailableForPeriod
{
/**
* Check if backoffice inputs are relevant or not
*
* @return bool
*/
public function checkBackOfficeInput()
{
// TODO: Implement checkBackOfficeInput() method.
}
/**
* Check if Checkout inputs are relevant or not
*
* @return bool
*/
public function checkCheckoutInput()
{
// TODO: Implement checkCheckoutInput() method.
}
}

View File

@@ -0,0 +1,59 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Constraint\Rule;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class AvailableForLocationX extends CouponRuleAbstract
{
/**
* Check if backoffice inputs are relevant or not
*
* @return bool
*/
public function checkBackOfficeInput()
{
// TODO: Implement checkBackOfficeInput() method.
}
/**
* Check if Checkout inputs are relevant or not
*
* @return bool
*/
public function checkCheckoutInput()
{
// TODO: Implement checkCheckoutInput() method.
}
}

View File

@@ -0,0 +1,57 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Constraint\Rule;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class AvailableForPeriod extends CouponRuleAbstract
{
/**
* Check if backoffice inputs are relevant or not
*
* @return bool
*/
public function checkBackOfficeInput()
{
// TODO: Implement checkBackOfficeInput() method.
}
/**
* Check if Checkout inputs are relevant or not
*
* @return bool
*/
public function checkCheckoutInput()
{
// TODO: Implement checkCheckoutInput() method.
}
}

View File

@@ -0,0 +1,57 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Constraint\Rule;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class AvailableForRepeatedDate extends AvailableForDate
{
/**
* Check if backoffice inputs are relevant or not
*
* @return bool
*/
public function checkBackOfficeInput()
{
// TODO: Implement checkBackOfficeInput() method.
}
/**
* Check if Checkout inputs are relevant or not
*
* @return bool
*/
public function checkCheckoutInput()
{
// TODO: Implement checkCheckoutInput() method.
}
}

View File

@@ -0,0 +1,73 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Constraint\Rule;
use Thelia\Coupon\CouponAdapterInterface;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class AvailableForRepeatedPeriod extends AvailableForPeriod
{
/**
* Generate current Rule param to be validated from adapter
*
* @param CouponAdapterInterface $adapter allowing to gather
* all necessary Thelia variables
*
* @throws \Symfony\Component\Intl\Exception\NotImplementedException
* @return $this
*/
public function setParametersToValidate(CouponAdapterInterface $adapter)
{
// @todo implement
}
/**
* Check if backoffice inputs are relevant or not
*
* @return bool
*/
public function checkBackOfficeInput()
{
// TODO: Implement checkBackOfficeInput() method.
}
/**
* Check if Checkout inputs are relevant or not
*
* @return bool
*/
public function checkCheckoutInput()
{
// TODO: Implement checkCheckoutInput() method.
}
}

View File

@@ -0,0 +1,38 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Constraint\Rule;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class AvailableForTotalAmountForCategoryY extends AvailableForTotalAmount
{
}

View File

@@ -0,0 +1,368 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Constraint\Rule;
use Symfony\Component\Intl\Exception\NotImplementedException;
use Symfony\Component\Translation\Translator;
use Thelia\Constraint\ConstraintValidator;
use Thelia\Coupon\CouponAdapterInterface;
use Thelia\Constraint\Validator\PriceParam;
use Thelia\Constraint\Validator\RuleValidator;
use Thelia\Exception\InvalidRuleException;
use Thelia\Exception\InvalidRuleOperatorException;
use Thelia\Exception\InvalidRuleValueException;
use Thelia\Type\FloatType;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* Rule AvailableForTotalAmount
* Check if a Checkout total amount match criteria
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class AvailableForTotalAmountManager extends CouponRuleAbstract
{
/** Rule 1st parameter : price */
CONST INPUT1 = 'price';
/** Rule 1st parameter : currency */
CONST INPUT2 = 'currency';
/** @var string Service Id from Resources/config.xml */
protected $serviceId = 'thelia.constraint.rule.available_for_total_amount';
/** @var array Available Operators (Operators::CONST) */
protected $availableOperators = array(
self::INPUT1 => array(
Operators::INFERIOR,
Operators::INFERIOR_OR_EQUAL,
Operators::EQUAL,
Operators::SUPERIOR_OR_EQUAL,
Operators::SUPERIOR
),
self::INPUT2 => array(
Operators::EQUAL,
)
);
// /** @var RuleValidator Price Validator */
// protected $priceValidator = null;
// /**
// * Check if backoffice inputs are relevant or not
// *
// * @throws InvalidRuleOperatorException if Operator is not allowed
// * @throws InvalidRuleValueException if Value is not allowed
// * @return bool
// */
// public function checkBackOfficeInput()
// {
// if (!isset($this->validators)
// || empty($this->validators)
// ||!isset($this->validators[self::PARAM1_PRICE])
// ||!isset($this->validators[self::PARAM1_PRICE])
// ) {
// throw new InvalidRuleValueException(get_class(), self::PARAM1_PRICE);
// }
//
// /** @var RuleValidator $ruleValidator */
// $ruleValidator = $this->validators[self::PARAM1_PRICE];
// /** @var PriceParam $price */
// $price = $ruleValidator->getParam();
//
// if (!$price instanceof PriceParam) {
// throw new InvalidRuleValueException(get_class(), self::PARAM1_PRICE);
// }
//
// $this->checkBackOfficeInputsOperators();
//
// return $this->isPriceValid($price->getPrice(), $price->getCurrency());
// }
// /**
// * Check if Checkout inputs are relevant or not
// *
// * @throws InvalidRuleValueException if Value is not allowed
// * @return bool
// */
// public function checkCheckoutInput()
// {
// $currency = $this->adapter->getCheckoutCurrency();
// if (empty($currency)) {
// throw new InvalidRuleValueException(
// get_class(), self::PARAM1_CURRENCY
// );
// }
//
// $price = $this->adapter->getCartTotalPrice();
// if (empty($price)) {
// throw new InvalidRuleValueException(
// get_class(), self::PARAM1_PRICE
// );
// }
//
// $this->paramsToValidate = array(
// self::PARAM1_PRICE => $this->adapter->getCartTotalPrice(),
// self::PARAM1_CURRENCY => $this->adapter->getCheckoutCurrency()
// );
//
// return $this->isPriceValid($price, $currency);
// }
/**
* Check validators relevancy and store them
*
* @param array $operators Operators the Admin set in BackOffice
* @param array $values Values the Admin set in BackOffice
*
* @throws \InvalidArgumentException
* @return $this
*/
public function setValidatorsFromForm(array $operators, array $values)
{
$this->setValidators(
$operators[self::INPUT1],
$values[self::INPUT1],
$operators[self::INPUT2],
$values[self::INPUT2]
);
return $this;
}
/**
* Check validators relevancy and store them
*
* @param string $priceOperator Price Operator ex <
* @param float $priceValue Price set to meet condition
* @param string $currencyOperator Currency Operator ex =
* @param string $currencyValue Currency set to meet condition
*
* @throws \InvalidArgumentException
* @return $this
*/
protected function setValidators($priceOperator, $priceValue, $currencyOperator, $currencyValue)
{
$isOperator1Legit = $this->isOperatorLegit(
$priceOperator,
$this->availableOperators[self::INPUT1]
);
if (!$isOperator1Legit) {
throw new \InvalidArgumentException(
'Operator for price field is not legit'
);
}
$isOperator1Legit = $this->isOperatorLegit(
$currencyOperator,
$this->availableOperators[self::INPUT2]
);
if (!$isOperator1Legit) {
throw new \InvalidArgumentException(
'Operator for currency field is not legit'
);
}
$floatType = new FloatType();
if (!$floatType->isValid($priceValue) || $priceValue <= 0) {
throw new \InvalidArgumentException(
'Value for price field is not legit'
);
}
// @todo check currency is legit or not
$this->operators = array(
self::INPUT1 => $priceOperator,
self::INPUT2 => $currencyOperator,
);
$this->values = array(
self::INPUT1 => $priceValue,
self::INPUT2 => $currencyValue,
);
return $this;
}
/**
* Test if Customer meets conditions
*
* @return bool
*/
public function isMatching()
{
$isOperator1Legit = $this->isOperatorLegit(
$this->operators[self::INPUT1],
$this->availableOperators[self::INPUT1]
);
$isOperator2Legit = $this->isOperatorLegit(
$this->operators[self::INPUT2],
$this->availableOperators[self::INPUT2]
);
if (!$isOperator1Legit || !$isOperator2Legit) {
return false;
}
$constrainValidator = new ConstraintValidator();
$constraint1 =$constrainValidator->variableOpComparison(
$this->adapter->getCartTotalPrice(),
$this->operators[self::INPUT1],
$this->values[self::INPUT1]
);
$constraint2 =$constrainValidator->variableOpComparison(
$this->adapter->getCheckoutCurrency(),
$this->operators[self::INPUT2],
$this->values[self::INPUT2]
);
if ($constraint1 && $constraint2) {
return true;
}
return false;
}
// /**
// * Check if a price is valid
// *
// * @param float $price Price to check
// * @param string $currency Price currency
// *
// * @throws InvalidRuleValueException if Value is not allowed
// * @return bool
// */
// protected function isPriceValid($price, $currency)
// {
// $priceValidator = $this->priceValidator;
//
// /** @var PriceParam $param */
// $param = $priceValidator->getParam();
// if ($currency == $param->getCurrency()) {
// try {
// $priceValidator->getParam()->compareTo($price);
// } catch(\InvalidArgumentException $e) {
// throw new InvalidRuleValueException(get_class(), self::PARAM1_PRICE);
// }
// } else {
// throw new InvalidRuleValueException(get_class(), self::PARAM1_CURRENCY);
// }
//
// return true;
// }
// /**
// * Generate current Rule param to be validated from adapter
// *
// * @return $this
// */
// protected function setParametersToValidate()
// {
// $this->paramsToValidate = array(
// self::PARAM1_PRICE => $this->adapter->getCartTotalPrice(),
// self::PARAM1_CURRENCY => $this->adapter->getCheckoutCurrency()
// );
//
// return $this;
// }
/**
* Get I18n name
*
* @return string
*/
public function getName()
{
return $this->adapter->get('thelia.translator')->trans(
'Cart total amount',
array(),
'constraint'
);
}
/**
* Get I18n tooltip
*
* @return string
*/
public function getToolTip()
{
$i18nOperator = Operators::getI18n(
$this->translator, $this->operators[self::INPUT1]
);
$toolTip = $this->translator->trans(
'If cart total amount is <strong>%operator%</strong> %amount% %currency%',
array(
'%operator%' => $i18nOperator,
'%amount%' => $this->values[self::INPUT1],
'%currency%' => $this->values[self::INPUT2]
),
'constraint'
);
return $toolTip;
}
// /**
// * Populate a Rule from a form admin
// *
// * @param array $operators Rule Operator set by the Admin
// * @param array $values Rule Values set by the Admin
// *
// * @throws \InvalidArgumentException
// * @return $this
// */
// public function populateFromForm(array $operators, array $values)
// {
// if ($values[self::PARAM1_PRICE] === null
// || $values[self::PARAM1_CURRENCY] === null
// ) {
// throw new \InvalidArgumentException(
// 'The Rule ' . get_class() . 'needs at least a quantity set (' . self::PARAM1_PRICE . ', ' . self::PARAM1_CURRENCY . ')'
// );
// }
//
// $this->priceValidator = new RuleValidator(
// $operators[self::PARAM1_PRICE],
// new PriceParam(
// $this->translator,
// $values[self::PARAM1_PRICE],
// $values[self::PARAM1_CURRENCY]
// )
// );
//
// $this->validators = array(self::PARAM1_PRICE => $this->priceValidator);
//
// return $this;
// }
}

View File

@@ -0,0 +1,300 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Constraint\Rule;
use InvalidArgumentException;
use Symfony\Component\Translation\Translator;
use Thelia\Constraint\ConstraintValidator;
use Thelia\Constraint\Validator\QuantityParam;
use Thelia\Constraint\Validator\RuleValidator;
use Thelia\Coupon\CouponAdapterInterface;
use Thelia\Exception\InvalidRuleException;
use Thelia\Exception\InvalidRuleValueException;
use Thelia\Type\FloatType;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* Check a Checkout against its Product number
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class AvailableForXArticlesManager extends CouponRuleAbstract
{
/** Rule 1st parameter : quantity */
CONST INPUT1 = 'quantity';
/** @var string Service Id from Resources/config.xml */
protected $serviceId = 'thelia.constraint.rule.available_for_x_articles';
/** @var array Available Operators (Operators::CONST) */
protected $availableOperators = array(
self::INPUT1 => array(
Operators::INFERIOR,
Operators::INFERIOR_OR_EQUAL,
Operators::EQUAL,
Operators::SUPERIOR_OR_EQUAL,
Operators::SUPERIOR
)
);
// /** @var QuantityParam Quantity Validator */
// protected $quantityValidator = null;
// /**
// * Check if backoffice inputs are relevant or not
// *
// * @throws InvalidRuleOperatorException if Operator is not allowed
// * @throws InvalidRuleValueException if Value is not allowed
// * @return bool
// */
// public function checkBackOfficeInput()
// {
// if (!isset($this->validators)
// || empty($this->validators)
// ||!isset($this->validators[self::PARAM1_QUANTITY])
// ||!isset($this->validators[self::PARAM1_QUANTITY])
// ) {
// throw new InvalidRuleValueException(get_class(), self::PARAM1_QUANTITY);
// }
//
// /** @var RuleValidator $ruleValidator */
// $ruleValidator = $this->validators[self::PARAM1_QUANTITY];
// /** @var QuantityParam $quantity */
// $quantity = $ruleValidator->getParam();
//
// if (!$quantity instanceof QuantityParam) {
// throw new InvalidRuleValueException(get_class(), self::PARAM1_QUANTITY);
// }
//
// $this->checkBackOfficeInputsOperators();
//
// return $this->isQuantityValid($quantity->getInteger());
// }
// /**
// * Generate current Rule param to be validated from adapter
// *
// * @param CouponAdapterInterface $adapter allowing to gather
// * all necessary Thelia variables
// *
// * @return $this
// */
// protected function setParametersToValidate()
// {
// $this->paramsToValidate = array(
// self::PARAM1_QUANTITY => $this->adapter->getNbArticlesInCart()
// );
//
// return $this;
// }
// /**
// * Check if Checkout inputs are relevant or not
// *
// * @throws \Thelia\Exception\InvalidRuleValueException
// * @return bool
// */
// public function checkCheckoutInput()
// {
// if (!isset($this->paramsToValidate)
// || empty($this->paramsToValidate)
// ||!isset($this->paramsToValidate[self::PARAM1_QUANTITY])
// ) {
// throw new InvalidRuleValueException(get_class(), self::PARAM1_QUANTITY);
// }
//
// $price = $this->paramsToValidate[self::PARAM1_QUANTITY];
//
// return $this->isQuantityValid($price);
// }
/**
* Check validators relevancy and store them
*
* @param array $operators Operators the Admin set in BackOffice
* @param array $values Values the Admin set in BackOffice
*
* @throws \InvalidArgumentException
* @return $this
*/
public function setValidatorsFromForm(array $operators, array $values)
{
$this->setValidators(
$operators[self::INPUT1],
$values[self::INPUT1]
);
return $this;
}
/**
* Check validators relevancy and store them
*
* @param string $quantityOperator Quantity Operator ex <
* @param int $quantityValue Quantity set to meet condition
*
* @throws \InvalidArgumentException
* @return $this
*/
protected function setValidators($quantityOperator, $quantityValue)
{
$isOperator1Legit = $this->isOperatorLegit(
$quantityOperator,
$this->availableOperators[self::INPUT1]
);
if (!$isOperator1Legit) {
throw new \InvalidArgumentException(
'Operator for quantity field is not legit'
);
}
if (!is_int($quantityValue) || $quantityValue <= 0) {
throw new \InvalidArgumentException(
'Value for quantity field is not legit'
);
}
$this->operators = array(
self::INPUT1 => $quantityOperator,
);
$this->values = array(
self::INPUT1 => $quantityValue,
);
return $this;
}
/**
* Test if Customer meets conditions
*
* @return bool
*/
public function isMatching()
{
$constrainValidator = new ConstraintValidator();
$constraint1 =$constrainValidator->variableOpComparison(
$this->adapter->getNbArticlesInCart(),
$this->operators[self::INPUT1],
$this->values[self::INPUT1]
);
if ($constraint1) {
return true;
}
return false;
}
// /**
// * Check if a quantity is valid
// *
// * @param int $quantity Quantity to check
// *
// * @throws InvalidRuleValueException if Value is not allowed
// * @return bool
// */
// protected function isQuantityValid($quantity)
// {
// $quantityValidator = $this->quantityValidator;
// try {
// $quantityValidator->getParam()->compareTo($quantity);
// } catch(InvalidArgumentException $e) {
// throw new InvalidRuleValueException(get_class(), self::PARAM1_QUANTITY);
// }
//
// return true;
// }
/**
* Get I18n name
*
* @return string
*/
public function getName()
{
return $this->translator->trans(
'Number of articles in cart',
array(),
'constraint'
);
}
/**
* Get I18n tooltip
*
* @return string
*/
public function getToolTip()
{
$i18nOperator = Operators::getI18n(
$this->translator, $this->operators[self::INPUT1]
);
$toolTip = $this->translator->trans(
'If cart products quantity is <strong>%operator%</strong> %quantity%',
array(
'%operator%' => $i18nOperator,
'%quantity%' => $this->values[self::INPUT1]
),
'constraint'
);
return $toolTip;
}
// /**
// * Populate a Rule from a form admin
// *
// * @param array $operators Rule Operator set by the Admin
// * @param array $values Rule Values set by the Admin
// *
// * @throws InvalidArgumentException
// * @return $this
// */
// public function populateFromForm(array $operators, array $values)
// {
// if ($values[self::PARAM1_QUANTITY] === null) {
// throw new InvalidArgumentException(
// 'The Rule ' . get_class() . 'needs at least a quantity set (' . self::PARAM1_QUANTITY. ')'
// );
// }
//
// $this->quantityValidator = new RuleValidator(
// $operators[self::PARAM1_QUANTITY],
// new QuantityParam(
// $this->adapter,
// $values[self::PARAM1_QUANTITY]
// )
// );
//
// $this->validators = array(self::PARAM1_QUANTITY => $this->quantityValidator);
//
// return $this;
// }
}

View File

@@ -0,0 +1,236 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Constraint\Rule;
use Symfony\Component\Intl\Exception\NotImplementedException;
use Thelia\Core\Translation\Translator;
use Thelia\Coupon\CouponAdapterInterface;
use Thelia\Constraint\Validator\ComparableInterface;
use Thelia\Constraint\Validator\RuleValidator;
use Thelia\Exception\InvalidRuleException;
use Thelia\Exception\InvalidRuleOperatorException;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* Assist in writing a condition of whether the Rule is applied or not
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
abstract class CouponRuleAbstract implements CouponRuleInterface
{
// /** Operator key in $validators */
// CONST OPERATOR = 'operator';
// /** Value key in $validators */
// CONST VALUE = 'value';
/** @var string Service Id from Resources/config.xml */
protected $serviceId = null;
/** @var array Available Operators (Operators::CONST) */
protected $availableOperators = array();
/** @var array Parameters validating parameters against */
protected $validators = array();
// /** @var array Parameters to be validated */
// protected $paramsToValidate = array();
/** @var CouponAdapterInterface Provide necessary value from Thelia */
protected $adapter = null;
/** @var Translator Service Translator */
protected $translator = null;
/** @var array Operators set by Admin in BackOffice */
protected $operators = array();
/** @var array Values set by Admin in BackOffice */
protected $values = array();
/**
* Constructor
*
* @param CouponAdapterInterface $adapter Service adapter
*/
function __construct(CouponAdapterInterface $adapter)
{
$this->adapter = $adapter;
$this->translator = $adapter->getTranslator();
}
// /**
// * Check validator relevancy and store them
// *
// * @param array $validators Array of RuleValidator
// * validating $paramsToValidate against
// *
// * @return $this
// * @throws InvalidRuleException
// */
// protected function setValidators(array $validators)
// {
// foreach ($validators as $validator) {
// if (!$validator instanceof RuleValidator) {
// throw new InvalidRuleException(get_class());
// }
// if (!in_array($validator->getOperator(), $this->availableOperators)) {
// throw new InvalidRuleOperatorException(
// get_class(),
// $validator->getOperator()
// );
// }
// }
// $this->validators = $validators;
//
// return $this;
// }
// /**
// * Check if the current Checkout matches this condition
// *
// * @return bool
// */
// public function isMatching()
// {
// $this->checkBackOfficeInput();
// $this->checkCheckoutInput();
//
// $isMatching = true;
// /** @var $validator RuleValidator*/
// foreach ($this->validators as $param => $validator) {
// $a = $this->paramsToValidate[$param];
// $operator = $validator->getOperator();
// /** @var ComparableInterface, RuleParameterAbstract $b */
// $b = $validator->getParam();
//
// if (!Operators::isValid($a, $operator, $b)) {
// $isMatching = false;
// }
// }
//
// return $isMatching;
//
// }
/**
* Return all available Operators for this Rule
*
* @return array Operators::CONST
*/
public function getAvailableOperators()
{
return $this->availableOperators;
}
// /**
// * Check if Operators set for this Rule in the BackOffice are legit
// *
// * @throws InvalidRuleOperatorException if Operator is not allowed
// * @return bool
// */
// protected function checkBackOfficeInputsOperators()
// {
// /** @var RuleValidator $param */
// foreach ($this->validators as $key => $param) {
// $operator = $param->getOperator();
// if (!isset($operator)
// ||!in_array($operator, $this->availableOperators)
// ) {
// throw new InvalidRuleOperatorException(get_class(), $key);
// }
// }
// return true;
// }
// /**
// * Generate current Rule param to be validated from adapter
// *
// * @throws \Thelia\Exception\NotImplementedException
// * @return $this
// */
// protected function setParametersToValidate()
// {
// throw new \Thelia\Exception\NotImplementedException();
// }
/**
* Return all validators
*
* @return array
*/
public function getValidators()
{
return array(
$this->operators,
$this->values
);
}
/**
* Get Rule Service id
*
* @return string
*/
public function getServiceId()
{
return $this->serviceId;
}
/**
* Validate if Operator given is available for this Coupon
*
* @param string $operator Operator to validate ex <
* @param array $availableOperators Available operators
*
* @return bool
*/
protected function isOperatorLegit($operator, array $availableOperators)
{
return in_array($operator, $availableOperators);
}
/**
* Return a serializable Rule
*
* @return SerializableRule
*/
public function getSerializableRule()
{
$serializableRule = new SerializableRule();
$serializableRule->ruleServiceId = $this->serviceId;
$serializableRule->operators = $this->operators;
$serializableRule->values = $this->values;
return $serializableRule;
}
}

View File

@@ -0,0 +1,144 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Constraint\Rule;
use Thelia\Core\Translation\Translator;
use Thelia\Coupon\CouponAdapterInterface;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* Represents a condition of whether the Rule is applied or not
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
interface CouponRuleInterface
{
/**
* Constructor
*
* @param CouponAdapterInterface $adapter Service adapter
*/
function __construct(CouponAdapterInterface $adapter);
/**
* Get Rule Service id
*
* @return string
*/
public function getServiceId();
// /**
// * Check if backoffice inputs are relevant or not
// *
// * @return bool
// */
// public function checkBackOfficeInput();
// /**
// * Check if Checkout inputs are relevant or not
// *
// * @return bool
// */
// public function checkCheckoutInput();
/**
* Check validators relevancy and store them
*
* @param array $operators Operators the Admin set in BackOffice
* @param array $values Values the Admin set in BackOffice
*
* @throws \InvalidArgumentException
* @return $this
*/
public function setValidatorsFromForm(array $operators, array $values);
// /**
// * Check if the current Checkout matches this condition
// *
// * @return bool
// */
// public function isMatching();
/**
* Test if Customer meets conditions
*
* @return bool
*/
public function isMatching();
/**
* Return all available Operators for this Rule
*
* @return array Operators::CONST
*/
public function getAvailableOperators();
/**
* Get I18n name
*
* @return string
*/
public function getName();
/**
* Get I18n tooltip
*
* @return string
*/
public function getToolTip();
/**
* Return all validators
*
* @return array
*/
public function getValidators();
// /**
// * Populate a Rule from a form admin
// *
// * @param array $operators Rule Operator set by the Admin
// * @param array $values Rule Values set by the Admin
// *
// * @return bool
// */
// public function populateFromForm(array$operators, array $values);
/**
* Return a serializable Rule
*
* @return SerializableRule
*/
public function getSerializableRule();
}

View File

@@ -0,0 +1,188 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Constraint\Rule;
use Symfony\Component\Translation\Translator;
use Thelia\Constraint\Validator\ComparableInterface;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* Represent available Operations in rule checking
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
abstract class Operators
{
/** Param1 is inferior to Param2 */
CONST INFERIOR = '<';
/** Param1 is inferior to Param2 */
CONST INFERIOR_OR_EQUAL = '<=';
/** Param1 is equal to Param2 */
CONST EQUAL = '==';
/** Param1 is superior to Param2 */
CONST SUPERIOR_OR_EQUAL = '>=';
/** Param1 is superior to Param2 */
CONST SUPERIOR = '>';
/** Param1 is different to Param2 */
CONST DIFFERENT = '!=';
/** Param1 is in Param2 */
CONST IN = 'in';
/** Param1 is not in Param2 */
CONST OUT = 'out';
// /**
// * Check if a parameter is valid against a ComparableInterface from its operator
// *
// * @param mixed $a Parameter to validate
// * @param string $operator Operator to validate against
// * @param ComparableInterface $b Comparable to validate against
// *
// * @return bool
// */
// public static function isValid($a, $operator, ComparableInterface $b)
// {
// $ret = false;
//
// try {
// $comparison = $b->compareTo($a);
// } catch (\Exception $e) {
// return false;
// }
//
// switch ($operator) {
// case self::INFERIOR:
// if ($comparison == 1) {
// return true;
// }
// break;
// case self::INFERIOR_OR_EQUAL:
// if ($comparison == 1 || $comparison == 0) {
// return true;
// }
// break;
// case self::EQUAL:
// if ($comparison == 0) {
// return true;
// }
// break;
// case self::SUPERIOR_OR_EQUAL:
// if ($comparison == -1 || $comparison == 0) {
// return true;
// }
// break;
// case self::SUPERIOR:
// if ($comparison == -1) {
// return true;
// }
// break;
// case self::DIFFERENT:
// if ($comparison != 0) {
// return true;
// }
// break;
// default:
// }
//
// return $ret;
// }
/**
* Get operator translation
*
* @param Translator $translator Provide necessary value from Thelia
* @param string $operator Operator const
*
* @return string
*/
public static function getI18n(Translator $translator, $operator)
{
$ret = $operator;
switch ($operator) {
case self::INFERIOR:
$ret = $translator->trans(
'inferior to',
array(),
'constraint'
);
break;
case self::INFERIOR_OR_EQUAL:
$ret = $translator->trans(
'inferior or equals to',
array(),
'constraint'
);
break;
case self::EQUAL:
$ret = $translator->trans(
'equals to',
array(),
'constraint'
);
break;
case self::SUPERIOR_OR_EQUAL:
$ret = $translator->trans(
'superior or equals to',
array(),
'constraint'
);
break;
case self::SUPERIOR:
$ret = $translator->trans(
'superior to',
array(),
'constraint'
);
break;
case self::DIFFERENT:
$ret = $translator->trans(
'different from',
array(),
'constraint'
);
break;
case self::IN:
$ret = $translator->trans(
'in',
array(),
'constraint'
);
break;
case self::OUT:
$ret = $translator->trans(
'not in',
array(),
'constraint'
);
break;
default:
}
return $ret;
}
}

View File

@@ -0,0 +1,81 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Constraint\Rule;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* A rule set by an admin ready to be serialized and stored in DataBase
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class SerializableRule
{
/** @var string Rule Service id */
public $ruleServiceId = null;
/** @var array Operators set by Admin for this Rule */
public $operators = array();
/** @var array Values set by Admin for this Rule */
public $values = array();
/**
* Get Operators set by Admin for this Rule
*
* @return array
*/
public function getOperators()
{
return $this->operators;
}
/**
* Get Rule Service id
*
* @return string
*/
public function getRuleServiceId()
{
return $this->ruleServiceId;
}
/**
* Get Values set by Admin for this Rule
*
* @return array
*/
public function getValues()
{
return $this->values;
}
}

View File

@@ -0,0 +1,49 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Constraint\Validator;
/**
* Comparable interface
* Allows to compare two value objects to each other for similarity.
*
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
*/
interface ComparableInterface
{
/**
* Compare the current object to the passed $other.
*
* Returns 0 if they are semantically equal, 1 if the other object
* is less than the current one, or -1 if its more than the current one.
*
* This method should not check for identity using ===, only for semantically equality for example
* when two different DateTime instances point to the exact same Date + TZ.
*
* @param mixed $other Object
*
* @return int
*/
public function compareTo($other);
}

View File

@@ -0,0 +1,158 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Constraint\Validator;
use InvalidArgumentException;
use Propel\Runtime\ActiveQuery\ModelCriteria;
use Thelia\Coupon\CouponAdapterInterface;
use Thelia\Model\Customer;
use Thelia\Model\CustomerQuery;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* Represent a Customer
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class CustomerParam extends IntegerParam
{
/** @var string Model Class name */
protected $modelClass = '\Thelia\Model\Customer';
/** @var ModelCriteria */
protected $queryBuilder = null;
/** @var string Customer firstname */
protected $firstName = null;
/** @var string Customer lastname */
protected $lastName = null;
/** @var string Customer email */
protected $email = null;
/**
* Constructor
*
* @param CouponAdapterInterface $adapter Provide necessary value from Thelia
* @param int $integer Integer
*
* @throws InvalidArgumentException
*/
public function __construct(CouponAdapterInterface $adapter, $integer)
{
$this->integer = $integer;
$this->adapter = $adapter;
$this->queryBuilder = CustomerQuery::create();
/** @var Customer $customer */
$customer = $this->queryBuilder->findById($integer);
if ($customer !== null) {
$this->firstName = $customer->getFirstname();
$this->lastName = $customer->getLastname();
$this->email = $customer->getEmail();
} else {
throw new \InvalidArgumentException(
'CustomerParam can compare only existing Customers'
);
}
}
/**
* Compare the current object to the passed $other.
*
* Returns 0 if they are semantically equal, 1 if the other object
* is less than the current one, or -1 if its more than the current one.
*
* This method should not check for identity using ===, only for semantically equality for example
* when two different DateTime instances point to the exact same Date + TZ.
*
* @param mixed $other Object
*
* @throws InvalidArgumentException
* @return int
*/
public function compareTo($other)
{
if (!is_integer($other) || $other < 0) {
throw new InvalidArgumentException(
'IntegerParam can compare only positive int'
);
}
return parent::compareTo($other);
}
/**
* Customer email
*
* @return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Customer first name
*
* @return string
*/
public function getFirstName()
{
return $this->firstName;
}
/**
* Customer last name
*
* @return string
*/
public function getLastName()
{
return $this->lastName;
}
/**
* Get I18n tooltip
*
* @return string
*/
public function getToolTip()
{
return $this->adapter
->getTranslator()
->trans(
'A Customer',
null,
'constraint'
);
}
}

View File

@@ -0,0 +1,120 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Constraint\Validator;
use Thelia\Coupon\CouponAdapterInterface;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* Represent a DateTime
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class DateParam extends RuleParameterAbstract
{
/** @var \DateTime Date */
protected $dateTime = null;
/**
* Constructor
*
* @param CouponAdapterInterface $adapter Provide necessary value from Thelia
* @param \DateTime $dateTime DateTime
*/
public function __construct(CouponAdapterInterface $adapter, \DateTime $dateTime)
{
$this->dateTime = $dateTime;
$this->adapter = $adapter;
}
/**
* Get DateTime
*
* @return \DateTime
*/
public function getDateTime()
{
return clone $this->dateTime;
}
/**
* Compare the current object to the passed $other.
*
* Returns 0 if they are semantically equal, 1 if the other object
* is less than the current one, or -1 if its more than the current one.
*
* This method should not check for identity using ===, only for semantically equality for example
* when two different DateTime instances point to the exact same Date + TZ.
*
* @param mixed $other Object
*
* @throws \InvalidArgumentException
* @return int
*/
public function compareTo($other)
{
if (!$other instanceof \DateTime) {
throw new \InvalidArgumentException('DateParam can compare only DateTime');
}
$ret = -1;
if ($this->dateTime == $other) {
$ret = 0;
} elseif ($this->dateTime > $other) {
$ret = 1;
} else {
$ret = -1;
}
return $ret;
}
/**
* Get Parameter value to test against
*
* @return \Datetime
*/
public function getValue()
{
return clone $this->dateTime;
}
/**
* Get I18n tooltip
*
* @return string
*/
public function getToolTip()
{
return $this->adapter
->getTranslator()
->trans('A date (ex: YYYY-MM-DD HH:MM:SS)', null, 'constraint');
}
}

View File

@@ -0,0 +1,121 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Constraint\Validator;
use Thelia\Coupon\CouponAdapterInterface;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* Represent an Integer
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class IntegerParam extends RuleParameterAbstract
{
/** @var int Integer to compare with */
protected $integer = 0;
/**
* Constructor
*
* @param CouponAdapterInterface $adapter Provide necessary value from Thelia
* @param int $integer Integer
*/
public function __construct(CouponAdapterInterface $adapter, $integer)
{
$this->integer = $integer;
$this->adapter = $adapter;
}
/**
* Get integer
*
* @return int
*/
public function getInteger()
{
return $this->integer;
}
/**
* Compare the current object to the passed $other.
*
* Returns 0 if they are semantically equal, 1 if the other object
* is less than the current one, or -1 if its more than the current one.
*
* This method should not check for identity using ===, only for semantically equality for example
* when two different DateTime instances point to the exact same Date + TZ.
*
* @param mixed $other Object
*
* @throws \InvalidArgumentException
* @return int
*/
public function compareTo($other)
{
if (!is_integer($other)) {
throw new \InvalidArgumentException('IntegerParam can compare only int');
}
$ret = -1;
if ($this->integer == $other) {
$ret = 0;
} elseif ($this->integer > $other) {
$ret = 1;
} else {
$ret = -1;
}
return $ret;
}
/**
* Get Parameter value to test against
*
* @return int
*/
public function getValue()
{
return $this->integer;
}
/**
* Get I18n tooltip
*
* @return string
*/
public function getToolTip()
{
return $this->adapter
->getTranslator()
->trans('A number (ex: 42)', null, 'constraint');
}
}

View File

@@ -0,0 +1,165 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Constraint\Validator;
use Thelia\Coupon\CouponAdapterInterface;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* Represent an DateTime period
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class IntervalParam extends RuleParameterAbstract
{
/** @var \DatePeriod Date period */
protected $datePeriod = null;
/** @var \DateTime Start date */
protected $start = null;
/** @var \DateInterval Interval date */
protected $interval = null;
/**
* Constructor
*
* @param CouponAdapterInterface $adapter Provide necessary value from Thelia
* @param \DateTime $start Start interval
* @param \DateInterval $interval Period
*/
public function __construct(CouponAdapterInterface $adapter, \DateTime $start, \DateInterval $interval)
{
$this->datePeriod = new \DatePeriod($start, $interval, 1);
$this->adapter = $adapter;
$this->start = $start;
$this->interval = $interval;
}
/**
* Get Interval
*
* @return \DateInterval
*/
public function getInterval()
{
return $this->interval;
}
/**
* Get start date
*
* @return \DateTime
*/
public function getStart()
{
return $this->start;
}
/**
* Get DatePeriod
*
* @return \DatePeriod
*/
public function getDatePeriod()
{
return clone $this->datePeriod;
}
/**
* Compare the current object to the passed $other.
*
* Returns 0 if they are semantically equal, 1 if the other object
* is less than the current one, or -1 if its more than the current one.
*
* This method should not check for identity using ===, only for semantically equality for example
* when two different DateTime instances point to the exact same Date + TZ.
*
* @param mixed $other Object
*
* @throws \InvalidArgumentException
* @return int
*/
public function compareTo($other)
{
if (!$other instanceof \DateTime) {
throw new \InvalidArgumentException('IntervalParam can compare only DateTime');
}
/** @var \DateTime Start Date */
$startDate = null;
/** @var \DateTime End Date */
$endDate = null;
foreach ($this->datePeriod as $key => $value) {
if ($key == 0) {
$startDate = $value;
}
if ($key == 1) {
$endDate = $value;
}
}
$ret = -1;
if ($startDate <= $other && $other <= $endDate) {
$ret = 0;
} elseif ($startDate > $other) {
$ret = 1;
} else {
$ret = -1;
}
return $ret;
}
/**
* Get Parameter value to test against
*
* @return \DatePeriod
*/
public function getValue()
{
return clone $this->datePeriod;
}
/**
* Get I18n tooltip
*
* @return string
*/
public function getToolTip()
{
return $this->adapter
->getTranslator()
->trans('An interval between two dates', null, 'constraint');
}
}

View File

@@ -0,0 +1,115 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Constraint\Validator;
use InvalidArgumentException;
use Thelia\Coupon\CouponAdapterInterface;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* Represent a Model
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class ModelParam extends IntegerParam
{
/** @var string Model Class name */
protected $modelClass = null;
/** @var ModelCriteria */
protected $queryBuilder = null;
/**
* Constructor
*
* @param CouponAdapterInterface $adapter Provide necessary value from Thelia
* @param int $integer Integer
* @param string $modelClass Model class name
*
* @throws InvalidArgumentException
*/
public function __construct(CouponAdapterInterface $adapter, $integer, $modelClass)
{
if ($integer < 0) {
$integer = 0;
}
$this->integer = $integer;
$this->adapter = $adapter;
$this->modelClass = $modelClass;
$queryClassName = $modelClass . 'Query';
try {
$this->queryBuilder = $queryClassName::create();
} catch (\Exception $e) {
throw new InvalidArgumentException('ModelParam can only compare Models');
}
}
/**
* Compare the current object to the passed $other.
*
* Returns 0 if they are semantically equal, 1 if the other object
* is less than the current one, or -1 if its more than the current one.
*
* This method should not check for identity using ===, only for semantically equality for example
* when two different DateTime instances point to the exact same Date + TZ.
*
* @param mixed $other Object
*
* @throws InvalidArgumentException
* @return int
*/
public function compareTo($other)
{
if (!is_integer($other) || $other < 0) {
throw new InvalidArgumentException(
'IntegerParam can compare only positive int'
);
}
return parent::compareTo($other);
}
/**
* Get I18n tooltip
*
* @return string
*/
public function getToolTip()
{
return $this->adapter
->getTranslator()
->trans(
'A Model',
null,
'constraint'
);
}
}

View File

@@ -0,0 +1,145 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Constraint\Validator;
use Thelia\Core\Translation\Translator;
use Thelia\Coupon\CouponAdapterInterface;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* Represent a Price
* Positive value with currency
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class PriceParam extends RuleParameterAbstract
{
/** @var float Positive Float to compare with */
protected $price = null;
/** @var string Currency Code ISO 4217 EUR|USD|GBP */
protected $currency = null;
/**
* Constructor
*
* @param Translator $translator Service translator
* @param float $price Positive float
* @param string $currency Currency Code ISO 4217 EUR|USD|GBP
*/
public function __construct(Translator $translator, $price, $currency)
{
$this->price = $price;
$this->currency = $currency;
$this->translator = $translator;
}
/**
* Get currency code
*
* @return string
*/
public function getCurrency()
{
return $this->currency;
}
/**
* Get price
*
* @return float
*/
public function getPrice()
{
return $this->price;
}
/**
* Compare the current object to the passed $other.
*
* Returns 0 if they are semantically equal, 1 if the other object
* is less than the current one, or -1 if its more than the current one.
*
* This method should not check for identity using ===, only for semantically equality for example
* when two different DateTime instances point to the exact same Date + TZ.
*
* @param mixed $other Object
*
* @throws \InvalidArgumentException
* @return int
*/
public function compareTo($other)
{
if (!is_float($other)) {
throw new \InvalidArgumentException(
'PriceParam can compare only positive float'
);
}
$epsilon = 0.00001;
$ret = -1;
if (abs($this->price - $other) < $epsilon) {
$ret = 0;
} elseif ($this->price > $other) {
$ret = 1;
} else {
$ret = -1;
}
return $ret;
}
/**
* Get Parameter value to test against
*
* @return float
*/
public function getValue()
{
return $this->price;
}
/**
* Get I18n tooltip
*
* @return string
*/
public function getToolTip()
{
return $this->translator
->trans(
'A price in %currency% (ex: 14.50)',
array(
'%currency%' => $this->currency
),
'constraint'
);
}
}

View File

@@ -0,0 +1,96 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Constraint\Validator;
use Thelia\Coupon\CouponAdapterInterface;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* Represent a Quantity
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class QuantityParam extends IntegerParam
{
/**
* Constructor
*
* @param CouponAdapterInterface $adapter Provide necessary value from Thelia
* @param int $integer Integer
*/
public function __construct(CouponAdapterInterface $adapter, $integer)
{
$this->integer = $integer;
$this->adapter = $adapter;
}
/**
* Compare the current object to the passed $other.
*
* Returns 0 if they are semantically equal, 1 if the other object
* is less than the current one, or -1 if its more than the current one.
*
* This method should not check for identity using ===, only for semantically equality for example
* when two different DateTime instances point to the exact same Date + TZ.
*
* @param mixed $other Object
*
* @throws \InvalidArgumentException
* @return int
*/
public function compareTo($other)
{
if (!is_integer($other) || $other < 0) {
throw new \InvalidArgumentException(
'IntegerParam can compare only positive int'
);
}
return parent::compareTo($other);
}
/**
* Get I18n tooltip
*
* @return string
*/
public function getToolTip()
{
return $this->adapter
->getTranslator()
->trans(
'A positive quantity (ex: 42)',
null,
'constraint'
);
}
}

View File

@@ -0,0 +1,117 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Constraint\Validator;
use Thelia\Coupon\CouponAdapterInterface;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* Represent A repeated Date across the time
* Ex :
* A date repeated every 1 months 5 times
* ---------*---*---*---*---*---*---------------------------> time
* 1 2 3 4 5 6
* 1 : $this->from Start date of the repetition
* *--- : $this->interval Duration of a whole cycle
* x5 : $this->recurrences How many repeated cycle, 1st excluded
* x6 : How many occurrence
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class RepeatedDateParam extends RepeatedParam
{
/**
* Constructor
*
* @param CouponAdapterInterface $adapter Provide necessary value from Thelia
*/
public function __construct(CouponAdapterInterface $adapter)
{
$this->defaultConstructor();
$this->adapter = $adapter;
}
/**
* Compare the current object to the passed $other.
*
* Returns 0 if they are semantically equal, 1 if the other object
* is less than the current one, or -1 if its more than the current one.
*
* This method should not check for identity using ===, only for semantically equality for example
* when two different DateTime instances point to the exact same Date + TZ.
*
* @param mixed $other Object
*
* @throws \InvalidArgumentException
* @return int
*/
public function compareTo($other)
{
if (!$other instanceof \DateTime) {
throw new \InvalidArgumentException('RepeatedDateParam can compare only DateTime');
}
$ret = -1;
$dates = array();
/** @var $value \DateTime */
foreach ($this->datePeriod as $value) {
$dates[$value->getTimestamp()] = $value;
}
foreach ($dates as $date) {
if ($date == $other) {
return 0;
}
}
return $ret;
}
/**
* Get Parameter value to test against
*
* @return \DatePeriod
*/
public function getValue()
{
return clone $this->datePeriod;
}
/**
* Get I18n tooltip
*
* @return string
*/
public function getToolTip()
{
return $this->adapter
->getTranslator()
->trans('A date (ex: YYYY-MM-DD HH:MM:SS)', null, 'constraint');
}
}

View File

@@ -0,0 +1,151 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Constraint\Validator;
use Thelia\Coupon\CouponAdapterInterface;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* Represent A repeated DateInterval across the time
* Ex :
* A duration of 1 month repeated every 2 months 5 times
* ---------****----****----****----****----****----****-----------------> time
* 1 2 3 4 5 6
* 1 : $this->from Start date of the repetition
* ****---- : $this->interval Duration of a whole cycle
* x5 : $this->recurrences How many repeated cycle, 1st excluded
* x6 : How many occurrence
* **** : $this->durationInDays Duration of a period
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class RepeatedIntervalParam extends RepeatedParam
{
/** @var int duration of the param */
protected $durationInDays = 1;
/**
* Get how many day a Param is lasting
*
* @return int
*/
public function getDurationInDays()
{
return $this->durationInDays;
}
/**
* Set how many day a Param is lasting
*
* @param int $durationInDays How many day a Param is lasting
*
* @return $this
*/
public function setDurationInDays($durationInDays = 1)
{
$this->durationInDays = $durationInDays;
return $this;
}
/**
* Constructor
*
* @param CouponAdapterInterface $adapter Provide necessary value from Thelia
*/
public function __construct(CouponAdapterInterface $adapter)
{
$this->defaultConstructor();
$this->adapter = $adapter;
}
/**
* Compare the current object to the passed $other.
*
* Returns 0 if they are semantically equal, 1 if the other object
* is less than the current one, or -1 if its more than the current one.
*
* This method should not check for identity using ===, only for semantically equality for example
* when two different DateTime instances point to the exact same Date + TZ.
*
* @param mixed $other Object
*
* @throws \InvalidArgumentException
* @return int
*/
public function compareTo($other)
{
if (!$other instanceof \DateTime) {
throw new \InvalidArgumentException('RepeatedIntervalParam can compare only DateTime');
}
$ret = -1;
$dates = array();
/** @var $value \DateTime */
foreach ($this->datePeriod as $value) {
$dates[$value->getTimestamp()]['startDate'] = $value;
$endDate = new \DateTime();
$dates[$value->getTimestamp()]['endDate'] = $endDate->setTimestamp(
$value->getTimestamp() + ($this->durationInDays * 60 *60 *24)
);
}
foreach ($dates as $date) {
if ($date['startDate'] <= $other && $other <= $date['endDate']) {
return 0;
}
}
return $ret;
}
/**
* Get Parameter value to test against
*
* @return \DatePeriod
*/
public function getValue()
{
return clone $this->datePeriod;
}
/**
* Get I18n tooltip
*
* @return string
*/
public function getToolTip()
{
return $this->adapter
->getTranslator()
->trans('A date (ex: YYYY-MM-DD HH:MM:SS)', null, 'constraint');
}
}

View File

@@ -0,0 +1,297 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Constraint\Validator;
use DateInterval;
use DatePeriod;
use DateTime;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* Allow to set the way a parameter can be repeated across the time
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
abstract class RepeatedParam extends RuleParameterAbstract
{
/** @var DateTime The start date of the period. */
protected $from = null;
/** @var DateInterval The interval between recurrences within the period. */
protected $interval = null;
/** @var int Nb time the object will be repeated (1st occurrence excluded). */
protected $recurrences = null;
/** @var DatePeriod dates recurring at regular intervals, over a given period */
protected $datePeriod = null;
/** @var int Frequency the object will be repeated */
protected $frequency = null;
/** @var int $nbRepetition Time the object will be repeated */
protected $nbRepetition = null;
/**
* Get frequency
*
* @return int
*/
public function getFrequency()
{
return $this->frequency;
}
/**
* Get Interval
*
* @return \DateInterval
*/
public function getInterval()
{
return $this->interval;
}
/**
* Get number of time it will be repeated
*
* @return int
*/
public function getNbRepetition()
{
return $this->nbRepetition;
}
/**
* Get number of recurrences
*
* @return int
*/
public function getRecurrences()
{
return $this->recurrences;
}
/**
* Generate default repetition
* Every 1 week 100 times from now
*
* @return $this
*/
protected function defaultConstructor()
{
$this->from = new \DateTime();
$this->interval = new \DateInterval('P1W'); // 1 week
$this->recurrences = 100;
$this->generateDatePeriod();
return $this;
}
/**
* Generate DatePeriod from class attributes
* Will repeat every DatePeriod
*
* @return $this
*/
protected function generateDatePeriod()
{
$this->datePeriod = new DatePeriod(
$this->from,
$this->interval,
$this->recurrences
);
return $this;
}
/**
* Set the Object to be repeated every days
* Ex : $obj->repeatEveryDay() will occur once
* $obj->repeatEveryDay(10) will occur once
* $obj->repeatEveryDay(10, 0) will occur once
* $obj->repeatEveryDay(10, 4) will occur every 10 days 5 times
*
* @param int $frequency Frequency the object will be repeated
* @param int $nbRepetition Time the object will be repeated
*
* @return $this
*/
public function repeatEveryDay($frequency = 1, $nbRepetition = 0)
{
$this->_repeatEveryPeriod($period = 'D', $frequency, $nbRepetition);
return $this;
}
/**
* Set the Object to be repeated every week
* Ex : $obj->repeatEveryWeek() will occur once
* $obj->repeatEveryWeek(10) will occur once
* $obj->repeatEveryWeek(10, 0) will occur once
* $obj->repeatEveryWeek(10, 4) will occur every 10 weeks (70days) 5 times
*
* @param int $frequency Frequency the object will be repeated
* @param int $nbRepetition Time the object will be repeated
*
* @return $this
*/
public function repeatEveryWeek($frequency = 1, $nbRepetition = 0)
{
$this->_repeatEveryPeriod($period = 'W', $frequency, $nbRepetition);
return $this;
}
/**
* Set the Object to be repeated every month
* Ex : $obj->repeatEveryWeek() will occur once
* $obj->repeatEveryWeek(10) will occur once
* $obj->repeatEveryWeek(10, 0) will occur once
* $obj->repeatEveryWeek(10, 4) will occur every 10 month (70days) 5times
*
* @param int $frequency Frequency the object will be repeated
* @param int $nbRepetition Time the object will be repeated
*
* @return $this
*/
public function repeatEveryMonth($frequency = 1, $nbRepetition = 0)
{
$this->_repeatEveryPeriod($period = 'M', $frequency, $nbRepetition);
return $this;
}
/**
* Set the Object to be repeated every year
* Ex : $obj->repeatEveryWeek() will occur once
* $obj->repeatEveryWeek(10) will occur once
* $obj->repeatEveryWeek(10, 0) will occur once
* $obj->repeatEveryWeek(10, 4) will occur every 10 year 5 times
*
* @param int $frequency Frequency the object will be repeated
* @param int $nbRepetition Time the object will be repeated
*
* @return $this
*/
public function repeatEveryYear($frequency = 1, $nbRepetition = 0)
{
$this->_repeatEveryPeriod($period = 'Y', $frequency, $nbRepetition);
return $this;
}
/**
* Set the Object to be repeated every Period
* Ex : $obj->repeatEveryPeriod('D') will occur once
* $obj->repeatEveryPeriod('W', 10) will occur once
* $obj->repeatEveryPeriod('W', 10, 0) will occur once
* $obj->repeatEveryPeriod('M', 10, 4) will occur every 10 month 5 times
*
* @param string $period Period Y|M||D|W
* @param int $frequency Frequency the object will be repeated
* @param int $nbRepetition Time the object will be repeated
*
* @return $this
*/
private function _repeatEveryPeriod($period, $frequency = 1, $nbRepetition = 0)
{
if (is_numeric($frequency) && $frequency > 0) {
$this->interval = new \DateInterval('P' . $frequency . $period);
}
if (is_numeric($nbRepetition) && $nbRepetition >= 0) {
$this->recurrences = $nbRepetition;
}
$this->generateDatePeriod();
return $this;
}
/**
* Set Start time
*
* @param \DateTime $from Start time
*
* @return $this
*/
public function setFrom($from)
{
$this->from = $from;
return $this;
}
/**
* Get Start time
*
* @return \DateTime
*/
public function getFrom()
{
return clone $this->from;
}
/**
* Set DatePeriod
*
* @param DatePeriod $datePeriod DatePeriod
*
* @return $this
*/
public function setDatePeriod(DatePeriod $datePeriod)
{
$this->datePeriod = $datePeriod;
return $this;
}
/**
* Get date DatePeriod
*
* @return \DatePeriod
*/
public function getDatePeriod()
{
return clone $this->datePeriod;
}
/**
* Get Parameter value to test against
*
* @return \DatePeriod
*/
public function getValue()
{
return clone $this->datePeriod;
}
}

View File

@@ -0,0 +1,67 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Constraint\Validator;
use Thelia\Core\Translation\Translator;
use Thelia\Coupon\CouponAdapterInterface;
use Thelia\Exception\NotImplementedException;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* Get a Param value
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
abstract class RuleParameterAbstract implements ComparableInterface
{
/** @var Translator Service Translator */
protected $translator = null;
/**
* Get Parameter value to test against
*
* @return mixed
*/
public function getValue()
{
return new NotImplementedException();
}
/**
* Get I18n tooltip
*
* @return string
*/
public function getToolTip()
{
return new NotImplementedException();
}
}

View File

@@ -0,0 +1,77 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Constraint\Validator;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* Allow to validate parameters
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class RuleValidator
{
/** @var string Operator ex: Operators::INFERIOR */
protected $operator = null;
/** @var ComparableInterface Validator */
protected $param = null;
/**
* Constructor
*
* @param string $operator Operator ex: Operators::INFERIOR
* @param ComparableInterface $param Validator ex: PriceParam
*/
function __construct($operator, ComparableInterface $param)
{
$this->operator = $operator;
$this->param = $param;
}
/**
* Get Validator Operator
*
* @return string
*/
public function getOperator()
{
return $this->operator;
}
/**
* Get Validator Param
*
* @return ComparableInterface
*/
public function getParam()
{
return $this->param;
}
}

View File

@@ -29,10 +29,4 @@ class AdminController extends BaseAdminController
{
return $this->render("home");
}
public function processAction()
{
echo "not yet coded !";
exit();
}
}

View File

@@ -0,0 +1,63 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Controller\Admin;
use Thelia\Core\Event\MessageDeleteEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Tools\URL;
use Thelia\Core\Event\MessageUpdateEvent;
use Thelia\Core\Event\MessageCreateEvent;
use Thelia\Log\Tlog;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Core\Security\Exception\AuthorizationException;
use Thelia\Model\MessageQuery;
use Thelia\Form\MessageModificationForm;
use Thelia\Form\MessageCreationForm;
/**
* Manages messages sent by mail
*
* @author Franck Allimant <franck@cqfdev.fr>
*/
class AttributeController extends BaseAdminController
{
/**
* The default action is displaying the attributes list.
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
public function defaultAction() {
if (null !== $response = $this->checkAuth("admin.configuration.attributes.view")) return $response;
return $this->render('product-attributes');
}
public function updateAction() {
if (null !== $response = $this->checkAuth("admin.configuration.attributes.update")) return $response;
return $this->render('product-attributes-edit');
}
}

199
core/lib/Thelia/Controller/Admin/BaseAdminController.php Normal file → Executable file
View File

@@ -22,6 +22,9 @@
/*************************************************************************************/
namespace Thelia\Controller\Admin;
use Symfony\Component\Routing\Exception\InvalidParameterException;
use Symfony\Component\Routing\Exception\MissingMandatoryParametersException;
use Symfony\Component\Routing\Exception\RouteNotFoundException;
use Thelia\Controller\BaseController;
use Symfony\Component\HttpFoundation\Response;
use Thelia\Core\Security\Exception\AuthorizationException;
@@ -30,22 +33,46 @@ 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;
use Thelia\Model\Lang;
use Thelia\Model\LangQuery;
use Thelia\Form\BaseForm;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Log\Tlog;
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());
}
/**
* This method process the rendering of view called from an admin page
*
* @param unknown $template
* @return Response the reponse which contains the rendered view
*/
public function processTemplateAction($template)
{
try {
if (! empty($template)) {
// If we have a view in the URL, render this view
return $this->render($template);
} elseif (null != $view = $this->getRequest()->get('view')) {
}
elseif (null != $view = $this->getRequest()->get('view')) {
return $this->render($view);
}
} catch (\Exception $ex) {
// Nothing special
}
catch (\Exception $ex) {
return $this->errorPage($ex->getMessage());
}
return $this->pageNotFound();
@@ -64,10 +91,16 @@ class BaseAdminController extends BaseController
/**
* Return a general error page
*
* @param mixed $message a message string, or an exception instance
*
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function errorPage($message)
{
if ($message instanceof \Exception) {
$message = sprintf($this->getTranslator()->trans("Sorry, an error occured: %msg"), array('msg' => $message->getMessage()));
}
return $this->render('general_error', array(
"error_message" => $message)
);
@@ -76,19 +109,80 @@ class BaseAdminController extends BaseController
/**
* Check current admin user authorisations. An ADMIN role is assumed.
*
* @param unknown $permissions a single permission or an array of permissions.
* @param mixed $permissions a single permission or an array of permissions.
*
* @return mixed null if authorization is granted, or a Response object which contains the error page otherwise
*
* @throws AuthenticationException if permissions are not granted ti the current user.
*/
protected function checkAuth($permissions)
{
if (! $this->getSecurityContext()->isGranted(array("ADMIN"), is_array($permissions) ? $permissions : array($permissions))) {
throw new AuthorizationException("Sorry, you're not allowed to perform this action");
$permArr = is_array($permissions) ? $permissions : array($permissions);
if ($this->getSecurityContext()->isGranted(array("ADMIN"), $permArr)) {
// Okay !
return null;
}
// Log the problem
$this->adminLogAppend("User is not granted for permissions %s", implode(", ", $permArr));
// Generate the proper response
$response = new Response();
return $this->errorPage($this->getTranslator()->trans("Sorry, you're not allowed to perform this action"));
}
/*
* Create the standard message displayed to the user when the form cannot be validated.
*/
protected function createStandardFormValidationErrorMessage(FormValidationException $exception) {
return $this->getTranslator()->trans(
"Please check your input: %error",
array(
'%error' => $exception->getMessage()
)
);
}
/**
* Setup the error context when an error occurs in a action method.
*
* @param string $action the action that caused the error (category modification, variable creation, currency update, etc.)
* @param BaseForm $form the form where the error occured, or null if no form was involved
* @param string $error_message the error message
* @param Exception $exception the exception or null if no exception
*/
protected function setupFormErrorContext($action, $error_message, BaseForm $form = null, \Exception $exception = null) {
if ($error_message !== false) {
// Log the error message
Tlog::getInstance()->error(
$this->getTranslator()->trans(
"Error during %action process : %error. Exception was %exc",
array(
'%action' => $action,
'%error' => $error_message,
'%exc' => $exception != null ? $exception->getMessage() : 'no exception'
)
)
);
if ($form != null) {
// Mark the form as errored
$form->setErrorMessage($error_message);
// Pass it to the parser context
$this->getParserContext()->addForm($form);
}
// Pass the error message to the parser.
$this->getParserContext()->setGeneralError($error_message);
}
}
/**
* @return a ParserInterfac instance parser
* @return a ParserInterface instance parser
*/
protected function getParser()
{
@@ -117,6 +211,65 @@ class BaseAdminController extends BaseController
return $this->container->get('http_kernel')->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
}
/**
* Return the route path defined for the givent route ID
*
* @param string $routeId a route ID, as defines in Config/Resources/routing/admin.xml
* @param mixed $parameters An array of parameters
* @param Boolean|string $referenceType The type of reference to be generated (one of the constants)
*
* @throws RouteNotFoundException If the named route doesn't exist
* @throws MissingMandatoryParametersException When some parameters are missing that are mandatory for the route
* @throws InvalidParameterException When a parameter value for a placeholder is not correct because
* it does not match the requirement
* @throws \InvalidArgumentException When the router doesn't exist
* @return string The generated URL
*
* @see \Thelia\Controller\BaseController::getRouteFromRouter()
*/
protected function getRoute($routeId, $parameters = array(), $referenceType = Router::ABSOLUTE_PATH) {
return $this->getRouteFromRouter(
'router.admin',
$routeId,
$parameters,
$referenceType
);
}
/**
* Redirect to à route ID related URL
*
* @param unknown $routeId the route ID, as found in Config/Resources/routing/admin.xml
* @param unknown $urlParameters the URL parametrs, as a var/value pair array
*/
public function redirectToRoute($routeId, $urlParameters = array()) {
$this->redirect(URL::getInstance()->absoluteUrl($this->getRoute($routeId), $urlParameters));
}
/**
* Get the current edition lang ID, checking if a change was requested in the current request.
*/
protected function getCurrentEditionLang() {
// Return the new language if a change is required.
if (null !== $edit_language_id = $this->getRequest()->get('edit_language_id', null)) {
if (null !== $edit_language = LangQuery::create()->findOneById($edit_language_id)) {
return $edit_language;
}
}
// Otherwise return the lang stored in session.
return $this->getSession()->getAdminEditionLang();
}
/**
* A simple helper to get the current edition locale.
*/
protected function getCurrentEditionLocale() {
return $this->getCurrentEditionLang()->getLocale();
}
/**
* Render the given template, and returns the result as an Http Response.
*
@@ -140,26 +293,44 @@ class BaseAdminController extends BaseController
*/
protected function renderRaw($templateName, $args = array())
{
// Add the template standard extension
$templateName .= '.html';
$session = $this->getSession();
// Find the current edit language ID
$edition_language = $this->getCurrentEditionLang();
// Prepare common template variables
$args = array_merge($args, array(
'locale' => $session->getLocale(),
'lang' => $session->getLang()
'locale' => $session->getLang()->getLocale(),
'lang_code' => $session->getLang()->getCode(),
'lang_id' => $session->getLang()->getId(),
'edit_language_id' => $edition_language->getId(),
'edit_language_locale' => $edition_language->getLocale(),
'current_url' => htmlspecialchars($this->getRequest()->getUri())
));
// Update the current edition language in session
$this->getSession()->setAdminEditionLang($edition_language);
// Render the template.
try {
$data = $this->getParser()->render($templateName, $args);
return $data;
} catch (AuthenticationException $ex) {
}
catch (AuthenticationException $ex) {
// User is not authenticated, and templates requires authentication -> redirect to login page
// We user login_tpl as a path, not a template.
Redirect::exec(URL::absoluteUrl($ex->getLoginTemplate()));
Redirect::exec(URL::getInstance()->absoluteUrl($ex->getLoginTemplate()));
}
catch (AuthorizationException $ex) {
// User is not allowed to perform the required action. Return the error page instead of the requested page.
return $this->errorPage($this->getTranslator()->trans("Sorry, you are not allowed to perform this action."));
}
}
}

388
core/lib/Thelia/Controller/Admin/CategoryController.php Normal file → Executable file
View File

@@ -25,126 +25,314 @@ 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;
use Thelia\Model\Lang;
use Thelia\Core\Translation\Translator;
use Thelia\Core\Event\CategoryUpdatePositionEvent;
use Thelia\Model\CategoryQuery;
use Thelia\Form\CategoryModificationForm;
class CategoryController extends BaseAdminController
{
protected function createNewCategory($args)
{
$this->dispatchEvent("createCategory");
// At this point, the form has error, and should be redisplayed.
return $this->render('categories', $args);
/**
* Render the categories list, ensuring the sort order is set.
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
protected function renderList() {
return $this->render('categories', $this->getTemplateArgs());
}
protected function editCategory($args)
{
$this->checkAuth("ADMIN", "admin.category.edit");
return $this->render('edit_category', $args);
}
protected function deleteCategory($args)
{
$this->dispatchEvent("deleteCategory");
// Something was wrong, category was not deleted. Display parent category list
return $this->render('categories', $args);
}
protected function browseCategory($args)
{
$this->checkAuth("AMIN", "admin.catalog.view");
return $this->render('categories', $args);
}
protected function visibilityToggle($args)
{
$this->dispatchEvent("toggleCategoryVisibility");
return $this->nullResponse();
}
protected function changePosition($args)
{
$this->dispatchEvent("changeCategoryPosition");
return $this->render('categories', $args);
}
protected function positionDown($args)
{
$this->dispatchEvent("changeCategoryPositionDown");
return $this->render('categories', $args);
}
protected function positionUp($args)
{
$this->dispatchEvent("changeCategoryPositionUp");
return $this->render('categories', $args);
}
public function indexAction()
{
return $this->processAction();
}
public function processAction()
{
// Get the current action
$action = $this->getRequest()->get('action', 'browse');
protected function getTemplateArgs() {
// Get the category ID
$id = $this->getRequest()->get('id', 0);
$category_id = $this->getRequest()->get('category_id', 0);
$args = array(
'action' => $action,
'current_category_id' => $id
// Find the current category order
$category_order = $this->getRequest()->get(
'order',
$this->getSession()->get('admin.category_order', 'manual')
);
$args = array(
'current_category_id' => $category_id,
'category_order' => $category_order,
);
// Store the current sort order in session
$this->getSession()->set('admin.category_order', $category_order);
return $args;
}
/**
* The default action is displaying the categories list.
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
public function defaultAction() {
if (null !== $response = $this->checkAuth("admin.categories.view")) return $response;
return $this->renderList();
}
/**
* Create a new category object
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
public function createAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.categories.create")) return $response;
$error_msg = false;
// Create the Creation Form
$creationForm = new CategoryCreationForm($this->getRequest());
try {
switch ($action) {
case 'browse' : // Browse categories
return $this->browseCategory($args);
// Validate the form, create the CategoryCreation event and dispatch it.
$form = $this->validateForm($creationForm, "POST");
case 'create' : // Create a new category
$data = $form->getData();
return $this->createNewCategory($args);
$createEvent = new CategoryCreateEvent(
$data["title"],
$data["parent"],
$data["locale"]
);
case 'edit' : // Edit an existing category
$this->dispatch(TheliaEvents::CATEGORY_CREATE, $createEvent);
return $this->editCategory($args);
if (! $createEvent->hasCategory()) throw new \LogicException($this->getTranslator()->trans("No category was created."));
case 'delete' : // Delete an existing category
$createdObject = $createEvent->getCategory();
return $this->deleteCategory($args);
// Log category creation
$this->adminLogAppend(sprintf("Category %s (ID %s) created", $createdObject->getTitle(), $createdObject->getId()));
case 'visibilityToggle' : // Toggle visibility
// Substitute _ID_ in the URL with the ID of the created object
$successUrl = str_replace('_ID_', $createdObject->getId(), $creationForm->getSuccessUrl());
return $this->visibilityToggle($id);
case 'changePosition' : // Change position
return $this->changePosition($args);
case 'positionUp' : // Move up category
return $this->positionUp($args);
case 'positionDown' : // Move down category
return $this->positionDown($args);
}
} catch (AuthorizationException $ex) {
return $this->errorPage($ex->getMessage());
} catch (AuthenticationException $ex) {
return $this->errorPage($ex->getMessage());
// Redirect to the success URL
$this->redirect($successUrl);
}
catch (FormValidationException $ex) {
// Form cannot be validated
$error_msg = $this->createStandardFormValidationErrorMessage($ex);
}
catch (\Exception $ex) {
// Any other error
$error_msg = $ex->getMessage();
}
// We did not recognized the action -> return a 404 page
return $this->pageNotFound();
$this->setupFormErrorContext("category creation", $error_msg, $creationForm, $ex);
// At this point, the form has error, and should be redisplayed.
return $this->renderList();
}
}
/**
* Load a category object for modification, and display the edit template.
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
public function changeAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.categories.update")) return $response;
// Load the category object
$category = CategoryQuery::create()
->joinWithI18n($this->getCurrentEditionLocale())
->findOneById($this->getRequest()->get('category_id'));
if ($category != null) {
// Prepare the data that will hydrate the form
$data = array(
'id' => $category->getId(),
'locale' => $category->getLocale(),
'title' => $category->getTitle(),
'chapo' => $category->getChapo(),
'description' => $category->getDescription(),
'postscriptum' => $category->getPostscriptum(),
'parent' => $category->getParent(),
'visible' => $category->getVisible() ? true : false,
'url' => $category->getUrl($this->getCurrentEditionLocale())
// tbc !!!
);
// Setup the object form
$changeForm = new CategoryModificationForm($this->getRequest(), "form", $data);
// Pass it to the parser
$this->getParserContext()->addForm($changeForm);
}
// Render the edition template.
return $this->render('category-edit', $this->getTemplateArgs());
}
/**
* Save changes on a modified category object, and either go back to the category list, or stay on the edition page.
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
public function saveChangeAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.categories.update")) return $response;
$error_msg = false;
// Create the form from the request
$changeForm = new CategoryModificationForm($this->getRequest());
// Get the category ID
$category_id = $this->getRequest()->get('category_id');
try {
// Check the form against constraints violations
$form = $this->validateForm($changeForm, "POST");
// Get the form field values
$data = $form->getData();
$changeEvent = new CategoryUpdateEvent($data['id']);
// Create and dispatch the change event
$changeEvent
->setCategoryName($data['name'])
->setLocale($data["locale"])
->setSymbol($data['symbol'])
->setCode($data['code'])
->setRate($data['rate'])
;
$this->dispatch(TheliaEvents::CATEGORY_UPDATE, $changeEvent);
if (! $createEvent->hasCategory()) throw new \LogicException($this->getTranslator()->trans("No category was updated."));
// Log category modification
$changedObject = $changeEvent->getCategory();
$this->adminLogAppend(sprintf("Category %s (ID %s) modified", $changedObject->getTitle(), $changedObject->getId()));
// If we have to stay on the same page, do not redirect to the succesUrl,
// just redirect to the edit page again.
if ($this->getRequest()->get('save_mode') == 'stay') {
$this->redirectToRoute(
"admin.categories.update",
array('category_id' => $category_id)
);
}
// Redirect to the success URL
$this->redirect($changeForm->getSuccessUrl());
}
catch (FormValidationException $ex) {
// Form cannot be validated
$error_msg = $this->createStandardFormValidationErrorMessage($ex);
}
catch (\Exception $ex) {
// Any other error
$error_msg = $ex->getMessage();
}
$this->setupFormErrorContext("category modification", $error_msg, $changeForm, $ex);
// At this point, the form has errors, and should be redisplayed.
return $this->render('category-edit', array('category_id' => $category_id));
}
/**
* Online status toggle category
*/
public function setToggleVisibilityAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.categories.update")) return $response;
$changeEvent = new CategoryUpdateEvent($this->getRequest()->get('category_id', 0));
// Create and dispatch the change event
$changeEvent->setIsDefault(true);
try {
$this->dispatch(TheliaEvents::CATEGORY_SET_DEFAULT, $changeEvent);
}
catch (\Exception $ex) {
// Any error
return $this->errorPage($ex);
}
$this->redirectToRoute('admin.categories.default');
}
/**
* Update categoryposition
*/
public function updatePositionAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.categories.update")) return $response;
try {
$mode = $this->getRequest()->get('mode', null);
if ($mode == 'up')
$mode = CategoryUpdatePositionEvent::POSITION_UP;
else if ($mode == 'down')
$mode = CategoryUpdatePositionEvent::POSITION_DOWN;
else
$mode = CategoryUpdatePositionEvent::POSITION_ABSOLUTE;
$position = $this->getRequest()->get('position', null);
$event = new CategoryUpdatePositionEvent(
$this->getRequest()->get('category_id', null),
$mode,
$this->getRequest()->get('position', null)
);
$this->dispatch(TheliaEvents::CATEGORY_UPDATE_POSITION, $event);
}
catch (\Exception $ex) {
// Any error
return $this->errorPage($ex);
}
$this->redirectToRoute('admin.categories.default');
}
/**
* Delete a category object
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
public function deleteAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.categories.delete")) return $response;
// Get the category id, and dispatch the deleted request
$event = new CategoryDeleteEvent($this->getRequest()->get('category_id'));
$this->dispatch(TheliaEvents::CATEGORY_DELETE, $event);
if ($event->hasCategory())
$this->adminLogAppend(sprintf("Category %s (ID %s) deleted", $event->getCategory()->getTitle(), $event->getCategory()->getId()));
$this->redirectToRoute('admin.categories.default');
}
}

View File

@@ -0,0 +1,302 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Controller\Admin;
use Thelia\Core\Event\ConfigDeleteEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Tools\URL;
use Thelia\Core\Event\ConfigUpdateEvent;
use Thelia\Core\Event\ConfigCreateEvent;
use Thelia\Log\Tlog;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Core\Security\Exception\AuthorizationException;
use Thelia\Model\ConfigQuery;
use Thelia\Form\ConfigModificationForm;
use Thelia\Form\ConfigCreationForm;
/**
* Manages Thelmia system variables, aka Config objects.
*
* @author Franck Allimant <franck@cqfdev.fr>
*/
class ConfigController extends BaseAdminController
{
/**
* Render the currencies list, ensuring the sort order is set.
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
protected function renderList() {
// Find the current order
$order = $this->getRequest()->get(
'order',
$this->getSession()->get('admin.variables_order', 'name')
);
// Store the current sort order in session
$this->getSession()->set('admin.variables_order', $order);
return $this->render('variables', array('order' => $order));
}
/**
* The default action is displaying the variables list.
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
public function defaultAction() {
if (null !== $response = $this->checkAuth("admin.configuration.variables.view")) return $response;
return $this->renderList();
}
/**
* Create a new config object
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
public function createAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.configuration.variables.create")) return $response;
$message = false;
// Create the Creation Form
$creationForm = new ConfigCreationForm($this->getRequest());
try {
// Validate the form, create the ConfigCreation event and dispatch it.
$form = $this->validateForm($creationForm, "POST");
$data = $form->getData();
$createEvent = new ConfigCreateEvent();
$createEvent
->setEventName($data['name'])
->setValue($data['value'])
->setLocale($data["locale"])
->setTitle($data['title'])
->setHidden($data['hidden'])
->setSecured($data['secured'])
;
$this->dispatch(TheliaEvents::CONFIG_CREATE, $createEvent);
if (! $createEvent->hasConfig()) throw new \LogicException($this->getTranslator()->trans("No variable was created."));
$createdObject = $createEvent->getConfig();
// Log config creation
$this->adminLogAppend(sprintf("Variable %s (ID %s) created", $createdObject->getName(), $createdObject->getId()));
// Substitute _ID_ in the URL with the ID of the created object
$successUrl = str_replace('_ID_', $createdObject->getId(), $creationForm->getSuccessUrl());
// Redirect to the success URL
$this->redirect($successUrl);
}
catch (FormValidationException $ex) {
// Form cannot be validated
$message = $this->createStandardFormValidationErrorMessage($ex);
}
catch (\Exception $ex) {
// Any other error
$message = $ex->getMessage();
}
$this->setupFormErrorContext("variable creation", $message, $creationForm, $ex);
// At this point, the form has error, and should be redisplayed.
return $this->renderList();
}
/**
* Load a config object for modification, and display the edit template.
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
public function changeAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.configuration.variables.update")) return $response;
// Load the config object
$config = ConfigQuery::create()
->joinWithI18n($this->getCurrentEditionLocale())
->findOneById($this->getRequest()->get('variable_id'));
if ($config != null) {
// Prepare the data that will hydrate the form
$data = array(
'id' => $config->getId(),
'name' => $config->getName(),
'value' => $config->getValue(),
'hidden' => $config->getHidden(),
'secured' => $config->getSecured(),
'locale' => $config->getLocale(),
'title' => $config->getTitle(),
'chapo' => $config->getChapo(),
'description' => $config->getDescription(),
'postscriptum' => $config->getPostscriptum()
);
// Setup the object form
$changeForm = new ConfigModificationForm($this->getRequest(), "form", $data);
// Pass it to the parser
$this->getParserContext()->addForm($changeForm);
}
// Render the edition template.
return $this->render('variable-edit', array('variable_id' => $this->getRequest()->get('variable_id')));
}
/**
* Save changes on a modified config object, and either go back to the variable list, or stay on the edition page.
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
public function saveChangeAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.configuration.variables.update")) return $response;
$message = false;
// Create the form from the request
$changeForm = new ConfigModificationForm($this->getRequest());
// Get the variable ID
$variable_id = $this->getRequest()->get('variable_id');
try {
// Check the form against constraints violations
$form = $this->validateForm($changeForm, "POST");
// Get the form field values
$data = $form->getData();
$changeEvent = new ConfigUpdateEvent($data['id']);
// Create and dispatch the change event
$changeEvent
->setEventName($data['name'])
->setValue($data['value'])
->setHidden($data['hidden'])
->setSecured($data['secured'])
->setLocale($data["locale"])
->setTitle($data['title'])
->setChapo($data['chapo'])
->setDescription($data['description'])
->setPostscriptum($data['postscriptum'])
;
$this->dispatch(TheliaEvents::CONFIG_UPDATE, $changeEvent);
if (! $changeEvent->hasConfig()) throw new \LogicException($this->getTranslator()->trans("No variable was updated."));
// Log config modification
$changedObject = $changeEvent->getConfig();
$this->adminLogAppend(sprintf("Variable %s (ID %s) modified", $changedObject->getName(), $changedObject->getId()));
// If we have to stay on the same page, do not redirect to the succesUrl,
// just redirect to the edit page again.
if ($this->getRequest()->get('save_mode') == 'stay') {
$this->redirectToRoute(
"admin.configuration.variables.update",
array('variable_id' => $variable_id)
);
}
// Redirect to the success URL
$this->redirect($changeForm->getSuccessUrl());
}
catch (FormValidationException $ex) {
// Form cannot be validated
$message = $this->createStandardFormValidationErrorMessage($ex);
}
catch (\Exception $ex) {
// Any other error
$message = $ex->getMessage();
}
$this->setupFormErrorContext("variable edition", $message, $changeForm, $ex);
// At this point, the form has errors, and should be redisplayed.
return $this->render('variable-edit', array('variable_id' => $variable_id));
}
/**
* Change values modified directly from the variable list
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
public function changeValuesAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.configuration.variables.update")) return $response;
$variables = $this->getRequest()->get('variable', array());
// Process all changed variables
foreach($variables as $id => $value) {
$event = new ConfigUpdateEvent($id);
$event->setValue($value);
$this->dispatch(TheliaEvents::CONFIG_SETVALUE, $event);
}
$this->redirectToRoute('admin.configuration.variables.default');
}
/**
* Delete a config object
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
public function deleteAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.configuration.variables.delete")) return $response;
// Get the config id, and dispatch the delet request
$event = new ConfigDeleteEvent($this->getRequest()->get('variable_id'));
$this->dispatch(TheliaEvents::CONFIG_DELETE, $event);
if ($event->hasConfig())
$this->adminLogAppend(sprintf("Variable %s (ID %s) modified", $event->getConfig()->getName(), $event->getConfig()->getId()));
$this->redirectToRoute('admin.configuration.variables.default');
}
}

View File

@@ -0,0 +1,514 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Controller\Admin;
use Symfony\Component\HttpFoundation\Request;
use Thelia\Constraint\ConstraintFactory;
use Thelia\Constraint\ConstraintFactoryTest;
use Thelia\Constraint\Rule\AvailableForTotalAmount;
use Thelia\Constraint\Rule\CouponRuleInterface;
use Thelia\Constraint\Validator\PriceParam;
use Thelia\Core\Event\Coupon\CouponCreateEvent;
use Thelia\Core\Event\Coupon\CouponCreateOrUpdateEvent;
use Thelia\Core\Event\Coupon\CouponEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\HttpFoundation\Session\Session;
use Thelia\Core\Security\Exception\AuthenticationException;
use Thelia\Core\Security\Exception\AuthorizationException;
use Thelia\Core\Translation\Translator;
use Thelia\Coupon\CouponAdapterInterface;
use Thelia\Coupon\CouponRuleCollection;
use Thelia\Form\CouponCreationForm;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Log\Tlog;
use Thelia\Model\Coupon;
use Thelia\Model\CouponQuery;
use Thelia\Model\Lang;
use Thelia\Tools\I18n;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* Control View and Action (Model) via Events
*
* @package Coupon
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class CouponController extends BaseAdminController
{
/**
* Manage Coupons list display
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function browseAction()
{
$this->checkAuth('ADMIN', 'admin.coupon.view');
return $this->render('coupon-list');
}
/**
* Manage Coupons creation display
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function createAction()
{
// Check current user authorization
$response = $this->checkAuth('admin.coupon.create');
if ($response !== null) {
return $response;
}
// Parameters given to the template
$args = array();
$i18n = new I18n();
/** @var Lang $lang */
$lang = $this->getSession()->get('lang');
$eventToDispatch = TheliaEvents::COUPON_CREATE;
if ($this->getRequest()->isMethod('POST')) {
$this->validateCreateOrUpdateForm(
$i18n,
$lang,
$eventToDispatch,
'created',
'creation'
);
} else {
// If no input for expirationDate, now + 2 months
$defaultDate = new \DateTime();
$args['defaultDate'] = $defaultDate->modify('+2 month')
->format($lang->getDateFormat());
}
$args['formAction'] = 'admin/coupon/create';
return $this->render(
'coupon-create',
$args
);
}
/**
* Manage Coupons edition display
*
* @param int $couponId Coupon id
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function updateAction($couponId)
{
// Check current user authorization
$response = $this->checkAuth('admin.coupon.update');
if ($response !== null) {
return $response;
}
/** @var Coupon $coupon */
$coupon = CouponQuery::create()->findOneById($couponId);
if (!$coupon) {
$this->pageNotFound();
}
// Parameters given to the template
$args = array();
$i18n = new I18n();
/** @var Lang $lang */
$lang = $this->getSession()->get('lang');
$eventToDispatch = TheliaEvents::COUPON_UPDATE;
if ($this->getRequest()->isMethod('POST')) {
$this->validateCreateOrUpdateForm(
$i18n,
$lang,
$eventToDispatch,
'updated',
'update'
);
} else {
// Prepare the data that will hydrate the form
$data = array(
'code' => $coupon->getCode(),
'title' => $coupon->getTitle(),
'amount' => $coupon->getAmount(),
'effect' => $coupon->getType(),
'shortDescription' => $coupon->getShortDescription(),
'description' => $coupon->getDescription(),
'isEnabled' => ($coupon->getIsEnabled() == 1),
'expirationDate' => $coupon->getExpirationDate($lang->getDateFormat()),
'isAvailableOnSpecialOffers' => ($coupon->getIsAvailableOnSpecialOffers() == 1),
'isCumulative' => ($coupon->getIsCumulative() == 1),
'isRemovingPostage' => ($coupon->getIsRemovingPostage() == 1),
'maxUsage' => $coupon->getMaxUsage(),
'rules' => new CouponRuleCollection(array()),
'locale' => $coupon->getLocale(),
);
/** @var CouponAdapterInterface $adapter */
$adapter = $this->container->get('thelia.adapter');
/** @var Translator $translator */
$translator = $this->container->get('thelia.translator');
$args['rulesObject'] = array();
/** @var CouponRuleInterface $rule */
foreach ($coupon->getRules()->getRules() as $rule) {
$args['rulesObject'][] = array(
'name' => $rule->getName(),
'tooltip' => $rule->getToolTip(),
'validators' => $rule->getValidators()
);
}
// Setup the object form
$changeForm = new CouponCreationForm($this->getRequest(), 'form', $data);
// Pass it to the parser
$this->getParserContext()->addForm($changeForm);
}
$args['formAction'] = 'admin/coupon/update/' . $couponId;
return $this->render(
'coupon-update',
$args
);
}
/**
* Manage Coupons Rule creation display
*
* @param int $couponId Coupon id
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function createRuleAction($couponId)
{
// Check current user authorization
$response = $this->checkAuth('admin.coupon.update');
if ($response !== null) {
return $response;
}
/** @var Coupon $coupon */
$coupon = CouponQuery::create()->findOneById($couponId);
if (!$coupon) {
$this->pageNotFound();
}
// Parameters given to the template
$args = array();
$i18n = new I18n();
/** @var Lang $lang */
$lang = $this->getSession()->get('lang');
$eventToDispatch = TheliaEvents::COUPON_RULE_CREATE;
if ($this->getRequest()->isMethod('POST')) {
$this->validateCreateOrUpdateForm(
$i18n,
$lang,
$eventToDispatch,
'updated',
'update'
);
} else {
// Prepare the data that will hydrate the form
$data = array(
'code' => $coupon->getCode(),
'title' => $coupon->getTitle(),
'amount' => $coupon->getAmount(),
'effect' => $coupon->getType(),
'shortDescription' => $coupon->getShortDescription(),
'description' => $coupon->getDescription(),
'isEnabled' => ($coupon->getIsEnabled() == 1),
'expirationDate' => $coupon->getExpirationDate($lang->getDateFormat()),
'isAvailableOnSpecialOffers' => ($coupon->getIsAvailableOnSpecialOffers() == 1),
'isCumulative' => ($coupon->getIsCumulative() == 1),
'isRemovingPostage' => ($coupon->getIsRemovingPostage() == 1),
'maxUsage' => $coupon->getMaxUsage(),
'rules' => new CouponRuleCollection(array()),
'locale' => $coupon->getLocale(),
);
/** @var CouponAdapterInterface $adapter */
$adapter = $this->container->get('thelia.adapter');
/** @var Translator $translator */
$translator = $this->container->get('thelia.translator');
$args['rulesObject'] = array();
/** @var CouponRuleInterface $rule */
foreach ($coupon->getRules()->getRules() as $rule) {
$args['rulesObject'][] = array(
'name' => $rule->getName($translator),
'tooltip' => $rule->getToolTip($translator),
'validators' => $rule->getValidators()
);
}
// Setup the object form
$changeForm = new CouponCreationForm($this->getRequest(), 'form', $data);
// Pass it to the parser
$this->getParserContext()->addForm($changeForm);
}
$args['formAction'] = 'admin/coupon/update/' . $couponId;
return $this->render(
'coupon-update',
$args
);
}
/**
* Manage Coupons read display
*
* @param int $couponId Coupon Id
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function readAction($couponId)
{
$this->checkAuth('ADMIN', 'admin.coupon.read');
// Database request repeated in the loop but cached
$search = CouponQuery::create();
$coupon = $search->findOneById($couponId);
if ($coupon === null) {
return $this->pageNotFound();
}
return $this->render('coupon-read', array('couponId' => $couponId));
}
/**
* Manage Coupons read display
*
* @param int $couponId Coupon Id
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function getRuleInputAction($ruleId)
{
$this->checkAuth('ADMIN', 'admin.coupon.read');
// @todo uncomment
// if (!$this->getRequest()->isXmlHttpRequest()) {
// $this->redirect('index');
// }
/** @var ConstraintFactory $constraintFactory */
$constraintFactory = $this->container->get('thelia.constraint.factory');
$inputs = $constraintFactory->getInputs($ruleId);
if (!$inputs) {
return $this->pageNotFound();
}
return $this->render(
'coupon/rule-input-ajax',
array(
'ruleId' => $ruleId,
'inputs' => $inputs
)
);
}
/**
* Build a Coupon from its form
*
* @param array $data Form data
*
* @return Coupon
*/
protected function buildCouponFromForm(array $data)
{
$couponBeingCreated = new Coupon();
$couponBeingCreated->setCode($data['code']);
$couponBeingCreated->setType($data['type']);
$couponBeingCreated->setTitle($data['title']);
$couponBeingCreated->setShortDescription($data['shortDescription']);
$couponBeingCreated->setDescription($data['description']);
$couponBeingCreated->setAmount($data['amount']);
$couponBeingCreated->setIsEnabled($data['isEnabled']);
$couponBeingCreated->setExpirationDate($data['expirationDate']);
$couponBeingCreated->setSerializedRules(
new CouponRuleCollection(
array()
)
);
$couponBeingCreated->setIsCumulative($data['isCumulative']);
$couponBeingCreated->setIsRemovingPostage(
$data['isRemovingPostage']
);
$couponBeingCreated->setMaxUsage($data['maxUsage']);
$couponBeingCreated->setIsAvailableOnSpecialOffers(
$data['isAvailableOnSpecialOffers']
);
return $couponBeingCreated;
}
/**
* Log error message
*
* @param string $action Creation|Update|Delete
* @param string $message Message to log
* @param \Exception $e Exception to log
*
* @return $this
*/
protected function logError($action, $message, $e)
{
Tlog::getInstance()->error(
sprintf(
'Error during Coupon ' . $action . ' process : %s. Exception was %s',
$message,
$e->getMessage()
)
);
return $this;
}
/**
* Validate the CreateOrUpdate form
*
* @param string $i18n Local code (fr_FR)
* @param Lang $lang Local variables container
* @param string $eventToDispatch Event which will activate actions
* @param string $log created|edited
* @param string $action creation|edition
*
* @return $this
*/
protected function validateCreateOrUpdateForm($i18n, $lang, $eventToDispatch, $log, $action)
{
// Create the form from the request
$creationForm = new CouponCreationForm($this->getRequest());
$message = false;
try {
// Check the form against constraints violations
$form = $this->validateForm($creationForm, 'POST');
// Get the form field values
$data = $form->getData();
$couponEvent = new CouponCreateOrUpdateEvent(
$data['code'],
$data['title'],
$data['amount'],
$data['effect'],
$data['shortDescription'],
$data['description'],
$data['isEnabled'],
$i18n->getDateTimeFromForm($lang, $data['expirationDate']),
$data['isAvailableOnSpecialOffers'],
$data['isCumulative'],
$data['isRemovingPostage'],
$data['maxUsage'],
new CouponRuleCollection(array()),
$data['locale']
);
// Dispatch Event to the Action
$this->dispatch(
$eventToDispatch,
$couponEvent
);
$this->adminLogAppend(
sprintf(
'Coupon %s (ID ) ' . $log,
$couponEvent->getTitle(),
$couponEvent->getCoupon()->getId()
)
);
$this->redirect(
str_replace(
'{id}',
$couponEvent->getCoupon()->getId(),
$creationForm->getSuccessUrl()
)
);
} catch (FormValidationException $e) {
// Invalid data entered
$message = 'Please check your input:';
$this->logError($action, $message, $e);
} catch (\Exception $e) {
// Any other error
$message = 'Sorry, an error occurred:';
$this->logError($action, $message, $e);
}
if ($message !== false) {
// Mark the form as with error
$creationForm->setErrorMessage($message);
// Send the form and the error to the parser
$this->getParserContext()
->addForm($creationForm)
->setGeneralError($message);
}
return $this;
}
// /**
// * Validation Rule creation
// *
// * @param string $type Rule class type
// * @param string $operator Rule operator (<, >, =, etc)
// * @param array $values Rules values
// *
// * @return bool
// */
// protected function validateRulesCreation($type, $operator, $values)
// {
// /** @var CouponAdapterInterface $adapter */
// $adapter = $this->container->get('thelia.adapter');
// $validator = new PriceParam()
// try {
// $rule = new AvailableForTotalAmount($adapter, $validators);
// $rule = new $type($adapter, $validators);
// } catch (\Exception $e) {
// return false;
// }
// }
}

View File

@@ -0,0 +1,347 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Controller\Admin;
use Thelia\Core\Event\CurrencyDeleteEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Tools\URL;
use Thelia\Core\Event\CurrencyUpdateEvent;
use Thelia\Core\Event\CurrencyCreateEvent;
use Thelia\Log\Tlog;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Core\Security\Exception\AuthorizationException;
use Thelia\Model\CurrencyQuery;
use Thelia\Form\CurrencyModificationForm;
use Thelia\Form\CurrencyCreationForm;
use Thelia\Core\Event\CurrencyUpdatePositionEvent;
/**
* Manages currencies sent by mail
*
* @author Franck Allimant <franck@cqfdev.fr>
*/
class CurrencyController extends BaseAdminController
{
/**
* Render the currencies list, ensuring the sort order is set.
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
protected function renderList() {
// Find the current order
$order = $this->getRequest()->get(
'order',
$this->getSession()->get('admin.currency_order', 'manual')
);
// Store the current sort order in session
$this->getSession()->set('admin.currency_order', $order);
return $this->render('currencies', array('order' => $order));
}
/**
* The default action is displaying the currencies list.
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
public function defaultAction() {
if (null !== $response = $this->checkAuth("admin.configuration.currencies.view")) return $response;
return $this->renderList();
}
/**
* Create a new currency object
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
public function createAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.configuration.currencies.create")) return $response;
$error_msg = false;
// Create the Creation Form
$creationForm = new CurrencyCreationForm($this->getRequest());
try {
// Validate the form, create the CurrencyCreation event and dispatch it.
$form = $this->validateForm($creationForm, "POST");
$data = $form->getData();
$createEvent = new CurrencyCreateEvent();
$createEvent
->setCurrencyName($data['name'])
->setLocale($data["locale"])
->setSymbol($data['symbol'])
->setCode($data['code'])
->setRate($data['rate'])
;
$this->dispatch(TheliaEvents::CURRENCY_CREATE, $createEvent);
if (! $createEvent->hasCurrency()) throw new \LogicException($this->getTranslator()->trans("No currency was created."));
$createdObject = $createEvent->getCurrency();
// Log currency creation
$this->adminLogAppend(sprintf("Currency %s (ID %s) created", $createdObject->getName(), $createdObject->getId()));
// Substitute _ID_ in the URL with the ID of the created object
$successUrl = str_replace('_ID_', $createdObject->getId(), $creationForm->getSuccessUrl());
// Redirect to the success URL
$this->redirect($successUrl);
}
catch (FormValidationException $ex) {
// Form cannot be validated
$error_msg = $this->createStandardFormValidationErrorMessage($ex);
}
catch (\Exception $ex) {
// Any other error
$error_msg = $ex->getMessage();
}
$this->setupFormErrorContext("currency creation", $error_msg, $creationForm, $ex);
// At this point, the form has error, and should be redisplayed.
return $this->renderList();
}
/**
* Load a currency object for modification, and display the edit template.
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
public function changeAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.configuration.currencies.update")) return $response;
// Load the currency object
$currency = CurrencyQuery::create()
->joinWithI18n($this->getCurrentEditionLocale())
->findOneById($this->getRequest()->get('currency_id'));
if ($currency != null) {
// Prepare the data that will hydrate the form
$data = array(
'id' => $currency->getId(),
'name' => $currency->getName(),
'locale' => $currency->getLocale(),
'code' => $currency->getCode(),
'symbol' => $currency->getSymbol(),
'rate' => $currency->getRate()
);
// Setup the object form
$changeForm = new CurrencyModificationForm($this->getRequest(), "form", $data);
// Pass it to the parser
$this->getParserContext()->addForm($changeForm);
}
// Render the edition template.
return $this->render('currency-edit', array('currency_id' => $this->getRequest()->get('currency_id')));
}
/**
* Save changes on a modified currency object, and either go back to the currency list, or stay on the edition page.
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
public function saveChangeAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.configuration.currencies.update")) return $response;
$error_msg = false;
// Create the form from the request
$changeForm = new CurrencyModificationForm($this->getRequest());
// Get the currency ID
$currency_id = $this->getRequest()->get('currency_id');
try {
// Check the form against constraints violations
$form = $this->validateForm($changeForm, "POST");
// Get the form field values
$data = $form->getData();
$changeEvent = new CurrencyUpdateEvent($data['id']);
// Create and dispatch the change event
$changeEvent
->setCurrencyName($data['name'])
->setLocale($data["locale"])
->setSymbol($data['symbol'])
->setCode($data['code'])
->setRate($data['rate'])
;
$this->dispatch(TheliaEvents::CURRENCY_UPDATE, $changeEvent);
if (! $changeEvent->hasCurrency()) throw new \LogicException($this->getTranslator()->trans("No currency was updated."));
// Log currency modification
$changedObject = $changeEvent->getCurrency();
$this->adminLogAppend(sprintf("Currency %s (ID %s) modified", $changedObject->getName(), $changedObject->getId()));
// If we have to stay on the same page, do not redirect to the succesUrl,
// just redirect to the edit page again.
if ($this->getRequest()->get('save_mode') == 'stay') {
$this->redirectToRoute(
"admin.configuration.currencies.update",
array('currency_id' => $currency_id)
);
}
// Redirect to the success URL
$this->redirect($changeForm->getSuccessUrl());
}
catch (FormValidationException $ex) {
// Form cannot be validated
$error_msg = $this->createStandardFormValidationErrorMessage($ex);
}
catch (\Exception $ex) {
// Any other error
$error_msg = $ex->getMessage();
}
$this->setupFormErrorContext("currency modification", $error_msg, $changeForm, $ex);
// At this point, the form has errors, and should be redisplayed.
return $this->render('currency-edit', array('currency_id' => $currency_id));
}
/**
* Sets the default currency
*/
public function setDefaultAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.configuration.currencies.update")) return $response;
$changeEvent = new CurrencyUpdateEvent($this->getRequest()->get('currency_id', 0));
// Create and dispatch the change event
$changeEvent->setIsDefault(true);
try {
$this->dispatch(TheliaEvents::CURRENCY_SET_DEFAULT, $changeEvent);
}
catch (\Exception $ex) {
// Any error
return $this->errorPage($ex);
}
$this->redirectToRoute('admin.configuration.currencies.default');
}
/**
* Update currencies rates
*/
public function updateRatesAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.configuration.currencies.update")) return $response;
try {
$this->dispatch(TheliaEvents::CURRENCY_UPDATE_RATES);
}
catch (\Exception $ex) {
// Any error
return $this->errorPage($ex);
}
$this->redirectToRoute('admin.configuration.currencies.default');
}
/**
* Update currencyposition
*/
public function updatePositionAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.configuration.currencies.update")) return $response;
try {
$mode = $this->getRequest()->get('mode', null);
if ($mode == 'up')
$mode = CurrencyUpdatePositionEvent::POSITION_UP;
else if ($mode == 'down')
$mode = CurrencyUpdatePositionEvent::POSITION_DOWN;
else
$mode = CurrencyUpdatePositionEvent::POSITION_ABSOLUTE;
$position = $this->getRequest()->get('position', null);
$event = new CurrencyUpdatePositionEvent(
$this->getRequest()->get('currency_id', null),
$mode,
$this->getRequest()->get('position', null)
);
$this->dispatch(TheliaEvents::CURRENCY_UPDATE_POSITION, $event);
}
catch (\Exception $ex) {
// Any error
return $this->errorPage($ex);
}
$this->redirectToRoute('admin.configuration.currencies.default');
}
/**
* Delete a currency object
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
public function deleteAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.configuration.currencies.delete")) return $response;
// Get the currency id, and dispatch the delet request
$event = new CurrencyDeleteEvent($this->getRequest()->get('currency_id'));
$this->dispatch(TheliaEvents::CURRENCY_DELETE, $event);
if ($event->hasCurrency())
$this->adminLogAppend(sprintf("Currency %s (ID %s) modified", $event->getCurrency()->getName(), $event->getCurrency()->getId()));
$this->redirectToRoute('admin.configuration.currencies.default');
}
}

View File

@@ -0,0 +1,40 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Controller\Admin;
/**
* Class CustomerController
* @package Thelia\Controller\Admin
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class CustomerController extends BaseAdminController
{
public function indexAction()
{
if (null !== $response = $this->checkAuth("admin.customers.view")) return $response;
return $this->render("customers", array("display_customer" => 20));
}
}

View File

@@ -0,0 +1,260 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Controller\Admin;
use Thelia\Core\Event\MessageDeleteEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Tools\URL;
use Thelia\Core\Event\MessageUpdateEvent;
use Thelia\Core\Event\MessageCreateEvent;
use Thelia\Log\Tlog;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Core\Security\Exception\AuthorizationException;
use Thelia\Model\MessageQuery;
use Thelia\Form\MessageModificationForm;
use Thelia\Form\MessageCreationForm;
/**
* Manages messages sent by mail
*
* @author Franck Allimant <franck@cqfdev.fr>
*/
class MessageController extends BaseAdminController
{
/**
* Render the messages list
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
protected function renderList() {
return $this->render('messages');
}
/**
* The default action is displaying the messages list.
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
public function defaultAction() {
if (null !== $response = $this->checkAuth("admin.configuration.messages.view")) return $response;
return $this->renderList();
}
/**
* Create a new message object
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
public function createAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.configuration.messages.create")) return $response;
$message = false;
// Create the creation Form
$creationForm = new MessageCreationForm($this->getRequest());
try {
// Validate the form, create the MessageCreation event and dispatch it.
$form = $this->validateForm($creationForm, "POST");
$data = $form->getData();
$createEvent = new MessageCreateEvent();
$createEvent
->setMessageName($data['name'])
->setLocale($data["locale"])
->setTitle($data['title'])
->setSecured($data['secured'])
;
$this->dispatch(TheliaEvents::MESSAGE_CREATE, $createEvent);
if (! $createEvent->hasMessage()) throw new \LogicException($this->getTranslator()->trans("No message was created."));
$createdObject = $createEvent->getMessage();
$this->adminLogAppend(sprintf("Message %s (ID %s) created", $createdObject->getName(), $createdObject->getId()));
// Substitute _ID_ in the URL with the ID of the created object
$successUrl = str_replace('_ID_', $createdObject->getId(), $creationForm->getSuccessUrl());
// Redirect to the success URL
$this->redirect($successUrl);
}
catch (FormValidationException $ex) {
// Form cannot be validated
$message = $this->createStandardFormValidationErrorMessage($ex);
}
catch (\Exception $ex) {
// Any other error
$message = $ex->getMessage();
}
$this->setupFormErrorContext("message modification", $message, $creationForm, $ex);
// At this point, the form has error, and should be redisplayed.
return $this->render('messages');
}
/**
* Load a message object for modification, and display the edit template.
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
public function changeAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.configuration.messages.update")) return $response;
// Load the message object
$message = MessageQuery::create()
->joinWithI18n($this->getCurrentEditionLocale())
->findOneById($this->getRequest()->get('message_id'));
if ($message != null) {
// Prepare the data that will hydrate the form
$data = array(
'id' => $message->getId(),
'name' => $message->getName(),
'secured' => $message->getSecured(),
'locale' => $message->getLocale(),
'title' => $message->getTitle(),
'subject' => $message->getSubject(),
'html_message' => $message->getHtmlMessage(),
'text_message' => $message->getTextMessage()
);
// Setup the object form
$changeForm = new MessageModificationForm($this->getRequest(), "form", $data);
// Pass it to the parser
$this->getParserContext()->addForm($changeForm);
}
// Render the edition template.
return $this->render('message-edit', array('message_id' => $this->getRequest()->get('message_id')));
}
/**
* Save changes on a modified message object, and either go back to the message list, or stay on the edition page.
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
public function saveChangeAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.configuration.messages.update")) return $response;
$message = false;
// Create the form from the request
$changeForm = new MessageModificationForm($this->getRequest());
// Get the message ID
$message_id = $this->getRequest()->get('message_id');
try {
// Check the form against constraints violations
$form = $this->validateForm($changeForm, "POST");
// Get the form field values
$data = $form->getData();
$changeEvent = new MessageUpdateEvent($data['id']);
// Create and dispatch the change event
$changeEvent
->setMessageName($data['name'])
->setSecured($data['secured'])
->setLocale($data["locale"])
->setTitle($data['title'])
->setSubject($data['subject'])
->setHtmlMessage($data['html_message'])
->setTextMessage($data['text_message'])
;
$this->dispatch(TheliaEvents::MESSAGE_UPDATE, $changeEvent);
if (! $changeEvent->hasMessage()) throw new \LogicException($this->getTranslator()->trans("No message was updated."));
$changedObject = $changeEvent->getMessage();
$this->adminLogAppend(sprintf("Variable %s (ID %s) modified", $changedObject->getName(), $changedObject->getId()));
// If we have to stay on the same page, do not redirect to the succesUrl,
// just redirect to the edit page again.
if ($this->getRequest()->get('save_mode') == 'stay') {
$this->redirectToRoute(
"admin.configuration.messages.update",
array('message_id' => $message_id)
);
}
// Redirect to the success URL
$this->redirect($changeForm->getSuccessUrl());
}
catch (FormValidationException $ex) {
// Form cannot be validated
$message = $this->createStandardFormValidationErrorMessage($ex);
}
catch (\Exception $ex) {
// Any other error
$message = $ex->getMessage();
}
$this->setupFormErrorContext("message modification", $message, $changeForm, $ex);
// At this point, the form has errors, and should be redisplayed.
return $this->render('message-edit', array('message_id' => $message_id));
}
/**
* Delete a message object
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
public function deleteAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.configuration.messages.delete")) return $response;
// Get the message id, and dispatch the delet request
$event = new MessageDeleteEvent($this->getRequest()->get('message_id'));
$this->dispatch(TheliaEvents::MESSAGE_DELETE, $event);
if ($event->hasMessage())
$this->adminLogAppend(sprintf("Message %s (ID %s) modified", $event->getMessage()->getName(), $event->getMessage()->getId()));
$this->redirectToRoute('admin.configuration.messages.default');
}
}

View File

@@ -43,25 +43,28 @@ 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
$this->redirectToRoute('admin.login');
}
public function checkLoginAction()
{
$adminLoginForm = new AdminLogin($this->getRequest());
$request = $this->getRequest();
$authenticator = new AdminUsernamePasswordFormAuthenticator($request, $adminLoginForm);
$adminLoginForm = new AdminLogin($request);
try {
$form = $this->validateForm($adminLoginForm, "post");
$authenticator = new AdminUsernamePasswordFormAuthenticator($request, $adminLoginForm);
$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);
@@ -70,32 +73,34 @@ class SessionController extends BaseAdminController
// Redirect to the success URL
return Redirect::exec($adminLoginForm->getSuccessUrl());
} catch (ValidatorException $ex) {
}
catch (FormValidationException $ex) {
// Validation problem
$message = "Missing or invalid information. Please check your input.";
} catch (AuthenticationException $ex) {
$message = $this->createStandardFormValidationErrorMessage($ex);
}
catch (AuthenticationException $ex) {
// Log authentication failure
AdminLog::append(sprintf("Authentication failure for username '%s'", $authenticator->getUsername()), $request);
$message = "Login failed. Please check your username and password.";
} catch (\Exception $ex) {
$message = $this->getTranslator()->trans("Login failed. Please check your username and password.");
}
catch (\Exception $ex) {
// Log authentication failure
AdminLog::append(sprintf("Undefined error: %s", $ex->getMessage()), $request);
$message = "Unable to process your request. Please try again.";
$message = $this->getTranslator()->trans(
"Unable to process your request. Please try again (%err).",
array("%err" => $ex->getMessage())
);
}
// Store error information in the form
$adminLoginForm->setError(true);
$adminLoginForm->setErrorMessage($message);
// Store the form name in session (see Form Smarty plugin to find usage of this parameter)
$this->getParserContext()->setErrorForm($adminLoginForm);
$this->setupFormErrorContext("Login process", $message, $adminLoginForm, $ex);
// Display the login form again
return $this->render("login");
}
}
}

View File

@@ -25,15 +25,22 @@ namespace Thelia\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\DependencyInjection\ContainerAware;
use Symfony\Component\Routing\Exception\InvalidParameterException;
use Symfony\Component\Routing\Exception\MissingMandatoryParametersException;
use Symfony\Component\Routing\Exception\RouteNotFoundException;
use Symfony\Component\Routing\Router;
use Thelia\Core\Security\SecurityContext;
use Thelia\Tools\URL;
use Thelia\Tools\Redirect;
use Thelia\Core\Template\ParserContext;
use Thelia\Core\Event\ActionEvent;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Thelia\Core\Factory\ActionEventFactory;
use Thelia\Form\BaseForm;
use Thelia\Form\Exception\FormValidationException;
use Symfony\Component\EventDispatcher\Event;
use Thelia\Core\Event\DefaultActionEvent;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
*
@@ -56,35 +63,15 @@ class BaseController extends ContainerAware
}
/**
* Create an action event
* Dispatch a Thelia event
*
* @param string $action
* @return EventDispatcher
*/
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
* @param string $eventName a TheliaEvent name, as defined in TheliaEvents class
* @param Event $event the action event, or null (a DefaultActionEvent will be dispatched)
*/
protected function dispatch($eventName, ActionEvent $event = null)
{
if ($event == null) $event = new DefaultActionEvent();
$this->getDispatcher()->dispatch($eventName, $event);
}
@@ -98,6 +85,17 @@ class BaseController extends ContainerAware
return $this->container->get('event_dispatcher');
}
/**
*
* return the Translator
*
* @return mixed \Thelia\Core\Translation\Translator
*/
public function getTranslator()
{
return $this->container->get('thelia.translator');
}
/**
* Return the parser context,
*
@@ -113,13 +111,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');
}
/**
@@ -142,6 +136,29 @@ class BaseController extends ContainerAware
return $request->getSession();
}
/**
* Get all errors that occured in a form
*
* @param \Symfony\Component\Form\Form $form
* @return string the error string
*/
private function getErrorMessages(\Symfony\Component\Form\Form $form) {
$errors = '';
foreach ($form->getErrors() as $key => $error) {
$errors .= $error->getMessage() . ', ';
}
foreach ($form->all() as $child) {
if (!$child->isValid()) {
$errors .= $this->getErrorMessages($child) . ', ';
}
}
return rtrim($errors, ', ');
}
/**
* Validate a BaseForm
*
@@ -160,31 +177,78 @@ class BaseController extends ContainerAware
if ($form->isValid()) {
return $form;
} else {
throw new FormValidationException("Missing or invalid data");
}
} else {
else {
throw new FormValidationException(sprintf("Missing or invalid data: %s", $this->getErrorMessages($form)));
}
}
else {
throw new FormValidationException(sprintf("Wrong form method, %s expected.", $expectedMethod));
}
}
/**
*
* redirect request to specify url
* redirect request to the specified url
*
* @param string $url
*/
public function redirect($url)
public function redirect($url, $status = 302)
{
Redirect::exec($url);
Redirect::exec($url, $status);
}
/**
* If success_url param is present in request, follow this link.
* If success_url param is present in request or in the provided form, redirect to this URL.
*
* @param BaseForm $form a base form, which may contains the success URL
*/
protected function redirectSuccess()
protected function redirectSuccess(BaseForm $form = null)
{
if (null !== $url = $this->getRequest()->get("success_url")) {
$this->redirect($url);
if ($form != null) {
$url = $form->getSuccessUrl();
}
else {
$url = $this->getRequest()->get("success_url");
}
echo "url=$url";
if (null !== $url) $this->redirect($url);
}
}
/**
* Get a route path from the route id.
*
* @param string $routerName Router name
* @param string $routeId The name of the route
* @param mixed $parameters An array of parameters
* @param Boolean|string $referenceType The type of reference to be generated (one of the constants)
*
* @throws RouteNotFoundException If the named route doesn't exist
* @throws MissingMandatoryParametersException When some parameters are missing that are mandatory for the route
* @throws InvalidParameterException When a parameter value for a placeholder is not correct because
* it does not match the requirement
* @throws \InvalidArgumentException When the router doesn't exist
* @return string The generated URL
*/
protected function getRouteFromRouter($routerName, $routeId, $parameters = array(), $referenceType = Router::ABSOLUTE_PATH) {
/** @var Router $router */
$router = $this->container->get($routerName);
if ($router == null) {
throw new \InvalidArgumentException(sprintf("Router '%s' does not exists.", $routerName));
}
return $router->generate($routeId, $parameters, $referenceType);
}
/**
* Return a 404 error
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
*/
protected function pageNotFound()
{
throw new NotFoundHttpException();
}
}

View File

@@ -0,0 +1,158 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Controller\Front;
use Thelia\Core\Event\AddressCreateOrUpdateEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Form\AddressCreateForm;
use Thelia\Form\AddressUpdateForm;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Model\Base\AddressQuery;
use Thelia\Model\Customer;
use Thelia\Tools\URL;
/**
* Class AddressController
* @package Thelia\Controller\Front
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class AddressController extends BaseFrontController
{
/**
* Create controller.
* Check if customer is logged in
*
* Dispatch TheliaEvents::ADDRESS_CREATE event
*/
public function createAction()
{
if ($this->getSecurityContext()->hasCustomerUser() === false) {
$this->redirect(URL::getInstance()->getIndexPage());
}
$addressCreate = new AddressCreateForm($this->getRequest());
try {
$customer = $this->getSecurityContext()->getCustomerUser();
$form = $this->validateForm($addressCreate, "post");
$event = $this->createAddressEvent($form);
$event->setCustomer($customer);
$this->dispatch(TheliaEvents::ADDRESS_CREATE, $event);
$this->redirectSuccess($addressCreate);
}catch (FormValidationException $e) {
$message = sprintf("Please check your input: %s", $e->getMessage());
}
catch (\Exception $e) {
$message = sprintf("Sorry, an error occured: %s", $e->getMessage());
}
if ($message !== false) {
\Thelia\Log\Tlog::getInstance()->error(sprintf("Error during address creation process : %s", $message));
$addressCreate->setErrorMessage($message);
$this->getParserContext()
->addForm($addressCreate)
->setGeneralError($message)
;
}
}
public function updateAction()
{
$request = $this->getRequest();
if ($this->getSecurityContext()->hasCustomerUser() === false) {
$this->redirectToRoute("home");
}
if(null === $address_id = $request->get("address_id")) {
$this->redirectToRoute("home");
}
$addressUpdate = new AddressUpdateForm($request);
try {
$customer = $this->getSecurityContext()->getCustomerUser();
$form = $this->validateForm($addressUpdate);
$address = AddressQuery::create()->findPk($address_id);
if (null === $address) {
$this->redirectToRoute("home");
}
if($address->getCustomer()->getId() != $customer->getId()) {
$this->redirectToRoute("home");
}
$event = $this->createAddressEvent($form);
$event->setAddress($address);
$this->dispatch(TheliaEvents::ADDRESS_UPDATE, $event);
$this->redirectSuccess($addressUpdate);
}catch (FormValidationException $e) {
$message = sprintf("Please check your input: %s", $e->getMessage());
}
catch (\Exception $e) {
$message = sprintf("Sorry, an error occured: %s", $e->getMessage());
}
if ($message !== false) {
\Thelia\Log\Tlog::getInstance()->error(sprintf("Error during address creation process : %s", $message));
$addressUpdate->setErrorMessage($message);
$this->getParserContext()
->addForm($addressUpdate)
->setGeneralError($message)
;
}
}
protected function createAddressEvent($form)
{
return new AddressCreateOrUpdateEvent(
$form->get("label")->getData(),
$form->get("title")->getData(),
$form->get("firstname")->getData(),
$form->get("lastname")->getData(),
$form->get("address1")->getData(),
$form->get("address2")->getData(),
$form->get("address3")->getData(),
$form->get("zipcode")->getData(),
$form->get("city")->getData(),
$form->get("country")->getData(),
$form->get("cellphone")->getData(),
$form->get("phone")->getData(),
$form->get("company")->getData()
);
}
}

View File

@@ -23,7 +23,28 @@
namespace Thelia\Controller\Front;
use Thelia\Controller\BaseController;
use Thelia\Tools\URL;
class BaseFrontController extends BaseController
{
/**
* Return the route path defined for the givent route ID
*
* @param string $routeId a route ID, as defines in Config/Resources/routing/front.xml
*
* @see \Thelia\Controller\BaseController::getRouteFromRouter()
*/
protected function getRoute($routeId) {
return $this->getRouteFromRouter('router.front', $routeId);
}
/**
* Redirect to à route ID related URL
*
* @param unknown $routeId the route ID, as found in Config/Resources/routing/admin.xml
* @param unknown $urlParameters the URL parametrs, as a var/value pair array
*/
public function redirectToRoute($routeId, $urlParameters = array()) {
$this->redirect(URL::getInstance()->absoluteUrl($this->getRoute($routeId), $urlParameters));
}
}

4
core/lib/Thelia/Controller/Front/CartController.php Normal file → Executable file
View File

@@ -63,7 +63,7 @@ class CartController extends BaseFrontController
if ($message) {
$cartAdd->setErrorMessage($message);
$this->getParserContext()->setErrorForm($cartAdd);
$this->getParserContext()->addForm($cartAdd);
}
}
@@ -74,7 +74,7 @@ class CartController extends BaseFrontController
$cartEvent->setQuantity($this->getRequest()->get("quantity"));
try {
$this->getDispatcher()->dispatch(TheliaEvents::CART_CHANGEITEM, $cartEvent);
$this->getDispatcher()->dispatch(TheliaEvents::CART_UPDATEITEM, $cartEvent);
$this->redirectSuccess();
} catch(PropelException $e) {

183
core/lib/Thelia/Controller/Front/CustomerController.php Normal file → Executable file
View File

@@ -22,8 +22,6 @@
/*************************************************************************************/
namespace Thelia\Controller\Front;
use Propel\Runtime\Exception\PropelException;
use Symfony\Component\Validator\Exception\ValidatorException;
use Thelia\Core\Event\CustomerCreateOrUpdateEvent;
use Thelia\Core\Event\CustomerLoginEvent;
use Thelia\Core\Security\Authentication\CustomerUsernamePasswordFormAuthenticator;
@@ -36,65 +34,107 @@ use Thelia\Form\CustomerModification;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Model\Customer;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\Event\CustomerEvent;
use Thelia\Core\Factory\ActionEventFactory;
use Thelia\Tools\URL;
use Thelia\Log\Tlog;
use Thelia\Core\Security\Exception\WrongPasswordException;
/**
* Class CustomerController
* @package Thelia\Controller\Front
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class CustomerController extends BaseFrontController
{
/**
* create a new Customer. Retrieve data in form and dispatch a action.createCustomer event
*
* if error occurs, message is set in the parserContext
* Create a new customer.
* On success, redirect to success_url if exists, otherwise, display the same view again.
*/
public function createAction()
{
$request = $this->getRequest();
$customerCreation = new CustomerCreation($request);
try {
$form = $this->validateForm($customerCreation, "post");
if (! $this->getSecurityContext()->hasCustomerUser()) {
$customerCreateEvent = $this->createEventInstance($form->getData());
$message = false;
$this->getDispatcher()->dispatch(TheliaEvents::CUSTOMER_CREATEACCOUNT, $customerCreateEvent);
$customerCreation = new CustomerCreation($this->getRequest());
$this->processLogin($customerCreateEvent->getCustomer());
try {
$form = $this->validateForm($customerCreation, "post");
$this->redirectSuccess();
$customerCreateEvent = $this->createEventInstance($form->getData());
} catch (FormValidationException $e) {
$customerCreation->setErrorMessage($e->getMessage());
$this->getParserContext()->setErrorForm($customerCreation);
} catch (PropelException $e) {
\Thelia\Log\Tlog::getInstance()->error(sprintf("error during customer creation process in front context with message : %s", $e->getMessage()));
$this->getParserContext()->setGeneralError($e->getMessage());
$this->dispatch(TheliaEvents::CUSTOMER_CREATEACCOUNT, $customerCreateEvent);
$this->processLogin($customerCreateEvent->getCustomer());
$this->redirectSuccess($customerCreation);
}
catch (FormValidationException $e) {
$message = sprintf("Please check your input: %s", $e->getMessage());
}
catch (\Exception $e) {
$message = sprintf("Sorry, an error occured: %s", $e->getMessage());
}
if ($message !== false) {
Tlog::getInstance()->error(sprintf("Error during customer creation process : %s. Exception was %s", $message, $e->getMessage()));
$customerCreation->setErrorMessage($message);
$this->getParserContext()
->addForm($customerCreation)
->setGeneralError($message)
;
}
}
}
/**
* Update customer data. On success, redirect to success_url if exists.
* Otherwise, display the same view again.
*/
public function updateAction()
{
$request = $this->getRequest();
$customerModification = new CustomerModification($request);
if ($this->getSecurityContext()->hasCustomerUser()) {
try {
$message = false;
$customer = $this->getSecurityContext(SecurityContext::CONTEXT_FRONT_OFFICE)->getUser();
$customerModification = new CustomerModification($this->getRequest());
$form = $this->validateForm($customerModification, "post");
try {
$customerChangeEvent = $this->createEventInstance($form->getData());
$customerChangeEvent->setCustomer($customer);
$customer = $this->getSecurityContext()->getCustomerUser();
$this->getDispatcher()->dispatch(TheliaEvents::CUSTOMER_UPDATEACCOUNT, $customerChangeEvent);
$form = $this->validateForm($customerModification, "post");
$this->processLogin($customerChangeEvent->getCustomer());
$customerChangeEvent = $this->createEventInstance($form->getData());
$customerChangeEvent->setCustomer($customer);
$this->redirectSuccess();
$this->dispatch(TheliaEvents::CUSTOMER_UPDATEACCOUNT, $customerChangeEvent);
} catch (FormValidationException $e) {
$customerModification->setErrorMessage($e->getMessage());
$this->getParserContext()->setErrorForm($customerModification);
} catch (PropelException $e) {
\Thelia\Log\Tlog::getInstance()->error(sprintf("error during updating customer in front context with message : %s", $e->getMessage()));
$this->getParserContext()->setGeneralError($e->getMessage());
$this->processLogin($customerChangeEvent->getCustomer());
$this->redirectSuccess($customerModification);
}
catch (FormValidationException $e) {
$message = sprintf("Please check your input: %s", $e->getMessage());
}
catch (\Exception $e) {
$message = sprintf("Sorry, an error occured: %s", $e->getMessage());
}
if ($message !== false) {
Tlog::getInstance()->error(sprintf("Error during customer modification process : %s.", $message));
$customerModification->setErrorMessage($message);
$this->getParserContext()
->addForm($customerModification)
->setGeneralError($message)
;
}
}
}
@@ -102,41 +142,77 @@ class CustomerController extends BaseFrontController
* Perform user login. On a successful login, the user is redirected to the URL
* found in the success_url form parameter, or / if none was found.
*
* If login is not successfull, the same view is dispolyed again.
* If login is not successfull, the same view is displayed again.
*
*/
public function loginAction()
{
$request = $this->getRequest();
if (! $this->getSecurityContext()->hasCustomerUser()) {
$message = false;
$customerLoginForm = new CustomerLogin($request);
$request = $this->getRequest();
$customerLoginForm = new CustomerLogin($request);
$authenticator = new CustomerUsernamePasswordFormAuthenticator($request, $customerLoginForm);
try {
try {
$customer = $authenticator->getAuthentifiedUser();
$form = $this->validateForm($customerLoginForm, "post");
$customerLoginEvent = new CustomerLoginEvent($customer);
$authenticator = new CustomerUsernamePasswordFormAuthenticator($request, $customerLoginForm);
$this->processLogin($customer, $customerLoginEvent);
$customer = $authenticator->getAuthentifiedUser();
$this->redirectSuccess();
} catch (ValidatorException $e) {
$this->processLogin($customer);
} catch(UsernameNotFoundException $e) {
$this->redirectSuccess($customerLoginForm);
} catch(AuthenticationException $e) {
}
catch (FormValidationException $e) {
$message = sprintf("Please check your input: %s", $e->getMessage());
}
catch(UsernameNotFoundException $e) {
$message = "This customer email was not found.";
}
catch (WrongPasswordException $e) {
$message = "Wrong password. Please try again.";
}
catch(AuthenticationException $e) {
$message = "Sorry, we failed to authentify you. Please try again.";
}
catch (\Exception $e) {
$message = sprintf("Sorry, an error occured: %s", $e->getMessage());
}
} catch (\Exception $e) {
if ($message !== false) {
Tlog::getInstance()->error(sprintf("Error during customer login process : %s. Exception was %s", $message, $e->getMessage()));
$customerLoginForm->setErrorMessage($message);
$this->getParserContext()->addForm($customerLoginForm);
}
}
}
public function processLogin(Customer $customer,$event = null)
/**
* Perform customer logout.
*/
public function logoutAction()
{
$this->getSecurityContext(SecurityContext::CONTEXT_FRONT_OFFICE)->setUser($customer);
if ($this->getSecurityContext()->hasCustomerUser()) {
$this->dispatch(TheliaEvents::CUSTOMER_LOGOUT);
}
if($event) $this->dispatch(TheliaEvents::CUSTOMER_LOGIN, $event);
// Redirect to home page
$this->redirect(URL::getInstance()->getIndexPage());
}
/**
* Dispatch event for customer login action
*
* @param Customer $customer
*/
protected function processLogin(Customer $customer)
{
$this->dispatch(TheliaEvents::CUSTOMER_LOGIN, new CustomerLoginEvent($customer));
}
/**
@@ -162,10 +238,9 @@ class CustomerController extends BaseFrontController
$this->getRequest()->getSession()->getLang(),
isset($data["reseller"])?$data["reseller"]:null,
isset($data["sponsor"])?$data["sponsor"]:null,
isset($data["discount"])?$data["discount"]:nullsch
isset($data["discount"])?$data["discount"]:null
);
return $customerCreateEvent;
}
}

View File

@@ -23,6 +23,9 @@
namespace Thelia\Controller\Front;
use Symfony\Component\HttpFoundation\Request;
use Thelia\Model\ConfigQuery;
use Thelia\Tools\Redirect;
use Thelia\Tools\URL;
/**
*
@@ -43,13 +46,30 @@ class DefaultController extends BaseFrontController
*/
public function noAction(Request $request)
{
$view = null;
if (! $view = $request->query->get('view')) {
$view = "index";
if ($request->request->has('view')) {
$view = $request->request->get('view');
}
}
if(null !== $view) {
$request->attributes->set('_view', $view);
}
$request->attributes->set('_view', $view);
if (null === $view && null === $request->attributes->get("_view")) {
$request->attributes->set("_view", "index");
}
if(ConfigQuery::isRewritingEnable()) {
if($request->attributes->get('_rewritten', false) === false) {
/* Does the query GET parameters match a rewritten URL ? */
$rewrittenUrl = URL::getInstance()->retrieveCurrent($request);
if($rewrittenUrl->rewrittenUrl !== null) {
/* 301 redirection to rewritten URL */
$this->redirect($rewrittenUrl->rewrittenUrl, 301);
}
}
}
}
}

View File

@@ -0,0 +1,56 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Controller\Front;
use Thelia\Model\ModuleQuery;
use Thelia\Tools\URL;
/**
* Class DeliveryController
* @package Thelia\Controller\Front
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class DeliveryController extends BaseFrontController
{
public function select($delivery_id)
{
if ($this->getSecurityContext()->hasCustomerUser() === false) {
$this->redirect(URL::getInstance()->getIndexPage());
}
$request = $this->getRequest();
$deliveryModule = ModuleQuery::create()
->filterById($delivery_id)
->filterByActivate(1)
->findOne()
;
if ($deliveryModule) {
$request->getSession()->setDelivery($delivery_id);
} else {
$this->pageNotFound();
}
}
}

View File

@@ -0,0 +1,60 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Controller\Install;
use Symfony\Component\HttpFoundation\Response;
use Thelia\Controller\BaseController;
/**
* Class BaseInstallController
* @package Thelia\Controller\Install
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class BaseInstallController extends BaseController
{
/**
* @return a ParserInterface instance parser
*/
protected function getParser()
{
$parser = $this->container->get("thelia.parser");
// Define the template thant shoud be used
$parser->setTemplate("install");
return $parser;
}
public function render($templateName, $args = array())
{
return new Response($this->renderRaw($templateName, $args));
}
public function renderRaw($templateName, $args = array())
{
$data = $this->getParser()->render($templateName, $args);
return $data;
}
}

View File

@@ -0,0 +1,69 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Controller\Install;
use Thelia\Install\BaseInstall;
use Thelia\Install\CheckPermission;
/**
* Class InstallController
* @package Thelia\Controller\Install
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class InstallController extends BaseInstallController {
public function index()
{
$this->verifyStep(1);
$this->getSession()->set("step", 1);
$this->render("index.html");
}
public function checkPermission()
{
$this->verifyStep(2);
$permission = new CheckPermission();
}
protected function verifyStep($step)
{
$session = $this->getSession();
if ($session->has("step")) {
$sessionStep = $session->get("step");
} else {
return true;
}
switch($step) {
case "1" :
if ($sessionStep > 1) {
$this->redirect("/install/step/2");
}
break;
}
}
}

View File

@@ -29,6 +29,12 @@ use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\HttpKernel\KernelInterface;
/**
* cli application for Thelia
* Class Application
* @package Thelia\Core
* mfony\Component\HttpFoundation\Session\Session
*/
class Application extends BaseApplication
{

View File

@@ -26,9 +26,11 @@ use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Scope;
use Thelia\Core\DependencyInjection\Compiler\RegisterCouponPass;
use Thelia\Core\DependencyInjection\Compiler\RegisterListenersPass;
use Thelia\Core\DependencyInjection\Compiler\RegisterParserPluginPass;
use Thelia\Core\DependencyInjection\Compiler\RegisterRouterPass;
use Thelia\Core\DependencyInjection\Compiler\RegisterRulePass;
/**
* First Bundle use in Thelia
@@ -60,6 +62,8 @@ class TheliaBundle extends Bundle
->addCompilerPass(new RegisterListenersPass())
->addCompilerPass(new RegisterParserPluginPass())
->addCompilerPass(new RegisterRouterPass())
->addCompilerPass(new RegisterCouponPass())
->addCompilerPass(new RegisterRulePass())
;
}

View File

@@ -0,0 +1,69 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Core\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
/**
* Created by JetBrains PhpStorm.
* Date: 9/05/13
* Time: 3:24 PM
*
* Class RegisterListenersPass
* Source code come from Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\RegisterKernelListenersPass class
*
* @package Thelia\Core\DependencyInjection\Compiler
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class RegisterCouponPass implements CompilerPassInterface
{
/**
* You can modify the container here before it is dumped to PHP code.
*
* @param ContainerBuilder $container Container
*
* @api
*/
public function process(ContainerBuilder $container)
{
if (!$container->hasDefinition('thelia.coupon.manager')) {
return;
}
$couponManager = $container->getDefinition('thelia.coupon.manager');
$services = $container->findTaggedServiceIds("thelia.coupon.addCoupon");
foreach ($services as $id => $rule) {
$couponManager->addMethodCall(
'addAvailableCoupon',
array(
new Reference($id)
)
);
}
}
}

View File

@@ -31,6 +31,7 @@ use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
* @package Thelia\Core\DependencyInjection\Compiler
*
* Source code come from Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\RegisterKernelListenersPass class
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class RegisterListenersPass implements CompilerPassInterface
{

View File

@@ -31,7 +31,7 @@ use Symfony\Component\DependencyInjection\Reference;
* Register parser plugins. These plugins shouild be tagged thelia.parser.register_plugin
* in the configuration.
*
*
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class RegisterParserPluginPass implements CompilerPassInterface
{

View File

@@ -28,6 +28,14 @@ use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Reference;
/**
*
* this compiler can add many router to symfony-cms routing
*
* Class RegisterRouterPass
* @package Thelia\Core\DependencyInjection\Compiler
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class RegisterRouterPass implements CompilerPassInterface
{
@@ -76,7 +84,7 @@ class RegisterRouterPass implements CompilerPassInterface
$container->setDefinition("router.".$moduleCode, $definition);
$chainRouter->addMethodCall("add", array(new Reference("router.".$moduleCode), -1));
$chainRouter->addMethodCall("add", array(new Reference("router.".$moduleCode), 1));
}
}
}

View File

@@ -0,0 +1,69 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Core\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
/**
* Created by JetBrains PhpStorm.
* Date: 9/05/13
* Time: 3:24 PM
*
* Class RegisterListenersPass
* Source code come from Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\RegisterKernelListenersPass class
*
* @package Thelia\Core\DependencyInjection\Compiler
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class RegisterRulePass implements CompilerPassInterface
{
/**
* You can modify the container here before it is dumped to PHP code.
*
* @param ContainerBuilder $container Container
*
* @api
*/
public function process(ContainerBuilder $container)
{
if (!$container->hasDefinition('thelia.coupon.manager')) {
return;
}
$couponManager = $container->getDefinition('thelia.coupon.manager');
$services = $container->findTaggedServiceIds("thelia.coupon.addCoupon");
foreach ($services as $id => $rule) {
$couponManager->addMethodCall(
'addAvailableCoupon',
array(
new Reference($id)
)
);
}
}
}

View File

@@ -36,6 +36,14 @@ use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Loader\FileLoader;
/**
*
* Load, read and validate config xml files
*
* Class XmlFileLoader
* @package Thelia\Core\DependencyInjection\Loader
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class XmlFileLoader extends FileLoader
{
/**

View File

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

View File

@@ -0,0 +1,267 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Core\Event;
use Symfony\Component\EventDispatcher\Event;
use Thelia\Model\Address;
use Thelia\Model\Customer;
/**
* Class AddressCreateOrUpdateEvent
* @package Thelia\Core\Event
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class AddressCreateOrUpdateEvent extends ActionEvent
{
/**
* @var string address label
*/
protected $label;
/**
* @var int title id
*/
protected $title;
/**
* @var string|null company name
*/
protected $company;
/**
* @var string first name
*/
protected $firstname;
/**
* @var string last name
*/
protected $lastname;
/**
* @var string address
*/
protected $address1;
/**
* @var string address line 2
*/
protected $address2;
/**
* @var string address line 3
*/
protected $address3;
/**
* @var string zipcode
*/
protected $zipcode;
/**
* @var string city
*/
protected $city;
/**
* @var int country id
*/
protected $country;
/**
* @var string cell phone
*/
protected $cellphone;
/**
* @var string phone
*/
protected $phone;
/**
* @var \Thelia\Model\Customer
*/
protected $customer;
/**
* @var \Thelia\Model\Address
*/
protected $address;
function __construct($label, $title, $firstname, $lastname, $address1, $address2, $address3, $zipcode, $city, $country, $cellphone, $phone, $company)
{
$this->address1 = $address1;
$this->address2 = $address2;
$this->address3 = $address3;
$this->cellphone = $cellphone;
$this->city = $city;
$this->company = $company;
$this->country = $country;
$this->firstname = $firstname;
$this->label = $label;
$this->lastname = $lastname;
$this->phone = $phone;
$this->title = $title;
$this->zipcode = $zipcode;
}
/**
* @return string
*/
public function getAddress1()
{
return $this->address1;
}
/**
* @return string
*/
public function getAddress2()
{
return $this->address2;
}
/**
* @return string
*/
public function getAddress3()
{
return $this->address3;
}
/**
* @return string
*/
public function getCellphone()
{
return $this->cellphone;
}
/**
* @return string
*/
public function getCity()
{
return $this->city;
}
/**
* @return null|string
*/
public function getCompany()
{
return $this->company;
}
/**
* @return int
*/
public function getCountry()
{
return $this->country;
}
/**
* @return string
*/
public function getFirstname()
{
return $this->firstname;
}
/**
* @return string
*/
public function getLabel()
{
return $this->label;
}
/**
* @return string
*/
public function getLastname()
{
return $this->lastname;
}
/**
* @return string
*/
public function getPhone()
{
return $this->phone;
}
/**
* @return int
*/
public function getTitle()
{
return $this->title;
}
/**
* @return string
*/
public function getZipcode()
{
return $this->zipcode;
}
/**
* @param \Thelia\Model\Customer $customer
*/
public function setCustomer(Customer $customer)
{
$this->customer = $customer;
}
/**
* @return \Thelia\Model\Customer
*/
public function getCustomer()
{
return $this->customer;
}
/**
* @param \Thelia\Model\Address $address
*/
public function setAddress(Address $address)
{
$this->address = $address;
$this->setCustomer($address->getCustomer());
}
/**
* @return \Thelia\Model\Address
*/
public function getAddress()
{
return $this->address;
}
}

View File

@@ -0,0 +1,54 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Core\Event;
use Symfony\Component\EventDispatcher\Event;
use Thelia\Model\Address;
/**
* Class AddressEvent
* @package Thelia\Core\Event
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class AddressEvent extends ActionEvent
{
/**
* @var \Thelia\Model\Address
*/
protected $address;
function __construct(Address $address)
{
$this->address = $address;
}
/**
* @return \Thelia\Model\Address
*/
public function getAddress()
{
return $this->address;
}
}

View File

@@ -0,0 +1,48 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Core\Event;
class BaseToggleVisibilityEvent extends ActionEvent
{
protected $object_id;
protected $object;
public function __construct($object_id)
{
$this->object_id = $object_id;
}
public function getObjectId()
{
return $this->object_id;
}
public function setObjectId($object_id)
{
$this->object_id = $object_id;
return $this;
}
}

View File

@@ -0,0 +1,77 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Core\Event;
class BaseUpdatePositionEvent extends ActionEvent
{
const POSITION_UP = 1;
const POSITION_DOWN = 2;
const POSITION_ABSOLUTE = 3;
protected $object_id;
protected $mode;
protected $position;
protected $object;
public function __construct($object_id, $mode, $position = null)
{
$this->object_id = $object_id;
$this->mode = $mode;
$this->position = $position;
}
public function getMode()
{
return $this->mode;
}
public function setMode($mode)
{
$this->mode = $mode;
return $this;
}
public function getPosition()
{
return $this->position;
}
public function setPosition($position)
{
$this->position = $position;
return $this;
}
public function getObjectId()
{
return $this->object_id;
}
public function setObjectId($object_id)
{
$this->object_id = $object_id;
return $this;
}
}

2
core/lib/Thelia/Core/Event/CartEvent.php Normal file → Executable file
View File

@@ -26,7 +26,7 @@ namespace Thelia\Core\Event;
use Symfony\Component\EventDispatcher\Event;
use Thelia\Model\Cart;
class CartEvent extends Event
class CartEvent extends ActionEvent
{
protected $cart;
protected $quantity;

2
core/lib/Thelia/Core/Event/CartItemEvent.php Normal file → Executable file
View File

@@ -25,7 +25,7 @@ namespace Thelia\Core\Event;
use Thelia\Model\CartItem;
class CartItemEvent extends InternalEvent
class CartItemEvent extends ActionEvent
{
protected $cartItem;

View File

@@ -0,0 +1,73 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Core\Event;
use Thelia\Model\Category;
class CategoryCreateEvent extends CategoryEvent
{
protected $title;
protected $parent;
protected $locale;
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;
return $this;
}
public function getParent()
{
return $this->parent;
}
public function setParent($parent)
{
$this->parent = $parent;
return $this;
}
public function getLocale()
{
return $this->locale;
}
public function setLocale($locale)
{
$this->locale = $locale;
return $this;
}
}

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