Controller.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. <?php
  2. namespace think\addons;
  3. use app\common\library\Auth;
  4. use think\Config;
  5. use think\Hook;
  6. use think\Lang;
  7. use think\Loader;
  8. use think\Request;
  9. use think\Validate;
  10. /**
  11. * 插件基类控制器
  12. * @package think\addons
  13. */
  14. class Controller extends \think\Controller
  15. {
  16. // 当前插件操作
  17. protected $addon = null;
  18. protected $controller = null;
  19. protected $action = null;
  20. // 当前template
  21. protected $template;
  22. /**
  23. * 无需登录的方法,同时也就不需要鉴权了
  24. * @var array
  25. */
  26. protected $noNeedLogin = ['*'];
  27. /**
  28. * 无需鉴权的方法,但需要登录
  29. * @var array
  30. */
  31. protected $noNeedRight = ['*'];
  32. /**
  33. * 权限Auth
  34. * @var Auth
  35. */
  36. protected $auth = null;
  37. /**
  38. * 布局模板
  39. * @var string
  40. */
  41. protected $layout = null;
  42. /**
  43. * 架构函数
  44. * @param Request $request Request对象
  45. * @access public
  46. */
  47. public function __construct(Request $request = null)
  48. {
  49. if (is_null($request)) {
  50. $request = Request::instance();
  51. }
  52. // 生成request对象
  53. $this->request = $request;
  54. //移除HTML标签
  55. $this->request->filter('trim,strip_tags,htmlspecialchars');
  56. // 是否自动转换控制器和操作名
  57. $convert = Config::get('url_convert');
  58. $filter = $convert ? 'strtolower' : 'trim';
  59. // 处理路由参数
  60. $param = $this->request->param();
  61. $dispatch = $this->request->dispatch();
  62. $var = isset($dispatch['var']) ? $dispatch['var'] : [];
  63. $var = array_merge($param, $var);
  64. if (isset($dispatch['method']) && substr($dispatch['method'][0], 0, 7) == "\\addons") {
  65. $arr = explode("\\", $dispatch['method'][0]);
  66. $addon = strtolower($arr[2]);
  67. $controller = strtolower(end($arr));
  68. $action = $dispatch['method'][1];
  69. } else {
  70. $addon = isset($var['addon']) ? $var['addon'] : '';
  71. $controller = isset($var['controller']) ? $var['controller'] : '';
  72. $action = isset($var['action']) ? $var['action'] : '';
  73. }
  74. $this->addon = $addon ? call_user_func($filter, $addon) : '';
  75. $this->controller = $controller ? call_user_func($filter, $controller) : 'index';
  76. $this->action = $action ? call_user_func($filter, $action) : 'index';
  77. // 重置配置
  78. Config::set('template.view_path', ADDON_PATH . $this->addon . DS . 'view' . DS);
  79. // 父类的调用必须放在设置模板路径之后
  80. parent::__construct($this->request);
  81. }
  82. protected function _initialize()
  83. {
  84. // 检测IP是否允许
  85. if (function_exists("check_ip_allowed")) {
  86. check_ip_allowed();
  87. }
  88. // 渲染配置到视图中
  89. $config = get_addon_config($this->addon);
  90. $this->view->assign("config", $config);
  91. $lang = $this->request->langset();
  92. $lang = preg_match("/^([a-zA-Z\-_]{2,10})\$/i", $lang) ? $lang : 'zh-cn';
  93. // 加载系统语言包
  94. Lang::load([
  95. ADDON_PATH . $this->addon . DS . 'lang' . DS . $lang . EXT,
  96. ]);
  97. // 设置替换字符串
  98. $cdnurl = Config::get('site.cdnurl');
  99. $this->view->replace('__ADDON__', $cdnurl . "/assets/addons/" . $this->addon);
  100. $this->auth = Auth::instance();
  101. // token
  102. $token = $this->request->server('HTTP_TOKEN', $this->request->request('token', \think\Cookie::get('token')));
  103. $path = 'addons/' . $this->addon . '/' . str_replace('.', '/', $this->controller) . '/' . $this->action;
  104. // 设置当前请求的URI
  105. $this->auth->setRequestUri($path);
  106. // 检测是否需要验证登录
  107. if (!$this->auth->match($this->noNeedLogin)) {
  108. //初始化
  109. $this->auth->init($token);
  110. //检测是否登录
  111. if (!$this->auth->isLogin()) {
  112. $this->error(__('Please login first'), 'index/user/login');
  113. }
  114. // 判断是否需要验证权限
  115. if (!$this->auth->match($this->noNeedRight)) {
  116. // 判断控制器和方法判断是否有对应权限
  117. if (!$this->auth->check($path)) {
  118. $this->error(__('You have no permission'));
  119. }
  120. }
  121. } else {
  122. // 如果有传递token才验证是否登录状态
  123. if ($token) {
  124. $this->auth->init($token);
  125. }
  126. }
  127. // 如果有使用模板布局
  128. if ($this->layout) {
  129. $this->view->engine->layout('layout/' . $this->layout);
  130. }
  131. $this->view->assign('user', $this->auth->getUser());
  132. $site = Config::get("site");
  133. $upload = \app\common\model\Config::upload();
  134. // 上传信息配置后
  135. Hook::listen("upload_config_init", $upload);
  136. Config::set('upload', array_merge(Config::get('upload'), $upload));
  137. // 加载当前控制器语言包
  138. $this->assign('site', $site);
  139. }
  140. /**
  141. * 加载模板输出
  142. * @access protected
  143. * @param string $template 模板文件名
  144. * @param array $vars 模板输出变量
  145. * @param array $replace 模板替换
  146. * @param array $config 模板参数
  147. * @return mixed
  148. */
  149. protected function fetch($template = '', $vars = [], $replace = [], $config = [])
  150. {
  151. $controller = Loader::parseName($this->controller);
  152. if ('think' == strtolower(Config::get('template.type')) && $controller && 0 !== strpos($template, '/')) {
  153. $depr = Config::get('template.view_depr');
  154. $template = str_replace(['/', ':'], $depr, $template);
  155. if ('' == $template) {
  156. // 如果模板文件名为空 按照默认规则定位
  157. $template = str_replace('.', DS, $controller) . $depr . $this->action;
  158. } elseif (false === strpos($template, $depr)) {
  159. $template = str_replace('.', DS, $controller) . $depr . $template;
  160. }
  161. }
  162. return parent::fetch($template, $vars, $replace, $config);
  163. }
  164. /**
  165. * 刷新Token
  166. */
  167. protected function token()
  168. {
  169. $token = $this->request->param('__token__');
  170. //验证Token
  171. if (!Validate::make()->check(['__token__' => $token], ['__token__' => 'require|token'])) {
  172. $this->error(__('Token verification error'), '', ['__token__' => $this->request->token()]);
  173. }
  174. //刷新Token
  175. $this->request->token();
  176. }
  177. }