diff --git a/classes/Dispatcher.php b/classes/Dispatcher.php
index bfc08ec77..6e68c510b 100644
--- a/classes/Dispatcher.php
+++ b/classes/Dispatcher.php
@@ -2,14 +2,95 @@
class DispatcherCore
{
+ /**
+ * @var Dispatcher
+ */
+ public static $instance = null;
+
+ /**
+ * @var array
+ */
+ protected $defaultRoutes = array(
+ 'product' => array(
+ 'controller' => 'product',
+ 'rule' => '{number:id_product}-{word}.html',
+ ),
+ 'category' => array(
+ 'controller' => 'category',
+ 'rule' => '{number:id_category}-{word}',
+ ),
+ 'product_alt' => array(
+ 'controller' => 'product',
+ 'rule' => '{word1}/{number:id_product}-{word2}.html',
+ ),
+ 'supplier' => array(
+ 'controller' => 'supplier',
+ 'rule' => '{number:id_supplier}__{word}',
+ ),
+ 'manufacturer' => array(
+ 'controller' => 'manufacturer',
+ 'rule' => '{number:id_manufacturer}_{word}',
+ ),
+ 'cms' => array(
+ 'controller' => 'cms',
+ 'rule' => 'content/{number:id_cms}-{word}',
+ ),
+ 'cms_category' => array(
+ 'controller' => 'cms',
+ 'rule' => 'content/category/{number:id_cms_category}-{word}',
+ ),
+ );
+
+ /**
+ * @var $useRoutes bool
+ */
+ protected $useRoutes = false;
+
+ /**
+ * @var $routes array
+ */
+ protected $routes = array();
+
+ /**
+ * @var array
+ */
+ protected $keywords = array(
+ 'number' => '[0-9]+',
+ 'word' => '[a-zA-Z0-9-]*',
+ );
+
public static $controllers = array();
public static $controller;
- function __construct()
+ /**
+ * Get current instance of dispatcher (singleton)
+ *
+ * @return Dispatcher
+ */
+ public static function getInstance()
{
- $this->loadControllers();
+ if (!self::$instance)
+ self::$instance = new Dispatcher();
+ return self::$instance;
}
+ /**
+ * Need to be instancied from getInstance() method
+ */
+ protected function __construct()
+ {
+ $this->useRoutes = (bool)Configuration::get('PS_REWRITING_SETTINGS');
+ $this->loadControllers();
+
+ // Load default routes
+ if ($this->useRoutes)
+ foreach ($this->defaultRoutes as $id => $route)
+ $this->addRoute($id, $route['rule'], $route['controller']);
+ }
+
+ /**
+ * "main" method of dispatcher, call the controller
+ */
public function dispatch()
{
self::$controller = $this->getController();
@@ -19,7 +100,86 @@ class DispatcherCore
self::$controller = 'index';
ControllerFactory::getController(self::$controllers[self::$controller])->run();
}
+
+ /**
+ *
+ * @param string $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
+ */
+ public function addRoute($routeID, $rule, $controller)
+ {
+ $regexp = preg_quote($rule, '#');
+ $required = array();
+ preg_match_all('#\\\{('.implode('|', array_keys($this->keywords)).')[0-9]*(\\\:([a-z0-9_]+))?\\\}#', $regexp, $m);
+ for ($i = 0, $total = count($m[0]); $i < $total; $i++)
+ if ($m[3][$i])
+ {
+ $regexp = str_replace($m[0][$i], '(?P<'.$m[3][$i].'>'.$this->keywords[$m[1][$i]].')', $regexp);
+ $required[$m[3][$i]] = $m[1][$i];
+ }
+ else
+ $regexp = str_replace($m[0][$i], '('.$this->keywords[$m[1][$i]].')', $regexp);
+ $regexp = '#^/'.$regexp.'#';
+ $this->routes[$routeID] = array(
+ 'rule' => $rule,
+ 'regexp' => $regexp,
+ 'controller' => $controller,
+ 'required' => $required,
+ );
+ }
+
+ /**
+ *
+ *
+ * @param string $routeID Name the route
+ * @param array $params
+ */
+ public function createUrl($routeID, $params = array())
+ {
+ if (!is_array($params))
+ die('Dispatcher::createURL() $params must be an array');
+
+ if (!isset($this->routes[$routeID]))
+ return '';
+ $route = $this->routes[$routeID];
+
+ // Get required parameters
+ $queryParams = array();
+ foreach (array_keys($route['required']) as $key)
+ {
+ if (!array_key_exists($key, $params))
+ die("Dispatcher::createURL() miss required parameter '$key'");
+ $queryParams[$key] = $params[$key];
+ }
+
+ // Build an URL which match a route
+ if ($this->useRoutes)
+ {
+ $url = $route['rule'];
+
+ // Replace required parameters
+ foreach ($route['required'] as $key => $keyword)
+ {
+ $url = str_replace('{'.$keyword.':'.$key.'}', $params[$key], $url);
+ unset($params[$key]);
+ }
+
+ // Replace other parameters
+ foreach ($params as $key => $value)
+ $url = str_replace('{'.$key.'}', $value, $url);
+ }
+ // Build a classic URL index.php?controller=foo&...
+ else
+ $url = 'index.php?controller='.$route['controller'].(($queryParams) ? '&'.http_build_query($queryParams) : '');
+
+ return $url;
+ }
+
+ /**
+ * Load list of available controllers
+ */
public static function loadControllers()
{
$controller_files = scandir(_PS_ROOT_DIR_.DIRECTORY_SEPARATOR.'controllers');
@@ -35,17 +195,52 @@ class DispatcherCore
self::$controllers['productscomparison'] = self::$controllers['compare'];
}
+ /**
+ * Retrieve the controller from URL or request URI if routes are activated
+ *
+ * @return string
+ */
public function getController()
{
- $controller = Tools::getValue('controller');
- if (isset($controller) && preg_match('/^([0-9a-z_-]+)\?(.*)=(.*)$/Ui', $controller, $controller_string))
+ // Use routes ? (for URL rewriting)
+ if ($this->useRoutes)
{
- $controller = $controller_string[1];
- if (isset($_GET['controller']))
- $_GET[$controller_string[2]] = $controller_string[3];
- elseif (isset($_POST['controller']))
- $_POST[$controller_string[2]] = $controller_string[3];
+ // Get request URI (HTTP_X_REWRITE_URL is used by IIS)
+ if (isset($_SERVER['REQUEST_URI']))
+ $request = $_SERVER['REQUEST_URI'];
+ else if (isset($_SERVER['HTTP_X_REWRITE_URL']))
+ $request = $_SERVER['HTTP_X_REWRITE_URL'];
+ else
+ return 'index';
+
+ $controller = 'index';
+ foreach ($this->routes as $route)
+ if (preg_match($route['regexp'], $request, $m))
+ {
+ // Route found ! Now fill $_GET with parameters of URI
+ $controller = $route['controller'];
+ foreach ($m as $k => $v)
+ if (!is_numeric($k))
+ $_GET[$k] = $v;
+ break;
+ }
+
+ $_GET['controller'] = $controller;
+ return $controller;
+ }
+ // Default mode, take controller from URL
+ else
+ {
+ $controller = Tools::getValue('controller');
+ if (isset($controller) && preg_match('/^([0-9a-z_-]+)\?(.*)=(.*)$/Ui', $controller, $m))
+ {
+ $controller = $m[1];
+ if (isset($_GET['controller']))
+ $_GET[$m[2]] = $m[3];
+ else if (isset($_POST['controller']))
+ $_POST[$m[2]] = $m[3];
+ }
+ return (!empty($controller)) ? $controller : 'index';
}
- return (!empty($controller)) ? $controller : 'index';
}
}
diff --git a/classes/Tools.php b/classes/Tools.php
index 166cf3292..9b582b922 100644
--- a/classes/Tools.php
+++ b/classes/Tools.php
@@ -551,9 +551,9 @@ class ToolsCore
*/
public static function dieObject($object, $kill = true)
{
- echo '
';
+ echo '';
print_r($object);
- echo '
';
+ echo '
';
if ($kill)
die('END');
return $object;
@@ -1634,23 +1634,23 @@ class ToolsCore
$tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?/[_a-zA-Z0-9-]*\.jpg$'] = _PS_PROD_IMG_.'$1/$2/$3/$4/$5/$6/$7/$8/$1$2$3$4$5$6$7$8$9.jpg [L]';
$tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'c/([0-9]+)(\-[_a-zA-Z0-9-]*)/[_a-zA-Z0-9-]*\.jpg$'] = 'img/c/$1$2.jpg [L]';
- $tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([0-9]+)\-[a-zA-Z0-9-]*\.html'] = 'index.php?controller=product&id_product=$1 [QSA,L]';
- $tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([0-9]+)\-[a-zA-Z0-9-]*'] = 'index.php?controller=category&id_category=$1 [QSA,L]';
- $tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'[a-zA-Z0-9-]*/([0-9]+)\-[a-zA-Z0-9-]*\.html'] = 'index.php?controller=product&id_product=$1 [QSA,L]';
- $tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([0-9]+)__([a-zA-Z0-9-]*)'] = 'index.php?controller=supplier&id_supplier=$1 [QSA,L]';
- $tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([0-9]+)_([a-zA-Z0-9-]*)'] = 'index.php?controller=manufacturer&id_manufacturer=$1 [QSA,L]';
- $tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'content/([0-9]+)\-([a-zA-Z0-9-]*)'] = 'index.php?controller=cms&id_cms=$1 [QSA,L]';
- $tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'content/category/([0-9]+)\-([a-zA-Z0-9-]*)'] = 'index.php?controller=cms&id_cms_category=$1 [QSA,L]';
+ //$tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([0-9]+)\-[a-zA-Z0-9-]*\.html'] = 'index.php?controller=product&id_product=$1 [QSA,L]';
+ //$tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([0-9]+)\-[a-zA-Z0-9-]*'] = 'index.php?controller=category&id_category=$1 [QSA,L]';
+ //$tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'[a-zA-Z0-9-]*/([0-9]+)\-[a-zA-Z0-9-]*\.html'] = 'index.php?controller=product&id_product=$1 [QSA,L]';
+ //$tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([0-9]+)__([a-zA-Z0-9-]*)'] = 'index.php?controller=supplier&id_supplier=$1 [QSA,L]';
+ //$tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([0-9]+)_([a-zA-Z0-9-]*)'] = 'index.php?controller=manufacturer&id_manufacturer=$1 [QSA,L]';
+ //$tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'content/([0-9]+)\-([a-zA-Z0-9-]*)'] = 'index.php?controller=cms&id_cms=$1 [QSA,L]';
+ //$tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'content/category/([0-9]+)\-([a-zA-Z0-9-]*)'] = 'index.php?controller=cms&id_cms_category=$1 [QSA,L]';
if ($multilang)
{
- $tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([a-z]{2})/[a-zA-Z0-9-]*/([0-9]+)\-[a-zA-Z0-9-]*\.html'] = 'index.php?controller=product&id_product=$2&isolang=$1&id_shop='.$uri['id_shop'].' [QSA,L]';
- $tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([a-z]{2})/([0-9]+)\-[a-zA-Z0-9-]*\.html'] = 'index.php?controller=product&id_product=$2&isolang=$1&id_shop='.$uri['id_shop'].' [QSA,L]';
- $tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([a-z]{2})/([0-9]+)\-[a-zA-Z0-9-]*'] = 'index.php?controller=category&id_category=$2&isolang=$1&id_shop='.$uri['id_shop'].' [QSA,L]';
- $tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([a-z]{2})/content/([0-9]+)\-[a-zA-Z0-9-]*'] = 'index.php?controller=cms&isolang=$1&id_cms=$2&id_shop='.$uri['id_shop'].' [QSA,L]';
- $tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([a-z]{2})/content/category/([0-9]+)\-[a-zA-Z0-9-]*'] = 'index.php?controller=cms&isolang=$1&id_cms_category=$2&id_shop='.$uri['id_shop'].' [QSA,L]';
- $tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([a-z]{2})/([0-9]+)__[a-zA-Z0-9-]*'] = 'index.php?controller=supplier&isolang=$1&id_supplier=$2&id_shop='.$uri['id_shop'].' [QSA,L]';
- $tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([a-z]{2})/([0-9]+)_[a-zA-Z0-9-]*'] = 'index.php?controller=manufacturer&isolang=$1&id_manufacturer=$2&id_shop='.$uri['id_shop'].' [QSA,L]';
+ //$tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([a-z]{2})/[a-zA-Z0-9-]*/([0-9]+)\-[a-zA-Z0-9-]*\.html'] = 'index.php?controller=product&id_product=$2&isolang=$1&id_shop='.$uri['id_shop'].' [QSA,L]';
+ //$tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([a-z]{2})/([0-9]+)\-[a-zA-Z0-9-]*\.html'] = 'index.php?controller=product&id_product=$2&isolang=$1&id_shop='.$uri['id_shop'].' [QSA,L]';
+ //$tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([a-z]{2})/([0-9]+)\-[a-zA-Z0-9-]*'] = 'index.php?controller=category&id_category=$2&isolang=$1&id_shop='.$uri['id_shop'].' [QSA,L]';
+ //$tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([a-z]{2})/content/([0-9]+)\-[a-zA-Z0-9-]*'] = 'index.php?controller=cms&isolang=$1&id_cms=$2&id_shop='.$uri['id_shop'].' [QSA,L]';
+ //$tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([a-z]{2})/content/category/([0-9]+)\-[a-zA-Z0-9-]*'] = 'index.php?controller=cms&isolang=$1&id_cms_category=$2&id_shop='.$uri['id_shop'].' [QSA,L]';
+ //$tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([a-z]{2})/([0-9]+)__[a-zA-Z0-9-]*'] = 'index.php?controller=supplier&isolang=$1&id_supplier=$2&id_shop='.$uri['id_shop'].' [QSA,L]';
+ //$tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([a-z]{2})/([0-9]+)_[a-zA-Z0-9-]*'] = 'index.php?controller=manufacturer&isolang=$1&id_manufacturer=$2&id_shop='.$uri['id_shop'].' [QSA,L]';
}
// PS BASE URI automaticaly prepend the string, do not use PS defines for the image directories
@@ -1658,13 +1658,13 @@ class ToolsCore
$tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([0-9]+)\-([0-9]+)/[_a-zA-Z0-9-]*\.jpg$'] = _PS_PROD_IMG_.'$1-$2.jpg [L]';
$tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([0-9]+)(\-[_a-zA-Z0-9-]*)/[_a-zA-Z0-9-]*\.jpg$'] = 'img/c/$1$2.jpg [L]';
- $tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([0-9]+)\-[a-zA-Z0-9-]*\.html'] = 'index.php?controller=product&id_product=$1&id_shop='.$uri['id_shop'].' [QSA,L]';
- $tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'[a-zA-Z0-9-]*/([0-9]+)\-[a-zA-Z0-9-]*\.html'] = 'index.php?controller=product&id_product=$1&id_shop='.$uri['id_shop'].' [QSA,L]';
- $tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([0-9]+)\-[a-zA-Z0-9-]*'] = 'index.php?controller=category&id_category=$1&id_shop='.$uri['id_shop'].' [QSA,L]';
- $tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([0-9]+)__([a-zA-Z0-9-]*)'] = 'index.php?controller=supplier&id_supplier=$1&id_shop='.$uri['id_shop'].' [QSA,L]';
- $tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([0-9]+)_([a-zA-Z0-9-]*)'] = 'index.php?controller=manufacturer&id_manufacturer=$1&id_shop='.$uri['id_shop'].' [QSA,L]';
- $tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'content/([0-9]+)\-([a-zA-Z0-9-]*)'] = 'index.php?controller=cms&id_cms=$1&id_shop='.$uri['id_shop'].' [QSA,L]';
- $tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'content/category/([0-9]+)\-([a-zA-Z0-9-]*)'] = 'index.php?controller=cms&id_cms_category=$1&id_shop='.$uri['id_shop'].' [QSA,L]';
+ //$tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([0-9]+)\-[a-zA-Z0-9-]*\.html'] = 'index.php?controller=product&id_product=$1&id_shop='.$uri['id_shop'].' [QSA,L]';
+ //$tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'[a-zA-Z0-9-]*/([0-9]+)\-[a-zA-Z0-9-]*\.html'] = 'index.php?controller=product&id_product=$1&id_shop='.$uri['id_shop'].' [QSA,L]';
+ //$tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([0-9]+)\-[a-zA-Z0-9-]*'] = 'index.php?controller=category&id_category=$1&id_shop='.$uri['id_shop'].' [QSA,L]';
+ //$tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([0-9]+)__([a-zA-Z0-9-]*)'] = 'index.php?controller=supplier&id_supplier=$1&id_shop='.$uri['id_shop'].' [QSA,L]';
+ //$tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'([0-9]+)_([a-zA-Z0-9-]*)'] = 'index.php?controller=manufacturer&id_manufacturer=$1&id_shop='.$uri['id_shop'].' [QSA,L]';
+ //$tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'content/([0-9]+)\-([a-zA-Z0-9-]*)'] = 'index.php?controller=cms&id_cms=$1&id_shop='.$uri['id_shop'].' [QSA,L]';
+ //$tab['RewriteRule'][$domain]['content']['^'.ltrim($uri['uri'], '/').'content/category/([0-9]+)\-([a-zA-Z0-9-]*)'] = 'index.php?controller=cms&id_cms_category=$1&id_shop='.$uri['id_shop'].' [QSA,L]';
Language::loadLanguages();
$default_meta = Meta::getMetasByIdLang((int)Configuration::get('PS_LANG_DEFAULT'), new Shop($uri['id_shop']));
diff --git a/index.php b/index.php
index 4057bdc9e..bb4a9a351 100644
--- a/index.php
+++ b/index.php
@@ -26,5 +26,4 @@
*/
require(dirname(__FILE__).'/config/config.inc.php');
-$dispatcher = new Dispatcher();
-$dispatcher->dispatch();
+Dispatcher::getInstance()->dispatch();