心理咨询网
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

IndexController.php 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  1. <?php
  2. /**
  3. * @copyright (C)2016-2099 Hnaoyun Inc.
  4. * @author XingMeng
  5. * @email hnxsh@foxmail.com
  6. * @date 2018年2月14日
  7. * 首页控制器
  8. */
  9. namespace app\home\controller;
  10. use core\basic\Controller;
  11. use app\home\model\ParserModel;
  12. use core\basic\Config;
  13. use core\basic\Url;
  14. class IndexController extends Controller
  15. {
  16. protected $parser;
  17. protected $model;
  18. protected $htmldir;
  19. public function __construct()
  20. {
  21. $this->parser = new ParserController();
  22. $this->model = new ParserModel();
  23. $this->htmldir = $this->config('tpl_html_dir') ? $this->config('tpl_html_dir') . '/' : '';
  24. //var_dump("开始加载");
  25. }
  26. // 空拦截器, 实现文章路由转发
  27. public function _empty()
  28. {
  29. // 地址类型
  30. $url_rule_type = $this->config('url_rule_type') ?: 3;
  31. if (PATH) { // 采用pathinfo模式及p参数伪静态模式
  32. if ($url_rule_type == 2 && stripos(URL, $_SERVER['SCRIPT_NAME']) !== false) { // 禁止伪静态时带index.php访问
  33. //_404('您访问的内容不存在,请核对后重试!');
  34. _301();
  35. }
  36. $path = PATH;
  37. } elseif ($url_rule_type == 3 && isset($_SERVER["QUERY_STRING"]) && $qs = $_SERVER["QUERY_STRING"]) { // 采用简短传参模式
  38. parse_str($qs, $output);
  39. unset($output['page']); // 去除分页
  40. if ($output && ! current($output)) { // 第一个路径参数不能有值,否则非标准路径参数
  41. $path = key($output); // 第一个参数为路径信息,注意PHP数组会自动将key点符号转换下划线
  42. } elseif (get('tag')) { // 对于兼容模式tag需要自动跳转tag独立页面
  43. $tag = new TagController();
  44. $tag->index();
  45. } elseif (get('keyword')) { // 兼容模式搜索处理
  46. $search = new SearchController();
  47. $search->index();
  48. }
  49. }
  50. // 判断是否存在后缀
  51. $url_rule_suffix = substr($this->config('url_rule_suffix'), 1);
  52. $suffix = false;
  53. $slash = false;
  54. if (preg_match('/(.*)(_|\.)' . $url_rule_suffix . '$/', $path, $matchs)) {
  55. $path = $matchs[1];
  56. $suffix = true;
  57. } elseif (preg_match('/^[\w\-\/]+\/$/', $path)) {
  58. $slash = true;
  59. $path = trim($path, '/');
  60. }
  61. //强制忽略后缀 假设后缀是存在的
  62. //后缀只是修饰 不存在不影响功能
  63. //$path 存在栏目二级目录
  64. //var_dump((int)$path);
  65. if((int)$path > 0){
  66. $suffix = true;
  67. }
  68. $path = escape_string($path);
  69. $path_arr = $path ? explode('/', $path) : array();
  70. // 开始路由
  71. if (isset($path_arr) && count($path_arr) > 0 && ( in_array('tag',$path_arr) || preg_match('/^[\w\-\/]+$/', $path)) ) {
  72. //var_dump("存在路由");
  73. //var_dump(strtolower($path_arr[0]));
  74. switch (strtolower($path_arr[0])) {
  75. case 'search':
  76. case 'keyword':
  77. $search = new SearchController();
  78. $search->index();
  79. break;
  80. case 'message':
  81. $msg = new MessageController();
  82. $msg->index();
  83. break;
  84. case 'form':
  85. $_GET['fcode'] = $path_arr[1];
  86. $form = new FormController();
  87. $form->index();
  88. break;
  89. case 'sitemap':
  90. case 'sitemap_xml':
  91. $sitemap = new SitemapController();
  92. $sitemap->index();
  93. break;
  94. case 'sitemap_txt':
  95. $sitemap = new SitemapController();
  96. $sitemap->linkTxt();
  97. break;
  98. case 'tag':
  99. $tag = new TagController();
  100. $tag->index();
  101. break;
  102. case 'member':
  103. $member = new MemberController();
  104. $member->{$path_arr[1]}();
  105. break;
  106. case 'comment':
  107. $comment = new CommentController();
  108. $comment->{$path_arr[1]}();
  109. break;
  110. case 'spider':
  111. $spider = new SpiderController();
  112. $spider->index();
  113. break;
  114. default:
  115. //var_dump(strtolower($path_arr[0]));
  116. $url_break_char = $this->config('url_break_char') ?: '_';
  117. $url_rule_content_path = $this->config('url_rule_content_path') ? true : false;
  118. $err = '';
  119. $iscontent = false;
  120. // 开始进行地址匹配
  121. if (! $suffix && ! ! $sort = $this->model->getSort($path)) {
  122. // 栏目名称,即栏目全路径匹配
  123. } elseif (preg_match('/^([a-zA-Z0-9\-\/]+)' . $url_break_char . '([0-9]+)$/i', $path, $matchs) && ! ! $sort = $this->model->getSort($matchs[1])) {
  124. // 栏目名称_分页,栏目分页的情况
  125. define('CMS_PAGE_CUSTOM', true); // 设置走自定义CMS分页
  126. $_GET['page'] = $matchs[2]; // 设置分页参数
  127. } else {
  128. //var_dump(strtolower($path_arr[0]));
  129. if ($url_rule_content_path && ! ! $data = $this->model->getContent($path)) {
  130. //var_dump(strtolower($path_arr[0]));
  131. $iscontent = true; // 短路径情况
  132. } elseif (! $url_rule_content_path) {
  133. //var_dump(strtolower($path_arr[0]));
  134. // 详情页至少是2级,对地址进行栏目和内容路径拆分,访问详情页
  135. $part1 = dirname($path);
  136. $part2 = basename($path);
  137. while ($part1 != '.') {
  138. if ((! ! $sort = $this->model->getSort($part1)) && ! ! $data = $this->model->getContent($part2)) {
  139. // 栏目名称/内容名称或ID
  140. $iscontent = true;
  141. $scode = $sort->scode;
  142. break;
  143. } elseif (preg_match('/^([a-zA-Z0-9\-\/]+)' . $url_break_char . '([0-9]+)$/i', $part1, $matchs) && ! ! $model = $this->model->checkModelUrlname($matchs[1])) {
  144. // 模型名称_栏目ID/内容名称或ID
  145. $data = $this->model->getContent($part2);
  146. $iscontent = true;
  147. $scode = $matchs[2];
  148. // 限制串模型多路径
  149. if (! ! $data->urlname && $matchs[1] != $data->urlname) {
  150. $err = true;
  151. }
  152. break;
  153. } else {
  154. $part2 = basename($part1) . '/' . $part2;
  155. $part1 = dirname($part1);
  156. }
  157. }
  158. // 限制串栏目多路径
  159. if ($scode != $data->scode) {
  160. $err = true;
  161. }
  162. // 限制串内容ID及名称多路径
  163. if (! ! $data->filename && $part2 != $data->filename) {
  164. $err = true;
  165. }
  166. }
  167. // 执行未配置栏目名称但是配置了模型路径的情况路径匹配
  168. if (! $iscontent) {
  169. //var_dump(strtolower($path_arr[0]));
  170. preg_match('/^([a-zA-Z0-9\-\/]+)(' . $url_break_char . '([0-9]+))?' . $url_break_char . '([0-9]+)$/i', $path, $matchs);
  171. if ($matchs[2] && $model = $this->model->checkModelUrlname($matchs[1])) {
  172. // 模型名称_栏目ID_分页
  173. define('CMS_PAGE_CUSTOM', false);
  174. $sort = $this->model->getSort($matchs[3]);
  175. $_GET['page'] = $matchs[4]; // 分页
  176. } elseif (! ! $model = $this->model->checkModelUrlname($matchs[1])) {
  177. // 模型名称_栏目ID
  178. $sort = $this->model->getSort($matchs[4]);
  179. }
  180. // 限制串模型和栏目名称多路径,当栏目名称不为空时不允许使用模型路径
  181. if ($sort->filename != '') {
  182. $err = true;
  183. }
  184. // 限制串模型多路径
  185. if (! ! $sort->urlname && $matchs[1] != $sort->urlname) {
  186. $err = true;
  187. }
  188. }
  189. }
  190. if ($iscontent) {
  191. //var_dump(strtolower($path_arr[0]));
  192. define('CMS_PAGE', false); // 使用普通分页处理模型
  193. //var_dump($suffix);
  194. if (! ! $data && $suffix && ! $err) {
  195. $this->getContentPage($data);
  196. } else {
  197. //var_dump(strtolower($path_arr[0]));
  198. //_404('您访问的内容不存在,请核对后重试!');
  199. _301();
  200. }
  201. } else {
  202. define('CMS_PAGE', true); // 使用cms分页处理模型
  203. if (! ! $sort && ! $suffix && ! $err) {
  204. if ($sort->type == 1) {
  205. $this->getAboutPage($sort);
  206. } else {
  207. $this->getListPage($sort);
  208. }
  209. } else {
  210. //_404('您访问的页面不存在,请核对后重试!');
  211. _301();
  212. }
  213. }
  214. }
  215. } else {
  216. //var_dump("不存在路由");
  217. if(SITE_DIR == ''){
  218. //一级目录
  219. $this->urlJump($url_rule_type,false);
  220. } else {
  221. //二级目录
  222. $this->urlJump($url_rule_type,true);
  223. }
  224. }
  225. //var_dump("f555e");
  226. }
  227. // 首页
  228. private function getIndexPage()
  229. {
  230. $cur_city = cookie('city');
  231. //tyqngp
  232. //var_dump($cur_city);
  233. //var_dump(get_http_url());
  234. $domain_url = get_http_url();
  235. $ap = explode('.',$domain_url);
  236. if($ap[1] == 'cn' || $ap[1] == 'com'){
  237. $aps = $ap[0];
  238. $aps = str_replace('https://', '', $aps);
  239. $aps = str_replace('http://', '', $aps);
  240. }else{
  241. $aps = $ap[1];
  242. }
  243. //var_dump($aps);
  244. if($cur_city == $aps){
  245. //城市页面
  246. $content = parent::parser($this->htmldir . 'city.html'); // 框架标签解析
  247. }else{
  248. //主页
  249. $content = parent::parser($this->htmldir . 'index.html'); // 框架标签解析
  250. }
  251. $content = $this->parser->parserBefore($content); // CMS公共标签前置解析
  252. if( !! $cur_city ){ //如果是分站
  253. $citys = Config::get('citys');
  254. $city = $citys[$cur_city];
  255. $content = str_replace('{pboot:pagetitle}', $city['seo_title']?:($this->config('index_title') ?: '{pboot:sitetitle}-{pboot:sitesubtitle}'), $content);
  256. $content = str_replace('{pboot:pagekeywords}', $city['seo_keywords']?:'{pboot:sitekeywords}', $content);
  257. $content = str_replace('{pboot:pagedescription}', $city['seo_description']?:'{pboot:sitedescription}', $content);
  258. }else{
  259. $content = str_replace('{pboot:pagetitle}', $this->config('index_title') ?: '{pboot:sitetitle}-{pboot:sitesubtitle}', $content);
  260. }
  261. $content = $this->parser->parserPositionLabel($content, - 1, '首页', SITE_INDEX_DIR . '/'); // CMS当前位置标签解析
  262. $content = $this->parser->parserSpecialPageSortLabel($content, 0, '', SITE_INDEX_DIR . '/'); // 解析分类标签
  263. $content = $this->parser->parserAfter($content); // CMS公共标签后置解析
  264. $this->cache($content, true);
  265. }
  266. // 列表
  267. private function getListPage($sort)
  268. {
  269. // 调用栏目语言与当前语言不一致时,自动切换语言
  270. if ($sort->acode != get_lg() && Config::get('lgautosw') !== '0') {
  271. cookie('lg', $sort->acode);
  272. }
  273. if ($sort->listtpl) {
  274. $this->checkPageLevel($sort->gcode, $sort->gtype, $sort->gnote);
  275. $content = parent::parser($this->htmldir . $sort->listtpl); // 框架标签解析
  276. $content = $this->parser->parserBefore($content); // CMS公共标签前置解析
  277. $pagetitle = $sort->title ? "{sort:title}" : "{sort:name}"; // 页面标题
  278. $content = str_replace('{pboot:pagetitle}', $this->config('list_title') ?: ($pagetitle . '-{pboot:sitetitle}-{pboot:sitesubtitle}'), $content);
  279. $content = str_replace('{pboot:pagekeywords}', '{sort:keywords}', $content);
  280. $content = str_replace('{pboot:pagedescription}', '{sort:description}', $content);
  281. $content = $this->parser->parserPositionLabel($content, $sort->scode); // CMS当前位置标签解析
  282. $content = $this->parser->parserSortLabel($content, $sort); // CMS分类信息标签解析
  283. $content = $this->parser->parserListLabel($content, $sort->scode); // CMS分类列表标签解析
  284. $content = $this->parser->parserAfter($content); // CMS公共标签后置解析
  285. } else {
  286. error('请到后台设置分类栏目列表页模板!');
  287. }
  288. $this->cache($content, true);
  289. }
  290. // 详情页
  291. private function getContentPage($data)
  292. {
  293. // 调用内容语言与当前语言不一致时,自动切换语言
  294. if ($data->acode != get_lg() && Config::get('lgautosw') !== '0') {
  295. cookie('lg', $data->acode);
  296. }
  297. // 读取模板
  298. if (! ! $sort = $this->model->getSort($data->scode)) {
  299. if ($sort->contenttpl) {
  300. $this->checkPageLevel($sort->gcode, $sort->gtype, $sort->gnote); // 检查栏目权限
  301. $this->checkPageLevel($data->gcode, $data->gtype, $data->gnote); // 检查内容权限
  302. $content = parent::parser($this->htmldir . $sort->contenttpl); // 框架标签解析
  303. $content = $this->parser->parserBefore($content); // CMS公共标签前置解析
  304. $content = str_replace('{pboot:pagetitle}', $this->config('content_title') ?: '{content:title}-{sort:name}-{pboot:sitetitle}-{pboot:sitesubtitle}', $content);
  305. $content = str_replace('{pboot:pagekeywords}', '{content:keywords}', $content);
  306. $content = str_replace('{pboot:pagedescription}', '{content:description}', $content);
  307. $content = $this->parser->parserPositionLabel($content, $sort->scode); // CMS当前位置标签解析
  308. $content = $this->parser->parserSortLabel($content, $sort); // CMS分类信息标签解析
  309. $content = $this->parser->parserCurrentContentLabel($content, $sort, $data); // CMS内容标签解析
  310. $content = $this->parser->parserCommentLabel($content); // 文章评论
  311. $content = $this->parser->parserAfter($content); // CMS公共标签后置解析
  312. } else {
  313. error('请到后台设置分类栏目内容页模板!');
  314. }
  315. } else {
  316. //_404('您访问内容的分类已经不存在,请核对后再试!');
  317. _301();
  318. }
  319. $this->cache($content, true);
  320. }
  321. // 单页
  322. private function getAboutPage($sort)
  323. {
  324. // 调用栏目语言与当前语言不一致时,自动切换语言
  325. if ($sort->acode != get_lg() && Config::get('lgautosw') !== '0') {
  326. cookie('lg', $sort->acode);
  327. }
  328. // 读取数据
  329. if (! $data = $this->model->getAbout($sort->scode)) {
  330. //_404('您访问的内容不存在,请核对后重试!');
  331. _301();
  332. }
  333. if ($sort->contenttpl) {
  334. $this->checkPageLevel($sort->gcode, $sort->gtype, $sort->gnote);
  335. $content = parent::parser($this->htmldir . $sort->contenttpl); // 框架标签解析
  336. $content = $this->parser->parserBefore($content); // CMS公共标签前置解析
  337. $pagetitle = $sort->title ? "{sort:title}" : "{content:title}"; // 页面标题
  338. $content = str_replace('{pboot:pagetitle}', $this->config('about_title') ?: ($pagetitle . '-{pboot:sitetitle}-{pboot:sitesubtitle}'), $content);
  339. $content = str_replace('{pboot:pagekeywords}', '{content:keywords}', $content);
  340. $content = str_replace('{pboot:pagedescription}', '{content:description}', $content);
  341. $content = $this->parser->parserPositionLabel($content, $sort->scode); // CMS当前位置标签解析
  342. $content = $this->parser->parserSortLabel($content, $sort); // CMS分类信息标签解析
  343. $content = $this->parser->parserCurrentContentLabel($content, $sort, $data); // CMS内容标签解析
  344. $content = $this->parser->parserCommentLabel($content); // 文章评论
  345. $content = $this->parser->parserAfter($content); // CMS公共标签后置解析
  346. } else {
  347. error('请到后台设置分类栏目内容页模板!');
  348. }
  349. $this->cache($content, true);
  350. }
  351. // 检查页面权限
  352. private function checkPageLevel($gcode, $gtype, $gnote)
  353. {
  354. if ($gcode) {
  355. $deny = false;
  356. $gtype = $gtype ?: 4;
  357. switch ($gtype) {
  358. case 1:
  359. if ($gcode <= session('pboot_gcode')) {
  360. $deny = true;
  361. }
  362. break;
  363. case 2:
  364. if ($gcode < session('pboot_gcode')) {
  365. $deny = true;
  366. }
  367. break;
  368. case 3:
  369. if ($gcode != session('pboot_gcode')) {
  370. $deny = true;
  371. }
  372. break;
  373. case 4:
  374. if ($gcode > session('pboot_gcode')) {
  375. $deny = true;
  376. }
  377. break;
  378. case 5:
  379. if ($gcode >= session('pboot_gcode')) {
  380. $deny = true;
  381. }
  382. break;
  383. }
  384. if ($deny) {
  385. $gnote = $gnote ?: '您的权限不足,无法浏览本页面!';
  386. if (session('pboot_uid')) { // 已经登录
  387. error($gnote);
  388. } else {
  389. if ($this->config('login_no_wait')) {
  390. location(Url::home('member/login', null, "backurl=" . urlencode(get_current_url())));
  391. } else {
  392. error($gnote, Url::home('member/login', null, "backurl=" . urlencode(get_current_url())));
  393. }
  394. }
  395. }
  396. }
  397. }
  398. //首页跳转并过滤注入字符
  399. /*
  400. * @param $type url模式
  401. * @param $isSecSiteDir 是否为二级目录 boolean
  402. * */
  403. private function urlJump($type, $isSecSiteDir){
  404. $http = is_https() ? 'https://' : 'http://';
  405. $matches1 = '';
  406. switch ($type){
  407. //普通模式
  408. case 1:
  409. $preg1 = '';
  410. if($isSecSiteDir === true){
  411. if($_SERVER['REQUEST_URI'] == SITE_DIR . '/index.php'){
  412. $preg1 = '/^\/.*?\/index.php/';
  413. } elseif($_SERVER['REQUEST_URI'] == '/index.php'){
  414. $preg1 = '/^\/index.php/';
  415. }
  416. } else {
  417. $preg1 = '/^\/index.php/';
  418. }
  419. preg_match($preg1,$_SERVER['REQUEST_URI'],$matches1);
  420. break;
  421. //伪静态
  422. case 2:
  423. $preg2 = '';
  424. if($isSecSiteDir === true){
  425. if($_SERVER['REQUEST_URI'] == SITE_DIR . '/'){
  426. $preg2 = '/^\/.*/';
  427. } elseif($_SERVER['REQUEST_URI'] == '/'){
  428. $preg2 = '/^\/$/';
  429. }
  430. } else {
  431. $preg2 = '/^\/.*/';
  432. }
  433. preg_match($preg2,$_SERVER['REQUEST_URI'],$matches1);
  434. break;
  435. //兼容模式
  436. case 3:
  437. $preg3 = '';
  438. if($isSecSiteDir === true){
  439. if(strpos($_SERVER['REQUEST_URI'], SITE_DIR) === 0){
  440. $preg3 = '/(^\/.*?\/index.php)|(^\/.*)/';
  441. } elseif(strpos($_SERVER['REQUEST_URI'], '/') === 0){
  442. $preg3 = '/(^\/index.php)|(^\/)/';
  443. }
  444. } else {
  445. $preg3 = '/(^\/index.php)|(^\/)/';
  446. }
  447. preg_match($preg3,$_SERVER['REQUEST_URI'],$matches1);
  448. break;
  449. }
  450. if($matches1[0]){
  451. if($_SERVER['REQUEST_URI'] == $matches1[0]){
  452. $this->getIndexPage();
  453. } else {
  454. //读取后台首页404访问配置
  455. if($this->config('url_index_404') == 1){
  456. // _404('您访问的页面不存在,请核对后重试!');
  457. _301();
  458. }
  459. header("Location: " . $http . $_SERVER['HTTP_HOST'] . $matches1[0], true, 301);
  460. }
  461. } else {
  462. if( file_exists(ROOT_PATH . '/data/city.lock') ){
  463. $this->getIndexPage();
  464. }else{
  465. //_404('您访问的页面不存在,请核对后重试!');
  466. _301();
  467. }
  468. }
  469. }
  470. }