PluginBaseController.php 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2013-2018 http://www.thinkcmf.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +---------------------------------------------------------------------
  9. // | Author: Dean <zxxjjforever@163.com>
  10. // +----------------------------------------------------------------------
  11. namespace cmf\controller;
  12. use think\exception\ValidateException;
  13. use think\Request;
  14. use think\Config;
  15. use think\Loader;
  16. use think\exception\TemplateNotFoundException;
  17. class PluginBaseController extends BaseController
  18. {
  19. /**
  20. * @var \cmf\lib\Plugin
  21. */
  22. private $plugin;
  23. /**
  24. * 前置操作方法列表
  25. * @var array $beforeActionList
  26. * @access protected
  27. */
  28. protected $beforeActionList = [];
  29. /**
  30. * 构造函数
  31. * @param Request $request Request对象
  32. * @access public
  33. */
  34. public function __construct(Request $request = null)
  35. {
  36. if (is_null($request)) {
  37. $request = Request::instance();
  38. }
  39. $this->request = $request;
  40. $this->getPlugin();
  41. $this->view = $this->plugin->getView();
  42. $siteInfo = cmf_get_site_info();
  43. $this->assign('site_info', $siteInfo);
  44. // 控制器初始化
  45. $this->_initialize();
  46. // 前置操作方法
  47. if ($this->beforeActionList) {
  48. foreach ($this->beforeActionList as $method => $options) {
  49. is_numeric($method) ?
  50. $this->beforeAction($options) :
  51. $this->beforeAction($method, $options);
  52. }
  53. }
  54. }
  55. public function getPlugin()
  56. {
  57. if (is_null($this->plugin)) {
  58. $pluginName = $this->request->param('_plugin');
  59. $pluginName = cmf_parse_name($pluginName, 1);
  60. $class = cmf_get_plugin_class($pluginName);
  61. $this->plugin = new $class;
  62. }
  63. return $this->plugin;
  64. }
  65. // 初始化
  66. protected function _initialize()
  67. {
  68. }
  69. /**
  70. * 前置操作
  71. * @access protected
  72. * @param string $method 前置操作方法名
  73. * @param array $options 调用参数 ['only'=>[...]] 或者['except'=>[...]]
  74. */
  75. protected function beforeAction($method, $options = [])
  76. {
  77. if (isset($options['only'])) {
  78. if (is_string($options['only'])) {
  79. $options['only'] = explode(',', $options['only']);
  80. }
  81. if (!in_array($this->request->action(), $options['only'])) {
  82. return;
  83. }
  84. } elseif (isset($options['except'])) {
  85. if (is_string($options['except'])) {
  86. $options['except'] = explode(',', $options['except']);
  87. }
  88. if (in_array($this->request->action(), $options['except'])) {
  89. return;
  90. }
  91. }
  92. call_user_func([$this, $method]);
  93. }
  94. /**
  95. * 加载模板输出(支持:/index/index,index/index,index,空,:index,/index)
  96. * @access protected
  97. * @param string $template 模板文件名
  98. * @param array $vars 模板输出变量
  99. * @param array $replace 模板替换
  100. * @param array $config 模板参数
  101. * @return mixed
  102. */
  103. protected function fetch($template = '', $vars = [], $replace = [], $config = [])
  104. {
  105. $template = $this->parseTemplate($template);
  106. // 模板不存在 抛出异常
  107. if (!is_file($template)) {
  108. throw new TemplateNotFoundException('template not exists:' . $template, $template);
  109. }
  110. return $this->view->fetch($template, $vars, $replace, $config);
  111. }
  112. /**
  113. * 自动定位模板文件
  114. * @access private
  115. * @param string $template 模板文件规则
  116. * @return string
  117. */
  118. private function parseTemplate($template)
  119. {
  120. // 分析模板文件规则
  121. $viewEngineConfig = Config::get('template');
  122. $path = $this->plugin->getThemeRoot();
  123. $depr = $viewEngineConfig['view_depr'];
  124. $data = $this->request->param();
  125. $controller = $data['_controller'];
  126. $action = $data['_action'];
  127. if (0 !== strpos($template, '/')) {
  128. $template = str_replace(['/', ':'], $depr, $template);
  129. $controller = Loader::parseName($controller);
  130. if ($controller) {
  131. if ('' == $template) {
  132. // 如果模板文件名为空 按照默认规则定位
  133. $template = str_replace('.', DS, $controller) . $depr . $action;
  134. } elseif (false === strpos($template, $depr)) {
  135. $template = str_replace('.', DS, $controller) . $depr . $template;
  136. }
  137. }
  138. } else {
  139. $template = str_replace(['/', ':'], $depr, substr($template, 1));
  140. }
  141. return $path . ltrim($template, '/') . '.' . ltrim($viewEngineConfig['view_suffix'], '.');
  142. }
  143. /**
  144. * 渲染内容输出
  145. * @access protected
  146. * @param string $content 模板内容
  147. * @param array $vars 模板输出变量
  148. * @param array $replace 替换内容
  149. * @param array $config 模板参数
  150. * @return mixed
  151. */
  152. protected function display($content = '', $vars = [], $replace = [], $config = [])
  153. {
  154. return $this->view->display($content, $vars, $replace, $config);
  155. }
  156. /**
  157. * 模板变量赋值
  158. * @access protected
  159. * @param mixed $name 要显示的模板变量
  160. * @param mixed $value 变量的值
  161. * @return void
  162. */
  163. protected function assign($name, $value = '')
  164. {
  165. $this->view->assign($name, $value);
  166. }
  167. /**
  168. * 设置验证失败后是否抛出异常
  169. * @access protected
  170. * @param bool $fail 是否抛出异常
  171. * @return $this
  172. */
  173. protected function validateFailException($fail = true)
  174. {
  175. $this->failException = $fail;
  176. return $this;
  177. }
  178. /**
  179. * 验证数据
  180. * @access protected
  181. * @param array $data 数据
  182. * @param string|array $validate 验证器名或者验证规则数组
  183. * @param array $message 提示信息
  184. * @param bool $batch 是否批量验证
  185. * @param mixed $callback 回调方法(闭包)
  186. * @return array|string|true
  187. * @throws ValidateException
  188. */
  189. protected function validate($data, $validate, $message = [], $batch = false, $callback = null)
  190. {
  191. if (is_array($validate)) {
  192. $v = Loader::validate();
  193. $v->rule($validate);
  194. } else {
  195. if (strpos($validate, '.')) {
  196. // 支持场景
  197. list($validate, $scene) = explode('.', $validate);
  198. }
  199. $v = Loader::validate('\\plugins\\' . cmf_parse_name($this->plugin->getName()) . '\\validate\\' . $validate . 'Validate');
  200. if (!empty($scene)) {
  201. $v->scene($scene);
  202. }
  203. }
  204. // 是否批量验证
  205. if ($batch || $this->batchValidate) {
  206. $v->batch(true);
  207. }
  208. if (is_array($message)) {
  209. $v->message($message);
  210. }
  211. if ($callback && is_callable($callback)) {
  212. call_user_func_array($callback, [$v, &$data]);
  213. }
  214. if (!$v->check($data)) {
  215. if ($this->failException) {
  216. throw new ValidateException($v->getError());
  217. } else {
  218. return $v->getError();
  219. }
  220. } else {
  221. return true;
  222. }
  223. }
  224. }