Conflicts:
	templates/default/login.html
This commit is contained in:
franck
2013-08-30 19:48:26 +02:00
29 changed files with 532 additions and 175 deletions

View File

@@ -219,10 +219,10 @@ abstract class BaseLoop
} }
/** /**
* @param \ModelCriteria $search * @param ModelCriteria $search
* @param $pagination * @param $pagination
* *
* @return array|\PropelModelPager * @return array|\Propel\Runtime\Util\PropelModelPager
*/ */
protected function searchWithPagination(ModelCriteria $search, &$pagination) protected function searchWithPagination(ModelCriteria $search, &$pagination)
{ {
@@ -242,18 +242,21 @@ abstract class BaseLoop
* @param array $columns the i18n columns * @param array $columns the i18n columns
* @param string $foreignTable the specified table (default to criteria table) * @param string $foreignTable the specified table (default to criteria table)
* @param string $foreignKey the foreign key in this 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 */ /* manage translations */
ModelCriteriaTools::getI18n( return ModelCriteriaTools::getI18n(
$this->getBackend_context(), $this->getBackend_context(),
$this->getLang(), $this->getLang(),
$search, $search,
$this->request->getSession()->getLocale(), $this->request->getSession()->getLocale(),
$columns, $columns,
$foreignTable, $foreignTable,
$foreignKey $foreignKey,
$forceReturn
); );
} }

View File

@@ -97,7 +97,7 @@ class Category extends BaseLoop
$search = CategoryQuery::create(); $search = CategoryQuery::create();
/* manage translations */ /* manage translations */
$this->configureI18nProcessing($search); $locale = $this->configureI18nProcessing($search);
$id = $this->getId(); $id = $this->getId();
@@ -184,7 +184,7 @@ class Category extends BaseLoop
->set("DESCRIPTION", $category->getVirtualColumn('i18n_DESCRIPTION')) ->set("DESCRIPTION", $category->getVirtualColumn('i18n_DESCRIPTION'))
->set("POSTSCRIPTUM", $category->getVirtualColumn('i18n_POSTSCRIPTUM')) ->set("POSTSCRIPTUM", $category->getVirtualColumn('i18n_POSTSCRIPTUM'))
->set("PARENT", $category->getParent()) ->set("PARENT", $category->getParent())
->set("URL", $category->getUrl()) ->set("URL", $category->getUrl($locale))
->set("PRODUCT_COUNT", $category->countChild()) ->set("PRODUCT_COUNT", $category->countChild())
->set("VISIBLE", $category->getVisible() ? "1" : "0") ->set("VISIBLE", $category->getVisible() ? "1" : "0")
->set("POSITION", $category->getPosition()) ->set("POSITION", $category->getPosition())

View File

@@ -87,7 +87,7 @@ class Content extends BaseLoop
$search = ContentQuery::create(); $search = ContentQuery::create();
/* manage translations */ /* manage translations */
$this->configureI18nProcessing($search); $locale = $this->configureI18nProcessing($search);
$id = $this->getId(); $id = $this->getId();
@@ -220,7 +220,7 @@ class Content extends BaseLoop
->set("DESCRIPTION", $content->getVirtualColumn('i18n_DESCRIPTION')) ->set("DESCRIPTION", $content->getVirtualColumn('i18n_DESCRIPTION'))
->set("POSTSCRIPTUM", $content->getVirtualColumn('i18n_POSTSCRIPTUM')) ->set("POSTSCRIPTUM", $content->getVirtualColumn('i18n_POSTSCRIPTUM'))
->set("POSITION", $content->getPosition()) ->set("POSITION", $content->getPosition())
->set("URL", $content->getUrl()) ->set("URL", $content->getUrl($locale))
; ;
$loopResult->addRow($loopResultRow); $loopResult->addRow($loopResultRow);

View File

