Jelajahi Sumber

Ending routing

isundil 10 tahun lalu
induk
melakukan
4205dbe783

+ 8 - 1
core/autoload.php

@@ -7,6 +7,8 @@
 **/
 function __autoload($className)
 {
+	if (strpos($className, '\\') === false)
+		return FALSE;
     list($namespace, $class) = explode('\\', $className, 2);
     $path = null;
     switch ($namespace)
@@ -15,8 +17,13 @@ function __autoload($className)
         $path = "core/models/{$class}.php"; break;
     case "Tools":
         $path = "core/tools/{$class}.php"; break;
+	case "Controller":
+		$path = "core/controllers/{$class}.php"; break;
+	case "Exception":
+		$path = "core/exceptions/{$class}.php"; break;
     }
-    include_once ($path);
+	if (file_exists($path))
+		include_once ($path);
     return $path;
 }
 

+ 12 - 0
core/controllers/CategoryController.php

@@ -0,0 +1,12 @@
+<?php
+
+namespace Controller;
+
+class CategoryController extends \Tools\AController
+{
+	public function __construct($context, $params)
+	{
+		parent::__construct($context, $params);
+	}
+}
+

+ 13 - 0
core/controllers/ProductController.php

@@ -0,0 +1,13 @@
+<?php
+
+namespace Controller;
+
+class ProductController extends \Tools\AController
+{
+	public function __construct($context, $params)
+	{
+		parent::__construct($context, $params);
+		throw new \Exception\Error404();
+	}
+}
+

+ 0 - 0
core/controller/index.php → core/controllers/index.php


+ 12 - 0
core/exceptions/Error404.php

@@ -0,0 +1,12 @@
+<?php
+
+namespace Exception;
+
+/**
+ * Error404
+ * throw it before AController::start to get a 404 error
+**/
+class Error404 extends \Exception
+{
+}
+

+ 0 - 0
core/exceptions/index.php


+ 0 - 1
core/index.php

@@ -1 +0,0 @@
- 

+ 3 - 4
core/models/Cms.php

@@ -9,11 +9,10 @@ class Cms extends ModelBase
         $dbPrefix = $this->getDbPrefix();
         $result = self::$dbo->exec("CREATE TABLE IF NOT EXISTS `{$dbPrefix}cms` (
             `id` INTEGER(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
-            `lang` VARCHAR(8) NULL,
             `shurl` VARCHAR(255) NOT NULL,
-            `title` TEXT NOT NULL ,
-            `content` LONGTEXT NOT NULL,
-            UNIQUE(`lang`, `shurl`)
+			`controller` VARCHAR(255) NOT NULL,
+			`order` INTEGER UNSIGNED NOT NULL DEFAULT 0,
+            UNIQUE(`shurl`)
         )");
         if ($result === false)
             throw new \Exception(get_class().": ".self::$dbo->errorInfo()[2]);

+ 1 - 1
core/models/Product.php

@@ -13,7 +13,7 @@ class Product extends ModelBase
             `shurl` VARCHAR(255) NOT NULL,
             `priceExcl` FLOAT NULL,
             `priceIncl` FLOAT NULL,
-            `ean` VARCHAR(13) NULL,
+            `ean` VARCHAR(64) NULL,
             FOREIGN KEY (`parent`) REFERENCES `{$dbPrefix}product`(id)
         )");
         if ($result === false)

+ 0 - 1
core/setup/index.php

@@ -1 +0,0 @@
- 

+ 40 - 0
core/tools/AController.php

@@ -0,0 +1,40 @@
+<?php
+
+namespace Tools;
+
+// TODO RestController
+// TODO cliController
+
+/**
+ * Controller abstract class
+**/
+abstract class AController
+{
+	/**
+	 * @var array $params
+	 * Contains route parameter
+	 * ex: /product/:id will contains {
+	 *    0 => product
+	 *    1 => [ID]
+	 *    ':id' => [ID]
+	**/
+	protected $params;
+
+	/**
+	 * @param \Tools\Context $context
+	 * @param array $params
+	 * @throws \Exception\Error404 if parameters does not correspond
+	 * On 404 error, router will try to find another route
+	 * Initialize structure
+	**/
+	public function __construct($context, $params)
+	{
+		$this->params = $params;
+	}
+
+	/**
+	 * Fullfill Controller's request
+	**/
+	public abstract function start();
+}
+

+ 12 - 9
core/tools/AModule.php

@@ -71,6 +71,18 @@ abstract class AModule
             $this->entity = $entity;
     }
 
+	/**
+	 * Register hook to be triggered
+	 * Can only be triggered while module setup
+	**/
+    public static function registerHook($hookName)
+    {
+        $this->context->hooks->register($this, $hookname);
+    }
+
+	/**
+	 * Getter
+	**/
     public function __get($key)
     {
         switch ($key)
@@ -80,14 +92,5 @@ abstract class AModule
         }
         throw new \Exception("Cannot access attribute {$key}");
     }
-
-	/**
-	 * Register hook to be triggered
-	 * Can only be triggered while module setup
-	**/
-    public static function registerHook($hookName)
-    {
-        $this->context->hooks->register($this, $hookname);
-    }
 }
 

+ 18 - 1
core/tools/Context.php

@@ -51,6 +51,13 @@ class Context
     **/
     private $user;
 
