123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- <?php
- namespace laytp\library;
- use think\exception\HttpException;
- use think\facade\Config;
- use think\facade\Middleware;
- use think\facade\Request;
- use think\Response;
- use think\Route;
- class PluginRoute extends Route
- {
- protected $middleware;
- protected $actionName;
- /**
- * 插件路由
- * 路由访问规则,http(s)://yourDomain/plugin/[插件名称]/[插件controller目录下的类名,多级目录以.号分割]/[方法名]/[参数列表]
- * @param null $plugin
- * @return mixed
- */
- public function execute($plugin = null)
- {
- $this->middleware = Middleware::instance();
- $this->request = Request::instance();
- $url = $this->request->url();
- $urlArr = array_filter(explode('/', $url));
- // print_r($urlArr);
- if(SYS_TYPE == 'W7'){
- $controller = isset($urlArr[7]) ? $urlArr[7] : 'Index';
- }else{
- $controller = isset($urlArr[3]) ? $urlArr[3] : 'Index';
- }
- $plugin = $plugin ? trim(strtolower($plugin)) : $plugin;
- if (!defined('LT_PLUGIN')) {
- define('LT_PLUGIN', $plugin);
- }
- $controller = $controller ? str_replace('.', '\\', trim($controller)) : 'Index';
- $classAndAction = $this->getPluginClassAndAction($plugin, $controller);
- $this->request->setController($controller)->setAction($classAndAction['action']);
- $common_func_file = app()->getRootPath() . DS . 'plugin' . DS . $plugin . DS . 'common.php';
- if (file_exists($common_func_file)) {
- include_once app()->getRootPath() . DS . 'plugin' . DS . $plugin . DS . 'common.php';
- }
- $class = $classAndAction['class'];
- $action = $classAndAction['action'];
- $instance = app()->make($class, [], true);
- $this->actionName = $action;
- try {
- $this->registerControllerMiddleware($instance);
- } catch (\ReflectionException $e) {
- throw new HttpException(500, $e->getMessage());
- }
- return $this->middleware->pipeline('controller')
- ->send($this->request)
- ->then(function () use ($instance) {
- // 获取当前操作名
- $suffix = Config::get('route.action_suffix');
- $action = $this->actionName . $suffix;
- if (is_callable([$instance, $action])) {
- $vars = $this->request->param();
- try {
- $reflect = new \ReflectionMethod($instance, $action);
- // 严格获取当前操作方法名
- $actionName = $reflect->getName();
- if ($suffix) {
- $actionName = substr($actionName, 0, -strlen($suffix));
- }
- $this->request->setAction($actionName);
- } catch (\Exception $e) {
- $reflect = new \ReflectionMethod($instance, '__call');
- $vars = [$action, $vars];
- $this->request->setAction($action);
- }
- } else {
- // 操作不存在
- throw new HttpException(404, 'method not exists:' . get_class($instance) . '->' . $action . '()');
- }
- $data = $this->app->invokeReflectMethod($instance, $reflect, $vars);
- return $this->autoResponse($data);
- });
- }
- /**
- * 得到插件完整类名
- * @param $plugin
- * @param $controller
- * @return array
- */
- public function getPluginClassAndAction($plugin, $controller)
- {
- $request = Request::instance();
- $url = $request->url();
- $urlArr = array_filter(explode('/', $url));
- $controllerArr = explode("\\", $controller);
- $controllerArr[count($controllerArr) - 1] = ucfirst($controllerArr[count($controllerArr) - 1]);
- $controller = implode("\\", $controllerArr);
- $class = 'plugin\\' . $plugin . '\\controller\\' . $controller;
- // print_r($class);
- if (!class_exists($class)) {
- throw new HttpException(404, $class . '类不存在');
- }
- $class = 'plugin\\' . $plugin . '\\controller\\' . $controller;
- if(SYS_TYPE == 'W7'){
- if (isset($urlArr[8])) {
- $action_param = explode('?', $urlArr[8]);
- $action = $action_param[0];
- } else {
- $action = 'index';
- }
- }else{
- if (isset($urlArr[4])) {
- $action_param = explode('?', $urlArr[4]);
- $action = $action_param[0];
- } else {
- $action = 'index';
- }
- }
- $action = $action ? str_replace('.' . Config::get("route.url_html_suffix"), '', trim($action)) : 'index';
- if (!method_exists($class, $action)) {
- throw new HttpException(404, $class . '->' . $action . '()' . '方法不存在');
- }
- return ['class' => $class, 'action' => $action];
- }
- /**
- * 使用反射机制注册控制器中间件
- * @param $controller
- * @throws \ReflectionException
- */
- protected function registerControllerMiddleware($controller): void
- {
- $class = new \ReflectionClass($controller);
- if ($class->hasProperty('middleware')) {
- $reflectionProperty = $class->getProperty('middleware');
- $reflectionProperty->setAccessible(true);
- $middlewares = $reflectionProperty->getValue($controller);
- foreach ($middlewares as $key => $val) {
- if (!is_int($key)) {
- if (isset($val['only']) && !in_array($this->request->action(true), array_map(function ($item) {
- return strtolower($item);
- }, is_string($val['only']) ? explode(",", $val['only']) : $val['only']))) {
- continue;
- } elseif (isset($val['except']) && in_array($this->request->action(true), array_map(function ($item) {
- return strtolower($item);
- }, is_string($val['except']) ? explode(',', $val['except']) : $val['except']))) {
- continue;
- } else {
- $val = $key;
- }
- }
- if (is_string($val) && strpos($val, ':')) {
- $val = explode(':', $val);
- if (count($val) > 1) {
- $val = [$val[0], array_slice($val, 1)];
- }
- }
- $this->middleware->controller($val);
- }
- }
- }
- protected function autoResponse($data): Response
- {
- if ($data instanceof Response) {
- $response = $data;
- } elseif (!is_null($data)) {
- // 默认自动识别响应输出类型
- $type = $this->request->isJson() ? 'json' : 'html';
- $response = Response::create($data, $type);
- } else {
- $data = ob_get_clean();
- $content = false === $data ? '' : $data;
- $status = '' === $content && $this->request->isJson() ? 204 : 200;
- $response = Response::create($content, 'html', $status);
- }
- return $response;
- }
- }
|