【opencart3源码分析】加载类loader.php

<?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
 */

/**
 * 加载类
 */
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) {
	    // 返回参数列表的数组
		$args = func_get_args();
        //删除数组中第一个元素
		array_shift($args);

		// 过滤
		$route = preg_replace('/[^a-zA-Z0-9_\/]/', '', (string)$route);

		// 触发
		$trigger = $route;

		// 触发前置事件
		$result = $this->registry->get('event')->trigger('controller/' . $trigger . '/before', array(&$route, &$args));

		// 确保它只是在需要时返回输出的最后一个事件。
		if ($result != null && !$result instanceof Exception) {
			$output = $result;
		} else {
		    // 实例化操作
			$action = new Action($route);
			$output = $action->execute($this->registry, $args);
		}

		// 触发post事件
		$result = $this->registry->get('event')->trigger('controller/' . $trigger . '/after', array(&$route, &$args, &$output));

		if ($result && !$result instanceof Exception) {
			$output = $result;
		}

		if (!$output instanceof Exception) {
			return $output;
		}
	}

	/**
	 *
	 *  加载模型类s
	 * @param    string $route
	 */
	public function model($route) {
		// 过滤
		$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();

				// 覆盖模型有点困难所以我们必须使用PHP的魔术方法
				foreach (get_class_methods($class) as $method) {
					$proxy->{$method} = $this->callback($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()) {
		// 过滤
		$route = preg_replace('/[^a-zA-Z0-9_\/]/', '', (string)$route);

		// 触发
		$trigger = $route;

		$template = new Template($this->registry->get('config')->get('template_engine'));

		// 触发前置事件
		$result = $this->registry->get('event')->trigger('view/' . $trigger . '/before', array(&$route, &$data, &$template));

		// 确保它只是在需要时返回输出的最后一个事件。
		if ($result && !$result instanceof Exception) {
			$output = $result;
		} else {
			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'));
		}

		// 触发post事件
		$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($route) {
		return function () use ($route) {
			// Grab args using function because we don't know the number of args being passed.
			$args = func_get_args();

			$route = preg_replace('/[^a-zA-Z0-9_\/]/', '', (string)$route);

			// 触发
			$trigger = $route;

			// 触发前置事件
			$result = $this->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, '/')));

				// 存储模型对象
				$key = substr($route, 0, strrpos($route, '/'));

				// 检测模型是否已经初始化
				if (!$this->registry->has($key)) {
					$this->registry->set($key, new $class($this->registry));
				}

				$method = substr($route, strrpos($route, '/') + 1);

				$callable = array($this->registry->get($key), $method);

				if (is_callable($callable)) {
					$output = call_user_func_array($callable, $args);
				} else {
					throw new \Exception('Error: Could not call model/' . $route . '!');
				}
			}

			// 触发post事件
			$result = $this->registry->get('event')->trigger('model/' . $trigger . '/after', array(&$route, &$args, &$output));

			if ($result && !$result instanceof Exception) {
				$output = $result;
			}

			return $output;
		};
	}
}

猜你喜欢

转载自blog.csdn.net/qq2942713658/article/details/81351806
今日推荐