@@ -87,7 +87,8 @@ class FeatureValue extends BaseLoop
$search, $search,
array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'),
FeatureAvTableMap::TABLE_NAME, FeatureAvTableMap::TABLE_NAME,
'FEATURE_AV_ID' 'FEATURE_AV_ID',
true
); );
$feature = $this->getFeature(); $feature = $this->getFeature();

View File

@@ -79,7 +79,7 @@ class Folder extends BaseLoop
$search = FolderQuery::create(); $search = FolderQuery::create();
/* manage translations */ /* manage translations */
$this->configureI18nProcessing($search); $locale = $this->configureI18nProcessing($search);
$id = $this->getId(); $id = $this->getId();
@@ -162,7 +162,7 @@ class Folder extends BaseLoop
->set("DESCRIPTION", $folder->getVirtualColumn('i18n_DESCRIPTION')) ->set("DESCRIPTION", $folder->getVirtualColumn('i18n_DESCRIPTION'))
->set("POSTSCRIPTUM", $folder->getVirtualColumn('i18n_POSTSCRIPTUM')) ->set("POSTSCRIPTUM", $folder->getVirtualColumn('i18n_POSTSCRIPTUM'))
->set("PARENT", $folder->getParent()) ->set("PARENT", $folder->getParent())
->set("URL", $folder->getUrl()) ->set("URL", $folder->getUrl($locale))
->set("CONTENT_COUNT", $folder->countChild()) ->set("CONTENT_COUNT", $folder->countChild())
->set("VISIBLE", $folder->getVisible() ? "1" : "0") ->set("VISIBLE", $folder->getVisible() ? "1" : "0")
->set("POSITION", $folder->getPosition()) ->set("POSITION", $folder->getPosition())

View File

@@ -137,7 +137,7 @@ class Product extends BaseLoop
$search = ProductQuery::create(); $search = ProductQuery::create();
/* manage translations */ /* manage translations */
$this->configureI18nProcessing($search); $locale = $this->configureI18nProcessing($search);
$attributeNonStrictMatch = $this->getAttribute_non_strict_match(); $attributeNonStrictMatch = $this->getAttribute_non_strict_match();
$isPSELeftJoinList = array(); $isPSELeftJoinList = array();
@@ -514,7 +514,7 @@ class Product extends BaseLoop
->set("CHAPO", $product->getVirtualColumn('i18n_CHAPO')) ->set("CHAPO", $product->getVirtualColumn('i18n_CHAPO'))
->set("DESCRIPTION", $product->getVirtualColumn('i18n_DESCRIPTION')) ->set("DESCRIPTION", $product->getVirtualColumn('i18n_DESCRIPTION'))
->set("POSTSCRIPTUM", $product->getVirtualColumn('i18n_POSTSCRIPTUM')) ->set("POSTSCRIPTUM", $product->getVirtualColumn('i18n_POSTSCRIPTUM'))
->set("URL", $product->getUrl()) ->set("URL", $product->getUrl($locale))
->set("BEST_PRICE", $product->getVirtualColumn('real_lowest_price')) ->set("BEST_PRICE", $product->getVirtualColumn('real_lowest_price'))
->set("IS_PROMO", $product->getVirtualColumn('main_product_is_promo')) ->set("IS_PROMO", $product->getVirtualColumn('main_product_is_promo'))
->set("IS_NEW", $product->getVirtualColumn('main_product_is_new')) ->set("IS_NEW", $product->getVirtualColumn('main_product_is_new'))

View File

@@ -40,11 +40,7 @@ class ParserContext implements \IteratorAggregate
public function __construct(Request $request) public function __construct(Request $request)
{ {
// Setup basic variables // Setup basic variables
$this $this->set('THELIA_VERSION' , ConfigQuery::read('thelia_version', 'undefined'))
->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'))
; ;
} }

View File

