diff options
author | Jesús <heckyel@hyperbola.info> | 2019-08-18 21:14:58 -0500 |
---|---|---|
committer | Jesús <heckyel@hyperbola.info> | 2019-08-18 21:14:58 -0500 |
commit | 2eed7b082f83630301e51f57ca8394de228a8605 (patch) | |
tree | 1d19962d22d30f99317d9276e4bae7744fc93fc2 /public/system/engine | |
download | librecart-2eed7b082f83630301e51f57ca8394de228a8605.tar.lz librecart-2eed7b082f83630301e51f57ca8394de228a8605.tar.xz librecart-2eed7b082f83630301e51f57ca8394de228a8605.zip |
first commit
Diffstat (limited to 'public/system/engine')
-rw-r--r-- | public/system/engine/action.php | 84 | ||||
-rw-r--r-- | public/system/engine/controller.php | 27 | ||||
-rw-r--r-- | public/system/engine/event.php | 97 | ||||
-rw-r--r-- | public/system/engine/loader.php | 264 | ||||
-rw-r--r-- | public/system/engine/model.php | 27 | ||||
-rw-r--r-- | public/system/engine/proxy.php | 54 | ||||
-rw-r--r-- | public/system/engine/registry.php | 47 | ||||
-rw-r--r-- | public/system/engine/router.php | 81 |
8 files changed, 681 insertions, 0 deletions
diff --git a/public/system/engine/action.php b/public/system/engine/action.php new file mode 100644 index 0000000..bbb51e5 --- /dev/null +++ b/public/system/engine/action.php @@ -0,0 +1,84 @@ +<?php +/** + * @package OpenCart + * @author Daniel Kerr + * @copyright Copyright (c) 2005 - 2017, OpenCart, Ltd. (https://www.opencart.com/) + * @license https://opensource.org/licenses/GPL-3.0 + * @link https://www.opencart.com +*/ + +/** +* Action class +*/ +class Action { + private $id; + private $route; + private $method = 'index'; + + /** + * Constructor + * + * @param string $route + */ + public function __construct($route) { + $this->id = $route; + + $parts = explode('/', preg_replace('/[^a-zA-Z0-9_\/]/', '', (string)$route)); + + // Break apart the route + while ($parts) { + $file = DIR_APPLICATION . 'controller/' . implode('/', $parts) . '.php'; + + if (is_file($file)) { + $this->route = implode('/', $parts); + + break; + } else { + $this->method = array_pop($parts); + } + } + } + + /** + * + * + * @return string + * + */ + public function getId() { + return $this->id; + } + + /** + * + * + * @param object $registry + * @param array $args + */ + public function execute($registry, array $args = array()) { + // Stop any magical methods being called + if (substr($this->method, 0, 2) == '__') { + return new \Exception('Error: Calls to magic methods are not allowed!'); + } + + $file = DIR_APPLICATION . 'controller/' . $this->route . '.php'; + $class = 'Controller' . preg_replace('/[^a-zA-Z0-9]/', '', $this->route); + + // Initialize the class + if (is_file($file)) { + include_once($file); + + $controller = new $class($registry); + } else { + return new \Exception('Error: Could not call ' . $this->route . '/' . $this->method . '!'); + } + + $reflection = new ReflectionClass($class); + + if ($reflection->hasMethod($this->method) && $reflection->getMethod($this->method)->getNumberOfRequiredParameters() <= count($args)) { + return call_user_func_array(array($controller, $this->method), $args); + } else { + return new \Exception('Error: Could not call ' . $this->route . '/' . $this->method . '!'); + } + } +} diff --git a/public/system/engine/controller.php b/public/system/engine/controller.php new file mode 100644 index 0000000..c67890d --- /dev/null +++ b/public/system/engine/controller.php @@ -0,0 +1,27 @@ +<?php +/** + * @package OpenCart + * @author Daniel Kerr + * @copyright Copyright (c) 2005 - 2017, OpenCart, Ltd. (https://www.opencart.com/) + * @license https://opensource.org/licenses/GPL-3.0 + * @link https://www.opencart.com +*/ + +/** +* Controller class +*/ +abstract class Controller { + protected $registry; + + public function __construct($registry) { + $this->registry = $registry; + } + + public function __get($key) { + return $this->registry->get($key); + } + + public function __set($key, $value) { + $this->registry->set($key, $value); + } +}
\ No newline at end of file diff --git a/public/system/engine/event.php b/public/system/engine/event.php new file mode 100644 index 0000000..d4f92ec --- /dev/null +++ b/public/system/engine/event.php @@ -0,0 +1,97 @@ +<?php +/** + * @package OpenCart + * @author Daniel Kerr + * @copyright Copyright (c) 2005 - 2017, OpenCart, Ltd. (https://www.opencart.com/) + * @license https://opensource.org/licenses/GPL-3.0 + * @link https://www.opencart.com +*/ + +/** +* Event class +* +* Event System Userguide +* +* https://github.com/opencart/opencart/wiki/Events-(script-notifications)-2.2.x.x +*/ +class Event { + protected $registry; + protected $data = array(); + + /** + * Constructor + * + * @param object $route + */ + public function __construct($registry) { + $this->registry = $registry; + } + + /** + * + * + * @param string $trigger + * @param object $action + * @param int $priority + */ + public function register($trigger, Action $action, $priority = 0) { + $this->data[] = array( + 'trigger' => $trigger, + 'action' => $action, + 'priority' => $priority + ); + + $sort_order = array(); + + foreach ($this->data as $key => $value) { + $sort_order[$key] = $value['priority']; + } + + array_multisort($sort_order, SORT_ASC, $this->data); + } + + /** + * + * + * @param string $event + * @param array $args + */ + public function trigger($event, array $args = array()) { + foreach ($this->data as $value) { + if (preg_match('/^' . str_replace(array('\*', '\?'), array('.*', '.'), preg_quote($value['trigger'], '/')) . '/', $event)) { + $result = $value['action']->execute($this->registry, $args); + + if (!is_null($result) && !($result instanceof Exception)) { + return $result; + } + } + } + } + + /** + * + * + * @param string $trigger + * @param string $route + */ + public function unregister($trigger, $route) { + foreach ($this->data as $key => $value) { + if ($trigger == $value['trigger'] && $value['action']->getId() == $route) { + unset($this->data[$key]); + } + } + } + + /** + * + * + * @param string $trigger + */ + public function clear($trigger) { + foreach ($this->data as $key => $value) { + if ($trigger == $value['trigger']) { + unset($this->data[$key]); + } + } + } +}
\ No newline at end of file diff --git a/public/system/engine/loader.php b/public/system/engine/loader.php new file mode 100644 index 0000000..6c8f93f --- /dev/null +++ b/public/system/engine/loader.php @@ -0,0 +1,264 @@ +<?php +/** + * @package OpenCart + * @author Daniel Kerr + * @copyright Copyright (c) 2005 - 2017, OpenCart, Ltd. (https://www.opencart.com/) + * @license https://opensource.org/licenses/GPL-3.0 + * @link https://www.opencart.com +*/ + +/** +* Loader class +*/ +final class Loader { + protected $registry; + + /** + * Constructor + * + * @param object $registry + */ + public function __construct($registry) { + $this->registry = $registry; + } + + /** + * + * + * @param string $route + * @param array $data + * + * @return mixed + */ + public function controller($route, $data = array()) { + // Sanitize the call + $route = preg_replace('/[^a-zA-Z0-9_\/]/', '', (string)$route); + + // Keep the original trigger + $trigger = $route; + + // Trigger the pre events + $result = $this->registry->get('event')->trigger('controller/' . $trigger . '/before', array(&$route, &$data)); + + // Make sure its only the last event that returns an output if required. + if ($result != null && !$result instanceof Exception) { + $output = $result; + } else { + $action = new Action($route); + $output = $action->execute($this->registry, array(&$data)); + } + + // Trigger the post events + $result = $this->registry->get('event')->trigger('controller/' . $trigger . '/after', array(&$route, &$data, &$output)); + + if ($result && !$result instanceof Exception) { + $output = $result; + } + + if (!$output instanceof Exception) { + return $output; + } + } + + /** + * + * + * @param string $route + */ + public function model($route) { + // Sanitize the call + $route = preg_replace('/[^a-zA-Z0-9_\/]/', '', (string)$route); + + if (!$this->registry->has('model_' . str_replace('/', '_', $route))) { + $file = DIR_APPLICATION . 'model/' . $route . '.php'; + $class = 'Model' . preg_replace('/[^a-zA-Z0-9]/', '', $route); + + if (is_file($file)) { + include_once($file); + + $proxy = new Proxy(); + + // Overriding models is a little harder so we have to use PHP's magic methods + // In future version we can use runkit + foreach (get_class_methods($class) as $method) { + $proxy->{$method} = $this->callback($this->registry, $route . '/' . $method); + } + + $this->registry->set('model_' . str_replace('/', '_', (string)$route), $proxy); + } else { + throw new \Exception('Error: Could not load model ' . $route . '!'); + } + } + } + + /** + * + * + * @param string $route + * @param array $data + * + * @return string + */ + public function view($route, $data = array()) { + // Sanitize the call + $route = preg_replace('/[^a-zA-Z0-9_\/]/', '', (string)$route); + + // Keep the original trigger + $trigger = $route; + + // Template contents. Not the output! + $template = ''; + + // Trigger the pre events + $result = $this->registry->get('event')->trigger('view/' . $trigger . '/before', array(&$route, &$data, &$template)); + + // Make sure its only the last event that returns an output if required. + if ($result && !$result instanceof Exception) { + $output = $result; + } else { + $template = new Template($this->registry->get('config')->get('template_engine')); + + foreach ($data as $key => $value) { + $template->set($key, $value); + } + + $output = $template->render($this->registry->get('config')->get('template_directory') . $route, $this->registry->get('config')->get('template_cache')); + } + + // Trigger the post events + $result = $this->registry->get('event')->trigger('view/' . $trigger . '/after', array(&$route, &$data, &$output)); + + if ($result && !$result instanceof Exception) { + $output = $result; + } + + return $output; + } + + /** + * + * + * @param string $route + */ + public function library($route) { + // Sanitize the call + $route = preg_replace('/[^a-zA-Z0-9_\/]/', '', (string)$route); + + $file = DIR_SYSTEM . 'library/' . $route . '.php'; + $class = str_replace('/', '\\', $route); + + if (is_file($file)) { + include_once($file); + + $this->registry->set(basename($route), new $class($this->registry)); + } else { + throw new \Exception('Error: Could not load library ' . $route . '!'); + } + } + + /** + * + * + * @param string $route + */ + public function helper($route) { + $file = DIR_SYSTEM . 'helper/' . preg_replace('/[^a-zA-Z0-9_\/]/', '', (string)$route) . '.php'; + + if (is_file($file)) { + include_once($file); + } else { + throw new \Exception('Error: Could not load helper ' . $route . '!'); + } + } + + /** + * + * + * @param string $route + */ + public function config($route) { + $this->registry->get('event')->trigger('config/' . $route . '/before', array(&$route)); + + $this->registry->get('config')->load($route); + + $this->registry->get('event')->trigger('config/' . $route . '/after', array(&$route)); + } + + /** + * + * + * @param string $route + * @param string $key + * + * @return array + */ + public function language($route, $key = '') { + // Sanitize the call + $route = preg_replace('/[^a-zA-Z0-9_\/]/', '', (string)$route); + + // Keep the original trigger + $trigger = $route; + + $result = $this->registry->get('event')->trigger('language/' . $trigger . '/before', array(&$route, &$key)); + + if ($result && !$result instanceof Exception) { + $output = $result; + } else { + $output = $this->registry->get('language')->load($route, $key); + } + + $result = $this->registry->get('event')->trigger('language/' . $trigger . '/after', array(&$route, &$key, &$output)); + + if ($result && !$result instanceof Exception) { + $output = $result; + } + + return $output; + } + + protected function callback($registry, $route) { + return function($args) use($registry, $route) { + static $model; + + $route = preg_replace('/[^a-zA-Z0-9_\/]/', '', (string)$route); + + // Keep the original trigger + $trigger = $route; + + // Trigger the pre events + $result = $registry->get('event')->trigger('model/' . $trigger . '/before', array(&$route, &$args)); + + if ($result && !$result instanceof Exception) { + $output = $result; + } else { + $class = 'Model' . preg_replace('/[^a-zA-Z0-9]/', '', substr($route, 0, strrpos($route, '/'))); + + // Store the model object + $key = substr($route, 0, strrpos($route, '/')); + + if (!isset($model[$key])) { + $model[$key] = new $class($registry); + } + + $method = substr($route, strrpos($route, '/') + 1); + + $callable = array($model[$key], $method); + + if (is_callable($callable)) { + $output = call_user_func_array($callable, $args); + } else { + throw new \Exception('Error: Could not call model/' . $route . '!'); + } + } + + // Trigger the post events + $result = $registry->get('event')->trigger('model/' . $trigger . '/after', array(&$route, &$args, &$output)); + + if ($result && !$result instanceof Exception) { + $output = $result; + } + + return $output; + }; + } +}
\ No newline at end of file diff --git a/public/system/engine/model.php b/public/system/engine/model.php new file mode 100644 index 0000000..ae9a97a --- /dev/null +++ b/public/system/engine/model.php @@ -0,0 +1,27 @@ +<?php +/** + * @package OpenCart + * @author Daniel Kerr + * @copyright Copyright (c) 2005 - 2017, OpenCart, Ltd. (https://www.opencart.com/) + * @license https://opensource.org/licenses/GPL-3.0 + * @link https://www.opencart.com +*/ + +/** +* Model class +*/ +abstract class Model { + protected $registry; + + public function __construct($registry) { + $this->registry = $registry; + } + + public function __get($key) { + return $this->registry->get($key); + } + + public function __set($key, $value) { + $this->registry->set($key, $value); + } +}
\ No newline at end of file diff --git a/public/system/engine/proxy.php b/public/system/engine/proxy.php new file mode 100644 index 0000000..b0a21d0 --- /dev/null +++ b/public/system/engine/proxy.php @@ -0,0 +1,54 @@ +<?php +/** + * @package OpenCart + * @author Daniel Kerr + * @copyright Copyright (c) 2005 - 2017, OpenCart, Ltd. (https://www.opencart.com/) + * @license https://opensource.org/licenses/GPL-3.0 + * @link https://www.opencart.com +*/ + +/** +* Proxy class +*/ +class Proxy { + /** + * + * + * @param string $key + */ + public function __get($key) { + return $this->{$key}; + } + + /** + * + * + * @param string $key + * @param string $value + */ + public function __set($key, $value) { + $this->{$key} = $value; + } + + public function __call($key, $args) { + $arg_data = array(); + + $args = func_get_args(); + + foreach ($args as $arg) { + if ($arg instanceof Ref) { + $arg_data[] =& $arg->getRef(); + } else { + $arg_data[] =& $arg; + } + } + + if (isset($this->{$key})) { + return call_user_func_array($this->{$key}, $arg_data); + } else { + $trace = debug_backtrace(); + + exit('<b>Notice</b>: Undefined property: Proxy::' . $key . ' in <b>' . $trace[1]['file'] . '</b> on line <b>' . $trace[1]['line'] . '</b>'); + } + } +}
\ No newline at end of file diff --git a/public/system/engine/registry.php b/public/system/engine/registry.php new file mode 100644 index 0000000..0646cc8 --- /dev/null +++ b/public/system/engine/registry.php @@ -0,0 +1,47 @@ +<?php +/** + * @package OpenCart + * @author Daniel Kerr + * @copyright Copyright (c) 2005 - 2017, OpenCart, Ltd. (https://www.opencart.com/) + * @license https://opensource.org/licenses/GPL-3.0 + * @link https://www.opencart.com +*/ + +/** +* Registry class +*/ +final class Registry { + private $data = array(); + + /** + * + * + * @param string $key + * + * @return mixed + */ + public function get($key) { + return (isset($this->data[$key]) ? $this->data[$key] : null); + } + + /** + * + * + * @param string $key + * @param string $value + */ + public function set($key, $value) { + $this->data[$key] = $value; + } + + /** + * + * + * @param string $key + * + * @return bool + */ + public function has($key) { + return isset($this->data[$key]); + } +}
\ No newline at end of file diff --git a/public/system/engine/router.php b/public/system/engine/router.php new file mode 100644 index 0000000..650fb0d --- /dev/null +++ b/public/system/engine/router.php @@ -0,0 +1,81 @@ +<?php +/** + * @package OpenCart + * @author Daniel Kerr + * @copyright Copyright (c) 2005 - 2017, OpenCart, Ltd. (https://www.opencart.com/) + * @license https://opensource.org/licenses/GPL-3.0 + * @link https://www.opencart.com +*/ + +/** +* Router class +*/ +final class Router { + private $registry; + private $pre_action = array(); + private $error; + + /** + * Constructor + * + * @param object $route + */ + public function __construct($registry) { + $this->registry = $registry; + } + + /** + * + * + * @param object $pre_action + */ + public function addPreAction(Action $pre_action) { + $this->pre_action[] = $pre_action; + } + + /** + * + * + * @param object $action + * @param object $error + */ + public function dispatch(Action $action, Action $error) { + $this->error = $error; + + foreach ($this->pre_action as $pre_action) { + $result = $this->execute($pre_action); + + if ($result instanceof Action) { + $action = $result; + + break; + } + } + + while ($action instanceof Action) { + $action = $this->execute($action); + } + } + + /** + * + * + * @param object $action + * @return object + */ + private function execute(Action $action) { + $result = $action->execute($this->registry); + + if ($result instanceof Action) { + return $result; + } + + if ($result instanceof Exception) { + $action = $this->error; + + $this->error = null; + + return $action; + } + } +}
\ No newline at end of file |