diff --git a/classes/Dispatcher.php b/classes/Dispatcher.php
index 04b3b038e..264cf8d9f 100644
--- a/classes/Dispatcher.php
+++ b/classes/Dispatcher.php
@@ -221,6 +221,9 @@ class DispatcherCore
$this->setRequestUri();
+ // Switch language if needed
+ Tools::switchLanguage();
+
$this->loadRoutes();
}
@@ -368,19 +371,23 @@ class DispatcherCore
}
/**
- * Load default routes
+ * Load default routes group by languages
*/
protected function loadRoutes()
{
$context = Context::getContext();
- foreach ($this->default_routes as $id => $route)
- $this->addRoute(
- $id,
- $route['rule'],
- $route['controller'],
- $route['keywords'],
- isset($route['params']) ? $route['params'] : array()
- );
+
+ // Set default routes
+ foreach (Language::getLanguages() as $lang)
+ foreach ($this->default_routes as $id => $route)
+ $this->addRoute(
+ $id,
+ $route['rule'],
+ $route['controller'],
+ $lang['id_lang'],
+ $route['keywords'],
+ isset($route['params']) ? $route['params'] : array()
+ );
if ($this->use_routes)
{
@@ -391,16 +398,15 @@ class DispatcherCore
$id_lang = Language::getIdByIso($iso_lang);
// Load routes from meta table
- $sql = 'SELECT m.page, ml.url_rewrite
+ $sql = 'SELECT m.page, ml.url_rewrite, ml.id_lang
FROM `'._DB_PREFIX_.'meta` m
LEFT JOIN `'._DB_PREFIX_.'meta_lang` ml ON (m.id_meta = ml.id_meta'.Shop::addSqlRestrictionOnLang('ml').')
- WHERE id_lang = '.(int)$id_lang.'
ORDER BY LENGTH(ml.url_rewrite) DESC';
if ($results = Db::getInstance()->executeS($sql))
foreach ($results as $row)
{
if ($row['url_rewrite'])
- $this->addRoute($row['page'], $row['url_rewrite'], $row['page']);
+ $this->addRoute($row['page'], $row['url_rewrite'], $row['page'], $row['id_lang']);
else
$this->empty_route = array(
'routeID' => $row['page'],
@@ -420,24 +426,30 @@ class DispatcherCore
// Load custom routes
foreach ($this->default_routes as $route_id => $route_data)
if ($custom_route = Configuration::get('PS_ROUTE_'.$route_id))
- $this->addRoute(
- $route_id,
- $custom_route,
- $route_data['controller'],
- $route_data['keywords'],
- isset($route_data['params']) ? $route_data['params'] : array()
- );
+ foreach (Language::getLanguages() as $lang)
+ $this->addRoute(
+ $route_id,
+ $custom_route,
+ $route_data['controller'],
+ $lang['id_lang'],
+ $route_data['keywords'],
+ isset($route_data['params']) ? $route_data['params'] : array()
+ );
}
}
/**
*
- * @param string $id Name of the route (need to be uniq, a second route with same name will override the first)
+ * @param string $route_id Name of the route (need to be uniq, a second route with same name will override the first)
* @param string $rule Url rule
* @param string $controller Controller to call if request uri match the rule
+ * @param int $id_lang
*/
- public function addRoute($route_id, $rule, $controller, array $keywords = array(), array $params = array())
+ public function addRoute($route_id, $rule, $controller, $id_lang = null, array $keywords = array(), array $params = array())
{
+ if (is_null($id_lang))
+ $id_lang = Context::getContext()->language->id;
+
$regexp = preg_quote($rule, '#');
if ($keywords)
{
@@ -471,7 +483,10 @@ class DispatcherCore
}
$regexp = '#^/'.$regexp.'(\?.*)?$#u';
- $this->routes[$route_id] = array(
+ if (!isset($this->routes[$id_lang]))
+ $this->routes[$id_lang] = array();
+
+ $this->routes[$id_lang][$route_id] = array(
'rule' => $rule,
'regexp' => $regexp,
'controller' => $controller,
@@ -484,26 +499,31 @@ class DispatcherCore
* Check if a route exists
*
* @param string $route_id
+ * @param int $id_lang
* @return bool
*/
- public function hasRoute($route_id)
+ public function hasRoute($route_id, $id_lang = null)
{
- return isset($this->routes[$route_id]);
+ if (is_null($id_lang))
+ $id_lang = Context::getContext()->language->id;
+
+ return isset($this->routes[$id_lang]) && isset($this->routes[$id_lang][$route_id]);
}
/**
* Check if a keyword is written in a route rule
*
* @param string $route_id
+ * @param int $id_lang
* @param string $keyword
* @return bool
*/
- public function hasKeyword($route_id, $keyword)
+ public function hasKeyword($route_id, $id_lang, $keyword)
{
- if (!isset($this->routes[$route_id]))
+ if (!isset($this->routes[$id_lang]) && !isset($this->routes[$id_lang][$route_id]))
return false;
- return preg_match('#\{([^{}]+:)?'.preg_quote($keyword, '#').'(:[^{}])?\}#', $this->routes[$route_id]['rule']);
+ return preg_match('#\{([^{}]+:)?'.preg_quote($keyword, '#').'(:[^{}])?\}#', $this->routes[$id_lang][$route_id]['rule']);
}
/**
@@ -530,19 +550,23 @@ class DispatcherCore
* Create an url from
*
* @param string $route_id Name the route
+ * @param int $id_lang
* @param array $params
* @param bool $use_routes If false, don't use to create this url
* @param string $anchor Optional anchor to add at the end of this url
*/
- public function createUrl($route_id, array $params = array(), $force_routes = false, $anchor = '')
+ public function createUrl($route_id, $id_lang = null, array $params = array(), $force_routes = false, $anchor = '')
{
- if (!isset($this->routes[$route_id]))
+ if (!$id_lang)
+ $id_lang = Context::getContext()->language->id;
+
+ if (!isset($this->routes[$id_lang][$route_id]))
{
$query = http_build_query($params, '', '&');
$index_link = Configuration::get('PS_REWRITING_SETTINGS') ? '' : 'index.php';
return ($route_id == 'index') ? $index_link.(($query) ? '?'.$query : '') : 'index.php?controller='.$route_id.(($query) ? '&'.$query : '').$anchor;
}
- $route = $this->routes[$route_id];
+ $route = $this->routes[$id_lang][$route_id];
// Check required fields
$query_params = isset($route['params']) ? $route['params'] : array();
@@ -630,34 +654,35 @@ class DispatcherCore
// Add empty route as last route to prevent this greedy regexp to match request uri before right time
if ($this->empty_route)
- $this->addRoute($this->empty_route['routeID'], $this->empty_route['rule'], $this->empty_route['controller']);
+ $this->addRoute($this->empty_route['routeID'], $this->empty_route['rule'], $this->empty_route['controller'], Context::getContext()->language->id);
- foreach ($this->routes as $route)
- if (preg_match($route['regexp'], $this->request_uri, $m))
- {
- // Route found ! Now fill $_GET with parameters of uri
- foreach ($m as $k => $v)
- if (!is_numeric($k))
- $_GET[$k] = $v;
-
- $controller = $route['controller'] ? $route['controller'] : $_GET['controller'];
- if (!empty($route['params']))
- foreach ($route['params'] as $k => $v)
- $_GET[$k] = $v;
-
- // A patch for module friendly urls
- if (preg_match('#module-([a-z0-9_-]+)-([a-z0-9]+)$#i', $controller, $m))
+ if (isset($this->routes[Context::getContext()->language->id]))
+ foreach ($this->routes[Context::getContext()->language->id] as $route)
+ if (preg_match($route['regexp'], $this->request_uri, $m))
{
- $_GET['module'] = $m[1];
- $_GET['fc'] = 'module';
- $controller = $m[2];
+ // Route found ! Now fill $_GET with parameters of uri
+ foreach ($m as $k => $v)
+ if (!is_numeric($k))
+ $_GET[$k] = $v;
+
+ $controller = $route['controller'] ? $route['controller'] : $_GET['controller'];
+ if (!empty($route['params']))
+ foreach ($route['params'] as $k => $v)
+ $_GET[$k] = $v;
+
+ // A patch for module friendly urls
+ if (preg_match('#module-([a-z0-9_-]+)-([a-z0-9]+)$#i', $controller, $m))
+ {
+ $_GET['module'] = $m[1];
+ $_GET['fc'] = 'module';
+ $controller = $m[2];
+ }
+
+ if (isset($_GET['fc']) && $_GET['fc'] == 'module')
+ $this->front_controller = self::FC_MODULE;
+ break;
}
- if (isset($_GET['fc']) && $_GET['fc'] == 'module')
- $this->front_controller = self::FC_MODULE;
- break;
- }
-
if ($controller == 'index' || $this->request_uri == '/index.php')
$controller = $this->default_controller;
$this->controller = $controller;
diff --git a/classes/Link.php b/classes/Link.php
index fefb51eb1..25853b103 100644
--- a/classes/Link.php
+++ b/classes/Link.php
@@ -112,19 +112,19 @@ class LinkCore
$params['meta_keywords'] = Tools::str2url($product->getFieldByLang('meta_keywords'));
$params['meta_title'] = Tools::str2url($product->getFieldByLang('meta_title'));
- if ($dispatcher->hasKeyword('product_rule', 'manufacturer'))
+ if ($dispatcher->hasKeyword('product_rule', $id_lang, 'manufacturer'))
$params['manufacturer'] = Tools::str2url($product->isFullyLoaded ? $product->manufacturer_name : Manufacturer::getNameById($product->id_manufacturer));
- if ($dispatcher->hasKeyword('product_rule', 'supplier'))
+ if ($dispatcher->hasKeyword('product_rule', $id_lang, 'supplier'))
$params['supplier'] = Tools::str2url($product->isFullyLoaded ? $product->supplier_name : Supplier::getNameById($product->id_supplier));
- if ($dispatcher->hasKeyword('product_rule', 'price'))
+ if ($dispatcher->hasKeyword('product_rule', $id_lang, 'price'))
$params['price'] = $product->isFullyLoaded ? $product->price : Product::getPriceStatic($product->id, false, null, 6, null, false, true, 1, false, null, null, null, $product->specificPrice);
- if ($dispatcher->hasKeyword('product_rule', 'tags'))
+ if ($dispatcher->hasKeyword('product_rule', $id_lang, 'tags'))
$params['tags'] = Tools::str2url($product->getTags($id_lang));
- if ($dispatcher->hasKeyword('product_rule', 'categories'))
+ if ($dispatcher->hasKeyword('product_rule', $id_lang, 'categories'))
{
$cats = array();
foreach ($product->getParentCategories() as $cat)
@@ -133,7 +133,7 @@ class LinkCore
}
$anchor = $ipa ? $product->getAnchor($ipa) : '';
- return $url.$dispatcher->createUrl('product_rule', $params, $force_routes, $anchor);
+ return $url.$dispatcher->createUrl('product_rule', $id_lang, $params, $force_routes, $anchor);
}
/**
@@ -172,7 +172,7 @@ class LinkCore
$params['selected_filters'] = $selected_filters;
}
- return $url.Dispatcher::getInstance()->createUrl($rule, $params, $this->allow);
+ return $url.Dispatcher::getInstance()->createUrl($rule, $id_lang, $params, $this->allow);
}
/**
@@ -199,7 +199,7 @@ class LinkCore
$params['meta_keywords'] = Tools::str2url($category->meta_keywords);
$params['meta_title'] = Tools::str2url($category->meta_title);
- return $url.Dispatcher::getInstance()->createUrl('cms_category_rule', $params, $this->allow);
+ return $url.Dispatcher::getInstance()->createUrl('cms_category_rule', $id_lang, $params, $this->allow);
}
/**
@@ -237,7 +237,7 @@ class LinkCore
else
$params['meta_title'] = '';
- return $url.Dispatcher::getInstance()->createUrl('cms_rule', $params, $this->allow);
+ return $url.Dispatcher::getInstance()->createUrl('cms_rule', $id_lang, $params, $this->allow);
}
/**
@@ -264,7 +264,7 @@ class LinkCore
$params['meta_keywords'] = Tools::str2url($supplier->meta_keywords);
$params['meta_title'] = Tools::str2url($supplier->meta_title);
- return $url.Dispatcher::getInstance()->createUrl('supplier_rule', $params, $this->allow);
+ return $url.Dispatcher::getInstance()->createUrl('supplier_rule', $id_lang, $params, $this->allow);
}
/**
@@ -291,7 +291,7 @@ class LinkCore
$params['meta_keywords'] = Tools::str2url($manufacturer->meta_keywords);
$params['meta_title'] = Tools::str2url($manufacturer->meta_title);
- return $url.Dispatcher::getInstance()->createUrl('manufacturer_rule', $params, $this->allow);
+ return $url.Dispatcher::getInstance()->createUrl('manufacturer_rule', $id_lang, $params, $this->allow);
}
/**
@@ -316,10 +316,10 @@ class LinkCore
$params['controller'] = $controller ? $controller : 'default';
// If the module has its own route ... just use it !
- if (Dispatcher::getInstance()->hasRoute('module-'.$module.'-'.$controller))
+ if (Dispatcher::getInstance()->hasRoute('module-'.$module.'-'.$controller, $id_lang))
return $this->getPageLink('module-'.$module.'-'.$controller, $params);
else
- return $url.Dispatcher::getInstance()->createUrl('module', $params, $this->allow);
+ return $url.Dispatcher::getInstance()->createUrl('module', $id_lang, $params, $this->allow);
}
/**
@@ -331,8 +331,10 @@ class LinkCore
*/
public function getAdminLink($controller, $with_token = true)
{
+ $id_lang = Context::getContext()->language->id;
+
$params = $with_token ? array('token' => Tools::getAdminTokenLite($controller)) : array();
- return Dispatcher::getInstance()->createUrl($controller, $params, false);
+ return Dispatcher::getInstance()->createUrl($controller, $id_lang, $params, false);
}
/**
@@ -404,7 +406,7 @@ class LinkCore
}
unset($request['controller']);
- $uri_path = Dispatcher::getInstance()->createUrl($controller, $request);
+ $uri_path = Dispatcher::getInstance()->createUrl($controller, $id_lang, $request);
$url = ($ssl && $this->ssl_enable) ? Tools::getShopDomainSsl(true) : Tools::getShopDomain(true);
$url .= __PS_BASE_URI__.$this->getLangLink($id_lang).ltrim($uri_path, '/');
@@ -426,24 +428,20 @@ class LinkCore
{
if (!$context)
$context = Context::getContext();
- $matches = array();
- $request = $_SERVER['REQUEST_URI'];
- preg_match('#^/([a-z]{2})/([^\?]*).*$#', $request, $matches);
- if ($matches)
- {
- $current_iso = $matches[1];
- $rewrite = $matches[2];
- $url_rewrite = Meta::getEquivalentUrlRewrite($id_lang, Language::getIdByIso($current_iso), $rewrite);
- $request = str_replace($rewrite, $url_rewrite, $request);
- }
$params = $_GET;
unset($params['isolang'], $params['controller']);
if (!$this->allow)
$params['id_lang'] = $id_lang;
+ else
+ unset($params['id_lang']);
- return $this->getPageLink(Dispatcher::getInstance()->getController(), false, $id_lang, $params);
+ $controller = Dispatcher::getInstance()->getController();
+ if (!empty(Context::getContext()->controller->php_self))
+ $controller = Context::getContext()->controller->php_self;
+
+ return $this->getPageLink($controller, false, $id_lang, $params);
}
public function goPage($url, $p)
diff --git a/classes/Tools.php b/classes/Tools.php
index ec6fc07e9..50d0beabf 100644
--- a/classes/Tools.php
+++ b/classes/Tools.php
@@ -378,6 +378,9 @@ class ToolsCore
if (!$context)
$context = Context::getContext();
+ if (($iso = Tools::getValue('isolang')) && Validate::isLanguageIsoCode($iso) && ($id_lang = (int)Language::getIdByIso($iso)))
+ $_GET['id_lang'] = $id_lang;
+
// update language only if new id is different from old id
// or if default language changed
$cookie_id_lang = $context->cookie->id_lang;
@@ -392,7 +395,19 @@ class ToolsCore
$params = $_GET;
unset($params['id_lang']);
- Tools::redirect('index.php?'.http_build_query($params));
+
+ if (!Configuration::get('PS_REWRITING_SETTINGS'))
+ {
+ if (empty($params['controller']))
+ unset($params['controller']);
+ elseif (!empty(Context::getContext()->controller->php_self))
+ $params['controller'] = Context::getContext()->controller->php_self;
+
+ if (empty($params))
+ Tools::redirect('index.php');
+ else
+ Tools::redirect('index.php?'.http_build_query($params));
+ }
}
}
diff --git a/classes/controller/FrontController.php b/classes/controller/FrontController.php
index c418a6730..d5e4834c6 100755
--- a/classes/controller/FrontController.php
+++ b/classes/controller/FrontController.php
@@ -145,12 +145,10 @@ class FrontControllerCore extends Controller
ob_start();
- // Switch language if needed and init cookie language
- if (($iso = Tools::getValue('isolang')) && Validate::isLanguageIsoCode($iso) && ($id_lang = (int)Language::getIdByIso($iso)))
- $_GET['id_lang'] = $id_lang;
-
- Tools::switchLanguage();
+ // Init cookie language
+ // @TODO This method must be moved into switchLanguage
Tools::setCookieLanguage($this->context->cookie);
+
$currency = Tools::setCurrency($this->context->cookie);
$protocol_link = (Configuration::get('PS_SSL_ENABLED') || Tools::usingSecureMode()) ? 'https://' : 'http://';
@@ -525,7 +523,7 @@ class FrontControllerCore extends Controller
if (Tools::isSubmit('live_edit'))
$this->context->smarty->assign('live_edit', $this->getLiveEditFooter());
- $layout = $this->getLayout();
+ $layout = $this->getLayout();
if ($layout)
{
if ($this->template)
@@ -608,15 +606,26 @@ class FrontControllerCore extends Controller
$params[$key] = $value;
$str_params = '';
- if ($params)
- $str_params = ((strpos($canonical_url, '?') === false) ? '?' : '&').http_build_query($params, '', '&');
+ $url_details = parse_url($canonical_url);
+ if (!empty($url_details['query']))
+ {
+ parse_str($url_details['query'], $query);
+ foreach ($query as $key => $value)
+ $params[$key] = $value;
+ }
+
+ $str_params = http_build_query($params, '', '&');
+ if (!empty($str_params))
+ $final_url = preg_replace('/^([^?]*)?.*$/', '$1', $canonical_url).'?'.Tools::safeOutput($str_params);
+ else
+ $final_url = preg_replace('/^([^?]*)?.*$/', '$1', $canonical_url);
if (defined('_PS_MODE_DEV_') && _PS_MODE_DEV_ && $_SERVER['REQUEST_URI'] != __PS_BASE_URI__)
- die('[Debug] This page has moved
Please use the following URL instead: '.$canonical_url.Tools::safeOutput($str_params).'');
+ die('[Debug] This page has moved
Please use the following URL instead: '.$final_url.'');
header('HTTP/1.0 301 Moved');
header('Cache-Control: no-cache');
- Tools::redirectLink($canonical_url.$str_params);
+ Tools::redirectLink($final_url);
}
}