288 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			288 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| // +----------------------------------------------------------------------
 | |
| // | ThinkPHP [ WE CAN DO IT JUST THINK ]
 | |
| // +----------------------------------------------------------------------
 | |
| // | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
 | |
| // +----------------------------------------------------------------------
 | |
| // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 | |
| // +----------------------------------------------------------------------
 | |
| // | Author: liu21st <liu21st@gmail.com>
 | |
| // +----------------------------------------------------------------------
 | |
| 
 | |
| namespace think;
 | |
| 
 | |
| use think\exception\ValidateException;
 | |
| use traits\controller\Jump;
 | |
| 
 | |
| class Controller
 | |
| {
 | |
|     use Jump;
 | |
| 
 | |
|     /**
 | |
|      * 视图类实例
 | |
|      * @var \think\View
 | |
|      */
 | |
|     protected $view;
 | |
| 
 | |
|     /**
 | |
|      * Request实例
 | |
|      * @var \think\Request
 | |
|      */
 | |
|     protected $request;
 | |
| 
 | |
|     /**
 | |
|      * 验证失败是否抛出异常
 | |
|      * @var bool
 | |
|      */
 | |
|     protected $failException = false;
 | |
| 
 | |
|     /**
 | |
|      * 是否批量验证
 | |
|      * @var bool
 | |
|      */
 | |
|     protected $batchValidate = false;
 | |
| 
 | |
|     /**
 | |
|      * 前置操作方法列表(即将废弃)
 | |
|      * @var array $beforeActionList
 | |
|      */
 | |
|     protected $beforeActionList = [];
 | |
| 
 | |
|     /**
 | |
|      * 控制器中间件
 | |
|      * @var array
 | |
|      */
 | |
|     protected $middleware = [];
 | |
| 
 | |
|     /**
 | |
|      * 构造方法
 | |
|      * @access public
 | |
|      */
 | |
|     public function __construct(App $app = null)
 | |
|     {
 | |
|         $this->app     = $app ?: Container::get('app');
 | |
|         $this->request = $this->app['request'];
 | |
|         $this->view    = $this->app['view'];
 | |
| 
 | |
|         // 控制器初始化
 | |
|         $this->initialize();
 | |
| 
 | |
|         $this->registerMiddleware();
 | |
| 
 | |
|         // 前置操作方法 即将废弃
 | |
|         foreach ((array) $this->beforeActionList as $method => $options) {
 | |
|             is_numeric($method) ?
 | |
|             $this->beforeAction($options) :
 | |
|             $this->beforeAction($method, $options);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // 初始化
 | |
|     protected function initialize()
 | |
|     {}
 | |
| 
 | |
|     // 注册控制器中间件
 | |
|     public function registerMiddleware()
 | |
|     {
 | |
|         foreach ($this->middleware as $key => $val) {
 | |
|             if (!is_int($key)) {
 | |
|                 $only = $except = null;
 | |
| 
 | |
|                 if (isset($val['only'])) {
 | |
|                     $only = array_map(function ($item) {
 | |
|                         return strtolower($item);
 | |
|                     }, $val['only']);
 | |
|                 } elseif (isset($val['except'])) {
 | |
|                     $except = array_map(function ($item) {
 | |
|                         return strtolower($item);
 | |
|                     }, $val['except']);
 | |
|                 }
 | |
| 
 | |
|                 if (isset($only) && !in_array($this->request->action(), $only)) {
 | |
|                     continue;
 | |
|                 } elseif (isset($except) && in_array($this->request->action(), $except)) {
 | |
|                     continue;
 | |
|                 } else {
 | |
|                     $val = $key;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             $this->app['middleware']->controller($val);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * 前置操作
 | |
|      * @access protected
 | |
|      * @param  string $method  前置操作方法名
 | |
|      * @param  array  $options 调用参数 ['only'=>[...]] 或者['except'=>[...]]
 | |
|      */
 | |
|     protected function beforeAction($method, $options = [])
 | |
|     {
 | |
|         if (isset($options['only'])) {
 | |
|             if (is_string($options['only'])) {
 | |
|                 $options['only'] = explode(',', $options['only']);
 | |
|             }
 | |
| 
 | |
|             $only = array_map(function ($val) {
 | |
|                 return strtolower($val);
 | |
|             }, $options['only']);
 | |
| 
 | |
|             if (!in_array($this->request->action(), $only)) {
 | |
|                 return;
 | |
|             }
 | |
|         } elseif (isset($options['except'])) {
 | |
|             if (is_string($options['except'])) {
 | |
|                 $options['except'] = explode(',', $options['except']);
 | |
|             }
 | |
| 
 | |
|             $except = array_map(function ($val) {
 | |
|                 return strtolower($val);
 | |
|             }, $options['except']);
 | |
| 
 | |
|             if (in_array($this->request->action(), $except)) {
 | |
|                 return;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         call_user_func([$this, $method]);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * 加载模板输出
 | |
|      * @access protected
 | |
|      * @param  string $template 模板文件名
 | |
|      * @param  array  $vars     模板输出变量
 | |
|      * @param  array  $config   模板参数
 | |
|      * @return mixed
 | |
|      */
 | |
|     protected function fetch($template = '', $vars = [], $config = [])
 | |
|     {
 | |
|         return $this->view->fetch($template, $vars, $config);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * 渲染内容输出
 | |
|      * @access protected
 | |
|      * @param  string $content 模板内容
 | |
|      * @param  array  $vars    模板输出变量
 | |
|      * @param  array  $config  模板参数
 | |
|      * @return mixed
 | |
|      */
 | |
|     protected function display($content = '', $vars = [], $config = [])
 | |
|     {
 | |
|         return $this->view->display($content, $vars, $config);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * 模板变量赋值
 | |
|      * @access protected
 | |
|      * @param  mixed $name  要显示的模板变量
 | |
|      * @param  mixed $value 变量的值
 | |
|      * @return $this
 | |
|      */
 | |
|     protected function assign($name, $value = '')
 | |
|     {
 | |
|         $this->view->assign($name, $value);
 | |
| 
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * 视图过滤
 | |
|      * @access protected
 | |
|      * @param  Callable $filter 过滤方法或闭包
 | |
|      * @return $this
 | |
|      */
 | |
|     protected function filter($filter)
 | |
|     {
 | |
|         $this->view->filter($filter);
 | |
| 
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * 初始化模板引擎
 | |
|      * @access protected
 | |
|      * @param  array|string $engine 引擎参数
 | |
|      * @return $this
 | |
|      */
 | |
|     protected function engine($engine)
 | |
|     {
 | |
|         $this->view->engine($engine);
 | |
| 
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * 设置验证失败后是否抛出异常
 | |
|      * @access protected
 | |
|      * @param  bool $fail 是否抛出异常
 | |
|      * @return $this
 | |
|      */
 | |
|     protected function validateFailException($fail = true)
 | |
|     {
 | |
|         $this->failException = $fail;
 | |
| 
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * 验证数据
 | |
|      * @access protected
 | |
|      * @param  array        $data     数据
 | |
|      * @param  string|array $validate 验证器名或者验证规则数组
 | |
|      * @param  array        $message  提示信息
 | |
|      * @param  bool         $batch    是否批量验证
 | |
|      * @param  mixed        $callback 回调方法(闭包)
 | |
|      * @return array|string|true
 | |
|      * @throws ValidateException
 | |
|      */
 | |
|     protected function validate($data, $validate, $message = [], $batch = false, $callback = null)
 | |
|     {
 | |
|         if (is_array($validate)) {
 | |
|             $v = $this->app->validate();
 | |
|             $v->rule($validate);
 | |
|         } else {
 | |
|             if (strpos($validate, '.')) {
 | |
|                 // 支持场景
 | |
|                 list($validate, $scene) = explode('.', $validate);
 | |
|             }
 | |
|             $v = $this->app->validate($validate);
 | |
|             if (!empty($scene)) {
 | |
|                 $v->scene($scene);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         // 是否批量验证
 | |
|         if ($batch || $this->batchValidate) {
 | |
|             $v->batch(true);
 | |
|         }
 | |
| 
 | |
|         if (is_array($message)) {
 | |
|             $v->message($message);
 | |
|         }
 | |
| 
 | |
|         if ($callback && is_callable($callback)) {
 | |
|             call_user_func_array($callback, [$v, &$data]);
 | |
|         }
 | |
| 
 | |
|         if (!$v->check($data)) {
 | |
|             if ($this->failException) {
 | |
|                 throw new ValidateException($v->getError());
 | |
|             }
 | |
|             return $v->getError();
 | |
|         }
 | |
| 
 | |
|         return true;
 | |
|     }
 | |
| 
 | |
|     public function __debugInfo()
 | |
|     {
 | |
|         $data = get_object_vars($this);
 | |
|         unset($data['app'], $data['request']);
 | |
| 
 | |
|         return $data;
 | |
|     }
 | |
| }
 |