V2BaseController.php 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793
  1. <?php
  2. /**
  3. * V2BaseController.php UTF-8
  4. * V2版本基类
  5. *
  6. * @date : 2018/1/15 21:35
  7. *
  8. * @license 这不是一个自由软件,未经授权不许任何使用和传播。
  9. * @author : wuyonghong <wyh@huosdk.com>
  10. * @version : HUOSDK 8.0
  11. */
  12. namespace box\common\controller;
  13. use huo\controller\common\CommonFunc;
  14. use huo\controller\common\HuoCookie;
  15. use huo\controller\common\HuoSession;
  16. use huo\controller\member\Member;
  17. use huo\controller\member\MemCache;
  18. use huo\controller\request\Channel;
  19. use huo\controller\request\Crash;
  20. use huo\controller\request\Device;
  21. use huo\controller\request\Event;
  22. use huo\controller\request\Game;
  23. use huo\controller\request\Mem;
  24. use huo\controller\request\Order;
  25. use huo\controller\request\Role;
  26. use huo\logic\game\GameLogic;
  27. use huoCheck\HuoApiV2;
  28. use huolib\constant\CommonConst;
  29. use huolib\constant\DeviceTypeConst;
  30. use huolib\constant\FormatConst;
  31. use huolib\constant\FromConst;
  32. use huolib\status\CommonStatus;
  33. use huolib\tool\StrUtils;
  34. use think\Config;
  35. use think\Controller;
  36. use think\Db;
  37. use think\exception\HttpResponseException;
  38. use think\exception\ValidateException;
  39. use think\Loader;
  40. use think\Response;
  41. class V2BaseController extends Controller {
  42. //token
  43. protected $token = '';
  44. //设备类型
  45. protected $device_type = '';
  46. //用户 id
  47. protected $mem_id = 0;
  48. // 语言
  49. protected $lang = 'en';
  50. //用户
  51. protected $user;
  52. /* 返回类型 */
  53. protected $response_type = 'html';
  54. //用户类型
  55. protected $user_type;
  56. protected $allowed_device_types = ['mobile', 'android', 'iphone', 'ipad', 'web', 'pc', 'mac', 'wxapp'];
  57. /**
  58. * @var \think\Request Request实例
  59. */
  60. protected $request;
  61. protected $agent_site; /* 渠道专属链接 */
  62. // 验证失败是否抛出异常
  63. protected $fail_exception = false;
  64. // 是否批量验证
  65. protected $batch_validate = false;
  66. protected $rq_data = [];
  67. protected $sess_config
  68. = [
  69. 'id' => '',
  70. 'prefix' => '',
  71. 'type' => '',
  72. 'expire' => CommonConst::CONST_DAY_SECONDS
  73. ];
  74. /**
  75. * 前置操作方法列表
  76. *
  77. * @var array $before_action_list
  78. * @access protected
  79. */
  80. protected $before_action_list = [];
  81. // 初始化
  82. private function _initLang() {
  83. $_lang = $this->request->header('HS-Lang/s', 'en-us');
  84. $this->lang = $_lang;
  85. config('default_lang', $this->lang);
  86. }
  87. /**
  88. * 获取设备类型
  89. *
  90. * @return string
  91. */
  92. public function getDeviceType() {
  93. if ($this->request->isWeixin()) {
  94. return DeviceTypeConst::DEVICE_TYPE_WEIXIN;
  95. }
  96. if ($this->request->isMobile()) {
  97. return DeviceTypeConst::DEVICE_TYPE_WAP;
  98. }
  99. return DeviceTypeConst::DEVICE_TYPE_PC;
  100. }
  101. /**
  102. *
  103. */
  104. private function _initUser() {
  105. $_token = HuoCookie::getMemToken();
  106. if (empty($_token)) {
  107. $_token = $this->request->param('token/s', '');
  108. }
  109. $_game_data = get_val($this->rq_data, 'game', []);
  110. $_device_type = get_val($_game_data, 'mp_id');
  111. $_wx_param['wx_app_id'] = $this->request->param('wx_app_id/s', '');
  112. if (!empty($_wx_param['wx_app_id'])) {
  113. $this->device_type = $_wx_param['wx_app_id'];
  114. } elseif (!empty($_device_type)) {
  115. $this->device_type = $_device_type;
  116. } else {
  117. $this->device_type = DeviceTypeConst::DEVICE_TYPE_MP;
  118. }
  119. if ($this->request->isWeixin()) {
  120. $this->device_type = DeviceTypeConst::DEVICE_TYPE_WEIXIN;
  121. }
  122. $_mem_id = $this->getMemIdByToken($_token, $this->device_type);
  123. if (!empty($_mem_id)) {
  124. $this->mem_id = $_mem_id;
  125. }
  126. if (APP_DEBUG) {
  127. /* 调试环境直接登陆 */
  128. $_mem_id = $this->request->param('debug_mem_id/s', 0);
  129. if (!empty($_mem_id)) {
  130. $this->mem_id = $_mem_id;
  131. }
  132. }
  133. if (empty($this->mem_id)) {
  134. $_wx_param['url'] = $this->request->domain().$this->request->url();
  135. if ($this->request->isWeixin()) {
  136. /* 微信内 判断是否登陆 没有登录 调用微信登陆 */
  137. $_wx_param['type'] = FromConst::FROM_WEIXIN;
  138. //$_wx_login_url = MPBOXSITE.'/box/oauth/index?'.StrUtils::createLinkString($_wx_param);
  139. $_wx_login_url = H5ISITE.'/api/oauth/index?'.StrUtils::createLinkString($_wx_param);
  140. $this->redirect($_wx_login_url);
  141. }
  142. }
  143. }
  144. protected function _initialize() {
  145. $this->response_type = $this->request->param('format/s', FormatConst::FORMAT_HTML);
  146. $_token = $this->request->param('token');
  147. if (!empty($_token)) {
  148. $this->token = $_token;
  149. Config::set('session.id', $this->token);
  150. }
  151. Config::set('default_return_type', $this->response_type);
  152. $this->_initLang();
  153. $this->checkParam();
  154. // 用户验证初始化
  155. $this->_initUser();
  156. if ($this->request->isOptions()) {
  157. $this->success();
  158. }
  159. }
  160. /**
  161. * 前置操作
  162. *
  163. * @access protected
  164. *
  165. * @param string $method 前置操作方法名
  166. * @param array $options 调用参数 ['only'=>[...]] 或者['except'=>[...]]
  167. */
  168. protected function beforeAction($method, $options = []) {
  169. if (isset($options['only'])) {
  170. if (is_string($options['only'])) {
  171. $options['only'] = explode(',', $options['only']);
  172. }
  173. if (!in_array($this->request->action(), $options['only'])) {
  174. return;
  175. }
  176. } elseif (isset($options['except'])) {
  177. if (is_string($options['except'])) {
  178. $options['except'] = explode(',', $options['except']);
  179. }
  180. if (in_array($this->request->action(), $options['except'])) {
  181. return;
  182. }
  183. }
  184. call_user_func([$this, $method]);
  185. }
  186. /**
  187. * @param $token
  188. * @param $device_type
  189. *
  190. * @return array|bool|false|\PDOStatement|string|\think\Model
  191. */
  192. public function getMemIdByToken($token, $device_type) {
  193. if (empty($token)) {
  194. return 0;
  195. }
  196. $_path = 'mp/wx/login';
  197. $_is_up = $_path == request()->path() ? true : false;
  198. $_mem_id = (new Member())->getMemIdByToken($token, $device_type, $_is_up);
  199. if (empty($_mem_id)) {
  200. return 0;
  201. }
  202. return $_mem_id;
  203. }
  204. /**
  205. * 返回数据
  206. *
  207. * @param array $data
  208. */
  209. protected function returnData($data = []) {
  210. $_msg = $data['msg'];
  211. $_code = $data['code'];
  212. $_data = $data['data'];
  213. if (CommonStatus::NO_ERROR != $_code) {
  214. $this->error($_msg, $_data, $_code);
  215. }
  216. $this->success($_msg, $_data, $_code);
  217. }
  218. /**
  219. * 操作错误跳转的快捷方法
  220. *
  221. * @access protected
  222. *
  223. * @param mixed $msg 提示信息,若要指定错误码,可以传数组,格式为['code'=>您的错误码,'msg'=>'您的错误消息']
  224. * @param mixed $data 返回的数据
  225. * @param int $code
  226. *
  227. * @param array $header 发送的Header信息
  228. *
  229. * @param null $url
  230. * @param int $wait
  231. *
  232. * @return void
  233. */
  234. protected function error($msg = '', $data = '', $code = 400, array $header = [], $url = null, $wait = 3) {
  235. $type = $this->getResponseType();
  236. if ('html' == $type) {
  237. parent::error($msg, $data, $code, $header, $url, $wait);
  238. }
  239. if (empty($data)) {
  240. $data = null;
  241. }
  242. $result = [
  243. 'code' => $code,
  244. 'msg' => $msg,
  245. 'data' => $data,
  246. ];
  247. $header['Access-Control-Allow-Origin'] = '*';
  248. $header['Access-Control-Allow-Headers'] = 'X-Requested-With,Content-Type,HS-Device-Type,HS-Token,HS-Lang';
  249. $header['Access-Control-Allow-Methods'] = 'GET,POST,PATCH,PUT,DELETE,OPTIONS';
  250. $response = Response::create($result, $type)->header($header);
  251. throw new HttpResponseException($response);
  252. }
  253. /**
  254. * 获取当前的response 输出类型
  255. *
  256. * @access protected
  257. * @return string
  258. */
  259. protected function getResponseType() {
  260. return $this->response_type;
  261. }
  262. /**
  263. * 获取当前登录用户的id
  264. *
  265. * @return int
  266. */
  267. public function getMemId() {
  268. if (empty($this->mem_id)) {
  269. $this->error(lang('NO_LOGIN'), '', 1002);
  270. }
  271. // $this->mem_id = rand(1, 10);
  272. return $this->mem_id;
  273. }
  274. /**
  275. * 设置验证失败后是否抛出异常
  276. *
  277. * @access protected
  278. *
  279. * @param bool $fail 是否抛出异常
  280. *
  281. * @return $this
  282. */
  283. protected function validateFailException($fail = true) {
  284. $this->fail_exception = $fail;
  285. return $this;
  286. }
  287. /**
  288. * 验证数据
  289. *
  290. * @access protected
  291. *
  292. * @param array $data 数据
  293. * @param string|array $validate 验证器名或者验证规则数组
  294. * @param array $message 提示信息
  295. * @param bool $batch 是否批量验证
  296. * @param mixed $callback 回调方法(闭包)
  297. *
  298. * @return array|string|true
  299. * @throws ValidateException
  300. */
  301. protected function validate($data, $validate, $message = [], $batch = false, $callback = null) {
  302. if (is_array($validate)) {
  303. $_valid_class = Loader::validate();
  304. $_valid_class->rule($validate);
  305. } else {
  306. if (strpos($validate, '.')) {
  307. // 支持场景
  308. list($validate, $scene) = explode('.', $validate);
  309. }
  310. $_valid_class = Loader::validate($validate);
  311. if (!empty($scene)) {
  312. $_valid_class->scene($scene);
  313. }
  314. }
  315. // 是否批量验证
  316. if ($batch || $this->batch_validate) {
  317. $_valid_class->batch(true);
  318. }
  319. if (is_array($message)) {
  320. $_valid_class->message($message);
  321. }
  322. if ($callback && is_callable($callback)) {
  323. call_user_func_array($callback, [$_valid_class, &$data]);
  324. }
  325. if (!$_valid_class->check($data)) {
  326. if ($this->fail_exception) {
  327. throw new ValidateException($_valid_class->getError());
  328. } else {
  329. return $_valid_class->getError();
  330. }
  331. } else {
  332. return true;
  333. }
  334. }
  335. /**
  336. * 操作成功跳转的快捷方法
  337. *
  338. * @access protected
  339. *
  340. * @param mixed $msg 提示信息
  341. * @param mixed $data 返回的数据
  342. * @param array $header 发送的Header信息
  343. *
  344. * @param int $code 返回码
  345. *
  346. * @return void
  347. */
  348. protected function success($msg = '', $data = '', $code = 200, array $header = [], $url = null, $wait = 3) {
  349. $type = $this->getResponseType();
  350. if ('html' == $type) {
  351. parent::success($msg, $data, $code, $header, $url, $wait);
  352. }
  353. if (empty($data)) {
  354. $data = null;
  355. }
  356. $result = [
  357. 'code' => $code,
  358. 'msg' => $msg,
  359. 'data' => $data,
  360. ];
  361. $header['Access-Control-Allow-Origin'] = '*';
  362. $header['Access-Control-Allow-Headers'] = 'X-Requested-With,Content-Type,HS-Device-Type,HS-Token,HS-Lang';
  363. $header['Access-Control-Allow-Methods'] = 'GET,POST,PATCH,PUT,DELETE,OPTIONS';
  364. $response = Response::create($result, $type)->header($header);
  365. throw new HttpResponseException($response);
  366. }
  367. protected function checkParam() {
  368. $_is_json = false;
  369. $_params = $_REQUEST;
  370. $this->rq_data = $this->getParam($_params, $_is_json);
  371. if (empty($this->rq_data)) {
  372. $this->rq_data = [];
  373. }
  374. // $this->checkSign();
  375. $this->checkTime();
  376. }
  377. /**
  378. * 获取请求参数
  379. *
  380. * @param mixed $param
  381. * @param bool $is_json
  382. *
  383. * @return bool|mixed|string
  384. */
  385. public function getParam($param, $is_json = false) {
  386. if (empty($param)) {
  387. return '';
  388. }
  389. if ($is_json) {
  390. $_param = json_decode($param, true);
  391. if (JSON_ERROR_NONE != json_last_error()) {
  392. return false;
  393. }
  394. } else {
  395. foreach ($param as $_k => $_v) {
  396. if (strpos($_k, '-')) {
  397. list($_k1, $_k2) = explode('-', $_k);
  398. if (is_array($_k2)) {
  399. return false;
  400. }
  401. $_param[$_k1][$_k2] = $_v;
  402. } else {
  403. $_param[$_k] = $_v;
  404. }
  405. }
  406. }
  407. if (empty($_param)) {
  408. return false;
  409. }
  410. return $_param;
  411. }
  412. /**
  413. * @return bool|string
  414. */
  415. protected function getKey() {
  416. $_key = $this->token;
  417. if (in_array($this->device_type, ['android', 'iphone', 'ipad'])) {
  418. $_key = $this->getAppKey();
  419. }
  420. return $_key;
  421. }
  422. protected function getAppKey() {
  423. $_gl_class = new GameLogic();
  424. $_app_id = get_val($this->rq_data, 'app_id');
  425. if (empty($this->rq_data['game'])) {
  426. return false;
  427. }
  428. $_client_id = get_val($this->rq_data['game'], 'h_ver');
  429. if (empty($_client_id)) {
  430. return false;
  431. }
  432. $_client_key = $_gl_class->getVersionKey($_app_id, $_client_id);
  433. if (empty($_client_key)) {
  434. return false;
  435. }
  436. $_public_key_file = GLOBAL_CONF_PATH.'extra/key/rsa_public_key.pem';
  437. if (!file_exists($_public_key_file)) {
  438. return false;
  439. } else {
  440. $_key_content = file_get_contents($_public_key_file);
  441. }
  442. // 以下为了初始化公钥,保证公钥不管是带格式还是不带格式都可以通过验证。
  443. $_key_content = str_replace("-----BEGIN PUBLIC KEY-----", "", $_key_content);
  444. $_key_content = str_replace("-----END PUBLIC KEY-----", "", $_key_content);
  445. $_key_content = str_replace("\r\n", "", $_key_content);
  446. $_key_content = str_replace("\n", "", $_key_content);
  447. if (empty($_key_content)) {
  448. return false;
  449. }
  450. return $_client_key.'&'.$_key_content;
  451. }
  452. /**
  453. * 校验签名
  454. */
  455. protected function checkSign() {
  456. if (empty($this->device_type) || FormatConst::FORMAT_HTML == $this->response_type) {
  457. return true;
  458. }
  459. $_haV2 = new HuoApiV2();
  460. //获取client_key
  461. $_key = $this->getKey();
  462. $_haV2->setKey($_key);
  463. $_rs = $_haV2->check('api/'.$this->request->path(), $this->rq_data, $this->request->method());
  464. if (true != $_rs) {
  465. // $this->error(OrderStatus::getMsg(OrderStatus::SIGN_ERROR), '', OrderStatus::SIGN_ERROR);
  466. }
  467. }
  468. /**
  469. * 校验请求事件
  470. */
  471. protected function checkTime() {
  472. $_ts = get_val($this->rq_data, 'ts', 0);
  473. if (abs($_ts - time()) < 5) {
  474. $this->error('time is error');
  475. }
  476. }
  477. /**
  478. * 设置玩家入参
  479. *
  480. * @param bool $is_reg
  481. *
  482. * @return Mem
  483. */
  484. public function setMemData($is_reg = false) {
  485. $_mem = new Mem();
  486. $_mem->setData(get_val($this->rq_data, 'mem'));
  487. $_app_id = get_val($this->rq_data, 'app_id', 0);
  488. $_mg_mem_id = (new HuoSession($this->mem_id, $_app_id))->getMgMemId($_app_id);
  489. if (false == $is_reg) {
  490. $_mem_id = $this->mem_id;
  491. if (!empty($_mem_id)) {
  492. $_mem->setMemId($_mem_id);
  493. $_mem->setMgMemId($_mg_mem_id);
  494. $_mem_data = MemCache::ins()->getInfoById($_mem_id);
  495. $_mem->setAgentId($_mem_data['agent_id']);
  496. }
  497. }
  498. return $_mem;
  499. }
  500. /**
  501. * @return Order
  502. */
  503. public function setOrderData() {
  504. $_order = new Order();
  505. $_order->setData(get_val($this->rq_data, 'order', []));
  506. return $_order;
  507. }
  508. /**
  509. * @return Role
  510. */
  511. public function setRoleData() {
  512. $_role = new Role();
  513. $_role->setData(get_val($this->rq_data, 'role', []));
  514. return $_role;
  515. }
  516. /**
  517. * @return Crash
  518. */
  519. public function setCrashData() {
  520. $_crash = new Crash();
  521. $_crash->setData(get_val($this->rq_data, 'crash', []));
  522. return $_crash;
  523. }
  524. /**
  525. * @return Device
  526. */
  527. public function setDeviceData() {
  528. $_device = new Device();
  529. $_device->setData(get_val($this->rq_data, 'device', []));
  530. $_device->setDeviceType($this->device_type);
  531. $_device->setIp($this->request->ip());
  532. if (isset($this->rq_data['open_cnt'])) {
  533. $_device->setOpenCnt($this->rq_data['open_cnt']);
  534. // Session::set('open_cnt', $this->rq_data['open_cnt'], 'device');
  535. } else {
  536. // $_open_cnt = Session::get('open_cnt', 'device');
  537. if (empty($_open_cnt)) {
  538. $_open_cnt = 0;
  539. }
  540. $_device->setOpenCnt($_open_cnt);
  541. }
  542. $_device->setFromDevice($this->device_type);
  543. if (in_array($this->device_type, ['ipad', 'iphone'])) {
  544. $_device->setFrom(4);
  545. } else if ($this->device_type == 'android') {
  546. $_device->setFrom(3);
  547. }
  548. return $_device;
  549. }
  550. /**
  551. * @return Game
  552. */
  553. public function setGameData() {
  554. $_game = new Game();
  555. $_game->setData(get_val($this->rq_data, 'game', []));
  556. $_game->setHAppId(get_val($this->rq_data, 'app_id', 0));
  557. return $_game;
  558. }
  559. /**
  560. * @return Channel
  561. *
  562. */
  563. public function setChannelData() {
  564. $_channel = new Channel();
  565. $_channel->setData(get_val($this->rq_data, 'agent', []));
  566. $_device_data = get_val($this->rq_data, 'device', []);
  567. $_device_id = get_val($_device_data, 'device_id', '');
  568. /* 计算AgentId */
  569. $_agent_id = Commonfunc::getAgentId(
  570. 0,
  571. $_channel->getAgentGame(),
  572. $_channel->getAgentId(),
  573. $_device_id
  574. );
  575. $_channel->setAgentId($_agent_id);
  576. return $_channel;
  577. }
  578. /**
  579. * @return Event
  580. */
  581. public function setEventData() {
  582. $_event = new Event();
  583. $_event->setData(get_val($this->rq_data, 'event', []));
  584. return $_event;
  585. }
  586. public function _initializeView() {
  587. $cmfThemePath = config('cmf_theme_path');
  588. $cmfDefaultTheme = cmf_get_current_theme();
  589. $themePath = "{$cmfThemePath}{$cmfDefaultTheme}";
  590. $root = cmf_get_root();
  591. //使cdn设置生效
  592. $cdnSettings = cmf_get_option('cdn_settings');
  593. if (empty($cdnSettings['cdn_static_root'])) {
  594. $viewReplaceStr = [
  595. '__ROOT__' => $root,
  596. '__TMPL__' => "{$root}/{$themePath}",
  597. '__STATIC__' => "{$root}/static",
  598. '__WEB_ROOT__' => $root
  599. ];
  600. } else {
  601. $cdnStaticRoot = rtrim($cdnSettings['cdn_static_root'], '/');
  602. $viewReplaceStr = [
  603. '__ROOT__' => $root,
  604. '__TMPL__' => "{$cdnStaticRoot}/{$themePath}",
  605. '__STATIC__' => "{$cdnStaticRoot}/static",
  606. '__WEB_ROOT__' => $cdnStaticRoot
  607. ];
  608. }
  609. $viewReplaceStr = array_merge(config('view_replace_str'), $viewReplaceStr);
  610. config('template.view_base', "{$themePath}/");
  611. config('view_replace_str', $viewReplaceStr);
  612. $themeErrorTmpl = "{$themePath}/error.html";
  613. if (file_exists_case($themeErrorTmpl)) {
  614. config('dispatch_error_tmpl', $themeErrorTmpl);
  615. }
  616. $themeSuccessTmpl = "{$themePath}/success.html";
  617. if (file_exists_case($themeSuccessTmpl)) {
  618. config('dispatch_success_tmpl', $themeSuccessTmpl);
  619. }
  620. }
  621. /**
  622. * 加载模板输出
  623. *
  624. * @access protected
  625. *
  626. * @param string $template 模板文件名
  627. * @param array $vars 模板输出变量
  628. * @param array $replace 模板替换
  629. * @param array $config 模板参数
  630. *
  631. * @return mixed
  632. */
  633. protected function fetch($template = '', $vars = [], $replace = [], $config = []) {
  634. $template = $this->parseTemplate($template);
  635. $more = $this->getThemeFileMore($template);
  636. $this->assign('theme_vars', $more['vars']);
  637. $this->assign('theme_widgets', $more['widgets']);
  638. return parent::fetch($template, $vars, $replace, $config);
  639. }
  640. /**
  641. * 自动定位模板文件
  642. *
  643. * @access private
  644. *
  645. * @param string $template 模板文件规则
  646. *
  647. * @return string
  648. */
  649. private function parseTemplate($template) {
  650. // 分析模板文件规则
  651. $request = $this->request;
  652. // 获取视图根目录
  653. if (strpos($template, '@')) {
  654. // 跨模块调用
  655. list($module, $template) = explode('@', $template);
  656. }
  657. $viewBase = config('template.view_base');
  658. if ($viewBase) {
  659. // 基础视图目录
  660. $module = isset($module) ? $module : $request->module();
  661. $path = $viewBase.($module ? $module.DS : '');
  662. } else {
  663. $path = isset($module) ? APP_PATH.$module.DS.'view'.DS : config('template.view_path');
  664. }
  665. $depr = config('template.view_depr');
  666. if (0 !== strpos($template, '/')) {
  667. $template = str_replace(['/', ':'], $depr, $template);
  668. $controller = cmf_parse_name($request->controller());
  669. if ($controller) {
  670. if ('' == $template) {
  671. // 如果模板文件名为空 按照默认规则定位
  672. $template = str_replace('.', DS, $controller).$depr.$request->action();
  673. } elseif (false === strpos($template, $depr)) {
  674. $template = str_replace('.', DS, $controller).$depr.$template;
  675. }
  676. }
  677. } else {
  678. $template = str_replace(['/', ':'], $depr, substr($template, 1));
  679. }
  680. return $path.ltrim($template, '/').'.'.ltrim(config('template.view_suffix'), '.');
  681. }
  682. /**
  683. * 获取模板文件变量
  684. *
  685. * @param string $file
  686. * @param string $theme
  687. *
  688. * @return array
  689. */
  690. private function getThemeFileMore($file, $theme = "") {
  691. //TODO 增加缓存
  692. $theme = empty($theme) ? cmf_get_current_theme() : $theme;
  693. $themePath = config('cmf_theme_path');
  694. $file = str_replace('\\', '/', $file);
  695. $file = str_replace('//', '/', $file);
  696. $file = str_replace(['.html', '.php', $themePath.$theme."/"], '', $file);
  697. $files = Db::name('theme_file')->field('more')->where(['theme' => $theme])->where(
  698. function ($query) use ($file) {
  699. $query->where(['is_public' => 1])->whereOr(['file' => $file]);
  700. }
  701. )->select();
  702. $vars = [];
  703. $widgets = [];
  704. foreach ($files as $file) {
  705. $oldMore = json_decode($file['more'], true);
  706. if (!empty($oldMore['vars'])) {
  707. foreach ($oldMore['vars'] as $varName => $var) {
  708. $vars[$varName] = $var['value'];
  709. }
  710. }
  711. if (!empty($oldMore['widgets'])) {
  712. foreach ($oldMore['widgets'] as $widgetName => $widget) {
  713. $widgetVars = [];
  714. if (!empty($widget['vars'])) {
  715. foreach ($widget['vars'] as $varName => $var) {
  716. $widgetVars[$varName] = $var['value'];
  717. }
  718. }
  719. $widget['vars'] = $widgetVars;
  720. $widgets[$widgetName] = $widget;
  721. }
  722. }
  723. }
  724. return ['vars' => $vars, 'widgets' => $widgets];
  725. }
  726. /**
  727. * 检查是否登陆
  728. *
  729. * @param int $mem_id
  730. */
  731. public function checkLogin($mem_id = 0) {
  732. $_mem_id = $mem_id;
  733. if (empty($_mem_id)) {
  734. $_mem_id = $this->mem_id;
  735. }
  736. if (empty($_mem_id)) {
  737. $this->error('未登录');
  738. }
  739. }
  740. }