From 696b871acddc7bc2f979f5ba1c4b6b42b4e8da3e Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Thu, 29 Aug 2013 08:49:48 +0200 Subject: [PATCH 01/18] start rewriting --- .../Thelia/Core/Template/Element/BaseLoop.php | 6 +- .../Thelia/Core/Template/Loop/Attribute.php | 2 +- .../Template/Loop/AttributeAvailability.php | 2 +- .../Template/Loop/AttributeCombination.php | 4 +- .../Thelia/Core/Template/Loop/Category.php | 4 +- .../lib/Thelia/Core/Template/Loop/Content.php | 4 +- .../lib/Thelia/Core/Template/Loop/Country.php | 2 +- .../Thelia/Core/Template/Loop/Currency.php | 2 +- .../lib/Thelia/Core/Template/Loop/Feature.php | 2 +- .../Template/Loop/FeatureAvailability.php | 2 +- .../Core/Template/Loop/FeatureValue.php | 2 +- core/lib/Thelia/Core/Template/Loop/Folder.php | 4 +- core/lib/Thelia/Core/Template/Loop/Image.php | 2 +- .../lib/Thelia/Core/Template/Loop/Product.php | 4 +- core/lib/Thelia/Core/Template/Loop/Title.php | 2 +- core/lib/Thelia/Model/Category.php | 4 +- core/lib/Thelia/Model/ConfigQuery.php | 10 ++++ core/lib/Thelia/Model/Content.php | 5 +- core/lib/Thelia/Model/Folder.php | 5 +- core/lib/Thelia/Model/Product.php | 6 +- .../Thelia/Model/Tools/ModelCriteriaTools.php | 8 ++- .../Thelia/Rewriting/RewritingResolver.php | 35 ++++++++++++ .../Thelia/Rewriting/RewritingRetriever.php | 56 +++++++++++++++++++ core/lib/Thelia/Tools/URL.php | 12 ++++ install/insert.sql | 2 + local/config/schema.xml | 25 ++++++--- templates/default/category.html | 4 +- 27 files changed, 173 insertions(+), 43 deletions(-) create mode 100755 core/lib/Thelia/Rewriting/RewritingResolver.php create mode 100755 core/lib/Thelia/Rewriting/RewritingRetriever.php diff --git a/core/lib/Thelia/Core/Template/Element/BaseLoop.php b/core/lib/Thelia/Core/Template/Element/BaseLoop.php index 72f782309..9dcff5ab9 100755 --- a/core/lib/Thelia/Core/Template/Element/BaseLoop.php +++ b/core/lib/Thelia/Core/Template/Element/BaseLoop.php @@ -218,10 +218,10 @@ abstract class BaseLoop } /** - * @param \ModelCriteria $search - * @param $pagination + * @param ModelCriteria $search + * @param $pagination * - * @return array|\PropelModelPager + * @return array|\Propel\Runtime\Util\PropelModelPager */ protected function searchWithPagination(ModelCriteria $search, &$pagination) { diff --git a/core/lib/Thelia/Core/Template/Loop/Attribute.php b/core/lib/Thelia/Core/Template/Loop/Attribute.php index 41721350b..94afc96c7 100755 --- a/core/lib/Thelia/Core/Template/Loop/Attribute.php +++ b/core/lib/Thelia/Core/Template/Loop/Attribute.php @@ -92,7 +92,7 @@ class Attribute extends BaseLoop $lang = $this->getLang(); /* manage translations */ - ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale()); + ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::getDefaultLangWhenNoTranslationAvailable(), $this->request->getSession()->getLocale()); $id = $this->getId(); diff --git a/core/lib/Thelia/Core/Template/Loop/AttributeAvailability.php b/core/lib/Thelia/Core/Template/Loop/AttributeAvailability.php index be42f5dab..771058ad1 100755 --- a/core/lib/Thelia/Core/Template/Loop/AttributeAvailability.php +++ b/core/lib/Thelia/Core/Template/Loop/AttributeAvailability.php @@ -84,7 +84,7 @@ class AttributeAvailability extends BaseLoop $lang = $this->getLang(); /* manage translations */ - ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale()); + ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::getDefaultLangWhenNoTranslationAvailable(), $this->request->getSession()->getLocale()); $id = $this->getId(); diff --git a/core/lib/Thelia/Core/Template/Loop/AttributeCombination.php b/core/lib/Thelia/Core/Template/Loop/AttributeCombination.php index 833f1abb3..97c355763 100755 --- a/core/lib/Thelia/Core/Template/Loop/AttributeCombination.php +++ b/core/lib/Thelia/Core/Template/Loop/AttributeCombination.php @@ -81,7 +81,7 @@ class AttributeCombination extends BaseLoop /* manage attribute translations */ ModelCriteriaTools::getFrontEndI18n( $search, - ConfigQuery::read("default_lang_without_translation", 1), + ConfigQuery::getDefaultLangWhenNoTranslationAvailable(), $this->request->getSession()->getLocale(), array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), AttributeTableMap::TABLE_NAME, @@ -91,7 +91,7 @@ class AttributeCombination extends BaseLoop /* manage attributeAv translations */ ModelCriteriaTools::getFrontEndI18n( $search, - ConfigQuery::read("default_lang_without_translation", 1), + ConfigQuery::getDefaultLangWhenNoTranslationAvailable(), $this->request->getSession()->getLocale(), array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), AttributeAvTableMap::TABLE_NAME, diff --git a/core/lib/Thelia/Core/Template/Loop/Category.php b/core/lib/Thelia/Core/Template/Loop/Category.php index 9b497bb1a..1e959777c 100755 --- a/core/lib/Thelia/Core/Template/Loop/Category.php +++ b/core/lib/Thelia/Core/Template/Loop/Category.php @@ -103,7 +103,7 @@ class Category extends BaseLoop $lang = $this->getLang(); /* manage translations */ - ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale()); + $locale = ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::getDefaultLangWhenNoTranslationAvailable(), $this->request->getSession()->getLocale()); $id = $this->getId(); @@ -185,7 +185,7 @@ class Category extends BaseLoop ->set("DESCRIPTION", $category->getVirtualColumn('i18n_DESCRIPTION')) ->set("POSTSCRIPTUM", $category->getVirtualColumn('i18n_POSTSCRIPTUM')) ->set("PARENT", $category->getParent()) - ->set("URL", $category->getUrl()) + ->set("URL", $category->getUrl($locale)) ->set("PRODUCT_COUNT", $category->countChild()) ->set("VISIBLE", $category->getVisible() ? "1" : "0") ->set("POSITION", $category->getPosition()) diff --git a/core/lib/Thelia/Core/Template/Loop/Content.php b/core/lib/Thelia/Core/Template/Loop/Content.php index 6632a184c..b5a15f82d 100755 --- a/core/lib/Thelia/Core/Template/Loop/Content.php +++ b/core/lib/Thelia/Core/Template/Loop/Content.php @@ -93,7 +93,7 @@ class Content extends BaseLoop $lang = $this->getLang(); /* manage translations */ - ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale()); + $locale = ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::getDefaultLangWhenNoTranslationAvailable(), $this->request->getSession()->getLocale()); $id = $this->getId(); @@ -226,7 +226,7 @@ class Content extends BaseLoop ->set("DESCRIPTION", $content->getVirtualColumn('i18n_DESCRIPTION')) ->set("POSTSCRIPTUM", $content->getVirtualColumn('i18n_POSTSCRIPTUM')) ->set("POSITION", $content->getPosition()) - ->set("URL", $content->getUrl()) + ->set("URL", $content->getUrl($locale)) ; $loopResult->addRow($loopResultRow); diff --git a/core/lib/Thelia/Core/Template/Loop/Country.php b/core/lib/Thelia/Core/Template/Loop/Country.php index c6f7d16de..5064c20b5 100755 --- a/core/lib/Thelia/Core/Template/Loop/Country.php +++ b/core/lib/Thelia/Core/Template/Loop/Country.php @@ -75,7 +75,7 @@ class Country extends BaseLoop $lang = $this->getLang(); /* manage translations */ - ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale()); + ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::getDefaultLangWhenNoTranslationAvailable(), $this->request->getSession()->getLocale()); $id = $this->getId(); diff --git a/core/lib/Thelia/Core/Template/Loop/Currency.php b/core/lib/Thelia/Core/Template/Loop/Currency.php index d833ff8ae..50b606220 100755 --- a/core/lib/Thelia/Core/Template/Loop/Currency.php +++ b/core/lib/Thelia/Core/Template/Loop/Currency.php @@ -74,7 +74,7 @@ class Currency extends BaseLoop $lang = $this->getLang(); /* manage translations */ - ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale(), array('NAME')); + ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::getDefaultLangWhenNoTranslationAvailable(), $this->request->getSession()->getLocale(), array('NAME')); $id = $this->getId(); diff --git a/core/lib/Thelia/Core/Template/Loop/Feature.php b/core/lib/Thelia/Core/Template/Loop/Feature.php index 85d037080..fdce096c0 100755 --- a/core/lib/Thelia/Core/Template/Loop/Feature.php +++ b/core/lib/Thelia/Core/Template/Loop/Feature.php @@ -89,7 +89,7 @@ class Feature extends BaseLoop $lang = $this->getLang(); /* manage translations */ - ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale()); + ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::getDefaultLangWhenNoTranslationAvailable(), $this->request->getSession()->getLocale()); $id = $this->getId(); diff --git a/core/lib/Thelia/Core/Template/Loop/FeatureAvailability.php b/core/lib/Thelia/Core/Template/Loop/FeatureAvailability.php index ce6f8767a..41645aff7 100755 --- a/core/lib/Thelia/Core/Template/Loop/FeatureAvailability.php +++ b/core/lib/Thelia/Core/Template/Loop/FeatureAvailability.php @@ -82,7 +82,7 @@ class FeatureAvailability extends BaseLoop $lang = $this->getLang(); /* manage translations */ - ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale()); + ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::getDefaultLangWhenNoTranslationAvailable(), $this->request->getSession()->getLocale()); $id = $this->getId(); diff --git a/core/lib/Thelia/Core/Template/Loop/FeatureValue.php b/core/lib/Thelia/Core/Template/Loop/FeatureValue.php index 8a29d7c74..2a8cac955 100755 --- a/core/lib/Thelia/Core/Template/Loop/FeatureValue.php +++ b/core/lib/Thelia/Core/Template/Loop/FeatureValue.php @@ -86,7 +86,7 @@ class FeatureValue extends BaseLoop /* manage featureAv translations */ ModelCriteriaTools::getFrontEndI18n( $search, - ConfigQuery::read("default_lang_without_translation", 1), + ConfigQuery::getDefaultLangWhenNoTranslationAvailable(), $this->request->getSession()->getLocale(), array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), FeatureAvTableMap::TABLE_NAME, diff --git a/core/lib/Thelia/Core/Template/Loop/Folder.php b/core/lib/Thelia/Core/Template/Loop/Folder.php index c95b0dc42..4db07cc8f 100755 --- a/core/lib/Thelia/Core/Template/Loop/Folder.php +++ b/core/lib/Thelia/Core/Template/Loop/Folder.php @@ -85,7 +85,7 @@ class Folder extends BaseLoop $lang = $this->getLang(); /* manage translations */ - ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale()); + $locale = ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::getDefaultLangWhenNoTranslationAvailable(), $this->request->getSession()->getLocale()); $id = $this->getId(); @@ -168,7 +168,7 @@ class Folder extends BaseLoop ->set("DESCRIPTION", $folder->getVirtualColumn('i18n_DESCRIPTION')) ->set("POSTSCRIPTUM", $folder->getVirtualColumn('i18n_POSTSCRIPTUM')) ->set("PARENT", $folder->getParent()) - ->set("URL", $folder->getUrl()) + ->set("URL", $folder->getUrl($locale)) ->set("CONTENT_COUNT", $folder->countChild()) ->set("VISIBLE", $folder->getVisible() ? "1" : "0") ->set("POSITION", $folder->getPosition()) diff --git a/core/lib/Thelia/Core/Template/Loop/Image.php b/core/lib/Thelia/Core/Template/Loop/Image.php index a1e866cb2..80aa2fb9a 100755 --- a/core/lib/Thelia/Core/Template/Loop/Image.php +++ b/core/lib/Thelia/Core/Template/Loop/Image.php @@ -215,7 +215,7 @@ class Image extends BaseLoop $search->joinWithI18n( $this->request->getSession()->getLocale(), - (ConfigQuery::read("default_lang_without_translation", 1)) ? Criteria::LEFT_JOIN : Criteria::INNER_JOIN + (ConfigQuery::getDefaultLangWhenNoTranslationAvailable()) ? Criteria::LEFT_JOIN : Criteria::INNER_JOIN ); $results = $this->search($search, $pagination); diff --git a/core/lib/Thelia/Core/Template/Loop/Product.php b/core/lib/Thelia/Core/Template/Loop/Product.php index 10112ef28..7c00c6775 100755 --- a/core/lib/Thelia/Core/Template/Loop/Product.php +++ b/core/lib/Thelia/Core/Template/Loop/Product.php @@ -143,7 +143,7 @@ class Product extends BaseLoop $lang = $this->getLang(); /* manage translations */ - ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale()); + $locale = ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::getDefaultLangWhenNoTranslationAvailable(), $this->request->getSession()->getLocale()); $attributeNonStrictMatch = $this->getAttribute_non_strict_match(); $isPSELeftJoinList = array(); @@ -520,7 +520,7 @@ class Product extends BaseLoop ->set("CHAPO", $product->getVirtualColumn('i18n_CHAPO')) ->set("DESCRIPTION", $product->getVirtualColumn('i18n_DESCRIPTION')) ->set("POSTSCRIPTUM", $product->getVirtualColumn('i18n_POSTSCRIPTUM')) - ->set("URL", $product->getUrl()) + ->set("URL", $product->getUrl($locale)) ->set("BEST_PRICE", $product->getVirtualColumn('real_lowest_price')) ->set("IS_PROMO", $product->getVirtualColumn('main_product_is_promo')) ->set("IS_NEW", $product->getVirtualColumn('main_product_is_new')) diff --git a/core/lib/Thelia/Core/Template/Loop/Title.php b/core/lib/Thelia/Core/Template/Loop/Title.php index caa5e7d87..92451e764 100755 --- a/core/lib/Thelia/Core/Template/Loop/Title.php +++ b/core/lib/Thelia/Core/Template/Loop/Title.php @@ -72,7 +72,7 @@ class Title extends BaseLoop $lang = $this->getLang(); /* manage translations */ - ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale(), array('SHORT', 'LONG')); + ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::getDefaultLangWhenNoTranslationAvailable(), $this->request->getSession()->getLocale(), array('SHORT', 'LONG')); $id = $this->getId(); diff --git a/core/lib/Thelia/Model/Category.php b/core/lib/Thelia/Model/Category.php index 88e7cfc10..5f93f247c 100755 --- a/core/lib/Thelia/Model/Category.php +++ b/core/lib/Thelia/Model/Category.php @@ -4,6 +4,7 @@ namespace Thelia\Model; use Thelia\Model\Base\Category as BaseCategory; use Propel\Runtime\ActiveQuery\Criteria; +use Thelia\Tools\URL; class Category extends BaseCategory { @@ -15,8 +16,9 @@ class Category extends BaseCategory return CategoryQuery::countChild($this->getId()); } - public function getUrl() + public function getUrl($locale) { + return URL::retrieve('category', $this->getId(), $locale); } /** diff --git a/core/lib/Thelia/Model/ConfigQuery.php b/core/lib/Thelia/Model/ConfigQuery.php index b00ef7d8c..4165f4f7c 100755 --- a/core/lib/Thelia/Model/ConfigQuery.php +++ b/core/lib/Thelia/Model/ConfigQuery.php @@ -22,4 +22,14 @@ class ConfigQuery extends BaseConfigQuery { return $value ? $value->getValue() : $default; } + + public static function getDefaultLangWhenNoTranslationAvailable() + { + return ConfigQuery::read("default_lang_without_translation", 1); + } + + public static function isRewritingEnable() + { + return self::read("rewriting_enable") == 1; + } } // ConfigQuery diff --git a/core/lib/Thelia/Model/Content.php b/core/lib/Thelia/Model/Content.php index 3b5af9ede..1a797be89 100755 --- a/core/lib/Thelia/Model/Content.php +++ b/core/lib/Thelia/Model/Content.php @@ -3,11 +3,12 @@ namespace Thelia\Model; use Thelia\Model\Base\Content as BaseContent; +use Thelia\Tools\URL; class Content extends BaseContent { - public function getUrl() + public function getUrl($locale) { - + return URL::retrieve('content', $this->getId(), $locale); } } diff --git a/core/lib/Thelia/Model/Folder.php b/core/lib/Thelia/Model/Folder.php index 1179f6e72..05838e939 100755 --- a/core/lib/Thelia/Model/Folder.php +++ b/core/lib/Thelia/Model/Folder.php @@ -3,6 +3,7 @@ namespace Thelia\Model; use Thelia\Model\Base\Folder as BaseFolder; +use Thelia\Tools\URL; class Folder extends BaseFolder { @@ -14,9 +15,9 @@ class Folder extends BaseFolder return FolderQuery::countChild($this->getId()); } - public function getUrl() + public function getUrl($locale) { - + return URL::retrieve('folder', $this->getId(), $locale); } /** diff --git a/core/lib/Thelia/Model/Product.php b/core/lib/Thelia/Model/Product.php index ae693e0aa..e7d0586cc 100755 --- a/core/lib/Thelia/Model/Product.php +++ b/core/lib/Thelia/Model/Product.php @@ -3,12 +3,12 @@ namespace Thelia\Model; use Thelia\Model\Base\Product as BaseProduct; -use Thelia\Model\ProductSaleElements; +use Thelia\Tools\URL; class Product extends BaseProduct { - public function getUrl() + public function getUrl($locale) { - + return URL::retrieve('product', $this->getId(), $locale); } } diff --git a/core/lib/Thelia/Model/Tools/ModelCriteriaTools.php b/core/lib/Thelia/Model/Tools/ModelCriteriaTools.php index e9323ebfa..47c18a162 100755 --- a/core/lib/Thelia/Model/Tools/ModelCriteriaTools.php +++ b/core/lib/Thelia/Model/Tools/ModelCriteriaTools.php @@ -109,10 +109,14 @@ class ModelCriteriaTools } } + $askedLocale = $lang === null ? $currentLocale : $localeSearch->getLocale(); + if($backendContext) { - self::getBackEndI18n($search, $lang === null ? $currentLocale : $localeSearch->getLocale(), $columns, $foreignTable, $foreignKey); + self::getBackEndI18n($search, $askedLocale, $columns, $foreignTable, $foreignKey); } else { - self::getFrontEndI18n($search, $defaultLangWithoutTranslation, $lang === null ? $currentLocale : $localeSearch->getLocale(), $columns, $foreignTable, $foreignKey); + self::getFrontEndI18n($search, $defaultLangWithoutTranslation, $askedLocale, $columns, $foreignTable, $foreignKey); } + + return $askedLocale; } } diff --git a/core/lib/Thelia/Rewriting/RewritingResolver.php b/core/lib/Thelia/Rewriting/RewritingResolver.php new file mode 100755 index 000000000..818dbec32 --- /dev/null +++ b/core/lib/Thelia/Rewriting/RewritingResolver.php @@ -0,0 +1,35 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Rewriting; + +/** + * Class RewritingResolver + * @package Thelia\Rewriting + * @author Etienne Roudeix + * + * This class provides methods to resolve rewritten URL as a query + */ +class RewritingResolver +{ + +} diff --git a/core/lib/Thelia/Rewriting/RewritingRetriever.php b/core/lib/Thelia/Rewriting/RewritingRetriever.php new file mode 100755 index 000000000..5c49c4e2e --- /dev/null +++ b/core/lib/Thelia/Rewriting/RewritingRetriever.php @@ -0,0 +1,56 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Rewriting; + +use Propel\Runtime\ActiveQuery\Criteria; +use Thelia\Model\Base\RewritingUrlQuery; + +/** + * Class RewritingRetriever + * @package Thelia\Rewriting + * @author Etienne Roudeix + * + * This class provides methods to retrieve a rewritten URL from a query + */ +class RewritingRetriever +{ + public function getViewUrl($view, $viewId, $viewLocale) + { + $url = RewritingUrlQuery::create() + ->joinRewritingArgument('ra', Criteria::LEFT_JOIN) + ->where('ISNULL(`ra`.REWRITING_URL_ID)') + ->filterByView($view) + ->filterByViewId($viewId) + ->filterByViewLocale($viewLocale) + ->filterByRedirected(null) + ->orderByUpdatedAt(Criteria::DESC) + ->findOne(); + + return $url === null ? null : $url->getUrl(); + } + + /*public function getSpecificUrl($view, $viewId, $viewLocale, $viewOtherParameters = array()) + { + + }*/ +} diff --git a/core/lib/Thelia/Tools/URL.php b/core/lib/Thelia/Tools/URL.php index 5a88fa922..01958bc1c 100755 --- a/core/lib/Thelia/Tools/URL.php +++ b/core/lib/Thelia/Tools/URL.php @@ -24,6 +24,7 @@ namespace Thelia\Tools; use Thelia\Model\ConfigQuery; +use Thelia\Rewriting\RewritingRetriever; class URL { @@ -101,4 +102,15 @@ class URL return self::absoluteUrl($path, $parameters); } + + public static function retrieve($view, $viewId, $viewLocale) + { + $rewrittenUrl = null; + if(ConfigQuery::isRewritingEnable()) { + $retriever = new RewritingRetriever(); + $rewrittenUrl = $retriever->getViewUrl($view, $viewId, $viewLocale); + } + + return $rewrittenUrl === null ? self::viewUrl($view, array($view . '_id' => $viewId, 'locale' => $viewLocale)) : $rewrittenUrl; + } } diff --git a/install/insert.sql b/install/insert.sql index cbb6725f3..4336eaa0c 100755 --- a/install/insert.sql +++ b/install/insert.sql @@ -7,6 +7,8 @@ INSERT INTO `lang`(`id`,`title`,`code`,`locale`,`url`,`by_default`,`created_at`, INSERT INTO `config` (`name`, `value`, `secured`, `hidden`, `created_at`, `updated_at`) VALUES ('session_config.default', '1', 1, 1, NOW(), NOW()), ('verifyStock', '1', 1, 0, NOW(), NOW()), +('default_lang_without_translation', '1', 1, 0, NOW(), NOW()), +('rewriting_enable', '0', 1, 0, NOW(), NOW()), ('imagine_graphic_driver', 'gd', 1, 0, NOW(), NOW()), ('default_images_quality_percent', '75', 1, 0, NOW(), NOW()), ('original_image_delivery_mode', 'symlink', 1, 0, NOW(), NOW()), diff --git a/local/config/schema.xml b/local/config/schema.xml index 0e20f2562..dbd57314b 100755 --- a/local/config/schema.xml +++ b/local/config/schema.xml @@ -1095,24 +1095,19 @@ - - - - - - + - - - + + +
@@ -1126,4 +1121,16 @@
+ + + + + + + + + + + +
diff --git a/templates/default/category.html b/templates/default/category.html index af4cdcf14..440866a26 100755 --- a/templates/default/category.html +++ b/templates/default/category.html @@ -22,7 +22,7 @@ {loop name="product" type="product" category="#ID"}
-

PRODUCT : #REF (#LOOP_COUNT / #LOOP_TOTAL)

+

PRODUCT #ID : #REF (#LOOP_COUNT / #LOOP_TOTAL)

#TITLE

#DESCRIPTION

@@ -111,7 +111,7 @@ {loop name="product" type="product" category="#ID"}
-

PRODUCT : #REF (#LOOP_COUNT / #LOOP_TOTAL)

+

PRODUCT #ID : #REF (#LOOP_COUNT / #LOOP_TOTAL)

#TITLE

#DESCRIPTION

From 75b456429763840ccf85a44d45e6e2a7c4187600 Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Thu, 29 Aug 2013 09:20:58 +0200 Subject: [PATCH 02/18] rewriting tables --- local/config/schema.xml | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/local/config/schema.xml b/local/config/schema.xml index dbd57314b..0e20f2562 100755 --- a/local/config/schema.xml +++ b/local/config/schema.xml @@ -1095,19 +1095,24 @@ + - + + + + + + + + - - -
@@ -1121,16 +1126,4 @@
- - - - - - - - - - - -
From 4ba16dc2909586e03588cbd2085b5b5620e9afa0 Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Fri, 30 Aug 2013 09:13:54 +0200 Subject: [PATCH 03/18] sid : rewriting --- .../Thelia/Rewriting/RewritingRetriever.php | 57 +++++++++++++++++-- .../Rewriting/RewritingRetrieverTest.php | 44 ++++++++++++++ core/lib/Thelia/Tests/Tools/URLTest.php | 39 +++++++++++++ core/lib/Thelia/Tools/URL.php | 34 +++++++++++ web/index_dev.php | 2 + 5 files changed, 170 insertions(+), 6 deletions(-) create mode 100755 core/lib/Thelia/Tests/Rewriting/RewritingRetrieverTest.php create mode 100755 core/lib/Thelia/Tests/Tools/URLTest.php diff --git a/core/lib/Thelia/Rewriting/RewritingRetriever.php b/core/lib/Thelia/Rewriting/RewritingRetriever.php index 5c49c4e2e..546b9d077 100755 --- a/core/lib/Thelia/Rewriting/RewritingRetriever.php +++ b/core/lib/Thelia/Rewriting/RewritingRetriever.php @@ -24,6 +24,7 @@ namespace Thelia\Rewriting; use Propel\Runtime\ActiveQuery\Criteria; use Thelia\Model\Base\RewritingUrlQuery; +use Thelia\Model\Map\RewritingUrlTableMap; /** * Class RewritingRetriever @@ -36,7 +37,14 @@ class RewritingRetriever { public function getViewUrl($view, $viewId, $viewLocale) { - $url = RewritingUrlQuery::create() + $url = $this->getViewUrlQuery($view, $viewId, $viewLocale); + + return $url === null ? null : $url->getUrl(); + } + + protected function getViewUrlQuery($view, $viewId, $viewLocale) + { + return RewritingUrlQuery::create() ->joinRewritingArgument('ra', Criteria::LEFT_JOIN) ->where('ISNULL(`ra`.REWRITING_URL_ID)') ->filterByView($view) @@ -45,12 +53,49 @@ class RewritingRetriever ->filterByRedirected(null) ->orderByUpdatedAt(Criteria::DESC) ->findOne(); + } + + public function getSpecificUrl($view = null, $viewId = null, $viewLocale = null, $viewOtherParameters = array()) + { + $urlQuery = RewritingUrlQuery::create() + ->joinRewritingArgument('ra', Criteria::LEFT_JOIN) + ->withColumn('`ra`.PARAMETER', 'ra_parameter') + ->withColumn('`ra`.VALUE', 'ra_value') + ->filterByView($view) + ->filterByViewId($viewId) + ->filterByViewLocale($viewLocale) + ->filterByRedirected(null) + ->orderByUpdatedAt(Criteria::DESC); + + $otherParametersCount = count($viewOtherParameters); + if($otherParametersCount > 0) { + $parameterConditions = array(); + foreach($viewOtherParameters as $parameter => $value) { + $conditionName = 'other_parameter_condition_' . count($parameterConditions); + $urlQuery->condition('parameter_condition', '`ra_parameter`= ?', $parameter, \PDO::PARAM_STR) + ->condition('value_condition', '`ra_value` = ?', $value, \PDO::PARAM_STR) + ->combine(array('parameter_condition', 'value_condition'), Criteria::LOGICAL_AND, $conditionName); + $parameterConditions[] = $conditionName; + } + + $urlQuery->combine($parameterConditions, Criteria::LOGICAL_OR, 'parameter_full_condition'); + + $urlQuery->groupBy(RewritingUrlTableMap::ID); + + $urlQuery->condition('count_condition', 'COUNT(' . RewritingUrlTableMap::ID . ') = ?', $otherParametersCount, \PDO::PARAM_INT) + ->combine(array('count_condition', 'parameter_full_condition'), Criteria::LOGICAL_AND, 'full_having_condition'); + + + $urlQuery + ->having(array('full_having_condition')) + //->having('COUNT(' . RewritingUrlTableMap::ID . ') = ?', $otherParametersCount, \PDO::PARAM_INT) + ; + } else { + $urlQuery->where('ISNULL(`ra`.REWRITING_URL_ID)'); + } + + $url = $urlQuery->findOne(); return $url === null ? null : $url->getUrl(); } - - /*public function getSpecificUrl($view, $viewId, $viewLocale, $viewOtherParameters = array()) - { - - }*/ } diff --git a/core/lib/Thelia/Tests/Rewriting/RewritingRetrieverTest.php b/core/lib/Thelia/Tests/Rewriting/RewritingRetrieverTest.php new file mode 100755 index 000000000..741c22b4e --- /dev/null +++ b/core/lib/Thelia/Tests/Rewriting/RewritingRetrieverTest.php @@ -0,0 +1,44 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Tests\Rewriting; + +use Thelia\Rewriting\RewritingRetriever; + +/** + * + * @author Etienne Roudeix + * + */ +class RewritingRetrieverTest extends \PHPUnit_Framework_TestCase +{ + public function testGetViewUrl() + { + + } + + public function testGetSpecificUrl() + { + + } +} diff --git a/core/lib/Thelia/Tests/Tools/URLTest.php b/core/lib/Thelia/Tests/Tools/URLTest.php new file mode 100755 index 000000000..0c99651b4 --- /dev/null +++ b/core/lib/Thelia/Tests/Tools/URLTest.php @@ -0,0 +1,39 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Tests\Type; + +use Thelia\Tools\URL; + +/** + * + * @author Etienne Roudeix + * + */ +class URLTest extends \PHPUnit_Framework_TestCase +{ + public function testRetrieve() + { + + } +} diff --git a/core/lib/Thelia/Tools/URL.php b/core/lib/Thelia/Tools/URL.php index 01958bc1c..267e5554c 100755 --- a/core/lib/Thelia/Tools/URL.php +++ b/core/lib/Thelia/Tools/URL.php @@ -23,6 +23,7 @@ namespace Thelia\Tools; +use Symfony\Component\HttpFoundation\Request; use Thelia\Model\ConfigQuery; use Thelia\Rewriting\RewritingRetriever; @@ -103,6 +104,13 @@ class URL return self::absoluteUrl($path, $parameters); } + /** + * @param $view + * @param $viewId + * @param $viewLocale + * + * @return null|string + */ public static function retrieve($view, $viewId, $viewLocale) { $rewrittenUrl = null; @@ -113,4 +121,30 @@ class URL return $rewrittenUrl === null ? self::viewUrl($view, array($view . '_id' => $viewId, 'locale' => $viewLocale)) : $rewrittenUrl; } + + public static function retrieveCurrent(Request $request) + { + $rewrittenUrl = null; + if(ConfigQuery::isRewritingEnable()) { + $view = $request->query->get('view', null); + $viewId = $view === null ? null : $request->query->get($view . '_id', null); + $viewLocale = $request->query->get('locale', null); + + $allOtherParameters = $request->query->all(); + if($view !== null) { + unset($allOtherParameters['view']); + } + if($viewId !== null) { + unset($allOtherParameters[$view . '_id']); + } + if($viewLocale !== null) { + unset($allOtherParameters['locale']); + } + + $retriever = new RewritingRetriever(); + $rewrittenUrl = $retriever->getSpecificUrl($view, $viewId, $viewLocale, $allOtherParameters); + } + + return $rewrittenUrl === null ? self::viewUrl($view, array($view . '_id' => $viewId, 'locale' => $viewLocale)) : $rewrittenUrl; + } } diff --git a/web/index_dev.php b/web/index_dev.php index 8991dc4a8..b5a98978a 100755 --- a/web/index_dev.php +++ b/web/index_dev.php @@ -21,6 +21,8 @@ if ( false === in_array($request->getClientIp(), $trustIp)) { $thelia = new Thelia("dev", true); +\Thelia\Tools\URL::retrieveCurrent($request); + $response = $thelia->handle($request)->prepare($request)->send(); $thelia->terminate($request, $response); From 3c71aa613f9a10347dfa003699ea476b0eb67ee5 Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Fri, 30 Aug 2013 14:30:33 +0200 Subject: [PATCH 04/18] url global substitution --- .../Core/Template/Loop/FeatureValue.php | 3 +- .../Thelia/Core/Template/ParserContext.php | 6 +- .../Template/Smarty/Plugins/UrlGenerator.php | 65 ++++++++- .../Thelia/Model/Map/RewritingUrlTableMap.php | 4 +- .../Thelia/Model/Tools/ModelCriteriaTools.php | 14 +- .../Thelia/Rewriting/RewritingRetriever.php | 13 +- core/lib/Thelia/Tools/URL.php | 26 ++-- install/thelia.sql | 4 +- local/config/schema.xml | 4 +- .../admin/default/includes/header.inc.html | 2 +- templates/default/cart.html | 2 +- templates/default/category.html | 137 +++--------------- templates/default/connexion.html | 4 +- templates/default/login.html | 6 +- web/index_dev.php | 2 - 15 files changed, 126 insertions(+), 166 deletions(-) diff --git a/core/lib/Thelia/Core/Template/Loop/FeatureValue.php b/core/lib/Thelia/Core/Template/Loop/FeatureValue.php index 2a8cac955..62f9ceb47 100755 --- a/core/lib/Thelia/Core/Template/Loop/FeatureValue.php +++ b/core/lib/Thelia/Core/Template/Loop/FeatureValue.php @@ -90,7 +90,8 @@ class FeatureValue extends BaseLoop $this->request->getSession()->getLocale(), array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), FeatureAvTableMap::TABLE_NAME, - 'FEATURE_AV_ID' + 'FEATURE_AV_ID', + true ); $feature = $this->getFeature(); diff --git a/core/lib/Thelia/Core/Template/ParserContext.php b/core/lib/Thelia/Core/Template/ParserContext.php index 03c3cf45f..af12018e6 100755 --- a/core/lib/Thelia/Core/Template/ParserContext.php +++ b/core/lib/Thelia/Core/Template/ParserContext.php @@ -40,11 +40,7 @@ class ParserContext implements \IteratorAggregate public function __construct(Request $request) { // Setup basic variables - $this - ->set('BASE_URL' , ConfigQuery::read('base_url', '/')) - ->set('INDEX_PAGE' , URL::getIndexPage()) - ->set('RETURN_TO_URL' , URL::absoluteUrl($request->getSession()->getReturnToUrl())) - ->set('THELIA_VERSION' , ConfigQuery::read('thelia_version', 'undefined')) + $this->set('THELIA_VERSION' , ConfigQuery::read('thelia_version', 'undefined')) ; } diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/UrlGenerator.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/UrlGenerator.php index b3814f088..33e699c43 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/UrlGenerator.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/UrlGenerator.php @@ -47,14 +47,15 @@ class UrlGenerator extends AbstractSmartyPlugin public function generateUrlFunction($params, &$smarty) { // the path to process - $path = $this->getParam($params, 'path'); + $path = $this->getParam($params, 'path'); - $target = $this->getParam($params, 'target', null); + $target = $this->getParam($params, 'target', null); - $url = URL::absoluteUrl($path, $this->getArgsFromParam($params, array('path', 'target'))); + $url = URL::absoluteUrl($path, $this->getArgsFromParam($params, array('path', 'target'))); - if ($target != null) $url .= '#'.$target; - return $url; + if ($target != null) $url .= '#'.$target; + + return $url; } /** @@ -81,6 +82,15 @@ class UrlGenerator extends AbstractSmartyPlugin return $this->generateViewUrlFunction($params, true); } + public function navigateToUrlFunction($params, &$smarty) + { + $to = $this->getParam($params, 'to', null); + + $toMethod = $this->getNavigateToMethod($to); + + return $this->$toMethod(); + } + protected function generateViewUrlFunction($params, $forAdmin) { // the view name (without .html) @@ -125,7 +135,50 @@ class UrlGenerator extends AbstractSmartyPlugin return array( new SmartyPluginDescriptor('function', 'url', $this, 'generateUrlFunction'), new SmartyPluginDescriptor('function', 'viewurl', $this, 'generateFrontViewUrlFunction'), - new SmartyPluginDescriptor('function', 'admin_viewurl', $this, 'generateAdminViewUrlFunction') + new SmartyPluginDescriptor('function', 'admin_viewurl', $this, 'generateAdminViewUrlFunction'), + new SmartyPluginDescriptor('function', 'navigate', $this, 'navigateToUrlFunction'), ); } + + /** + * @return array sur le format "to_value" => "method_name" + */ + protected function getNavigateToValues() + { + return array( + "current" => "getCurrentUrl", + "return_to" => "getReturnToUrl", + "index" => "getIndexUrl", + ); + } + + protected function getNavigateToMethod($to) + { + if($to === null) { + throw new \InvalidArgumentException("Missing 'to' parameter in `navigate` substitution."); + } + + $navigateToValues = $this->getNavigateToValues(); + + if(!array_key_exists($to, $navigateToValues)) { + throw new \InvalidArgumentException("Incorrect value for parameter `to` in `navigate` substitution."); + } + + return $navigateToValues[$to]; + } + + protected function getCurrentUrl() + { + return URL::retrieveCurrent($this->request); + } + + protected function getReturnToUrl() + { + return URL::absoluteUrl($this->request->getSession()->getReturnToUrl()); + } + + protected function getIndexUrl() + { + return Url::getIndexPage(); + } } diff --git a/core/lib/Thelia/Model/Map/RewritingUrlTableMap.php b/core/lib/Thelia/Model/Map/RewritingUrlTableMap.php index c6d5e5473..1d6129ed8 100644 --- a/core/lib/Thelia/Model/Map/RewritingUrlTableMap.php +++ b/core/lib/Thelia/Model/Map/RewritingUrlTableMap.php @@ -162,9 +162,9 @@ class RewritingUrlTableMap extends TableMap // columns $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); $this->addColumn('URL', 'Url', 'VARCHAR', true, 255, null); - $this->addColumn('VIEW', 'View', 'VARCHAR', false, 255, null); + $this->addColumn('VIEW', 'View', 'VARCHAR', true, 255, null); $this->addColumn('VIEW_ID', 'ViewId', 'VARCHAR', false, 255, null); - $this->addColumn('VIEW_LOCALE', 'ViewLocale', 'VARCHAR', false, 255, null); + $this->addColumn('VIEW_LOCALE', 'ViewLocale', 'VARCHAR', true, 255, null); $this->addForeignKey('REDIRECTED', 'Redirected', 'INTEGER', 'rewriting_url', 'ID', false, null, null); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); diff --git a/core/lib/Thelia/Model/Tools/ModelCriteriaTools.php b/core/lib/Thelia/Model/Tools/ModelCriteriaTools.php index 47c18a162..209006988 100755 --- a/core/lib/Thelia/Model/Tools/ModelCriteriaTools.php +++ b/core/lib/Thelia/Model/Tools/ModelCriteriaTools.php @@ -23,7 +23,7 @@ class ModelCriteriaTools * @param null $foreignTable * @param string $foreignKey */ - public static function getFrontEndI18n(ModelCriteria &$search, $defaultLangWithoutTranslation, $askedLocale, $columns = array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), $foreignTable = null, $foreignKey = 'ID') + public static function getFrontEndI18n(ModelCriteria &$search, $defaultLangWithoutTranslation, $askedLocale, $columns = array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), $foreignTable = null, $foreignKey = 'ID', $forceReturn = false) { if($foreignTable === null) { $foreignTable = $search->getTableMap()->getName(); @@ -32,13 +32,13 @@ class ModelCriteriaTools $aliasPrefix = $foreignTable . '_'; } - $askedLocaleI18nAlias = 'asked_locale_i18n'; - $defaultLocaleI18nAlias = 'default_locale_i18n'; + $askedLocaleI18nAlias = $aliasPrefix . 'asked_locale_i18n'; + $defaultLocaleI18nAlias = $aliasPrefix . 'default_locale_i18n'; if($defaultLangWithoutTranslation == 0) { $askedLocaleJoin = new Join(); $askedLocaleJoin->addExplicitCondition($search->getTableMap()->getName(), $foreignKey, null, $foreignTable . '_i18n', 'ID', $askedLocaleI18nAlias); - $askedLocaleJoin->setJoinType(Criteria::INNER_JOIN); + $askedLocaleJoin->setJoinType($forceReturn === false ? Criteria::INNER_JOIN : Criteria::LEFT_JOIN); $search->addJoinObject($askedLocaleJoin, $askedLocaleI18nAlias) ->addJoinCondition($askedLocaleI18nAlias ,'`' . $askedLocaleI18nAlias . '`.LOCALE = ?', $askedLocale, null, \PDO::PARAM_STR); @@ -67,7 +67,9 @@ class ModelCriteriaTools $search->withColumn('NOT ISNULL(`' . $askedLocaleI18nAlias . '`.`ID`)', $aliasPrefix . 'IS_TRANSLATED'); - $search->where('NOT ISNULL(`' . $askedLocaleI18nAlias . '`.ID)')->_or()->where('NOT ISNULL(`' . $defaultLocaleI18nAlias . '`.ID)'); + if(!$forceReturn) { + $search->where('NOT ISNULL(`' . $askedLocaleI18nAlias . '`.ID)')->_or()->where('NOT ISNULL(`' . $defaultLocaleI18nAlias . '`.ID)'); + } foreach($columns as $column) { $search->withColumn('CASE WHEN NOT ISNULL(`' . $askedLocaleI18nAlias . '`.ID) THEN `' . $askedLocaleI18nAlias . '`.`' . $column . '` ELSE `' . $defaultLocaleI18nAlias . '`.`' . $column . '` END', $aliasPrefix . 'i18n_' . $column); @@ -84,7 +86,7 @@ class ModelCriteriaTools $aliasPrefix = $foreignTable . '_'; } - $askedLocaleI18nAlias = 'asked_locale_i18n'; + $askedLocaleI18nAlias = $aliasPrefix . 'asked_locale_i18n'; $askedLocaleJoin = new Join(); $askedLocaleJoin->addExplicitCondition($search->getTableMap()->getName(), $foreignKey, null, $foreignTable . '_i18n', 'ID', $askedLocaleI18nAlias); diff --git a/core/lib/Thelia/Rewriting/RewritingRetriever.php b/core/lib/Thelia/Rewriting/RewritingRetriever.php index 546b9d077..73b09dd2c 100755 --- a/core/lib/Thelia/Rewriting/RewritingRetriever.php +++ b/core/lib/Thelia/Rewriting/RewritingRetriever.php @@ -35,7 +35,7 @@ use Thelia\Model\Map\RewritingUrlTableMap; */ class RewritingRetriever { - public function getViewUrl($view, $viewId, $viewLocale) + public function getViewUrl($view, $viewLocale, $viewId) { $url = $this->getViewUrlQuery($view, $viewId, $viewLocale); @@ -48,22 +48,22 @@ class RewritingRetriever ->joinRewritingArgument('ra', Criteria::LEFT_JOIN) ->where('ISNULL(`ra`.REWRITING_URL_ID)') ->filterByView($view) - ->filterByViewId($viewId) ->filterByViewLocale($viewLocale) + ->filterByViewId($viewId) ->filterByRedirected(null) ->orderByUpdatedAt(Criteria::DESC) ->findOne(); } - public function getSpecificUrl($view = null, $viewId = null, $viewLocale = null, $viewOtherParameters = array()) + public function getSpecificUrl($view, $viewLocale, $viewId = null, $viewOtherParameters = array()) { $urlQuery = RewritingUrlQuery::create() ->joinRewritingArgument('ra', Criteria::LEFT_JOIN) ->withColumn('`ra`.PARAMETER', 'ra_parameter') ->withColumn('`ra`.VALUE', 'ra_value') ->filterByView($view) - ->filterByViewId($viewId) ->filterByViewLocale($viewLocale) + ->filterByViewId($viewId) ->filterByRedirected(null) ->orderByUpdatedAt(Criteria::DESC); @@ -86,10 +86,7 @@ class RewritingRetriever ->combine(array('count_condition', 'parameter_full_condition'), Criteria::LOGICAL_AND, 'full_having_condition'); - $urlQuery - ->having(array('full_having_condition')) - //->having('COUNT(' . RewritingUrlTableMap::ID . ') = ?', $otherParametersCount, \PDO::PARAM_INT) - ; + $urlQuery->having(array('full_having_condition')); } else { $urlQuery->where('ISNULL(`ra`.REWRITING_URL_ID)'); } diff --git a/core/lib/Thelia/Tools/URL.php b/core/lib/Thelia/Tools/URL.php index 267e5554c..1bf0e566c 100755 --- a/core/lib/Thelia/Tools/URL.php +++ b/core/lib/Thelia/Tools/URL.php @@ -53,7 +53,11 @@ class URL // Already absolute ? if (substr($path, 0, 4) != 'http') { - $root = $path_only == self::PATH_TO_FILE ? ConfigQuery::read('base_url', '/') : self::getIndexPage(); + /** + * @etienne : can't be done here for it's already done in ::viewUrl / ::adminViewUrl + */ + //$root = $path_only == self::PATH_TO_FILE ? ConfigQuery::read('base_url', '/') : self::getIndexPage(); + $root = $path_only == self::PATH_TO_FILE ? ConfigQuery::read('base_url', '/') : ''; $base = rtrim($root, '/') . '/' . ltrim($path, '/'); } else @@ -116,7 +120,7 @@ class URL $rewrittenUrl = null; if(ConfigQuery::isRewritingEnable()) { $retriever = new RewritingRetriever(); - $rewrittenUrl = $retriever->getViewUrl($view, $viewId, $viewLocale); + $rewrittenUrl = $retriever->getViewUrl($view, $viewLocale, $viewId); } return $rewrittenUrl === null ? self::viewUrl($view, array($view . '_id' => $viewId, 'locale' => $viewLocale)) : $rewrittenUrl; @@ -127,24 +131,26 @@ class URL $rewrittenUrl = null; if(ConfigQuery::isRewritingEnable()) { $view = $request->query->get('view', null); - $viewId = $view === null ? null : $request->query->get($view . '_id', null); $viewLocale = $request->query->get('locale', null); + $viewId = $view === null ? null : $request->query->get($view . '_id', null); - $allOtherParameters = $request->query->all(); + $allParameters = $request->query->all(); + $allParametersWithoutView = $allParameters; if($view !== null) { - unset($allOtherParameters['view']); + unset($allParametersWithoutView['view']); + } + $allOtherParameters = $allParametersWithoutView; + if($viewLocale !== null) { + unset($allOtherParameters['locale']); } if($viewId !== null) { unset($allOtherParameters[$view . '_id']); } - if($viewLocale !== null) { - unset($allOtherParameters['locale']); - } $retriever = new RewritingRetriever(); - $rewrittenUrl = $retriever->getSpecificUrl($view, $viewId, $viewLocale, $allOtherParameters); + $rewrittenUrl = $retriever->getSpecificUrl($view, $viewLocale, $viewId, $allOtherParameters); } - return $rewrittenUrl === null ? self::viewUrl($view, array($view . '_id' => $viewId, 'locale' => $viewLocale)) : $rewrittenUrl; + return $rewrittenUrl === null ? self::viewUrl($view, $allParametersWithoutView) : $rewrittenUrl; } } diff --git a/install/thelia.sql b/install/thelia.sql index 1993ee084..99b18513e 100755 --- a/install/thelia.sql +++ b/install/thelia.sql @@ -1443,9 +1443,9 @@ CREATE TABLE `rewriting_url` ( `id` INTEGER NOT NULL AUTO_INCREMENT, `url` VARCHAR(255) NOT NULL, - `view` VARCHAR(255), + `view` VARCHAR(255) NOT NULL, `view_id` VARCHAR(255), - `view_locale` VARCHAR(255), + `view_locale` VARCHAR(255) NOT NULL, `redirected` INTEGER, `created_at` DATETIME, `updated_at` DATETIME, diff --git a/local/config/schema.xml b/local/config/schema.xml index 0e20f2562..17fcf612f 100755 --- a/local/config/schema.xml +++ b/local/config/schema.xml @@ -1096,9 +1096,9 @@ - + - + diff --git a/templates/admin/default/includes/header.inc.html b/templates/admin/default/includes/header.inc.html index 65500f05a..05578de6b 100755 --- a/templates/admin/default/includes/header.inc.html +++ b/templates/admin/default/includes/header.inc.html @@ -67,7 +67,7 @@ {/loop} - + diff --git a/templates/default/cart.html b/templates/default/cart.html index 03ec8e3ee..5597d28ad 100755 --- a/templates/default/cart.html +++ b/templates/default/cart.html @@ -8,7 +8,7 @@ {form name="thelia.cart.add" } -{* We use $INDEX_PAGE as form action to avoid mixing post and get data *} +{* We use {navigate to="index"} as form action to avoid mixing post and get data *}
{* diff --git a/templates/default/category.html b/templates/default/category.html index 440866a26..dd5c6a20a 100755 --- a/templates/default/category.html +++ b/templates/default/category.html @@ -22,34 +22,10 @@ {loop name="product" type="product" category="#ID"}
-

PRODUCT #ID : #REF (#LOOP_COUNT / #LOOP_TOTAL)

+

PRODUCT #ID : #REF (#LOOP_COUNT / #LOOP_TOTAL)

#TITLE

#DESCRIPTION

- {ifloop rel="acc"} -
Accessories
-
    - {loop name="acc" type="accessory" product="#ID" order="accessory"} -
  • #REF
  • - {/loop} -
- {/ifloop} - {elseloop rel="acc"} -
No accessory
- {/elseloop} - - {ifloop rel="prod_ass_cont"} -
Associated Content
-
    - {loop name="prod_ass_cont" type="associated_content" product="#ID" order="associated_content"} -
  • #TITLE
  • - {/loop} -
- {/ifloop} - {elseloop rel="prod_ass_cont"} -
No associated content
- {/elseloop} - {ifloop rel="ft"}
Features
    @@ -67,29 +43,6 @@ {elseloop rel="ft"}
    No feature
    {/elseloop} - -
    Product sale elements
    - - {assign var=current_product value=#ID} - {loop name="pse" type="product_sale_elements" product="#ID"} -
    - {loop name="combi" type="attribute_combination" product_sale_elements="#ID"} - #ATTRIBUTE_TITLE = #ATTRIBUTE_AVAILABILITY_TITLE
    - {/loop} -
    #WEIGHT g -
    {if #IS_PROMO == 1} #PROMO_PRICE € (instead of #PRICE) {else} #PRICE € {/if} -

    - Add - - to my cart -
-
- {/loop} - {/loop} {loop name="catgory1" type="category" parent="#ID"} @@ -110,75 +63,29 @@ {loop name="product" type="product" category="#ID"} -
-

PRODUCT #ID : #REF (#LOOP_COUNT / #LOOP_TOTAL)

-

#TITLE

-

#DESCRIPTION

+
+

PRODUCT #ID : #REF (#LOOP_COUNT / #LOOP_TOTAL)

+

#TITLE

+

#DESCRIPTION

- {ifloop rel="acc"} -
Accessories
-
    - {loop name="acc" type="accessory" product="#ID" order="accessory"} -
  • #REF
  • - {/loop} -
- {/ifloop} - {elseloop rel="acc"} -
No accessory
- {/elseloop} - - {ifloop rel="prod_ass_cont"} -
Associated Content
-
    - {loop name="prod_ass_cont" type="associated_content" product="#ID" order="associated_content"} -
  • #TITLE
  • - {/loop} -
- {/ifloop} - {elseloop rel="prod_ass_cont"} -
No associated content
- {/elseloop} - - {ifloop rel="ft"} -
Features
-
    - {loop name="ft" type="feature" order="manual" product="#ID"} -
  • - #TITLE : - {loop name="ft_v" type="feature_value" product="{$current_product}" feature="#ID"} - #TITLE / #PERSONAL_VALUE + {ifloop rel="ft"} +
    Features
    +
      + {assign var=current_product value=#ID} + {loop name="ft" type="feature" order="manual" product="#ID"} +
    • + #TITLE : + {loop name="ft_v" type="feature_value" product="{$current_product}" feature="#ID"} + #TITLE / #PERSONAL_VALUE + {/loop} +
    • {/loop} - - {/loop} -
    - {/ifloop} - {elseloop rel="ft"} -
    No feature
    - {/elseloop} - -
    Product sale elements
    - - {assign var=current_product value=#ID} - {loop name="pse" type="product_sale_elements" product="#ID"} -
    - {loop name="combi" type="attribute_combination" product_sale_elements="#ID"} - #ATTRIBUTE_TITLE = #ATTRIBUTE_AVAILABILITY_TITLE
    - {/loop} -
    #WEIGHT g -
    {if #IS_PROMO == 1} #PROMO_PRICE € (instead of #PRICE) {else} #PRICE € {/if} -

    - Add - - to my cart -
-
- {/loop} - -
+ + {/ifloop} + {elseloop rel="ft"} +
No feature
+ {/elseloop} + {/loop} {/loop} diff --git a/templates/default/connexion.html b/templates/default/connexion.html index e3109e8b3..a6a2cc665 100755 --- a/templates/default/connexion.html +++ b/templates/default/connexion.html @@ -1,7 +1,7 @@ {include file="includes/header.html"} {form name="thelia.customer.creation"} -{* We use $INDEX_PAGE as form action to avoid mixing post and get data *} +{* We use {navigate to="index"} as form action to avoid mixing post and get data *} {* The two fields below are not par of the form, they are here to defines @@ -16,7 +16,7 @@ *} {form_field form=$form field='success_url'} - {* the url the user is redirected to on login success *} + {* the url the user is redirected to on login success *} {/form_field} {form_field form=$form field='auto_login'} diff --git a/templates/default/login.html b/templates/default/login.html index 0041fd80c..a5a7585b7 100755 --- a/templates/default/login.html +++ b/templates/default/login.html @@ -3,8 +3,8 @@

{intl l='Please login'}

{form name="thelia.customer.login" } -{* We use $INDEX_PAGE as form action to avoid mixing post and get data *} - +{* We use {navigate to="index"} as form action to avoid mixing post and get data *} + {* The two fields below are not par of the Login form, they are here to defines @@ -20,7 +20,7 @@ *} {form_field form=$form field='success_url'} - {* the url the user is redirected to on login success *} + {* the url the user is redirected to on login success *} {/form_field} {* diff --git a/web/index_dev.php b/web/index_dev.php index b5a98978a..8991dc4a8 100755 --- a/web/index_dev.php +++ b/web/index_dev.php @@ -21,8 +21,6 @@ if ( false === in_array($request->getClientIp(), $trustIp)) { $thelia = new Thelia("dev", true); -\Thelia\Tools\URL::retrieveCurrent($request); - $response = $thelia->handle($request)->prepare($request)->send(); $thelia->terminate($request, $response); From e63ff065c7ed884156b43c4fdd47bd473945f6b7 Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Fri, 30 Aug 2013 15:04:08 +0200 Subject: [PATCH 05/18] product page --- templates/default/product.html | 88 ++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100755 templates/default/product.html diff --git a/templates/default/product.html b/templates/default/product.html new file mode 100755 index 000000000..4f82b5fb8 --- /dev/null +++ b/templates/default/product.html @@ -0,0 +1,88 @@ +Here you are : {navigate to="current"}
+From : {navigate to="return_to"}
+Index : {navigate to="index"}
+ +

Product page

+ +{ifloop rel="product"} + +{loop type="product" name="product" current="true"} + +
+

PRODUCT (#ID) : #REF

+

#TITLE

+

#DESCRIPTION

+ + {ifloop rel="acc"} +

Accessories

+
    + {loop name="acc" type="accessory" product="#ID" order="accessory"} +
  • #REF
  • + {/loop} +
+ {/ifloop} + {elseloop rel="acc"} +

No accessory

+ {/elseloop} + + {ifloop rel="prod_ass_cont"} +

Associated Content

+
    + {loop name="prod_ass_cont" type="associated_content" product="#ID" order="associated_content"} +
  • #TITLE
  • + {/loop} +
+ {/ifloop} + {elseloop rel="prod_ass_cont"} +

No associated content

+ {/elseloop} + + {ifloop rel="ft"} +

Features

+
    + {assign var=current_product value=#ID} + {loop name="ft" type="feature" order="manual" product="#ID"} +
  • + #TITLE : + {loop name="ft_v" type="feature_value" product="{$current_product}" feature="#ID"} + #TITLE / #PERSONAL_VALUE + {/loop} +
  • + {/loop} +
+ {/ifloop} + {elseloop rel="ft"} +

No feature

+ {/elseloop} + +

Product sale elements

+ + {assign var=current_product value=#ID} + {loop name="pse" type="product_sale_elements" product="#ID"} +
+ {loop name="combi" type="attribute_combination" product_sale_elements="#ID"} + #ATTRIBUTE_TITLE = #ATTRIBUTE_AVAILABILITY_TITLE
+ {/loop} +
#WEIGHT g +
{if #IS_PROMO == 1} #PROMO_PRICE € (instead of #PRICE) {else} #PRICE € {/if} +

+ Add + + to my cart + +
+ {/loop} + +
+ +{/loop} + +{/ifloop} + +{elseloop rel="product"} +

Produit introuvable !

+{/elseloop} \ No newline at end of file From d8df46737dceab03eb6cbc71e817467d78d9ebd7 Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Fri, 30 Aug 2013 16:02:37 +0200 Subject: [PATCH 06/18] specific rewrittend url retrievement --- .../Thelia/Rewriting/RewritingRetriever.php | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/core/lib/Thelia/Rewriting/RewritingRetriever.php b/core/lib/Thelia/Rewriting/RewritingRetriever.php index 73b09dd2c..34be346f1 100755 --- a/core/lib/Thelia/Rewriting/RewritingRetriever.php +++ b/core/lib/Thelia/Rewriting/RewritingRetriever.php @@ -59,8 +59,9 @@ class RewritingRetriever { $urlQuery = RewritingUrlQuery::create() ->joinRewritingArgument('ra', Criteria::LEFT_JOIN) - ->withColumn('`ra`.PARAMETER', 'ra_parameter') - ->withColumn('`ra`.VALUE', 'ra_value') + //->withColumn('`ra`.PARAMETER', 'ra_parameter') + //->withColumn('`ra`.VALUE', 'ra_value') + ->withColumn('`ra`.REWRITING_URL_ID', 'ra_REWRITING_URL_ID') ->filterByView($view) ->filterByViewLocale($viewLocale) ->filterByViewId($viewId) @@ -70,23 +71,23 @@ class RewritingRetriever $otherParametersCount = count($viewOtherParameters); if($otherParametersCount > 0) { $parameterConditions = array(); + foreach($viewOtherParameters as $parameter => $value) { $conditionName = 'other_parameter_condition_' . count($parameterConditions); - $urlQuery->condition('parameter_condition', '`ra_parameter`= ?', $parameter, \PDO::PARAM_STR) - ->condition('value_condition', '`ra_value` = ?', $value, \PDO::PARAM_STR) + $urlQuery->condition('parameter_condition', '`ra`.PARAMETER= ?', $parameter, \PDO::PARAM_STR) + ->condition('value_condition', '`ra`.VALUE = ?', $value, \PDO::PARAM_STR) ->combine(array('parameter_condition', 'value_condition'), Criteria::LOGICAL_AND, $conditionName); $parameterConditions[] = $conditionName; } - $urlQuery->combine($parameterConditions, Criteria::LOGICAL_OR, 'parameter_full_condition'); + $urlQuery->where($parameterConditions, Criteria::LOGICAL_OR); $urlQuery->groupBy(RewritingUrlTableMap::ID); - $urlQuery->condition('count_condition', 'COUNT(' . RewritingUrlTableMap::ID . ') = ?', $otherParametersCount, \PDO::PARAM_INT) - ->combine(array('count_condition', 'parameter_full_condition'), Criteria::LOGICAL_AND, 'full_having_condition'); + $urlQuery->condition('count_condition_1', 'COUNT(' . RewritingUrlTableMap::ID . ') = ?', $otherParametersCount, \PDO::PARAM_INT) // ensure we got all the asked parameters (provided by the query) + ->condition('count_condition_2', 'COUNT(' . RewritingUrlTableMap::ID . ') = (SELECT COUNT(*) FROM rewriting_argument WHERE rewriting_argument.REWRITING_URL_ID = ra_REWRITING_URL_ID)'); // ensure we don't miss any parameters (needed to match the rewritten url) - - $urlQuery->having(array('full_having_condition')); + $urlQuery->having(array('count_condition_1', 'count_condition_2'), Criteria::LOGICAL_AND); } else { $urlQuery->where('ISNULL(`ra`.REWRITING_URL_ID)'); } From 6fa4d3a9238917c5eb01d199b4c008b085e26c2e Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Fri, 30 Aug 2013 16:47:13 +0200 Subject: [PATCH 07/18] rewriting --- .../Thelia/Rewriting/RewritingRetriever.php | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/core/lib/Thelia/Rewriting/RewritingRetriever.php b/core/lib/Thelia/Rewriting/RewritingRetriever.php index 34be346f1..0deb7de45 100755 --- a/core/lib/Thelia/Rewriting/RewritingRetriever.php +++ b/core/lib/Thelia/Rewriting/RewritingRetriever.php @@ -35,6 +35,13 @@ use Thelia\Model\Map\RewritingUrlTableMap; */ class RewritingRetriever { + /** + * @param $view + * @param $viewLocale + * @param $viewId + * + * @return null|$url + */ public function getViewUrl($view, $viewLocale, $viewId) { $url = $this->getViewUrlQuery($view, $viewId, $viewLocale); @@ -42,6 +49,13 @@ class RewritingRetriever return $url === null ? null : $url->getUrl(); } + /** + * @param $view + * @param $viewId + * @param $viewLocale + * + * @return null|RewritingUrl + */ protected function getViewUrlQuery($view, $viewId, $viewLocale) { return RewritingUrlQuery::create() @@ -55,12 +69,18 @@ class RewritingRetriever ->findOne(); } + /** + * @param $view + * @param $viewLocale + * @param null $viewId + * @param array $viewOtherParameters + * + * @return null|$url + */ public function getSpecificUrl($view, $viewLocale, $viewId = null, $viewOtherParameters = array()) { $urlQuery = RewritingUrlQuery::create() ->joinRewritingArgument('ra', Criteria::LEFT_JOIN) - //->withColumn('`ra`.PARAMETER', 'ra_parameter') - //->withColumn('`ra`.VALUE', 'ra_value') ->withColumn('`ra`.REWRITING_URL_ID', 'ra_REWRITING_URL_ID') ->filterByView($view) ->filterByViewLocale($viewLocale) From 6867eae9b76ea43eedecd13270f80954742a3e4e Mon Sep 17 00:00:00 2001 From: franck Date: Fri, 30 Aug 2013 19:46:12 +0200 Subject: [PATCH 08/18] Fixed customer front controller, events, addec admion config. --- core/lib/Thelia/Action/Category.php | 8 +- core/lib/Thelia/Action/Customer.php | 15 +- core/lib/Thelia/Config/Resources/action.xml | 4 +- .../Thelia/Config/Resources/routing/front.xml | 6 +- .../Controller/Admin/BaseAdminController.php | 8 +- .../Controller/Admin/CategoryController.php | 28 +- .../Controller/Admin/SessionController.php | 11 +- core/lib/Thelia/Controller/BaseController.php | 27 +- .../Controller/Front/CustomerController.php | 175 +++++++---- .../Thelia/Core/Event/CategoryChangeEvent.php | 44 +++ .../Event/CategoryChangePositionEvent.php | 29 +- .../Thelia/Core/Event/CategoryCreateEvent.php | 1 - .../Thelia/Core/Event/CategoryDeleteEvent.php | 14 +- .../Event/CategoryToggleVisibilityEvent.php | 14 +- .../Thelia/Core/Event/CustomerLoginEvent.php | 2 +- .../Core/EventListener/ControllerListener.php | 7 +- .../UsernamePasswordFormAuthenticator.php | 2 - .../Thelia/Core/Security/SecurityContext.php | 20 ++ .../Thelia/Core/Template/Element/BaseLoop.php | 2 +- .../Thelia/Core/Template/Loop/Category.php | 10 +- core/lib/Thelia/Core/Template/Loop/Image.php | 16 +- .../Thelia/Core/Template/ParserContext.php | 4 + core/lib/Thelia/Model/Base/Category.php | 1 - core/lib/Thelia/Model/Lang.php | 29 ++ .../Thelia/Model/Tools/ModelCriteriaTools.php | 3 +- install/faker.php | 8 +- templates/admin/default/assets/css/admin.less | 48 ++- templates/admin/default/categories.html | 71 ++++- templates/admin/default/configuration.html | 174 +++++++++++ templates/admin/default/edit_category.html | 279 ++++++++++-------- templates/admin/default/general_error.html | 2 +- .../admin/default/includes/header.inc.html | 12 +- templates/admin/default/login.html | 3 - templates/default/includes/header.html | 4 +- templates/default/login.html | 13 +- 35 files changed, 810 insertions(+), 284 deletions(-) create mode 100644 core/lib/Thelia/Core/Event/CategoryChangeEvent.php create mode 100644 templates/admin/default/configuration.html diff --git a/core/lib/Thelia/Action/Category.php b/core/lib/Thelia/Action/Category.php index d411d2a51..b9bde8a07 100755 --- a/core/lib/Thelia/Action/Category.php +++ b/core/lib/Thelia/Action/Category.php @@ -75,7 +75,7 @@ class Category extends BaseAction implements EventSubscriberInterface { $this->checkAuth("ADMIN", "admin.category.delete"); - $category = CategoryQuery::create()->findPk($event->getId()); + $category = CategoryQuery::create()->findPk($event->getCategoryId()); if ($category !== null) { @@ -98,7 +98,7 @@ class Category extends BaseAction implements EventSubscriberInterface { $this->checkAuth("ADMIN", "admin.category.edit"); - $category = CategoryQuery::create()->findPk($event->getId()); + $category = CategoryQuery::create()->findPk($event->getCategoryId()); if ($category !== null) { @@ -136,7 +136,7 @@ class Category extends BaseAction implements EventSubscriberInterface */ protected function exchangePosition(CategoryChangePositionEvent $event) { - $category = CategoryQuery::create()->findPk($event->getId()); + $category = CategoryQuery::create()->findPk($event->getCategoryId()); if ($category !== null) { @@ -195,7 +195,7 @@ class Category extends BaseAction implements EventSubscriberInterface { $this->checkAuth("ADMIN", "admin.category.edit"); - $category = CategoryQuery::create()->findPk($event->getId()); + $category = CategoryQuery::create()->findPk($event->getCategoryId()); if ($category !== null) { diff --git a/core/lib/Thelia/Action/Customer.php b/core/lib/Thelia/Action/Customer.php index 4c7a71d5e..aed93d390 100755 --- a/core/lib/Thelia/Action/Customer.php +++ b/core/lib/Thelia/Action/Customer.php @@ -38,6 +38,7 @@ 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; class Customer extends BaseAction implements EventSubscriberInterface { @@ -46,7 +47,6 @@ class Customer extends BaseAction implements EventSubscriberInterface { $customer = new CustomerModel(); - $customer->setDispatcher($this->getDispatcher()); $this->createOrUpdateCustomer($customer, $event); @@ -56,7 +56,6 @@ class Customer extends BaseAction implements EventSubscriberInterface { $customer = $event->getCustomer(); - $customer->setDispatcher($this->getDispatcher()); $this->createOrUpdateCustomer($customer, $event); @@ -64,6 +63,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 +88,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,8 +101,6 @@ class Customer extends BaseAction implements EventSubscriberInterface */ public function logout(ActionEvent $event) { - $event->getDispatcher()->dispatch(TheliaEvents::CUSTOMER_LOGOUT, $event); - $this->getSecurityContext()->clearCustomerUser(); } @@ -129,6 +134,8 @@ class Customer extends BaseAction implements EventSubscriberInterface return array( TheliaEvents::CUSTOMER_CREATEACCOUNT => array("create", 128), TheliaEvents::CUSTOMER_UPDATEACCOUNT => array("modify", 128), + TheliaEvents::CUSTOMER_LOGOUT => array("logout", 128), + TheliaEvents::CUSTOMER_LOGIN => array("login" , 128), ); } } diff --git a/core/lib/Thelia/Config/Resources/action.xml b/core/lib/Thelia/Config/Resources/action.xml index 2bd31ce3e..7d21eadee 100755 --- a/core/lib/Thelia/Config/Resources/action.xml +++ b/core/lib/Thelia/Config/Resources/action.xml @@ -22,12 +22,12 @@ - + - + diff --git a/core/lib/Thelia/Config/Resources/routing/front.xml b/core/lib/Thelia/Config/Resources/routing/front.xml index c420e1550..9329b22ad 100755 --- a/core/lib/Thelia/Config/Resources/routing/front.xml +++ b/core/lib/Thelia/Config/Resources/routing/front.xml @@ -18,10 +18,14 @@ Thelia\Controller\Front\CustomerController::updateAction - + Thelia\Controller\Front\CustomerController::loginAction + + Thelia\Controller\Front\CustomerController::logoutAction + + Thelia\Controller\Front\CartController::addItem cart diff --git a/core/lib/Thelia/Controller/Admin/BaseAdminController.php b/core/lib/Thelia/Controller/Admin/BaseAdminController.php index 271ce3c05..989715de4 100755 --- a/core/lib/Thelia/Controller/Admin/BaseAdminController.php +++ b/core/lib/Thelia/Controller/Admin/BaseAdminController.php @@ -52,11 +52,13 @@ class BaseAdminController extends BaseController 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 new Response($this->errorPage($ex->getMessage())); } return $this->pageNotFound(); diff --git a/core/lib/Thelia/Controller/Admin/CategoryController.php b/core/lib/Thelia/Controller/Admin/CategoryController.php index 4e798d683..f922f1b9d 100755 --- a/core/lib/Thelia/Controller/Admin/CategoryController.php +++ b/core/lib/Thelia/Controller/Admin/CategoryController.php @@ -33,6 +33,7 @@ use Thelia\Core\Event\CategoryDeleteEvent; use Thelia\Core\Event\CategoryToggleVisibilityEvent; use Thelia\Core\Event\CategoryChangePositionEvent; use Thelia\Form\CategoryDeletionForm; +use Thelia\Model\Lang; class CategoryController extends BaseAdminController { @@ -99,7 +100,7 @@ class CategoryController extends BaseAdminController $this->adminLogAppend(sprintf("Category %s (ID %s) deleted", $category->getTitle(), $category->getId())); // Substitute _ID_ in the URL with the ID of the created category - $successUrl = str_replace('_ID_', $categoryDeleteEvent->getDeletedCategory()->getId(), $categoryDeletionForm->getSuccessUrl()); + $successUrl = str_replace('_ID_', $categoryDeleteEvent->getDeletedCategory()->getParent(), $categoryDeletionForm->getSuccessUrl()); // Redirect to the success URL $this->redirect($successUrl); @@ -185,11 +186,34 @@ class CategoryController extends BaseAdminController // Get the category ID $id = $this->getRequest()->get('id', 0); + // Find the current order + $category_order = $this->getRequest()->get( + 'category_order', + $this->getSession()->get('admin.category_order', 'manual') + ); + + // Find the current edit language ID + $edition_language = $this->getRequest()->get( + 'edition_language', + $this->getSession()->get('admin.edition_language', Lang::getDefaultLanguage()->getId()) + ); + $args = array( 'action' => $action, - 'current_category_id' => $id + 'current_category_id' => $id, + 'category_order' => $category_order, + 'edition_language' => $edition_language, + 'date_format' => Lang::getDefaultLanguage()->getDateFormat(), + 'time_format' => Lang::getDefaultLanguage()->getTimeFormat(), + 'datetime_format' => Lang::getDefaultLanguage()->getDateTimeFormat(), ); + // Store the current sort order in session + $this->getSession()->set('admin.category_order', $category_order); + + // Store the current edition language in session + $this->getSession()->set('admin.edition_language', $edition_language); + try { switch ($action) { case 'browse' : // Browse categories diff --git a/core/lib/Thelia/Controller/Admin/SessionController.php b/core/lib/Thelia/Controller/Admin/SessionController.php index 39dbc1205..4e4e909e2 100755 --- a/core/lib/Thelia/Controller/Admin/SessionController.php +++ b/core/lib/Thelia/Controller/Admin/SessionController.php @@ -51,13 +51,16 @@ class SessionController extends BaseAdminController 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 @@ -85,7 +88,7 @@ class SessionController extends BaseAdminController // Log authentication failure AdminLog::append(sprintf("Undefined error: %s", $ex->getMessage()), $request); - $message = "Unable to process your request. Please try again."; + $message = "Unable to process your request. Please try again.".$ex->getMessage(); } // Store error information in the form diff --git a/core/lib/Thelia/Controller/BaseController.php b/core/lib/Thelia/Controller/BaseController.php index 1a610768d..bede9f08c 100755 --- a/core/lib/Thelia/Controller/BaseController.php +++ b/core/lib/Thelia/Controller/BaseController.php @@ -35,6 +35,7 @@ use Thelia\Core\Factory\ActionEventFactory; use Thelia\Form\BaseForm; use Thelia\Form\Exception\FormValidationException; use Symfony\Component\EventDispatcher\Event; +use Thelia\Core\Event\DefaultActionEvent; /** * @@ -60,10 +61,12 @@ class BaseController extends ContainerAware * Dispatch a Thelia event * * @param string $eventName a TheliaEvent name, as defined in TheliaEvents class - * @param Event $event the event + * @param Event $event the action event, or null (a DefaultActionEvent will be dispatched) */ - protected function dispatch($eventName, Event $event = null) + protected function dispatch($eventName, ActionEvent $event = null) { + if ($event == null) $event = new DefaultActionEvent(); + $this->getDispatcher()->dispatch($eventName, $event); } @@ -145,7 +148,8 @@ class BaseController extends ContainerAware /** * - * redirect request to specify url + * redirect request to the specified url + * * @param string $url */ public function redirect($url) @@ -154,12 +158,21 @@ class BaseController extends ContainerAware } /** - * 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); } } diff --git a/core/lib/Thelia/Controller/Front/CustomerController.php b/core/lib/Thelia/Controller/Front/CustomerController.php index 698c69d70..de6d15129 100755 --- a/core/lib/Thelia/Controller/Front/CustomerController.php +++ b/core/lib/Thelia/Controller/Front/CustomerController.php @@ -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; @@ -37,65 +35,101 @@ 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 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 = "Invalid or missing data. Please check your input"; + } + catch (\Exception $e) { + $message = "Sorry, an unknown error occured."; + } + + if ($message !== false) { + Tlog::getInstance()->error(sprintf("Error during customer creation process : %s. Exception was %s", $message, $e->getMessage())); + + $customerLoginForm->setErrorMessage($message); + + $this->getParserContext() + ->setErrorForm($customerLoginForm) + ->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()->getCustomerUser(); + $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 = "Invalid or missing data. Please check your input"; + } + catch (\Exception $e) { + $message = "Sorry, an unknown error occured."; + } + + if ($message !== false) { + Tlog::getInstance()->error(sprintf("Error during customer modification process : %s. Exception was %s", $message, $e->getMessage())); + + $customerLoginForm->setErrorMessage($message); + + $this->getParserContext() + ->setErrorForm($customerLoginForm) + ->setGeneralError($message) + ; + } } } @@ -103,39 +137,75 @@ 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(); - $authenticator = new CustomerUsernamePasswordFormAuthenticator($request, $customerLoginForm); + try { - try { - $customer = $authenticator->getAuthentifiedUser(); + $customerLoginForm = new CustomerLogin($request); - $this->processLogin($customer); + $form = $this->validateForm($customerLoginForm, "post"); - $this->redirectSuccess(); - } catch (ValidatorException $e) { + $authenticator = new CustomerUsernamePasswordFormAuthenticator($request, $customerLoginForm); - } catch(UsernameNotFoundException $e) { + $customer = $authenticator->getAuthentifiedUser(); - } catch(AuthenticationException $e) { + $this->processLogin($customer); - } catch (\Exception $e) { + $this->redirectSuccess($customerLoginForm); + } + catch (FormValidationException $e) { + $message = "Invalid or missing data. Please check your input"; + } + 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 = "Sorry, an unknown error occured."; + } + + if ($message !== false) { + Tlog::getInstance()->error(sprintf("Error during customer login process : %s. Exception was %s", $message, $e->getMessage())); + + $customerLoginForm->setErrorMessage($message); + + $this->getParserContext()->setErrorForm($customerLoginForm); + } } } - public function processLogin(Customer $customer) + /** + * Perform customer logout. + * + * @param Customer $customer + */ + public function logoutAction() { - $this->getSecurityContext()->setCustomerUser($customer); + if ($this->getSecurityContext()->hasCustomerUser()) { + $this->dispatch(TheliaEvents::CUSTOMER_LOGOUT); + } - if($event) $this->dispatch(TheliaEvents::CUSTOMER_LOGIN, new CustomerLoginEvent($customer)); + // Redirect to home page + $this->redirect(URL::getIndexPage()); + } + + protected function processLogin(Customer $customer) + { + $this->dispatch(TheliaEvents::CUSTOMER_LOGIN, new CustomerLoginEvent($customer)); } /** @@ -161,10 +231,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; } - } diff --git a/core/lib/Thelia/Core/Event/CategoryChangeEvent.php b/core/lib/Thelia/Core/Event/CategoryChangeEvent.php new file mode 100644 index 000000000..e8e183b3f --- /dev/null +++ b/core/lib/Thelia/Core/Event/CategoryChangeEvent.php @@ -0,0 +1,44 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; + +use Thelia\Model\Category; + +class CategoryCreateEvent extends ActionEvent +{ + protected $category_id; + protected $locale; + protected $title; + protected $chapo; + protected $description; + protected $postscriptum; + protected $url; + protected $visibility; + protected $parent; + + public function __construct($category_id) + { + $this->category_id = $category_id; + } +} diff --git a/core/lib/Thelia/Core/Event/CategoryChangePositionEvent.php b/core/lib/Thelia/Core/Event/CategoryChangePositionEvent.php index 141fc8182..94f131626 100644 --- a/core/lib/Thelia/Core/Event/CategoryChangePositionEvent.php +++ b/core/lib/Thelia/Core/Event/CategoryChangePositionEvent.php @@ -30,28 +30,18 @@ class CategoryChangePositionEvent extends ActionEvent const POSITION_DOWN = 2; const POSITION_ABSOLUTE = 3; - protected $id; + protected $category_id; protected $mode; protected $position; protected $category; - public function __construct($id, $mode, $position = null) + public function __construct($category_id, $mode, $position = null) { - $this->id = $id; + $this->category_id = $category_id; $this->mode = $mode; $this->position = $position; } - public function getId() - { - return $this->id; - } - - public function setId($id) - { - $this->id = $id; - } - public function getMode() { return $this->mode; @@ -81,4 +71,15 @@ class CategoryChangePositionEvent extends ActionEvent { $this->category = $category; } -} \ No newline at end of file + + public function getCategoryId() + { + return $this->category_id; + } + + public function setCategoryId($category_id) + { + $this->category_id = $category_id; + } + +} diff --git a/core/lib/Thelia/Core/Event/CategoryCreateEvent.php b/core/lib/Thelia/Core/Event/CategoryCreateEvent.php index 558b04277..f4d5a45ee 100644 --- a/core/lib/Thelia/Core/Event/CategoryCreateEvent.php +++ b/core/lib/Thelia/Core/Event/CategoryCreateEvent.php @@ -77,6 +77,5 @@ class CategoryCreateEvent extends ActionEvent public function setCreatedCategory(Category $created_category) { $this->created_category = $created_category; -var_dump($this->created_category); } } diff --git a/core/lib/Thelia/Core/Event/CategoryDeleteEvent.php b/core/lib/Thelia/Core/Event/CategoryDeleteEvent.php index c53cb7e10..3e863be8e 100644 --- a/core/lib/Thelia/Core/Event/CategoryDeleteEvent.php +++ b/core/lib/Thelia/Core/Event/CategoryDeleteEvent.php @@ -26,22 +26,22 @@ use Thelia\Model\Category; class CategoryDeleteEvent extends ActionEvent { - protected $id; + protected $category_id; protected $deleted_category; - public function __construct($id) + public function __construct($category_id) { - $this->id = $id; + $this->category_id = $category_id; } - public function getId() + public function getCategoryId() { - return $this->id; + return $this->category_id; } - public function setId($id) + public function setCategoryId($category_id) { - $this->id = $id; + $this->category_id = $category_id; } public function getDeletedCategory() diff --git a/core/lib/Thelia/Core/Event/CategoryToggleVisibilityEvent.php b/core/lib/Thelia/Core/Event/CategoryToggleVisibilityEvent.php index b7237924e..ef921a0de 100644 --- a/core/lib/Thelia/Core/Event/CategoryToggleVisibilityEvent.php +++ b/core/lib/Thelia/Core/Event/CategoryToggleVisibilityEvent.php @@ -26,22 +26,22 @@ use Thelia\Model\Category; class CategoryToggleVisibilityEvent extends ActionEvent { - protected $id; + protected $category_id; protected $category; - public function __construct($id) + public function __construct($category_id) { - $this->id = $id; + $this->category_id = $category_id; } - public function getId() + public function getCategoryId() { - return $this->id; + return $this->category_id; } - public function setId($id) + public function setCategoryId($category_id) { - $this->id = $id; + $this->category_id = $category_id; } public function getCategory() diff --git a/core/lib/Thelia/Core/Event/CustomerLoginEvent.php b/core/lib/Thelia/Core/Event/CustomerLoginEvent.php index cc363790d..9a26bba3f 100755 --- a/core/lib/Thelia/Core/Event/CustomerLoginEvent.php +++ b/core/lib/Thelia/Core/Event/CustomerLoginEvent.php @@ -26,7 +26,7 @@ namespace Thelia\Core\Event; use Thelia\Model\Customer; -class CustomerLoginEvent { +class CustomerLoginEvent extends ActionEvent { protected $customer; diff --git a/core/lib/Thelia/Core/EventListener/ControllerListener.php b/core/lib/Thelia/Core/EventListener/ControllerListener.php index 9bb432e6a..0585bbe81 100755 --- a/core/lib/Thelia/Core/EventListener/ControllerListener.php +++ b/core/lib/Thelia/Core/EventListener/ControllerListener.php @@ -59,12 +59,7 @@ class ControllerListener implements EventSubscriberInterface $event = new ActionEventFactory($request, $action, $event->getKernel()->getContainer()->getParameter("thelia.actionEvent")); $actionEvent = $event->createActionEvent(); $dispatcher->dispatch("action.".$action, $actionEvent); - - // Process form errors - if ($actionEvent->hasErrorForm()) { - $this->parserContext->setErrorForm($actionEvent->getErrorForm()); - } - } + } } public static function getSubscribedEvents() diff --git a/core/lib/Thelia/Core/Security/Authentication/UsernamePasswordFormAuthenticator.php b/core/lib/Thelia/Core/Security/Authentication/UsernamePasswordFormAuthenticator.php index 6dc938d88..d9a223430 100755 --- a/core/lib/Thelia/Core/Security/Authentication/UsernamePasswordFormAuthenticator.php +++ b/core/lib/Thelia/Core/Security/Authentication/UsernamePasswordFormAuthenticator.php @@ -55,8 +55,6 @@ class UsernamePasswordFormAuthenticator implements AuthenticatorInterface ); $this->options = array_merge($defaults, $options); - - $this->loginForm->bind($this->request); } /** diff --git a/core/lib/Thelia/Core/Security/SecurityContext.php b/core/lib/Thelia/Core/Security/SecurityContext.php index c09945f61..6ddb47f00 100755 --- a/core/lib/Thelia/Core/Security/SecurityContext.php +++ b/core/lib/Thelia/Core/Security/SecurityContext.php @@ -60,6 +60,16 @@ class SecurityContext return $this->getSession()->getAdminUser(); } + /** + * Check if an admin user is logged in. + * + * @return true if an admin user is logged in, false otherwise. + */ + public function hasAdminUser() + { + return $this->getSession()->getAdminUser() != null; + } + /** * Gets the currently authenticated customer, or null if none is defined * @@ -70,6 +80,16 @@ class SecurityContext return $this->getSession()->getCustomerUser(); } + /** + * Check if a customer user is logged in. + * + * @return true if a customer is logged in, false otherwise. + */ + public function hasCustomerUser() + { + return $this->getSession()->getCustomerUser() != null; + } + /** * Check if a user has at least one of the required roles * diff --git a/core/lib/Thelia/Core/Template/Element/BaseLoop.php b/core/lib/Thelia/Core/Template/Element/BaseLoop.php index 8861022e9..03956386d 100755 --- a/core/lib/Thelia/Core/Template/Element/BaseLoop.php +++ b/core/lib/Thelia/Core/Template/Element/BaseLoop.php @@ -138,7 +138,7 @@ abstract class BaseLoop } elseif ($value !== null && !$argument->type->isValid($value)) { /* check type */ $faultActor[] = $argument->name; - $faultDetails[] = sprintf('Invalid value for "%s" argument in loop type: %s, name: %s', $argument->name, $loopType, $loopName); + $faultDetails[] = sprintf('Invalid value "%s" for "%s" argument in loop type: %s, name: %s', $value, $argument->name, $loopType, $loopName); } else { /* set default */ /* did it as last checking for we consider default value is acceptable no matter type or empty restriction */ diff --git a/core/lib/Thelia/Core/Template/Loop/Category.php b/core/lib/Thelia/Core/Template/Loop/Category.php index e01ce3df4..d7ed1ddf9 100755 --- a/core/lib/Thelia/Core/Template/Loop/Category.php +++ b/core/lib/Thelia/Core/Template/Loop/Category.php @@ -79,7 +79,7 @@ class Category extends BaseLoop new Argument( 'order', new TypeCollection( - new Type\EnumListType(array('alpha', 'alpha_reverse', 'manual', 'manual_reverse', 'random')) + new Type\EnumListType(array('alpha', 'alpha_reverse', 'manual', 'manual_reverse', 'visible', 'visible_reverse', 'random')) ), 'manual' ), @@ -146,6 +146,12 @@ class Category extends BaseLoop case "manual": $search->orderByPosition(Criteria::ASC); break; + case "visible": + $search->orderByVisible(Criteria::ASC); + break; + case "visible_reverse": + $search->orderByVisible(Criteria::DESC); + break; case "random": $search->clearOrderByColumns(); $search->addAscendingOrderByColumn('RAND()'); @@ -173,7 +179,7 @@ class Category extends BaseLoop $loopResultRow ->set("ID", $category->getId()) ->set("IS_TRANSLATED",$category->getVirtualColumn('IS_TRANSLATED')) - ->set("TITLE",$category->getVirtualColumn('i18n_TITLE')) + ->set("TITLE", $category->getVirtualColumn('i18n_TITLE')) ->set("CHAPO", $category->getVirtualColumn('i18n_CHAPO')) ->set("DESCRIPTION", $category->getVirtualColumn('i18n_DESCRIPTION')) ->set("POSTSCRIPTUM", $category->getVirtualColumn('i18n_POSTSCRIPTUM')) diff --git a/core/lib/Thelia/Core/Template/Loop/Image.php b/core/lib/Thelia/Core/Template/Loop/Image.php index 638905dc2..e26bcc9fe 100755 --- a/core/lib/Thelia/Core/Template/Loop/Image.php +++ b/core/lib/Thelia/Core/Template/Loop/Image.php @@ -63,7 +63,6 @@ class Image extends BaseLoop $queryClass = sprintf("\Thelia\Model\%sImageQuery", $object); $filterMethod = sprintf("filterBy%sId", $object); - $mapClass = sprintf("\Thelia\Model\Map\%sI18nTableMap", $object); // xxxImageQuery::create() $method = new \ReflectionMethod($queryClass, 'create'); @@ -73,19 +72,16 @@ class Image extends BaseLoop $method = new \ReflectionMethod($queryClass, $filterMethod); $method->invoke($search, $object_id); - $map = new \ReflectionClass($mapClass); - $title_map = $map->getConstant('TITLE'); - $orders = $this->getOrder(); // Results ordering foreach ($orders as $order) { switch ($order) { case "alpha": - $search->addAscendingOrderByColumn($title_map); + $search->addAscendingOrderByColumn('i18n_TITLE'); break; case "alpha-reverse": - $search->addDescendingOrderByColumn($title_map); + $search->addDescendingOrderByColumn('i18n_TITLE'); break; case "manual-reverse": $search->orderByPosition(Criteria::DESC); @@ -122,7 +118,7 @@ class Image extends BaseLoop $source_id = $this->getSourceId(); - // echo "source = ".$this->getSource().", id=".$id."
"; + // echo "source = ".$this->getSource().", id=".$source_id." - ".$this->getArg('source_id')->getValue()."
"; if (is_null($source_id)) { throw new \InvalidArgumentException("'source_id' argument cannot be null if 'source' argument is specified."); @@ -167,6 +163,9 @@ class Image extends BaseLoop $search = $this->getSearchQuery($object_type, $object_id); + /* manage translations */ + $this->configureI18nProcessing($search); + $id = $this->getId(); if (! is_null($id)) { @@ -207,8 +206,7 @@ class Image extends BaseLoop } - /* manage translations */ - $this->configureI18nProcessing($search); + // echo "sql=".$search->toString(); $results = $this->search($search, $pagination); diff --git a/core/lib/Thelia/Core/Template/ParserContext.php b/core/lib/Thelia/Core/Template/ParserContext.php index 03c3cf45f..801b5a127 100755 --- a/core/lib/Thelia/Core/Template/ParserContext.php +++ b/core/lib/Thelia/Core/Template/ParserContext.php @@ -56,11 +56,15 @@ class ParserContext implements \IteratorAggregate public function setErrorForm(BaseForm $form) { $this->set('error_form', $form); + + return $this; } public function setGeneralError($error) { $this->set('general_error', $error); + + return $this; } public function getErrorForm() diff --git a/core/lib/Thelia/Model/Base/Category.php b/core/lib/Thelia/Model/Base/Category.php index 46a8876ef..d03fd04ad 100755 --- a/core/lib/Thelia/Model/Base/Category.php +++ b/core/lib/Thelia/Model/Base/Category.php @@ -474,7 +474,6 @@ abstract class Category implements ActiveRecordInterface if (!$this->hasVirtualColumn($name)) { throw new PropelException(sprintf('Cannot get value of inexistent virtual column %s.', $name)); } - return $this->virtualColumns[$name]; } diff --git a/core/lib/Thelia/Model/Lang.php b/core/lib/Thelia/Model/Lang.php index d63422680..3339dec64 100755 --- a/core/lib/Thelia/Model/Lang.php +++ b/core/lib/Thelia/Model/Lang.php @@ -6,4 +6,33 @@ use Thelia\Model\Base\Lang as BaseLang; class Lang extends BaseLang { + /** + * Return the default language object, using a local variable to cache it. + * + * @throws RuntimeException + */ + private static $default_lang = null; + + public static function getDefaultLanguage() { + + if (self::$default_lang == null) { + $default_lang = LangQuery::create()->findOneByByDefault(true); + + if ($default_lang == null) throw new RuntimeException("No default language is defined. Please define one."); + } + + return $default_lang; + } + + public function getDateFormat() { + return "d/m/Y"; + } + + public function getTimeFormat() { + return "H:i:s"; + } + + public function getDateTimeFormat() { + return "d/m/Y H:i:s"; + } } diff --git a/core/lib/Thelia/Model/Tools/ModelCriteriaTools.php b/core/lib/Thelia/Model/Tools/ModelCriteriaTools.php index 3913b2890..578b2c19d 100755 --- a/core/lib/Thelia/Model/Tools/ModelCriteriaTools.php +++ b/core/lib/Thelia/Model/Tools/ModelCriteriaTools.php @@ -7,6 +7,7 @@ use Propel\Runtime\ActiveQuery\Join; use Propel\Runtime\ActiveQuery\ModelCriteria; use Thelia\Model\Base\LangQuery; use Thelia\Model\ConfigQuery; +use Thelia\Model\Lang; /** * Class ModelCriteriaTools @@ -52,7 +53,7 @@ class ModelCriteriaTools $search->withColumn('`' . $requestedLocaleI18nAlias . '`.`' . $column . '`', $aliasPrefix . 'i18n_' . $column); } } else { - $defaultLocale = LangQuery::create()->findOneById($defaultLangWithoutTranslation)->getLocale(); + $defaultLocale = Lang::getDefaultLanguage()->getLocale(); $defaultLocaleJoin = new Join(); $defaultLocaleJoin->addExplicitCondition($search->getTableMap()->getName(), $foreignKey, null, $foreignTable . '_i18n', 'ID', $defaultLocaleI18nAlias); diff --git a/install/faker.php b/install/faker.php index 81edd767d..f1e7691d7 100755 --- a/install/faker.php +++ b/install/faker.php @@ -240,7 +240,7 @@ try { //categories and products $productIdList = array(); $categoryIdList = array(); - for($i=0; $i<4; $i++) { + for($i=1; $i<5; $i++) { $category = createCategory($faker, 0, $i, $categoryIdList, $contentIdList); for($j=1; $jsetProductId($productId); generate_image($image, 1, 'product', $productId); - + return $product; } @@ -415,7 +415,7 @@ function createCategory($faker, $parent, $position, &$categoryIdList, $contentId $image = new CategoryImage(); $image->setCategoryId($categoryId); generate_image($image, 1, 'category', $categoryId); - + return $category; } diff --git a/templates/admin/default/assets/css/admin.less b/templates/admin/default/assets/css/admin.less index 9d9f2c482..66a03ab37 100755 --- a/templates/admin/default/assets/css/admin.less +++ b/templates/admin/default/assets/css/admin.less @@ -216,6 +216,10 @@ hr { width: 23px; height: @top-bar-height; } + + a.profile { + color: #fff; + } } .view-shop { @@ -233,10 +237,6 @@ hr { .loginpage { - .brandbar { - width: 100%; - } - .hero-unit { background-color: transparent !important; @@ -316,6 +316,10 @@ hr { } } +.brandbar-wide { + width: 100%; +} + // -- Navigation bar ---------------------------------------------------------- .navbar { @@ -717,4 +721,40 @@ label { // Center the alert box (20px bottom margin) in the table cell padding: 20px 20px 0 20px; } + + th { + a { + color: inherit; + } + } + + td { + vertical-align: middle; + + img { + border: 2px solid white; + border-radius: 4px 4px 4px 4px; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); + } + } +} + +.menu-list-table .table-striped { + td, th { + text-align: left; + } + + td:nth-child(2) { + text-align: right; + } + + caption { + background-color: #FFFFFF; + border-bottom: 2px solid #A5CED8; + color: #5A6876; + font-weight: bold; + line-height: 30px; + text-align: left; + text-transform: uppercase; + } } \ No newline at end of file diff --git a/templates/admin/default/categories.html b/templates/admin/default/categories.html index 7bf76988c..5d2ef5842 100755 --- a/templates/admin/default/categories.html +++ b/templates/admin/default/categories.html @@ -41,20 +41,72 @@ {ifloop rel="category_list"}
- + + {module_include location='category_list_header'} - - + + + + - {loop name="category_list" type="category" visible="*" parent="{$current_category_id}" order="manual"} + {loop name="category_list" type="category" visible="*" parent="{$current_category_id}" order="$category_order"} - + + + {module_include location='category_list_row'} @@ -141,7 +193,7 @@ {ifloop rel="product_list"} - + @@ -156,7 +208,12 @@ {loop name="product_list" type="product" category="{$current_category_id}" order="manual"} - + diff --git a/templates/admin/default/configuration.html b/templates/admin/default/configuration.html new file mode 100644 index 000000000..6973807c7 --- /dev/null +++ b/templates/admin/default/configuration.html @@ -0,0 +1,174 @@ +{check_auth context="admin" roles="ADMIN" permissions="admin.configuration.view" login_tpl="/admin/login"} + +{$page_title={intl l='Configuration'}} + +{include file='includes/header.inc.html'} + +
+ +
+ + {module_include location='configuration_top'} + +

{intl l="Thelia configuration"}

+ +
+ +
+
{intl l="Category title"}  + {if $category_order == 'alpha'} + + {$order_change = 'alpha_reverse'} + {elseif $category_order == 'alpha_reverse'} + + {$order_change = 'alpha'} + {else} + {$order_change = 'alpha'} + {/if} + + {intl l="Category title"} + + {intl l="Online"}{intl l="Position"} + {if $category_order == 'visible'} + + {$order_change = 'visible_reverse'} + {elseif $category_order == 'visible_reverse'} + + {$order_change = 'visible'} + {else} + {$order_change = 'visible'} + {/if} + + + {intl l="Online"} + + + {if $category_order == 'manual'} + + {$order_change = 'manual_reverse'} + {elseif $category_order == 'manual_reverse'} + + {$order_change = 'manual'} + {else} + {$order_change = 'manual'} + {/if} + + {intl l="Position"} + {intl l="Actions"}
{$TITLE} + {loop type="image" name="cat_image" source="category" source_id="$ID" limit="1" width="50" height="50" resize_mode="crop" backend_context="1"} + #TITLE + {/loop} + + + {$TITLE} + +
{intl l="Image"}  {intl l="Product title"}
Image ! + {loop type="image" name="cat_image" source="product" source_id="$ID" limit="1" width="50" height="50" resize_mode="crop" backend_context="1"} + + #TITLE + + {/loop} {$TITLE}
+ + + {module_include location='catalog_configuration_top'} + + {loop type="auth" name="pcc1" context="admin" roles="ADMIN" permissions="admin.configuration.product_templates"} + + + + + {/loop} + + {loop type="auth" name="pcc2" context="admin" roles="ADMIN" permissions="admin.configuration.product_attributes"} + + + + + {/loop} + + {loop type="auth" name="pcc3" context="admin" roles="ADMIN" permissions="admin.configuration.product_features"} + + + + + {/loop} + + {loop type="auth" name="pcc4" context="admin" roles="ADMIN" permissions="admin.configuration.mailing_template"} + + + + + {/loop} + + {loop type="auth" name="pcc5" context="admin" roles="ADMIN" permissions="admin.configuration.currencies"} + + + + + {/loop} + + {module_include location='catalog_configuration_bottom'} + +
{intl l='Product catalog configuration'}
{intl l='Product templates'}
{intl l='Product attributes'}
{intl l='Product features'}
{intl l='Mailing templates'}
{intl l='Currencies'}
+
+
+ +
+ +
+ +
+ +
+ + {module_include location='configuration_bottom'} + + + + +{include file='includes/js.inc.html'} + +{include file='includes/footer.inc.html'} \ No newline at end of file diff --git a/templates/admin/default/edit_category.html b/templates/admin/default/edit_category.html index c1e19809f..dfd3b2b91 100755 --- a/templates/admin/default/edit_category.html +++ b/templates/admin/default/edit_category.html @@ -11,7 +11,7 @@
- + {loop name="category_edit" type="category" visible="*" id="{$current_category_id}" backend_context="1" lang="$edition_language"}
@@ -25,156 +25,187 @@
-
- -
+
-
- -
+
+
+
- {include file="includes/inner-form-toolbar.html"} + {include file="includes/inner-form-toolbar.html"} -
-
-
- +
+
+
+ -
- -
-
+
+ +
+
-
- +
+ -
- -
-
+
+ +
+
-
- +
+ -
- +
+ -
-
+
+
-
- +
+ -
- -
-
+
+ +
+
-
- +
+ -
-
- - {intl l='Use default'} +
+ +
{intl l="The rewritten URL to the category page. Click \"Use Default\" button to use the default URL. Use only digits, letters, - and _ characters."}
+
+
+ +
+
+ +
+
+
+   +
+

{intl l='Category created on %date_create. Last modification: %date_change' date_create=$CREATE_DATE->format($datetime_format) date_change=$UPDATE_DATE->format($datetime_format)}

+
+
+
+
+ +
+
+
+ +
+
+
+ {include file="includes/inner-form-toolbar.html"} + +
+
+
+ + +
+
-
{intl l="The rewritten URL to the category page. Click \"Use Default\" button to use the default URL. Use only digits, letters, - and _ characters."}
-
-
+
+
+ -
-
+
+ - + +
+
+
+
- {loop name="cat-parent" type="category-tree" visible="*" category="0" exclude="{$current_category_id}"} - - {/loop} +
+
+
+ - -
-
+
+ +
+
+
-
-
- +
+
+
-
- -
-
-
-
-

aff Date creation ?

-

aff date modif ?

- - -
+
+

Images

+
-
-

Détails divers

-
+
+

Documents

+
-
-

Images

-
+
+

Modules

+
-
-

Documents

-
- -
-

Modules

-
- - - + + + + {/loop} @@ -189,6 +220,12 @@ $(function() { e.preventDefault(); $(this).tab('show'); }); + + $('.use_default_rewriten_url').click(function(ev) { + alert("Not functionnal"); + + ev.preventDefault(); + }); }) diff --git a/templates/admin/default/general_error.html b/templates/admin/default/general_error.html index c41fee7a4..b8f9e8661 100755 --- a/templates/admin/default/general_error.html +++ b/templates/admin/default/general_error.html @@ -1,4 +1,4 @@ -{$page_title={intl l='AN error occured'}} +{$page_title={intl l='An error occured'}} {include file='includes/header.inc.html'} diff --git a/templates/admin/default/includes/header.inc.html b/templates/admin/default/includes/header.inc.html index 65500f05a..9b8d4b18a 100755 --- a/templates/admin/default/includes/header.inc.html +++ b/templates/admin/default/includes/header.inc.html @@ -54,7 +54,9 @@ {module_include location='inside_topbar'} - + {loop name="top-bar-search" type="auth" context="admin" roles="ADMIN" permissions="admin.search"}