+	/**
+	 * @var \Tools\AController $controller
+	 * /core/tools/AController.php
+	 * Controller being called by user's request
+	**/
+	private $controller;
+
     /**
      * Create context from $_SERVER environment
      * and initialize all data
@@ -67,7 +74,17 @@ class Context
         $this->router->init();
         $this->moduleManager = new ModuleManager($this);
         $this->hookManager->trigger("routerSetup");
-        $this->router->serveUrl();
+		try
+		{
+			$this->controller = $this->router->serveUrl();
+			if (!$this->controller)
+				throw new \Exception\Error404();
+			$this->controller->start();
+		}
+		catch (\Exception\Error404 $e)
+		{
+			echo "404";
+		}
     }
 
     /**

+ 27 - 0
core/tools/HookEvent.php

@@ -2,12 +2,36 @@
 
 namespace Tools;
 
+/**
+ * Event's parameters
+ * This classe is attached to a hook when fired
+**/
 class HookEvent
 {
+    /**
+     * @var \Tools\Context $context
+     * /core/tools/Context.php
+     * Contains website's informations
+    **/
     private $context;
+
+	/**
+	 * @var string $hookName
+	 * Contains hook name
+	 * Can be accessed read-only
+	**/
     private $hookName;
+
+	/**
+	 * @var mixed params
+	 * Contains parameters that can be passed to the hook when fired
+	 * Can be accessed read-only
+	**/
     private $params;
 
+	/**
+	 * Constructor
+	**/
     public function __construct($hookName, $context, $params)
     {
         $this->context = $context;
@@ -15,6 +39,9 @@ class HookEvent
         $this->params = $params;
     }
 
+	/**
+	 * Getter
+	**/
     public function __get($key)
     {
         switch ($key)

+ 3 - 0
core/tools/Hooks.php

@@ -102,6 +102,9 @@ class Hooks
             $this->hooks[$i->hookName][] = (int) $i->module_id;
     }
 
+	/**
+	 * Getter
+	**/
     public function __get($key)
     {
         switch ($key)

+ 3 - 0
core/tools/ModuleManager.php

@@ -113,6 +113,9 @@ class ModuleManager
         return FALSE;
     }
 
+	/**
+	 * Getter
+	**/
     public function __get($key)
     {
         switch ($key)

+ 77 - 3
core/tools/Router.php

@@ -40,6 +40,16 @@ class Router
     **/
     private $context;
 
+	/**
+	 * @var array RouteParams
+	 * Contains route parameter
+	 * ex: /product/:id will contains {
+	 *    0 => product
+	 *    1 => [ID]
+	 *    ':id' => [ID]
+	**/
+	private $routeParams;
+
     /**
      * @var string $modulePath
      * Contains the module directory
@@ -97,23 +107,84 @@ class Router
     **/
     public function serveUrl()
     {
+		//TODO trigger hook GET, POST
         $this->prepareUrl();
         $requestParams = explode("/", $this->requestUrl);
         foreach ($this->routes as $i)
         {
             $routeParams = explode("/", $i[0]);
+			$p = $this->routeMatch($requestParams, $routeParams);
+			if (!$p)
+				continue;
+			$controller = $this->createController($i[1], $p);
+			if ($controller)
+				return $controller;
         }
-        //TODO@2
+        return false;
     }
 
+	/**
+	 * Create and return Controller for the given route
+	 * @param $className
+	 * @param array $routeParameters
+	 * @return \Tools\AController on succes, false otherwise
+	**/
+	private function createController($className, $params)
+	{
+		if (!class_exists($className))
+			return false;
+		try
+		{
+			$this->routeParams = $params;
+			$result = new $className($this->context, $params);
+		}
+		catch (\Exception\Error404 $e)
+		{
+			return false;
+		}
+		if (!($result instanceof \Tools\AController))
+			return false;
+		return $result;
+	}
+
+	/**
+	 * Check if the request match route
+	 * @param array $request User request
+	 * @param array $route Route to check
+	 * @return array on success, false on failure
+	**/
+	private function routeMatch($request, $route)
+	{
+		$i = count($request);
+		$params = array();
+		if ($i != count($route))
+			return false;
+		while ($i)
+		{
+			$i--;
+			if ($route[$i] == '' && $request[$i] == '')
+				continue;
+			if ($route[$i] == '' || $request[$i] == '')
+				return false;
+			if ($route[$i][0] != ':' && ($route[$i] != $request[$i]))
+				return false;
+			if ($route[$i][0] == ':')
+				$params[$route[$i]] = $request[$i];
+			$params[$i -1] = $request[$i];
+		}
+		return array_reverse($params);
+	}
+
     /**
      * Append local routes to router
      * Will load CMS pages, categories page, products page, cart pages, etc.
     **/
     private function prepareUrl()
     {
-        $this->doRouteAdd("/:item", "\Controller\Product");
-        $this->doRouteAdd("/:category/:item", "\Controller\Product");
+		$fetcher = new \Entity\Cms();
+		$pages = $fetcher->selects(null, array("order"));
+		foreach ($pages as $i)
+			$this->doRouteAdd($i->shurl, $i->controller);
     }
 
 	/**
@@ -142,6 +213,9 @@ class Router
         $this->doRouteAdd($route, $controller);
     }
 
+	/**
+	 * Getter
+	**/
     public function __get($key)
     {
         switch ($key)