diff --git a/core/lib/Thelia/Core/Template/Element/BaseLoop.php b/core/lib/Thelia/Core/Template/Element/BaseLoop.php index 03956386d..befb53dc7 100755 --- a/core/lib/Thelia/Core/Template/Element/BaseLoop.php +++ b/core/lib/Thelia/Core/Template/Element/BaseLoop.php @@ -219,10 +219,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) { @@ -242,18 +242,21 @@ abstract class BaseLoop * @param array $columns the i18n columns * @param string $foreignTable the specified table (default to criteria table) * @param string $foreignKey the foreign key in this table (default to criteria table) + * + * @return mixed the locale */ - protected function configureI18nProcessing(ModelCriteria $search, $columns = array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), $foreignTable = null, $foreignKey = 'ID') { + protected function configureI18nProcessing(ModelCriteria $search, $columns = array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), $foreignTable = null, $foreignKey = 'ID', $forceReturn = false) { /* manage translations */ - ModelCriteriaTools::getI18n( + return ModelCriteriaTools::getI18n( $this->getBackend_context(), $this->getLang(), $search, $this->request->getSession()->getLocale(), $columns, $foreignTable, - $foreignKey + $foreignKey, + $forceReturn ); } diff --git a/core/lib/Thelia/Core/Template/Loop/Category.php b/core/lib/Thelia/Core/Template/Loop/Category.php index d7ed1ddf9..5eeab58be 100755 --- a/core/lib/Thelia/Core/Template/Loop/Category.php +++ b/core/lib/Thelia/Core/Template/Loop/Category.php @@ -97,7 +97,7 @@ class Category extends BaseLoop $search = CategoryQuery::create(); /* manage translations */ - $this->configureI18nProcessing($search); + $locale = $this->configureI18nProcessing($search); $id = $this->getId(); @@ -184,7 +184,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 701206ea8..b26e4d79f 100755 --- a/core/lib/Thelia/Core/Template/Loop/Content.php +++ b/core/lib/Thelia/Core/Template/Loop/Content.php @@ -87,7 +87,7 @@ class Content extends BaseLoop $search = ContentQuery::create(); /* manage translations */ - $this->configureI18nProcessing($search); + $locale = $this->configureI18nProcessing($search); $id = $this->getId(); @@ -220,7 +220,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/FeatureValue.php b/core/lib/Thelia/Core/Template/Loop/FeatureValue.php index 42d50c57b..7fef63c28 100755 --- a/core/lib/Thelia/Core/Template/Loop/FeatureValue.php +++ b/core/lib/Thelia/Core/Template/Loop/FeatureValue.php @@ -87,7 +87,8 @@ class FeatureValue extends BaseLoop $search, 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/Loop/Folder.php b/core/lib/Thelia/Core/Template/Loop/Folder.php index 327ce76d4..eb64d9996 100755 --- a/core/lib/Thelia/Core/Template/Loop/Folder.php +++ b/core/lib/Thelia/Core/Template/Loop/Folder.php @@ -79,7 +79,7 @@ class Folder extends BaseLoop $search = FolderQuery::create(); /* manage translations */ - $this->configureI18nProcessing($search); + $locale = $this->configureI18nProcessing($search); $id = $this->getId(); @@ -162,7 +162,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/Product.php b/core/lib/Thelia/Core/Template/Loop/Product.php index 1570acca8..4c1acdcc6 100755 --- a/core/lib/Thelia/Core/Template/Loop/Product.php +++ b/core/lib/Thelia/Core/Template/Loop/Product.php @@ -137,7 +137,7 @@ class Product extends BaseLoop $search = ProductQuery::create(); /* manage translations */ - $this->configureI18nProcessing($search); + $locale = $this->configureI18nProcessing($search); $attributeNonStrictMatch = $this->getAttribute_non_strict_match(); $isPSELeftJoinList = array(); @@ -514,7 +514,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/ParserContext.php b/core/lib/Thelia/Core/Template/ParserContext.php index 801b5a127..94d54d3ab 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/Category.php b/core/lib/Thelia/Model/Category.php index 2ffd375dd..b1d92cfdd 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); } /** @@ -74,4 +76,4 @@ class Category extends BaseCategory return $countProduct; } -} \ No newline at end of file +} 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/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/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 578b2c19d..5e22f08e9 100755 --- a/core/lib/Thelia/Model/Tools/ModelCriteriaTools.php +++ b/core/lib/Thelia/Model/Tools/ModelCriteriaTools.php @@ -24,7 +24,7 @@ class ModelCriteriaTools * @param null $foreignTable * @param string $foreignKey */ - public static function getFrontEndI18n(ModelCriteria &$search, $requestedLocale, $columns, $foreignTable, $foreignKey) + public static function getFrontEndI18n(ModelCriteria &$search, $requestedLocale, $columns, $foreignTable, $foreignKey, $forceReturn = false) { if($foreignTable === null) { $foreignTable = $search->getTableMap()->getName(); @@ -33,16 +33,16 @@ class ModelCriteriaTools $aliasPrefix = $foreignTable . '_'; } - $defaultLangWithoutTranslation = ConfigQuery::read("default_lang_without_translation", 1); + $defaultLangWithoutTranslation = ConfigQuery::getDefaultLangWhenNoTranslationAvailable(); - $requestedLocaleI18nAlias = 'requested_locale_i18n'; - $defaultLocaleI18nAlias = 'default_locale_i18n'; - - if (!$defaultLangWithoutTranslation == 0) { + $requestedLocaleI18nAlias = $aliasPrefix . 'requested_locale_i18n'; + $defaultLocaleI18nAlias = $aliasPrefix . 'default_locale_i18n'; + if($defaultLangWithoutTranslation == 0) { + $requestedLocaleJoin = new Join(); $requestedLocaleJoin->addExplicitCondition($search->getTableMap()->getName(), $foreignKey, null, $foreignTable . '_i18n', 'ID', $requestedLocaleI18nAlias); - $requestedLocaleJoin->setJoinType(Criteria::INNER_JOIN); + $requestedLocaleJoin->setJoinType($forceReturn === false ? Criteria::INNER_JOIN : Criteria::LEFT_JOIN); $search->addJoinObject($requestedLocaleJoin, $requestedLocaleI18nAlias) ->addJoinCondition($requestedLocaleI18nAlias ,'`' . $requestedLocaleI18nAlias . '`.LOCALE = ?', $requestedLocale, null, \PDO::PARAM_STR); @@ -71,7 +71,9 @@ class ModelCriteriaTools $search->withColumn('NOT ISNULL(`' . $requestedLocaleI18nAlias . '`.`ID`)', $aliasPrefix . 'IS_TRANSLATED'); - $search->where('NOT ISNULL(`' . $requestedLocaleI18nAlias . '`.ID)')->_or()->where('NOT ISNULL(`' . $defaultLocaleI18nAlias . '`.ID)'); + if($forceReturn === false) { + $search->where('NOT ISNULL(`' . $requestedLocaleI18nAlias . '`.ID)')->_or()->where('NOT ISNULL(`' . $defaultLocaleI18nAlias . '`.ID)'); + } foreach($columns as $column) { $search->withColumn('CASE WHEN NOT ISNULL(`' . $requestedLocaleI18nAlias . '`.ID) THEN `' . $requestedLocaleI18nAlias . '`.`' . $column . '` ELSE `' . $defaultLocaleI18nAlias . '`.`' . $column . '` END', $aliasPrefix . 'i18n_' . $column); @@ -79,7 +81,7 @@ class ModelCriteriaTools } } - public static function getBackEndI18n(ModelCriteria &$search, $requestedLocale, $columns, $foreignTable, $foreignKey) + public static function getBackEndI18n(ModelCriteria &$search, $requestedLocale, $columns = array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), $foreignTable = null, $foreignKey = 'ID') { if($foreignTable === null) { $foreignTable = $search->getTableMap()->getName(); @@ -104,7 +106,7 @@ class ModelCriteriaTools } } - public static function getI18n($backendContext, $requestedLangId, ModelCriteria &$search, $currentLocale, $columns, $foreignTable, $foreignKey) + public static function getI18n($backendContext, $requestedLangId, ModelCriteria &$search, $currentLocale, $columns, $foreignTable, $foreignKey, $forceReturn = false) { // If a lang has been requested, find the related Lang object, and get the locale if ($requestedLangId !== null) { @@ -125,7 +127,9 @@ class ModelCriteriaTools if ($backendContext) { self::getBackEndI18n($search, $locale, $columns, $foreignTable, $foreignKey); } else { - self::getFrontEndI18n($search, $locale, $columns, $foreignTable, $foreignKey); + self::getFrontEndI18n($search, $locale, $columns, $foreignTable, $foreignKey, $forceReturn); } + + return $locale; } } 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..0deb7de45 --- /dev/null +++ b/core/lib/Thelia/Rewriting/RewritingRetriever.php @@ -0,0 +1,119 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Rewriting; + +use Propel\Runtime\ActiveQuery\Criteria; +use Thelia\Model\Base\RewritingUrlQuery; +use Thelia\Model\Map\RewritingUrlTableMap; + +/** + * Class RewritingRetriever + * @package Thelia\Rewriting + * @author Etienne Roudeix + * + * This class provides methods to retrieve a rewritten URL from a query + */ +class RewritingRetriever +{ + /** + * @param $view + * @param $viewLocale + * @param $viewId + * + * @return null|$url + */ + public function getViewUrl($view, $viewLocale, $viewId) + { + $url = $this->getViewUrlQuery($view, $viewId, $viewLocale); + + return $url === null ? null : $url->getUrl(); + } + + /** + * @param $view + * @param $viewId + * @param $viewLocale + * + * @return null|RewritingUrl + */ + protected function getViewUrlQuery($view, $viewId, $viewLocale) + { + return RewritingUrlQuery::create() + ->joinRewritingArgument('ra', Criteria::LEFT_JOIN) + ->where('ISNULL(`ra`.REWRITING_URL_ID)') + ->filterByView($view) + ->filterByViewLocale($viewLocale) + ->filterByViewId($viewId) + ->filterByRedirected(null) + ->orderByUpdatedAt(Criteria::DESC) + ->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`.REWRITING_URL_ID', 'ra_REWRITING_URL_ID') + ->filterByView($view) + ->filterByViewLocale($viewLocale) + ->filterByViewId($viewId) + ->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->where($parameterConditions, Criteria::LOGICAL_OR); + + $urlQuery->groupBy(RewritingUrlTableMap::ID); + + $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('count_condition_1', 'count_condition_2'), Criteria::LOGICAL_AND); + } else { + $urlQuery->where('ISNULL(`ra`.REWRITING_URL_ID)'); + } + + $url = $urlQuery->findOne(); + + return $url === null ? null : $url->getUrl(); + } +} 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 5a88fa922..1bf0e566c 100755 --- a/core/lib/Thelia/Tools/URL.php +++ b/core/lib/Thelia/Tools/URL.php @@ -23,7 +23,9 @@ namespace Thelia\Tools; +use Symfony\Component\HttpFoundation\Request; use Thelia\Model\ConfigQuery; +use Thelia\Rewriting\RewritingRetriever; class URL { @@ -51,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 @@ -101,4 +107,50 @@ 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; + if(ConfigQuery::isRewritingEnable()) { + $retriever = new RewritingRetriever(); + $rewrittenUrl = $retriever->getViewUrl($view, $viewLocale, $viewId); + } + + 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); + $viewLocale = $request->query->get('locale', null); + $viewId = $view === null ? null : $request->query->get($view . '_id', null); + + $allParameters = $request->query->all(); + $allParametersWithoutView = $allParameters; + if($view !== null) { + unset($allParametersWithoutView['view']); + } + $allOtherParameters = $allParametersWithoutView; + if($viewLocale !== null) { + unset($allOtherParameters['locale']); + } + if($viewId !== null) { + unset($allOtherParameters[$view . '_id']); + } + + $retriever = new RewritingRetriever(); + $rewrittenUrl = $retriever->getSpecificUrl($view, $viewLocale, $viewId, $allOtherParameters); + } + + return $rewrittenUrl === null ? self::viewUrl($view, $allParametersWithoutView) : $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/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 9b8d4b18a..3982fb3d6 100755 --- a/templates/admin/default/includes/header.inc.html +++ b/templates/admin/default/includes/header.inc.html @@ -69,7 +69,7 @@ {/loop} - + @@ -164,4 +164,4 @@ -{/elseloop} \ No newline at end of file +{/elseloop} 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 af4cdcf14..dd5c6a20a 100755 --- a/templates/default/category.html +++ b/templates/default/category.html @@ -22,34 +22,10 @@ {loop name="product" type="product" category="#ID"}
-

PRODUCT : #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 : #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 90b6c8e05..702f0a710 100755 --- a/templates/default/login.html +++ b/templates/default/login.html @@ -3,8 +3,8 @@

{intl l='Please login'}

{form name="thelia.customer.login" } - + {* The field below are not par of the Login form, it defines view to render if the form cannot be validated *} @@ -17,7 +17,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/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