@@ -47,14 +47,15 @@ class UrlGenerator extends AbstractSmartyPlugin
public function generateUrlFunction($params, &$smarty) public function generateUrlFunction($params, &$smarty)
{ {
// the path to process // 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; if ($target != null) $url .= '#'.$target;
return $url;
return $url;
} }
/** /**
@@ -81,6 +82,15 @@ class UrlGenerator extends AbstractSmartyPlugin
return $this->generateViewUrlFunction($params, true); 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) protected function generateViewUrlFunction($params, $forAdmin)
{ {
// the view name (without .html) // the view name (without .html)
@@ -125,7 +135,50 @@ class UrlGenerator extends AbstractSmartyPlugin
return array( return array(
new SmartyPluginDescriptor('function', 'url', $this, 'generateUrlFunction'), new SmartyPluginDescriptor('function', 'url', $this, 'generateUrlFunction'),
new SmartyPluginDescriptor('function', 'viewurl', $this, 'generateFrontViewUrlFunction'), 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();
}
} }

View File

@@ -4,6 +4,7 @@ namespace Thelia\Model;
use Thelia\Model\Base\Category as BaseCategory; use Thelia\Model\Base\Category as BaseCategory;
use Propel\Runtime\ActiveQuery\Criteria; use Propel\Runtime\ActiveQuery\Criteria;
use Thelia\Tools\URL;
class Category extends BaseCategory class Category extends BaseCategory
{ {
@@ -15,8 +16,9 @@ class Category extends BaseCategory
return CategoryQuery::countChild($this->getId()); 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; return $countProduct;
} }
} }

View File

@@ -22,4 +22,14 @@ class ConfigQuery extends BaseConfigQuery {
return $value ? $value->getValue() : $default; 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 } // ConfigQuery

View File

@@ -3,11 +3,12 @@
namespace Thelia\Model; namespace Thelia\Model;
use Thelia\Model\Base\Content as BaseContent; use Thelia\Model\Base\Content as BaseContent;
use Thelia\Tools\URL;
class Content extends BaseContent class Content extends BaseContent
{ {
public function getUrl() public function getUrl($locale)
{ {
return URL::retrieve('content', $this->getId(), $locale);
} }
} }

View File

@@ -3,6 +3,7 @@
namespace Thelia\Model; namespace Thelia\Model;
use Thelia\Model\Base\Folder as BaseFolder; use Thelia\Model\Base\Folder as BaseFolder;
use Thelia\Tools\URL;
class Folder extends BaseFolder class Folder extends BaseFolder
{ {
@@ -14,9 +15,9 @@ class Folder extends BaseFolder
return FolderQuery::countChild($this->getId()); return FolderQuery::countChild($this->getId());
} }
public function getUrl() public function getUrl($locale)
{ {
return URL::retrieve('folder', $this->getId(), $locale);
} }
/** /**

View File

@@ -162,9 +162,9 @@ class RewritingUrlTableMap extends TableMap
// columns // columns
$this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null);
$this->addColumn('URL', 'Url', 'VARCHAR', true, 255, 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_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->addForeignKey('REDIRECTED', 'Redirected', 'INTEGER', 'rewriting_url', 'ID', false, null, null);
$this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null);
$this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null);

View File

@@ -3,12 +3,12 @@
namespace Thelia\Model; namespace Thelia\Model;
use Thelia\Model\Base\Product as BaseProduct; use Thelia\Model\Base\Product as BaseProduct;
use Thelia\Model\ProductSaleElements; use Thelia\Tools\URL;
class Product extends BaseProduct class Product extends BaseProduct
{ {
public function getUrl() public function getUrl($locale)
{ {
return URL::retrieve('product', $this->getId(), $locale);
} }
} }

View File

@@ -24,7 +24,7 @@ class ModelCriteriaTools
* @param null $foreignTable * @param null $foreignTable
* @param string $foreignKey * @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) { if($foreignTable === null) {
$foreignTable = $search->getTableMap()->getName(); $foreignTable = $search->getTableMap()->getName();
@@ -33,16 +33,16 @@ class ModelCriteriaTools
$aliasPrefix = $foreignTable . '_'; $aliasPrefix = $foreignTable . '_';
} }
$defaultLangWithoutTranslation = ConfigQuery::read("default_lang_without_translation", 1); $defaultLangWithoutTranslation = ConfigQuery::getDefaultLangWhenNoTranslationAvailable();
$requestedLocaleI18nAlias = 'requested_locale_i18n'; $requestedLocaleI18nAlias = $aliasPrefix . 'requested_locale_i18n';
$defaultLocaleI18nAlias = 'default_locale_i18n'; $defaultLocaleI18nAlias = $aliasPrefix . 'default_locale_i18n';
if (!$defaultLangWithoutTranslation == 0) {
if($defaultLangWithoutTranslation == 0) {
$requestedLocaleJoin = new Join(); $requestedLocaleJoin = new Join();
$requestedLocaleJoin->addExplicitCondition($search->getTableMap()->getName(), $foreignKey, null, $foreignTable . '_i18n', 'ID', $requestedLocaleI18nAlias); $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) $search->addJoinObject($requestedLocaleJoin, $requestedLocaleI18nAlias)
->addJoinCondition($requestedLocaleI18nAlias ,'`' . $requestedLocaleI18nAlias . '`.LOCALE = ?', $requestedLocale, null, \PDO::PARAM_STR); ->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->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) { foreach($columns as $column) {
$search->withColumn('CASE WHEN NOT ISNULL(`' . $requestedLocaleI18nAlias . '`.ID) THEN `' . $requestedLocaleI18nAlias . '`.`' . $column . '` ELSE `' . $defaultLocaleI18nAlias . '`.`' . $column . '` END', $aliasPrefix . 'i18n_' . $column); $search->withColumn('CASE WHEN NOT ISNULL(`' . $requestedLocaleI18nAlias . '`.ID) THEN `' . $requestedLocaleI18nAlias . '`.`' . $column . '` ELSE `' . $defaultLocaleI18nAlias . '`.`' . $column . '` END', $aliasPrefix . 'i18n_' . $column);
@@ -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) { if($foreignTable === null) {
$foreignTable = $search->getTableMap()->getName(); $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 a lang has been requested, find the related Lang object, and get the locale
if ($requestedLangId !== null) { if ($requestedLangId !== null) {
@@ -125,7 +127,9 @@ class ModelCriteriaTools
if ($backendContext) { if ($backendContext) {
self::getBackEndI18n($search, $locale, $columns, $foreignTable, $foreignKey); self::getBackEndI18n($search, $locale, $columns, $foreignTable, $foreignKey);
} else { } else {
self::getFrontEndI18n($search, $locale, $columns, $foreignTable, $foreignKey); self::getFrontEndI18n($search, $locale, $columns, $foreignTable, $foreignKey, $forceReturn);
} }
return $locale;
} }
} }

View File

@@ -0,0 +1,35 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Rewriting;
/**
* Class RewritingResolver
* @package Thelia\Rewriting
* @author Etienne Roudeix <eroudeix@openstudio.fr>
*
* This class provides methods to resolve rewritten URL as a query
*/
class RewritingResolver
{
}

