Service.php 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680
  1. <?php
  2. namespace addons\cms\library;
  3. use addons\cms\library\aip\AipContentCensor;
  4. use addons\cms\library\aip\AipNlp;
  5. use addons\cms\model\Autolink;
  6. use addons\cms\model\Diyform;
  7. use addons\cms\model\Fields;
  8. use addons\cms\model\Modelx;
  9. use addons\cms\model\Tag;
  10. use fast\Http;
  11. use fast\Random;
  12. use think\Cache;
  13. use think\Config;
  14. use think\Db;
  15. use think\Exception;
  16. use think\Hook;
  17. use think\Model;
  18. use think\model\Collection;
  19. class Service
  20. {
  21. /**
  22. * 检测内容是否合法
  23. * @param string $content 检测内容
  24. * @param string $type 类型
  25. * @return bool
  26. */
  27. public static function isContentLegal($content, $type = null)
  28. {
  29. $config = get_addon_config('cms');
  30. $type = is_null($type) ? $config['audittype'] : $type;
  31. if ($type == 'local') {
  32. // 敏感词过滤
  33. $handle = SensitiveHelper::init()->setTreeByFile(ADDON_PATH . 'cms/data/words.dic');
  34. //首先检测是否合法
  35. $isLegal = $handle->islegal($content);
  36. return $isLegal ? true : false;
  37. } elseif ($type == 'baiduyun') {
  38. $client = new AipContentCensor($config['aip_appid'], $config['aip_apikey'], $config['aip_secretkey']);
  39. $result = $client->textCensorUserDefined($content);
  40. if (!isset($result['conclusionType']) || $result['conclusionType'] > 1) {
  41. return false;
  42. }
  43. }
  44. return true;
  45. }
  46. /**
  47. * 获取标题的关键字
  48. * @param $title
  49. * @return array
  50. */
  51. public static function getContentTags($title)
  52. {
  53. $arr = [];
  54. $config = get_addon_config('cms');
  55. if ($config['nlptype'] == 'local') {
  56. !defined('_VIC_WORD_DICT_PATH_') && define('_VIC_WORD_DICT_PATH_', ADDON_PATH . 'cms/data/dict.json');
  57. $handle = new VicWord('json');
  58. $result = $handle->getAutoWord($title);
  59. foreach ($result as $index => $item) {
  60. $arr[] = $item[0];
  61. }
  62. } else {
  63. $client = new AipNlp($config['aip_appid'], $config['aip_apikey'], $config['aip_secretkey']);
  64. $result = $client->lexer($title);
  65. if (isset($result['items'])) {
  66. foreach ($result['items'] as $index => $item) {
  67. if (!in_array($item['pos'], ['v', 'vd', 'nd', 'a', 'ad', 'an', 'd', 'm', 'q', 'r', 'p', 'c', 'u', 'xc', 'w'])) {
  68. $arr[] = $item['item'];
  69. }
  70. }
  71. }
  72. }
  73. foreach ($arr as $index => $item) {
  74. if (mb_strlen($item) == 1) {
  75. unset($arr[$index]);
  76. }
  77. }
  78. return array_filter(array_unique($arr));
  79. }
  80. /**
  81. * 内容关键字自动加链接
  82. * 优先顺序为 站点配置自动链接 > 自动链接表 > 标签内链
  83. */
  84. public static function autolinks($content)
  85. {
  86. $stages = [];
  87. //先移除已有的自动链接
  88. $content = preg_replace_callback('/\<a\s*data\-rel="autolink".*?\>(.*?)\<\/a\>/i', function ($match) {
  89. return $match[1];
  90. }, $content);
  91. //存储所有A标签
  92. $content = preg_replace_callback('/\<a(.*?)href\s*=\s*(\'|")(.*?)(\'|")(.*?)\>(.*?)\<\/a\>/i', function ($match) use (&$stages) {
  93. $data = [$match[3], $match[5], $match[6]];
  94. return '<' . array_push($stages, $data) . '>';
  95. }, $content);
  96. //存在所有HTML标签
  97. $content = preg_replace_callback('/(<(?!\d+).*?>)/i', function ($match) use (&$stages) {
  98. return '<' . array_push($stages, $match[1]) . '>';
  99. }, $content);
  100. $config = get_addon_config('cms');
  101. $limit = $config['autolinks_max_replace'] ?? 2; //单一标签最大替换次数
  102. $autolinkArr = [];
  103. $tagList = Tag::where('autolink', 1)->cache(true)->where('status', 'normal')->select();
  104. foreach ($tagList as $index => $item) {
  105. $autolinkArr[$item['name']] = ['text' => $item['name'], 'type' => 'tag', 'url' => $item['fullurl']];
  106. }
  107. $autolinkList = Autolink::where('status', 'normal')->cache(true)->order('weigh DESC,id DESC')->select();
  108. foreach ($autolinkList as $index => $item) {
  109. $autolinkArr[$item['title']] = ['text' => $item['title'], 'type' => 'autolink', 'url' => $item['url'], 'target' => $item['target'], 'id' => $item['id']];
  110. }
  111. foreach ($config['autolinks'] as $text => $url) {
  112. $autolinkArr[$text] = ['text' => $text, 'type' => 'config', 'url' => $url];
  113. }
  114. $autolinkArr = array_values($autolinkArr);
  115. //字符串长的优先替换
  116. usort($autolinkArr, function ($a, $b) {
  117. if ($a['text'] == $b['text']) return 0;
  118. return (strlen($a['text']) > strlen($b['text'])) ? -1 : 1;
  119. });
  120. //替换链接
  121. foreach ($autolinkArr as $index => $item) {
  122. $content = preg_replace_callback('/(' . preg_quote($item['text'], '/') . ')/i', function ($match) use ($item, $config, &$stages) {
  123. $url = $item['type'] == 'autolink' && isset($item['id']) ? addon_url('cms/go/index', [], $config['urlsuffix'], true) . '?id=' . $item['id'] : $item['url'];
  124. $data = [$url, (isset($item['target']) && $item['target'] == 'blank' ? ' target="_blank"' : ''), $match[0]];
  125. return '<' . array_push($stages, $data) . '>';
  126. }, $content, $limit);
  127. }
  128. return preg_replace_callback('/<(\d+)>/', function ($match) use (&$stages, $config) {
  129. $data = $stages[$match[1] - 1];
  130. if (!is_array($data)) {
  131. return $data;
  132. }
  133. $url = $data[0];
  134. $urlArr = parse_url($url);
  135. //站内链接不中转,站外链接中转
  136. if (isset($urlArr['host']) && $urlArr['host'] != request()->host() && ($config['redirecturl'] ?? true)) {
  137. $url = addon_url('cms/go/index', [], $config['urlsuffix'], true) . '?' . http_build_query(['url' => $url]);
  138. }
  139. return "<a href=\"{$url}\" {$data[1]}>{$data[2]}</a>";
  140. }, $content);
  141. }
  142. /**
  143. * 推送消息通知
  144. * @param string $content 内容
  145. * @param string $type
  146. * @param string $template_id
  147. */
  148. public static function notice($content, $type = null, $template_id = null)
  149. {
  150. $config = get_addon_config('cms');
  151. $type = $type ? $type : $config['auditnotice'];
  152. $template_id = $template_id ? $template_id : $config['noticetemplateid'];
  153. try {
  154. if ($type == 'dinghorn') {
  155. //钉钉通知插件(dinghorn)
  156. Hook::listen('msg_notice', $template_id, [
  157. 'content' => $content
  158. ]);
  159. } elseif ($type == 'vbot') {
  160. //企业微信通知(vbot)
  161. Hook::listen('vbot_send_msg', $template_id, [
  162. 'content' => $content
  163. ]);
  164. } elseif ($type == 'notice') {
  165. //消息通知插件(notice)
  166. $params = [
  167. 'event' => $template_id,
  168. 'params' => [
  169. 'title' => $content,
  170. 'content' => $content,
  171. ]
  172. ];
  173. Hook::listen('notice_to_data', $params);
  174. }
  175. } catch (\Exception $e) {
  176. }
  177. }
  178. /**
  179. * 获取表字段信息
  180. * @param string $table 表名
  181. * @return array
  182. */
  183. public static function getTableFields($table)
  184. {
  185. $tagName = "cms-table-fields-{$table}";
  186. $fieldlist = Cache::get($tagName);
  187. if (!Config::get('app_debug') && $fieldlist) {
  188. return $fieldlist;
  189. }
  190. $dbname = Config::get('database.database');
  191. //从数据库中获取表字段信息
  192. $sql = "SELECT * FROM `information_schema`.`columns` WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? ORDER BY ORDINAL_POSITION";
  193. //加载主表的列
  194. $columnList = Db::query($sql, [$dbname, $table]);
  195. $fieldlist = [];
  196. foreach ($columnList as $index => $item) {
  197. $fieldlist[] = ['name' => $item['COLUMN_NAME'], 'title' => $item['COLUMN_COMMENT'], 'type' => $item['DATA_TYPE']];
  198. }
  199. Cache::set($tagName, $fieldlist);
  200. return $fieldlist;
  201. }
  202. /**
  203. * 获取指定类型的自定义字段列表
  204. */
  205. public static function getCustomFields($source, $source_id, $values = [], $conditions = [])
  206. {
  207. $fields = Fields::where('source', $source)
  208. ->where('source_id', $source_id)
  209. ->where($conditions)
  210. ->where('status', 'normal')
  211. ->order('weigh desc,id desc')
  212. ->select();
  213. foreach ($fields as $k => $v) {
  214. //优先取编辑的值,再次取默认值
  215. $v->value = $values[$v['name']] ?? (is_null($v['defaultvalue']) ? '' : $v['defaultvalue']);
  216. $v->rule = str_replace(',', '; ', $v->rule);
  217. if (in_array($v['type'], ['checkbox', 'lists', 'images'])) {
  218. $checked = '';
  219. if ($v['minimum'] && $v['maximum']) {
  220. $checked = "{$v['minimum']}~{$v['maximum']}";
  221. } elseif ($v['minimum']) {
  222. $checked = "{$v['minimum']}~";
  223. } elseif ($v['maximum']) {
  224. $checked = "~{$v['maximum']}";
  225. }
  226. if ($checked) {
  227. $v->rule .= (';checked(' . $checked . ')');
  228. }
  229. }
  230. if (in_array($v['type'], ['checkbox', 'radio']) && stripos($v->rule, 'required') !== false) {
  231. $v->rule = str_replace('required', 'checked', $v->rule);
  232. }
  233. if (in_array($v['type'], ['selects'])) {
  234. $v->extend .= (' ' . 'data-max-options="' . $v['maximum'] . '"');
  235. }
  236. }
  237. return $fields;
  238. }
  239. /**
  240. * 获取过滤列表
  241. * @param string $source 来源类型
  242. * @param int $source_id 来源ID
  243. * @param array $filter 过滤条件
  244. * @param array $params 搜索参数
  245. * @param bool $multiple 是否为复选模式
  246. * @return array
  247. */
  248. public static function getFilterList($source, $source_id, $filter, $params = [], $multiple = false)
  249. {
  250. $fieldsList = Fields::where('source', $source)
  251. ->where('source_id', $source_id)
  252. ->where('status', 'normal')
  253. ->cache(true)
  254. ->select();
  255. $filterList = [];
  256. $multiValueFields = [];
  257. $fields = [];
  258. if (in_array($source, ['model', 'diyform'])) {
  259. //查找主表启用过滤搜索的字段
  260. $model = $source == 'model' ? Modelx::get($source_id) : Diyform::get($source_id);
  261. $setting = $model->setting;
  262. if (isset($setting['filterfields'])) {
  263. foreach ($setting['filterfields'] as $index => $name) {
  264. $title = isset($setting['titlelist'][$name]) ? $setting['titlelist'][$name] : $name;
  265. $filterlist = isset($setting['filterlist'][$name]) ? $setting['filterlist'][$name] : '';
  266. $filterlist = \app\common\model\Config::decode($filterlist);
  267. if (!$filterlist) {
  268. continue;
  269. }
  270. if (in_array($name, ['special_ids', 'channel_ids', 'images', 'tags', 'keywords'])) {
  271. $multiValueFields[] = $name;
  272. }
  273. $fields[] = [
  274. 'name' => $name,
  275. 'title' => $title,
  276. 'content' => $filterlist
  277. ];
  278. }
  279. }
  280. }
  281. foreach ($fieldsList as $k => $v) {
  282. if (!$v['isfilter']) {
  283. continue;
  284. }
  285. $content = isset($v['filter_list']) && $v['filter_list'] ? $v['filter_list'] : $v['content_list'];
  286. if (!$content) {
  287. continue;
  288. }
  289. //多选值字段需要做特殊处理
  290. if (in_array($v['type'], ['selects', 'checkbox', 'array', 'selectpages'])) {
  291. $multiValueFields[] = $v['name'];
  292. }
  293. $fields[] = [
  294. 'name' => $v['name'],
  295. 'title' => $v['title'],
  296. 'content' => $content
  297. ];
  298. }
  299. $filter = array_intersect_key($filter, array_flip(array_column($fields, 'name')));
  300. foreach ($fields as $k => $v) {
  301. $content = [];
  302. $all = ['' => __('All')] + (is_array($v['content']) ? $v['content'] : []);
  303. foreach ($all as $m => $n) {
  304. $filterArr = isset($filter[$v['name']]) && $filter[$v['name']] !== '' ? ($multiple ? explode(';', $filter[$v['name']]) : [$filter[$v['name']]]) : [];
  305. $active = ($m === '' && !$filterArr) || ($m !== '' && in_array($m, $filterArr)) ? true : false;
  306. if ($active) {
  307. $current = implode(';', array_diff($filterArr, [$m]));
  308. } else {
  309. $current = $multiple ? implode(';', array_merge($filterArr, [$m])) : $m;
  310. }
  311. $prepare = $m === '' ? array_diff_key($filter, [$v['name'] => $m]) : array_merge($filter, [$v['name'] => $current]);
  312. //$url = '?' . http_build_query(array_merge(['filter' => $prepare], array_diff_key($params, ['filter' => ''])));
  313. $url = '?' . str_replace(['%2C', '%3B'], [',', ';'], http_build_query(array_merge($prepare, array_intersect_key($params, array_flip(['orderby', 'orderway', 'multiple'])))));
  314. $content[] = ['value' => $m, 'title' => $n, 'active' => $active, 'url' => $url];
  315. }
  316. $filterList[] = [
  317. 'name' => $v['name'],
  318. 'title' => $v['title'],
  319. 'content' => $content,
  320. ];
  321. }
  322. foreach ($filter as $index => &$item) {
  323. $item = is_array($item) ? $item : explode(',', str_replace(';', ',', $item));
  324. }
  325. return [$filterList, $filter, $params, $fields, $multiValueFields, $fieldsList];
  326. }
  327. /**
  328. * 获取排序列表
  329. * @param string $orderby
  330. * @param string $orderway
  331. * @param array $orders
  332. * @param array $params
  333. * @param array $fieldsList
  334. * @return array
  335. */
  336. public static function getOrderList($orderby, $orderway, $orders = [], $params = [], $fieldsList = [])
  337. {
  338. $lastOrderby = '';
  339. $lastOrderway = $orderway && in_array(strtolower($orderway), ['asc', 'desc']) ? $orderway : 'desc';
  340. foreach ($fieldsList as $index => $field) {
  341. if ($field['isorder']) {
  342. $orders[] = ['name' => $field['name'], 'field' => $field['name'], 'title' => $field['title']];
  343. }
  344. }
  345. $orderby = in_array($orderby, array_map(function ($item) {
  346. return $item['name'];
  347. }, $orders)) ? $orderby : 'default';
  348. foreach ($orders as $index => $order) {
  349. if ($orderby == $order['name']) {
  350. $lastOrderby = $order['field'];
  351. break;
  352. }
  353. }
  354. $orderList = [];
  355. foreach ($orders as $k => $v) {
  356. $url = '?' . http_build_query(array_merge($params, ['orderby' => $v['name'], 'orderway' => $v['name'] == $orderby ? ($lastOrderway == 'desc' ? 'asc' : 'desc') : 'desc']));
  357. $v['active'] = $orderby == $v['name'] ? true : false;
  358. $v['url'] = $url;
  359. $orderList[] = $v;
  360. }
  361. return [$orderList, $lastOrderby, $lastOrderway];
  362. }
  363. /**
  364. * 获取过滤的最终条件和绑定参数
  365. * @param array $filter 过滤条件
  366. * @param array $multiValueFields 多值字段
  367. * @param bool $multiple 是否为复选模式
  368. * @return array
  369. */
  370. public static function getFilterWhereBind($filter, $multiValueFields, $multiple = false)
  371. {
  372. //构造bind数据
  373. $bind = [];
  374. foreach ($filter as $field => &$item) {
  375. if (in_array($field, $multiValueFields)) {
  376. $item = !is_array($item) && stripos($item, ',') !== false ? explode(',', $item) : $item;
  377. if (is_array($item)) {
  378. foreach ($item as $index => $subitem) {
  379. $bind[$field . $index] = $subitem;
  380. }
  381. } else {
  382. $bind[$field] = $item;
  383. }
  384. }
  385. }
  386. $filterWhere = function ($query) use ($filter, $multiValueFields) {
  387. foreach ($filter as $field => $item) {
  388. $item = is_array($item) ? $item : [$item];
  389. if (in_array($field, $multiValueFields)) {
  390. $query->where(function ($query) use ($field, $item) {
  391. foreach ($item as $subindex => $subitem) {
  392. $query->whereOr("FIND_IN_SET(:" . $field . $subindex . ", `{$field}`)");
  393. }
  394. });
  395. } else {
  396. $query->where(function ($query) use ($field, $item) {
  397. foreach ($item as $subindex => $subitem) {
  398. //如果匹配区间,以~分隔
  399. if (preg_match("/[a-zA-Z0-9\.\-]+\~[a-zA-Z0-9\.\-]+/", $subitem)) {
  400. $condition = explode('~', $subitem);
  401. //判断是否时间区间
  402. $op = preg_match("/\d{4}\-\d{1,2}\-\d{1,2}/", $condition[0]) ? 'between time' : 'between';
  403. $query->whereOr($field, $op, $condition);
  404. } else {
  405. $query->whereOr($field, $subitem);
  406. }
  407. }
  408. });
  409. }
  410. }
  411. };
  412. return [$filterWhere, $bind];
  413. }
  414. /**
  415. * 获取pagelist标签参数
  416. * @param string $template
  417. * @return array
  418. */
  419. public static function getPagelistParams($template)
  420. {
  421. $config = get_addon_config('cms');
  422. $templateFile = ADDON_PATH . 'cms' . DS . 'view' . DS . $config['theme'] . $template . '.html';
  423. if (!is_file($templateFile)) {
  424. return [];
  425. }
  426. $templateContent = file_get_contents($templateFile);
  427. preg_match("/\{cms:pagelist(.*)\}/i", $templateContent, $matches);
  428. $attr = [];
  429. if ($matches) {
  430. $tagAttrText = $matches[1];
  431. preg_match_all('/\s+(?>(?P<name>[\w-]+)\s*)=(?>\s*)([\"\'])(?P<value>(?:(?!\\2).)*)\\2/is', $tagAttrText, $matches, PREG_SET_ORDER);
  432. foreach ($matches as $match) {
  433. $attr[$match['name']] = $match['value'];
  434. }
  435. unset($matches);
  436. }
  437. return $attr;
  438. }
  439. /**
  440. * 追加_text属性值
  441. * @param $fieldsContentList
  442. * @param $row
  443. */
  444. public static function appendTextAttr(&$fieldsContentList, &$row)
  445. {
  446. //附加列表字段
  447. array_walk($fieldsContentList, function ($content, $field) use (&$row) {
  448. if (isset($row[$field])) {
  449. if (isset($content[$row[$field]])) {
  450. $list = [$row[$field] => $content[$row[$field]]];
  451. } else {
  452. $keys = $values = explode(',', $row[$field]);
  453. foreach ($values as $index => &$item) {
  454. $item = isset($content[$item]) ? $content[$item] : $item;
  455. }
  456. $list = array_combine($keys, $values);
  457. }
  458. } else {
  459. $list = [];
  460. }
  461. $list = array_filter($list);
  462. $row[$field . '_text'] = implode(',', $list);
  463. $row[$field . '_list'] = $list;
  464. });
  465. }
  466. /**
  467. * 追加_text和_list后缀数据
  468. *
  469. * @param string $source
  470. * @param int $source_id
  471. * @param mixed $row
  472. * @param boolean $isMultiArray 是否为二维数组
  473. * @return mixed
  474. */
  475. public static function appendTextAndList($source, $source_id, &$row, $isMultiArray = false)
  476. {
  477. $list = Fields::where('source', $source)
  478. ->where('source_id', $source_id)
  479. ->field('id,name,type,content')
  480. ->where('status', 'normal')
  481. ->cache(true)
  482. ->select();
  483. $fieldsType = [];
  484. $fieldsList = [];
  485. $listFields = Fields::getListFields();
  486. foreach ($list as $field => $content) {
  487. $fieldsType[$content['name']] = $content['type'];
  488. if (in_array($content['type'], $listFields)) {
  489. $fieldsList[$content['name']] = $content['content_list'];
  490. }
  491. }
  492. $appendFunc = function ($field, $content, &$row) use ($fieldsType) {
  493. $fieldType = $fieldsType[$field] ?? '';
  494. if (isset($row[$field])) {
  495. if (isset($content[$row[$field]])) {
  496. $list = [$row[$field] => $content[$row[$field]]];
  497. } else {
  498. $keys = $values = explode(',', $row[$field]);
  499. foreach ($values as $index => &$item) {
  500. $item = isset($content[$item]) ? $content[$item] : $item;
  501. }
  502. $list = array_combine($keys, $values);
  503. }
  504. } else {
  505. $list = [];
  506. }
  507. $list = array_filter($list);
  508. $row[$field . '_text'] = $fieldType == 'array' ? $row[$field] : implode(',', $list);
  509. $row[$field . '_list'] = $fieldType == 'array' ? (array)json_decode($row[$field], true) : $list;
  510. };
  511. foreach ($fieldsList as $field => $content) {
  512. if ($isMultiArray) {
  513. foreach ($row as $subindex => &$subitem) {
  514. $appendFunc($field, $content, $subitem);
  515. }
  516. } else {
  517. $appendFunc($field, $content, $row);
  518. }
  519. }
  520. return $row;
  521. }
  522. /**
  523. * 获取自定义字段关联表数据
  524. * @param string $source
  525. * @param int $source_id
  526. * @param string $field
  527. * @param mixed $key
  528. * @return string
  529. */
  530. public static function getRelationFieldValue($source, $source_id, $field, $key)
  531. {
  532. $fieldInfo = Fields::where(['source' => $source, 'source_id' => $source_id, 'name' => $field])->cache(true)->find();
  533. if (!$fieldInfo) {
  534. return '';
  535. }
  536. $setting = $fieldInfo['setting'];
  537. if (!$setting || !isset($setting['table'])) {
  538. return '';
  539. }
  540. //显示的字段
  541. $field = $setting['field'];
  542. //主键
  543. $primarykey = $setting['primarykey'];
  544. //主键值
  545. $primaryvalue = $key;
  546. $field = $field ? $field : 'name';
  547. //如果有primaryvalue,说明当前是初始化传值
  548. $where = [$primarykey => ['in', $primaryvalue]];
  549. $result = [];
  550. $datalist = Db::table($setting['table'])->where($where)
  551. ->field($primarykey . "," . $field)
  552. ->select();
  553. foreach ($datalist as $index => &$item) {
  554. unset($item['password'], $item['salt']);
  555. $result[] = isset($item[$field]) ? $item[$field] : '';
  556. }
  557. return implode(',', $result);
  558. }
  559. /**
  560. * 根据类型获取Model
  561. * @param string $type
  562. * @param string $source_id
  563. * @param array $with
  564. * @return null|\think\Model
  565. * @throws Exception
  566. */
  567. public static function getModelByType($type, $source_id = '', $with = [])
  568. {
  569. if (!in_array($type, ['page', 'archives', 'special', 'diyform', 'block', 'channel'])) {
  570. throw new Exception("未找到指定类型");
  571. }
  572. $type = ucfirst(strtolower($type));
  573. $model = model("\\addons\cms\\model\\{$type}");
  574. if (!$model)
  575. return null;
  576. if ($source_id) {
  577. $model = $model->get($source_id, $with);
  578. }
  579. return $model;
  580. }
  581. /**
  582. * 获取缓存标签和时长
  583. * @param string $type
  584. * @param array $tag
  585. * @return array
  586. */
  587. public static function getCacheKeyExpire($type, $tag = [])
  588. {
  589. $config = get_addon_config('cms');
  590. $cache = !isset($tag['cache']) ? $config['cachelifetime'] : $tag['cache'];
  591. $cache = in_array($cache, ['true', 'false', true, false], true) ? (in_array($cache, ['true', true], true) ? 0 : -1) : (int)$cache;
  592. $cacheKey = $cache > -1 ? "cms-taglib-{$type}-" . md5(serialize($tag)) : false;
  593. $cacheExpire = $cache > -1 ? $cache : null;
  594. return [$cacheKey, $cacheExpire];
  595. }
  596. /**
  597. * 获取分页配置参数
  598. * @param string $type
  599. * @param array $params
  600. * @return array
  601. */
  602. public static function getPaginateParams($type, $params = [])
  603. {
  604. $row = empty($params['row']) ? 10 : (int)$params['row'];
  605. $paginate = !isset($params['paginate']) ? false : $params['paginate'];
  606. $paginateArr = explode(',', $paginate);
  607. $listRows = is_numeric($paginate) ? $paginate : (is_numeric($paginateArr[0]) ? $paginateArr[0] : $row);
  608. $simple = $paginateArr[1] ?? false;
  609. $simple = in_array($simple, ['true', 'false', true, false], true) ? in_array($simple, ['true', true], true) : (int)$simple;
  610. $config = [];
  611. $config['var_page'] = $paginateArr[2] ?? $type;
  612. $config['path'] = $paginateArr[3] ?? '';
  613. $config['fragment'] = $paginateArr[4] ?? '';
  614. $config['query'] = request()->get();
  615. $config['type'] = '\\addons\\cms\\library\\Bootstrap';
  616. return [$listRows, $simple, $config];
  617. }
  618. /**
  619. * 判断来源是否搜索引擎蜘蛛
  620. */
  621. public static function isSpider()
  622. {
  623. $config = get_addon_config('cms');
  624. $userAgent = strtolower(request()->server('HTTP_USER_AGENT', ''));
  625. $spiders = $config['spiders'] ?? [];
  626. foreach ($spiders as $name => $title) {
  627. if (stripos($userAgent, $name) !== false) {
  628. return $name;
  629. }
  630. }
  631. return '';
  632. }
  633. }