View File

@@ -0,0 +1,119 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Rewriting;
use Propel\Runtime\ActiveQuery\Criteria;
use Thelia\Model\Base\RewritingUrlQuery;
use Thelia\Model\Map\RewritingUrlTableMap;
/**
* Class RewritingRetriever
* @package Thelia\Rewriting
* @author Etienne Roudeix <eroudeix@openstudio.fr>
*
* 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();
}
}

View File

@@ -0,0 +1,44 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Tests\Rewriting;
use Thelia\Rewriting\RewritingRetriever;
/**
*
* @author Etienne Roudeix <eroudeix@openstudio.fr>
*
*/
class RewritingRetrieverTest extends \PHPUnit_Framework_TestCase
{
public function testGetViewUrl()
{
}
public function testGetSpecificUrl()
{
}
}

View File

@@ -0,0 +1,39 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Tests\Type;
use Thelia\Tools\URL;
/**
*
* @author Etienne Roudeix <eroudeix@openstudio.fr>
*
*/
class URLTest extends \PHPUnit_Framework_TestCase
{
public function testRetrieve()
{
}
}

View File

@@ -23,7 +23,9 @@
namespace Thelia\Tools; namespace Thelia\Tools;
use Symfony\Component\HttpFoundation\Request;
use Thelia\Model\ConfigQuery; use Thelia\Model\ConfigQuery;
use Thelia\Rewriting\RewritingRetriever;
class URL class URL
{ {
@@ -51,7 +53,11 @@ class URL
// Already absolute ? // Already absolute ?
if (substr($path, 0, 4) != 'http') { 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, '/'); $base = rtrim($root, '/') . '/' . ltrim($path, '/');
} else } else
@@ -101,4 +107,50 @@ class URL
return self::absoluteUrl($path, $parameters); 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;
}
} }

View File

@@ -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 INSERT INTO `config` (`name`, `value`, `secured`, `hidden`, `created_at`, `updated_at`) VALUES
('session_config.default', '1', 1, 1, NOW(), NOW()), ('session_config.default', '1', 1, 1, NOW(), NOW()),
('verifyStock', '1', 1, 0, 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()), ('imagine_graphic_driver', 'gd', 1, 0, NOW(), NOW()),
('default_images_quality_percent', '75', 1, 0, NOW(), NOW()), ('default_images_quality_percent', '75', 1, 0, NOW(), NOW()),
('original_image_delivery_mode', 'symlink', 1, 0, NOW(), NOW()), ('original_image_delivery_mode', 'symlink', 1, 0, NOW(), NOW()),

View File

@@ -1443,9 +1443,9 @@ CREATE TABLE `rewriting_url`
( (
`id` INTEGER NOT NULL AUTO_INCREMENT, `id` INTEGER NOT NULL AUTO_INCREMENT,
`url` VARCHAR(255) NOT NULL, `url` VARCHAR(255) NOT NULL,
`view` VARCHAR(255), `view` VARCHAR(255) NOT NULL,
`view_id` VARCHAR(255), `view_id` VARCHAR(255),
`view_locale` VARCHAR(255), `view_locale` VARCHAR(255) NOT NULL,
`redirected` INTEGER, `redirected` INTEGER,
`created_at` DATETIME, `created_at` DATETIME,
`updated_at` DATETIME, `updated_at` DATETIME,

View File

@@ -1096,9 +1096,9 @@
<table name="rewriting_url" namespace="Thelia\Model"> <table name="rewriting_url" namespace="Thelia\Model">
<column autoIncrement="true" name="id" primaryKey="true" required="true" type="INTEGER" /> <column autoIncrement="true" name="id" primaryKey="true" required="true" type="INTEGER" />
<column name="url" required="true" size="255" type="VARCHAR" /> <column name="url" required="true" size="255" type="VARCHAR" />
<column name="view" size="255" type="VARCHAR" /> <column name="view" required="true" size="255" type="VARCHAR" />
<column name="view_id" size="255" type="VARCHAR" /> <column name="view_id" size="255" type="VARCHAR" />
<column name="view_locale" size="255" type="VARCHAR" /> <column name="view_locale" required="true" size="255" type="VARCHAR" />
<column name="redirected" type="INTEGER" /> <column name="redirected" type="INTEGER" />
<foreign-key foreignTable="rewriting_url" name="fk_rewriting_url_redirected" onDelete="RESTRICT" onUpdate="RESTRICT"> <foreign-key foreignTable="rewriting_url" name="fk_rewriting_url_redirected" onDelete="RESTRICT" onUpdate="RESTRICT">
<reference foreign="id" local="redirected" /> <reference foreign="id" local="redirected" />

View File

@@ -69,7 +69,7 @@
</form> </form>
{/loop} {/loop}
<div class="view-shop"><a href="{$INDEX_PAGE}" title="{intl l='View site'}" target="_blank"><i class="icon-white icon-eye-open"></i> {intl l="View shop"}</a></div> <div class="view-shop"><a href="{navigate to="index"}" title="{intl l='View site'}" target="_blank"><i class="icon-white icon-eye-open"></i> {intl l="View shop"}</a></div>
</div> </div>
</div> </div>
@@ -164,4 +164,4 @@
<div class="brandbar brandbar-wide container"> <div class="brandbar brandbar-wide container">
<a class="brand" href="{url path='/admin'}">{images file='../assets/img/logo-thelia-34px.png'}<img src="{$asset_url}" alt="{intl l='Thelia, solution e-commerce libre'}" />{/images}</a> <a class="brand" href="{url path='/admin'}">{images file='../assets/img/logo-thelia-34px.png'}<img src="{$asset_url}" alt="{intl l='Thelia, solution e-commerce libre'}" />{/images}</a>
</div> </div>
{/elseloop} {/elseloop}

View File

@@ -8,7 +8,7 @@
</ul> </ul>
{form name="thelia.cart.add" } {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 *}
<form action="{url path="/cart/add" }" method="post" {form_enctype form=$form}> <form action="{url path="/cart/add" }" method="post" {form_enctype form=$form}>
{* {*

View File

@@ -22,34 +22,10 @@
{loop name="product" type="product" category="#ID"} {loop name="product" type="product" category="#ID"}
<div style="border: dashed 2px red; padding: 20px; margin: 10px;"> <div style="border: dashed 2px red; padding: 20px; margin: 10px;">
<h3><a name="#REF">PRODUCT : #REF (#LOOP_COUNT / #LOOP_TOTAL)</a></h3> <h3><a href="#URL">PRODUCT #ID : #REF (#LOOP_COUNT / #LOOP_TOTAL)</a></h3>
<h4>#TITLE</h4> <h4>#TITLE</h4>
<p>#DESCRIPTION</p> <p>#DESCRIPTION</p>
{ifloop rel="acc"}
<h5>Accessories</h5>
<ul>
{loop name="acc" type="accessory" product="#ID" order="accessory"}
<li><a href="##REF">#REF</a></li>
{/loop}
</ul>
{/ifloop}
{elseloop rel="acc"}
<h5>No accessory</h5>
{/elseloop}
{ifloop rel="prod_ass_cont"}
<h5>Associated Content</h5>
<ul>
{loop name="prod_ass_cont" type="associated_content" product="#ID" order="associated_content"}
<li>#TITLE</li>
{/loop}
</ul>
{/ifloop}
{elseloop rel="prod_ass_cont"}
<h5>No associated content</h5>
{/elseloop}
{ifloop rel="ft"} {ifloop rel="ft"}
<h5>Features</h5> <h5>Features</h5>
<ul> <ul>
@@ -67,29 +43,6 @@
{elseloop rel="ft"} {elseloop rel="ft"}
<h5>No feature</h5> <h5>No feature</h5>
{/elseloop} {/elseloop}
<h5>Product sale elements</h5>
{assign var=current_product value=#ID}
{loop name="pse" type="product_sale_elements" product="#ID"}
<div style="border: solid 2px darkorange; padding: 5px; margin: 5px;">
{loop name="combi" type="attribute_combination" product_sale_elements="#ID"}
#ATTRIBUTE_TITLE = #ATTRIBUTE_AVAILABILITY_TITLE<br />
{/loop}
<br />#WEIGHT g
<br /><strong>{if #IS_PROMO == 1} #PROMO_PRICE € (instead of #PRICE) {else} #PRICE € {/if}</strong>
<br /><br />
Add
<select>
{for $will=1 to #QUANTITY}
<option>{$will}</option>
{/for}
</select>
to my cart
</ul>
</div>
{/loop}
</div> </div>
{/loop} {/loop}
{loop name="catgory1" type="category" parent="#ID"} {loop name="catgory1" type="category" parent="#ID"}
@@ -110,75 +63,29 @@
{loop name="product" type="product" category="#ID"} {loop name="product" type="product" category="#ID"}
<div style="border: solid 1px green; padding: 20px; margin: 10px;"> <div style="border: solid 1px green; padding: 20px; margin: 10px;">
<h3><a name="#REF">PRODUCT : #REF (#LOOP_COUNT / #LOOP_TOTAL)</a></h3> <h3><a href="#URL">PRODUCT #ID : #REF (#LOOP_COUNT / #LOOP_TOTAL)</a></h3>
<h4>#TITLE</h4> <h4>#TITLE</h4>
<p>#DESCRIPTION</p> <p>#DESCRIPTION</p>
{ifloop rel="acc"} {ifloop rel="ft"}
<h5>Accessories</h5> <h5>Features</h5>
<ul> <ul>
{loop name="acc" type="accessory" product="#ID" order="accessory"} {assign var=current_product value=#ID}
<li><a href="##REF">#REF</a></li> {loop name="ft" type="feature" order="manual" product="#ID"}
{/loop} <li>
</ul> <strong>#TITLE</strong> :
{/ifloop} {loop name="ft_v" type="feature_value" product="{$current_product}" feature="#ID"}
{elseloop rel="acc"} #TITLE / #PERSONAL_VALUE
<h5>No accessory</h5> {/loop}
{/elseloop} </li>
{ifloop rel="prod_ass_cont"}
<h5>Associated Content</h5>
<ul>
{loop name="prod_ass_cont" type="associated_content" product="#ID" order="associated_content"}
<li>#TITLE</li>
{/loop}
</ul>
{/ifloop}
{elseloop rel="prod_ass_cont"}
<h5>No associated content</h5>
{/elseloop}
{ifloop rel="ft"}
<h5>Features</h5>
<ul>
{loop name="ft" type="feature" order="manual" product="#ID"}
<li>
<strong>#TITLE</strong> :
{loop name="ft_v" type="feature_value" product="{$current_product}" feature="#ID"}
#TITLE / #PERSONAL_VALUE
{/loop} {/loop}
</li> </ul>
{/loop} {/ifloop}
</ul> {elseloop rel="ft"}
{/ifloop} <h5>No feature</h5>
{elseloop rel="ft"} {/elseloop}
<h5>No feature</h5> </div>
{/elseloop}
<h5>Product sale elements</h5>
{assign var=current_product value=#ID}
{loop name="pse" type="product_sale_elements" product="#ID"}
<div style="border: solid 2px darkorange; padding: 5px; margin: 5px;">
{loop name="combi" type="attribute_combination" product_sale_elements="#ID"}
#ATTRIBUTE_TITLE = #ATTRIBUTE_AVAILABILITY_TITLE<br />
{/loop}
<br />#WEIGHT g
<br /><strong>{if #IS_PROMO == 1} #PROMO_PRICE € (instead of #PRICE) {else} #PRICE € {/if}</strong>
<br /><br />
Add
<select>
{for $will=1 to #QUANTITY}
<option>{$will}</option>
{/for}
</select>
to my cart
</ul>
</div>
{/loop}
</div>
{/loop} {/loop}
</div> </div>
{/loop} {/loop}

View File

@@ -1,7 +1,7 @@
{include file="includes/header.html"} {include file="includes/header.html"}
{form name="thelia.customer.creation"} {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 *}
<form action="{url path="/customer/create" }" method="post" {form_enctype form=$form}> <form action="{url path="/customer/create" }" method="post" {form_enctype form=$form}>
{* {*
The two fields below are not par of the form, they are here to defines 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'} {form_field form=$form field='success_url'}
<input type="hidden" name="{$name}" value="{$RETURN_TO_URL}" /> {* the url the user is redirected to on login success *} <input type="hidden" name="{$name}" value="{navigate to="return_to"}" /> {* the url the user is redirected to on login success *}
{/form_field} {/form_field}
{form_field form=$form field='auto_login'} {form_field form=$form field='auto_login'}

View File

@@ -3,8 +3,8 @@
<h1>{intl l='Please login'}</h1> <h1>{intl l='Please login'}</h1>
{form name="thelia.customer.login" } {form name="thelia.customer.login" }
<form action="{url path='/customer/login'}" method="post" {form_enctype form=$form}>
<form action="{url path='/customer/login'}" method="post" {form_enctype form=$form}>
{* {*
The field below are not par of the Login form, it defines view to render if the form cannot be validated 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'} {form_field form=$form field='success_url'}
<input type="hidden" name="{$name}" value="{$RETURN_TO_URL}" /> {* the url the user is redirected to on login success *} <input type="hidden" name="{$name}" value="{navigate to="return_to"}" /> {* the url the user is redirected to on login success *}
{/form_field} {/form_field}
{* {*

88
templates/default/product.html Executable file
View File

@@ -0,0 +1,88 @@
Here you are : {navigate to="current"}<br />
From : {navigate to="return_to"}<br />
Index : {navigate to="index"}<br />
<h1>Product page</h1>
{ifloop rel="product"}
{loop type="product" name="product" current="true"}
<div style="border: dashed 2px red; padding: 20px; margin: 10px;">
<h2>PRODUCT (#ID) : #REF</h2>
<h3>#TITLE</h3>
<p>#DESCRIPTION</p>
{ifloop rel="acc"}
<h4>Accessories</h4>
<ul>
{loop name="acc" type="accessory" product="#ID" order="accessory"}
<li><a href="#URL">#REF</a></li>
{/loop}
</ul>
{/ifloop}
{elseloop rel="acc"}
<h4>No accessory</h4>
{/elseloop}
{ifloop rel="prod_ass_cont"}
<h4>Associated Content</h4>
<ul>
{loop name="prod_ass_cont" type="associated_content" product="#ID" order="associated_content"}
<li>#TITLE</li>
{/loop}
</ul>
{/ifloop}
{elseloop rel="prod_ass_cont"}
<h4>No associated content</h4>
{/elseloop}
{ifloop rel="ft"}
<h4>Features</h4>
<ul>
{assign var=current_product value=#ID}
{loop name="ft" type="feature" order="manual" product="#ID"}
<li>
<strong>#TITLE</strong> :
{loop name="ft_v" type="feature_value" product="{$current_product}" feature="#ID"}
#TITLE / #PERSONAL_VALUE
{/loop}
</li>
{/loop}
</ul>
{/ifloop}
{elseloop rel="ft"}
<h4>No feature</h4>
{/elseloop}
<h4>Product sale elements</h4>
{assign var=current_product value=#ID}
{loop name="pse" type="product_sale_elements" product="#ID"}
<div style="border: solid 2px darkorange; padding: 5px; margin: 5px;">
{loop name="combi" type="attribute_combination" product_sale_elements="#ID"}
#ATTRIBUTE_TITLE = #ATTRIBUTE_AVAILABILITY_TITLE<br />
{/loop}
<br />#WEIGHT g
<br /><strong>{if #IS_PROMO == 1} #PROMO_PRICE € (instead of #PRICE) {else} #PRICE € {/if}</strong>
<br /><br />
Add
<select>
{for $will=1 to #QUANTITY}
<option>{$will}</option>
{/for}
</select>
to my cart
</ul>
</div>
{/loop}
</div>
{/loop}
{/ifloop}
{elseloop rel="product"}
<h2>Produit introuvable !</h2>
{/elseloop}