function.php 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  1. <?php
  2. use think\facade\Cache;
  3. use think\facade\Cookie;
  4. use think\facade\Db;
  5. use think\facade\Request;
  6. function cms_cache($name, $value = '', $options = null)
  7. {
  8. static $cache = '';
  9. if (empty($cache)) {
  10. $cache = \addons\cms\library\Cache_factory::instance();
  11. }
  12. if ('' === $value) {
  13. if (false !== strpos($name, '.')) {
  14. $vars = explode('.', $name);
  15. $data = $cache->get($vars[0]);
  16. return is_array($data) ? $data[$vars[1]] : $data;
  17. }
  18. return $cache->get($name);
  19. } elseif (is_null($value)) {
  20. return $cache->remove($name);
  21. } else {
  22. if (is_array($options)) {
  23. $expire = $options['expire'] ?? null;
  24. } else {
  25. $expire = is_numeric($options) ? $options : null;
  26. }
  27. return $cache->set($name, $value, $expire);
  28. }
  29. }
  30. function getModel($modelid, $name = '')
  31. {
  32. if (empty($modelid) || !is_numeric($modelid)) {
  33. return false;
  34. }
  35. $key = 'getModel_' . $modelid;
  36. $cache = Cache::get($key);
  37. if ($cache === 'false') {
  38. return false;
  39. }
  40. if (empty($cache)) {
  41. $cache = Db::name('cms_model')->find($modelid);
  42. if (empty($cache)) {
  43. Cache::set($key, 'false', 60);
  44. return false;
  45. }
  46. Cache::set($key, $cache, 3600);
  47. }
  48. return is_null($name) ? $cache : $cache[$name];
  49. }
  50. function cms_enabled_regions()
  51. {
  52. static $regions = null;
  53. if ($regions === null) {
  54. $regions = Db::name('region')
  55. ->where('is_enabled', 1)
  56. ->order('is_default desc,sort asc,id asc')
  57. ->select()
  58. ->toArray();
  59. foreach ($regions as &$region) {
  60. $region['code'] = strtoupper((string)($region['code'] ?? ''));
  61. $region['lang'] = strtolower((string)($region['lang'] ?? ''));
  62. }
  63. unset($region);
  64. }
  65. return $regions;
  66. }
  67. function cms_default_region()
  68. {
  69. static $default = null;
  70. if ($default !== null) {
  71. return $default;
  72. }
  73. $default = Db::name('region')
  74. ->where('is_enabled', 1)
  75. ->where('is_default', 1)
  76. ->find();
  77. if (!$default) {
  78. $default = Db::name('region')
  79. ->where('is_enabled', 1)
  80. ->order('sort asc,id asc')
  81. ->find();
  82. }
  83. if ($default) {
  84. $default['code'] = strtoupper((string)($default['code'] ?? ''));
  85. $default['lang'] = strtolower((string)($default['lang'] ?? ''));
  86. }
  87. return $default ?: null;
  88. }
  89. function cms_find_region($code = '', $lang = '')
  90. {
  91. $code = strtoupper(trim((string)$code));
  92. $lang = strtolower(trim((string)$lang));
  93. foreach (cms_enabled_regions() as $region) {
  94. if ($code !== '' && strtoupper((string)$region['code']) === $code) {
  95. return $region;
  96. }
  97. }
  98. if ($lang !== '') {
  99. $defaultRegion = cms_default_region();
  100. if ($defaultRegion && strtolower((string)($defaultRegion['lang'] ?? '')) === $lang) {
  101. return $defaultRegion;
  102. }
  103. foreach (cms_enabled_regions() as $region) {
  104. if (strtolower((string)$region['lang']) === $lang) {
  105. return $region;
  106. }
  107. }
  108. }
  109. return null;
  110. }
  111. function cms_path_region_code()
  112. {
  113. static $code = null;
  114. if ($code !== null) {
  115. return $code;
  116. }
  117. $pathinfo = trim(request()->pathinfo(), '/');
  118. if ($pathinfo === '') {
  119. $code = '';
  120. return $code;
  121. }
  122. $segments = explode('/', $pathinfo);
  123. $first = strtoupper(trim((string)($segments[0] ?? '')));
  124. if ($first !== '' && cms_find_region($first)) {
  125. $code = $first;
  126. return $code;
  127. }
  128. $code = '';
  129. return $code;
  130. }
  131. function cms_current_region()
  132. {
  133. static $region = false;
  134. if ($region !== false) {
  135. return $region;
  136. }
  137. $request = request();
  138. $requestRegionCode = strtoupper((string)$request->param('region/s', ''));
  139. $cookieRegionCode = strtoupper((string)Cookie::get('site_region', ''));
  140. $pathRegionCode = cms_path_region_code();
  141. $region = null;
  142. if ($requestRegionCode !== '') {
  143. $region = cms_find_region($requestRegionCode);
  144. }
  145. if (!$region && $cookieRegionCode !== '') {
  146. $region = cms_find_region($cookieRegionCode);
  147. }
  148. if (!$region && $pathRegionCode !== '') {
  149. $region = cms_find_region($pathRegionCode);
  150. }
  151. if (!$region) {
  152. $region = cms_default_region();
  153. }
  154. if (!$region) {
  155. $defaultLang = cms_default_lang();
  156. $region = ['id' => 0, 'name' => strtoupper($defaultLang), 'code' => strtoupper($defaultLang), 'lang' => $defaultLang];
  157. }
  158. if (!empty($region['code'])) {
  159. Cookie::set('site_region', strtoupper((string)$region['code']));
  160. }
  161. $region['code'] = strtoupper((string)($region['code'] ?? ''));
  162. $region['lang'] = strtolower((string)($region['lang'] ?? cms_default_lang()));
  163. $region = $region;
  164. return $region;
  165. }
  166. function cms_region_lang($region, $fallback = 'cn')
  167. {
  168. $fallback = strtolower(trim((string)$fallback));
  169. if (is_array($region)) {
  170. $lang = strtolower(trim((string)($region['lang'] ?? '')));
  171. } else {
  172. $lang = '';
  173. }
  174. if ($lang !== '' && Db::name('lang')->where(['mark' => $lang, 'is_enabled' => 1])->count()) {
  175. return $lang;
  176. }
  177. return $fallback !== '' ? $fallback : cms_default_lang();
  178. }
  179. function cms_lang_by_region_code($regionCode = '', $fallback = 'cn')
  180. {
  181. $fallback = strtolower(trim((string)$fallback));
  182. $region = cms_find_region($regionCode);
  183. if ($region) {
  184. return cms_region_lang($region, $fallback);
  185. }
  186. return $fallback !== '' ? $fallback : cms_default_lang();
  187. }
  188. function cms_current_region_lang($fallback = 'cn')
  189. {
  190. $fallback = strtolower(trim((string)$fallback));
  191. return cms_region_lang(cms_current_region(), $fallback);
  192. }
  193. function cms_region_display_name($region)
  194. {
  195. if (!is_array($region)) {
  196. return '';
  197. }
  198. $name = trim((string)($region['name'] ?? ''));
  199. $lang = cms_region_lang($region, '');
  200. if ($name === '') {
  201. $name = strtoupper((string)($region['code'] ?? ''));
  202. }
  203. $langLabel = cms_region_lang_label($lang);
  204. return $name . ($langLabel ? ' (' . $langLabel . ')' : '');
  205. }
  206. function cms_region_lang_label($lang)
  207. {
  208. static $langNameMap = null;
  209. $lang = strtolower(trim((string)$lang));
  210. if ($lang === '') {
  211. return '';
  212. }
  213. if ($langNameMap === null) {
  214. $langNameMap = Db::name('lang')
  215. ->where('is_enabled', 1)
  216. ->column('name', 'mark');
  217. $langNameMap = array_change_key_case((array)$langNameMap, CASE_LOWER);
  218. }
  219. $label = trim((string)($langNameMap[$lang] ?? ''));
  220. return $label !== '' ? $label : strtoupper($lang);
  221. }
  222. function cms_region_shop_url($region, $fallback = '')
  223. {
  224. if (empty($region) || !is_array($region)) {
  225. return (string)$fallback;
  226. }
  227. foreach (['shopurl', 'shop_url', 'mallurl', 'mall_url', 'storeurl', 'store_url'] as $field) {
  228. $value = trim((string)($region[$field] ?? ''));
  229. if ($value !== '') {
  230. return $value;
  231. }
  232. }
  233. return (string)$fallback;
  234. }
  235. function cms_default_lang()
  236. {
  237. static $default = null;
  238. if ($default === null) {
  239. $default = Db::name('lang')->where('is_default', 1)->value('mark') ?: 'cn';
  240. }
  241. return strtolower($default);
  242. }
  243. function cms_html_lang($lang = null)
  244. {
  245. $lang = strtolower(trim((string)($lang ?: cms_current_lang())));
  246. if ($lang === '') {
  247. $lang = cms_default_lang();
  248. }
  249. static $codeMap = null;
  250. if ($codeMap === null) {
  251. $codeMap = Db::name('lang')
  252. ->where('is_enabled', 1)
  253. ->column('code', 'mark');
  254. $codeMap = array_change_key_case((array)$codeMap, CASE_LOWER);
  255. }
  256. return trim((string)($codeMap[$lang] ?? $lang));
  257. }
  258. function cms_current_lang()
  259. {
  260. static $lang = null;
  261. if ($lang !== null) {
  262. return $lang;
  263. }
  264. $lang = cms_current_region_lang(cms_default_lang());
  265. return $lang;
  266. }
  267. function getCategory($cat, $fields = '', $newCache = false)
  268. {
  269. $url_mode = get_addon_config('cms')['site_url_mode'];
  270. if (empty($cat)) {
  271. return false;
  272. }
  273. $lang = cms_current_lang();
  274. $field = is_numeric($cat) ? 'id' : 'catdir';
  275. $key = 'getCategory_' . $cat . '_' . $lang;
  276. if ($newCache) {
  277. Cache::delete($key, null);
  278. }
  279. $cache = Cache::get($key);
  280. if ($cache === 'false') {
  281. return false;
  282. }
  283. if (empty($cache)) {
  284. $cache = \addons\cms\model\Category::where($field, $cat)->findOrEmpty()->toArray();
  285. if (empty($cache)) {
  286. Cache::tag('cms')->set($key, 'false', 60);
  287. return false;
  288. }
  289. $defaultLang = cms_default_lang();
  290. $translate = Db::name('cms_category_data')->where(['catid' => $cache['id'], 'lang' => $lang])->find();
  291. if (!$translate && $lang !== $defaultLang) {
  292. $translate = Db::name('cms_category_data')->where(['catid' => $cache['id'], 'lang' => $defaultLang])->find();
  293. }
  294. if ($translate) {
  295. $cache['catname'] = $translate['catname'] ?: ($cache['catname'] ?? '');
  296. $cache['description'] = $translate['description'] ?: ($cache['description'] ?? '');
  297. $cache['setting']['meta_title'] = $translate['meta_title'] ?: ($cache['setting']['meta_title'] ?? '');
  298. $cache['setting']['meta_keywords'] = $translate['meta_keywords'] ?: ($cache['setting']['meta_keywords'] ?? '');
  299. $cache['setting']['meta_description'] = $translate['meta_description'] ?: ($cache['setting']['meta_description'] ?? '');
  300. $cache['lang'] = $translate['lang'];
  301. } else {
  302. $cache['lang'] = $defaultLang;
  303. }
  304. $urlField = 1 == $url_mode ? 'id' : 'catdir';
  305. $cache['url'] = buildCatUrl($cache[$urlField], $cache['url']);
  306. Cache::tag('cms')->set($key, $cache, 3600);
  307. }
  308. if ($fields) {
  309. if (false !== strpos($fields, '.')) {
  310. $vars = explode('.', $fields);
  311. return $cache[$vars[0]][$vars[1]];
  312. }
  313. return $cache[$fields];
  314. }
  315. return $cache;
  316. }
  317. function filters($modelid, $catid)
  318. {
  319. $url_mode = get_addon_config('cms')['site_url_mode'];
  320. $data = get_filters_field($modelid);
  321. Request::filter('trim,strip_tags');
  322. $param = Request::except(['addon', 'controller', 'action']);
  323. unset($param['catid'], $param['catdir'], $param['page']);
  324. $conditionParam = [];
  325. foreach ($data as $name => $rs) {
  326. $data[$name]['options'][0] = '不限';
  327. $ifradio = 'checkbox' == $data[$name]['type'] ? false : true;
  328. if ($ifradio) {
  329. if (!empty($param[$name])) {
  330. $conditionParam[$name]['options'][$param[$name]]['active'] = true;
  331. $nowParam = $param;
  332. $nowParam[$name] = '';
  333. $conditionParam[$name]['options'][$param[$name]]['param'] = paramencode($nowParam);
  334. }
  335. } else {
  336. if (!empty($param[$name])) {
  337. $paramContent = explode('_', $param[$name]);
  338. foreach ($paramContent as $k => $v) {
  339. $nowParamContent = $paramContent;
  340. unset($nowParamContent[$k]);
  341. $nowParam = $param;
  342. $nowParam[$name] = implode('_', $nowParamContent);
  343. $conditionParam[$name]['options'][$v]['active'] = true;
  344. $conditionParam[$name]['options'][$v]['param'] = paramencode($nowParam);
  345. }
  346. }
  347. }
  348. $conditionParam[$name]['title'] = $rs['title'];
  349. $conditionParam[$name]['name'] = $rs['name'];
  350. foreach ($data[$name]['options'] as $k => $v) {
  351. $conditionParam[$name]['options'][$k]['title'] = $v;
  352. if (!isset($conditionParam[$name]['options'][$k]['active'])) {
  353. $conditionParam[$name]['options'][$k]['active'] = 0;
  354. $nowParam = $param;
  355. if ($ifradio) {
  356. $nowParam[$name] = $k;
  357. } else {
  358. $nowParam[$name] = empty($param[$name]) || !$k ? $k : $param[$name] . '_' . $k;
  359. }
  360. $conditionParam[$name]['options'][$k]['param'] = paramencode($nowParam);
  361. }
  362. if ($url_mode == 1) {
  363. $field = ':catid';
  364. } else {
  365. $field = ':catdir';
  366. $catid = getCategory($catid, 'catdir');
  367. }
  368. $newParam = $conditionParam[$name]['options'][$k]['param'];
  369. $conditionParam[$name]['options'][$k]['url'] = cms_lang_url(addon_url('cms/index/lists', [$field => $catid])) . ($newParam ? '?' . $newParam : '');
  370. ksort($conditionParam[$name]['options']);
  371. }
  372. if (!isset($param[$rs['name']]) && empty($param[$rs['name']])) {
  373. $conditionParam[$name]['options'][0]['active'] = true;
  374. }
  375. }
  376. return $conditionParam;
  377. }
  378. function structure_filters_sql($modelid)
  379. {
  380. $data = get_filters_field($modelid);
  381. $fields_key = array_keys($data);
  382. $sql = '`status` = \'1\'';
  383. $param = Request::param();
  384. foreach ($param as $k => $r) {
  385. if (isset($data[$k]['type']) && in_array($k, $fields_key) && intval($r) != 0) {
  386. if ('radio' == $data[$k]['type']) {
  387. $sql .= " AND `$k` = '$r'";
  388. } elseif ('checkbox' == $data[$k]['type']) {
  389. if (strpos($r, '_')) {
  390. $r = explode('_', $r);
  391. $flag = [];
  392. foreach ($r as $val) {
  393. $flag[] = "FIND_IN_SET($val,`$k`)";
  394. }
  395. $sql .= ' AND (' . implode(' OR ', $flag) . ')';
  396. } else {
  397. $sql .= " AND FIND_IN_SET($r,`$k`)";
  398. }
  399. }
  400. }
  401. }
  402. return $sql;
  403. }
  404. function get_filters_field($modelid)
  405. {
  406. static $filters_data = [];
  407. if ($filters_data) {
  408. return $filters_data;
  409. }
  410. $options = cms_cache('ModelField')[$modelid];
  411. foreach ($options as $_v) {
  412. if (isset($_v['filtertype']) && $_v['filtertype']) {
  413. $_v['options'] = parse_attr($_v['options']);
  414. } else {
  415. continue;
  416. }
  417. $filters_data[$_v['name']] = array_intersect_key($_v, array_flip(['name', 'title', 'type', 'options']));
  418. }
  419. return $filters_data;
  420. }
  421. function paramencode($arr)
  422. {
  423. $str = '';
  424. if (!empty($arr)) {
  425. foreach ($arr as $key => $vo) {
  426. if (!empty($vo)) {
  427. $str .= $key . '=' . $vo . '&';
  428. }
  429. }
  430. $str = $str ? substr($str, 0, -1) : '';
  431. }
  432. return $str;
  433. }
  434. function seo($catid = '', $title = '', $description = '', $keyword = '')
  435. {
  436. if (!empty($title)) {
  437. $title = strip_tags($title);
  438. }
  439. if (!empty($description)) {
  440. $description = strip_tags($description);
  441. }
  442. if (!empty($keyword)) {
  443. $keyword = str_replace(' ', ',', strip_tags($keyword));
  444. }
  445. $site = get_addon_config('cms');
  446. $lang = cms_current_lang();
  447. $defaultLang = cms_default_lang();
  448. if ($lang && $lang !== $defaultLang) {
  449. $translate = Db::name('cms_config_data')->where('lang', $lang)->find();
  450. if ($translate) {
  451. foreach (['site_name', 'site_title', 'site_keyword', 'site_description'] as $field) {
  452. if (!empty($translate[$field])) {
  453. $site[$field] = $translate[$field];
  454. }
  455. }
  456. }
  457. }
  458. if (!empty($catid)) {
  459. $cat = getCategory($catid);
  460. }
  461. $seo['site_title'] = !empty($site['site_title']) ? $site['site_title'] : $site['site_name'];
  462. $seo['keyword'] = !empty($keyword) ? $keyword : $site['site_keyword'];
  463. $seo['description'] = !empty($description) ? $description : (($cat['setting']['meta_description'] ?? '') ?: ($site['site_description'] ?? ''));
  464. $seo['title'] = (!empty($title) ? $title . ' - ' : '') . (($cat['setting']['meta_title'] ?? '') ? $cat['setting']['meta_title'] . ' - ' : (($cat['catname'] ?? '') ? $cat['catname'] . ' - ' : ''));
  465. foreach ($seo as $k => $v) {
  466. $seo[$k] = str_replace(["\n", "\r"], '', $v);
  467. }
  468. return $seo;
  469. }
  470. function cms_lang_url($url, $lang = null, $regionCode = null)
  471. {
  472. $parts = parse_url($url);
  473. if (!$parts) {
  474. return $url;
  475. }
  476. $path = $parts['path'] ?? '/';
  477. $path = '/' . ltrim($path, '/');
  478. $region = null;
  479. if ($regionCode !== null && $regionCode !== '') {
  480. $region = cms_find_region($regionCode);
  481. }
  482. if (!$region && $lang !== null && $lang !== '') {
  483. $region = cms_find_region('', strtolower((string)$lang));
  484. }
  485. if (!$region) {
  486. $region = cms_current_region();
  487. }
  488. if (!$region) {
  489. $region = cms_default_region();
  490. }
  491. $regionSegment = strtolower((string)($region['code'] ?? ''));
  492. $knownPrefixes = [];
  493. foreach (cms_enabled_regions() as $item) {
  494. $knownPrefixes[] = strtolower((string)($item['code'] ?? ''));
  495. }
  496. $enabledLangs = Db::name('lang')->where('is_enabled', 1)->column('mark');
  497. $knownPrefixes = array_unique(array_merge($knownPrefixes, array_map('strtolower', $enabledLangs ?: [])));
  498. $segments = array_values(array_filter(explode('/', trim($path, '/')), 'strlen'));
  499. $first = strtolower((string)($segments[0] ?? ''));
  500. if ($first !== '' && in_array($first, $knownPrefixes, true)) {
  501. array_shift($segments);
  502. }
  503. if ($regionSegment !== '') {
  504. array_unshift($segments, $regionSegment);
  505. }
  506. $newPath = '/' . implode('/', $segments);
  507. if ($newPath === '') {
  508. $newPath = '/';
  509. }
  510. $query = [];
  511. if (!empty($parts['query'])) {
  512. parse_str($parts['query'], $query);
  513. }
  514. unset($query['region'], $query['lang']);
  515. $result = '';
  516. if (!empty($parts['scheme'])) {
  517. $result .= $parts['scheme'] . '://';
  518. }
  519. if (!empty($parts['user'])) {
  520. $result .= $parts['user'];
  521. if (!empty($parts['pass'])) {
  522. $result .= ':' . $parts['pass'];
  523. }
  524. $result .= '@';
  525. }
  526. if (!empty($parts['host'])) {
  527. $result .= $parts['host'];
  528. }
  529. if (!empty($parts['port'])) {
  530. $result .= ':' . $parts['port'];
  531. }
  532. $result .= $newPath;
  533. if (!empty($query)) {
  534. $result .= '?' . http_build_query($query);
  535. }
  536. if (!empty($parts['fragment'])) {
  537. $result .= '#' . $parts['fragment'];
  538. }
  539. return $result;
  540. }
  541. function cms_switch_lang_url($lang, $url = '')
  542. {
  543. $lang = strtolower((string) $lang);
  544. if ($url === '') {
  545. $url = request()->url(true);
  546. }
  547. $region = cms_find_region('', $lang);
  548. if ($region) {
  549. return cms_lang_url($url, $lang, (string)$region['code']);
  550. }
  551. return cms_lang_url($url, $lang, '');
  552. }
  553. function cms_switch_region_url($regionCode, $url = '')
  554. {
  555. $regionCode = strtoupper((string)$regionCode);
  556. $region = cms_find_region($regionCode);
  557. if ($url === '') {
  558. $url = request()->url(true);
  559. }
  560. if (!$region) {
  561. return cms_lang_url($url, cms_current_region_lang(cms_default_lang()), $regionCode);
  562. }
  563. return cms_lang_url($url, cms_region_lang($region, cms_default_lang()), $regionCode);
  564. }
  565. function cms_load_lang_dict($lang)
  566. {
  567. static $loaded = [];
  568. if (isset($loaded[$lang])) {
  569. return $loaded[$lang];
  570. }
  571. $dict = [];
  572. $lang = strtolower((string)$lang);
  573. $basePath = root_path() . 'addons/cms/lang/' . $lang;
  574. if (is_dir($basePath)) {
  575. foreach (glob($basePath . '/*.php') ?: [] as $file) {
  576. $data = include $file;
  577. if (is_array($data)) {
  578. $dict = array_merge($dict, $data);
  579. }
  580. }
  581. }
  582. $loaded[$lang] = $dict;
  583. return $dict;
  584. }
  585. function cms_t($key, $default = '')
  586. {
  587. $lang = cms_current_lang();
  588. $defaultLang = cms_default_lang();
  589. $fileDict = cms_load_lang_dict($lang);
  590. $defaultFileDict = $lang === $defaultLang ? $fileDict : cms_load_lang_dict($defaultLang);
  591. return $fileDict[$key]
  592. ?? $defaultFileDict[$key]
  593. ?? $default;
  594. }
  595. function buildCatUrl($cat, $url = '', $suffix = true, $domain = false)
  596. {
  597. $url_mode = get_addon_config('cms')['site_url_mode'];
  598. $category = cms_cache('Category');
  599. $field = is_numeric($cat) ? ':catid' : ':catdir';
  600. if (is_numeric($cat) && $url_mode == 2 && isset($category[$cat])) {
  601. $cat = $category[$cat]['catdir'];
  602. $field = ':catdir';
  603. }
  604. if (empty($url)) {
  605. return cms_lang_url(addon_url('cms/index/lists', [$field => $cat], $suffix, $domain));
  606. }
  607. $parsedUrl = parse_url($url);
  608. if (isset($parsedUrl['scheme']) && strpos($url, '://') !== false) {
  609. return $url;
  610. }
  611. $queryParams = $parsedUrl['query'] ?? [];
  612. return cms_lang_url(addon_url($parsedUrl['path'], $queryParams, $suffix, $domain));
  613. }
  614. function buildContentUrl($cat, $id, $url = '', $suffix = true, $domain = false)
  615. {
  616. $url_mode = get_addon_config('cms')['site_url_mode'];
  617. $category = cms_cache('Category');
  618. $field = is_numeric($cat) ? ':catid' : ':catdir';
  619. if (is_numeric($cat) && $url_mode == 2 && isset($category[$cat])) {
  620. $cat = $category[$cat]['catdir'];
  621. $field = ':catdir';
  622. }
  623. if (empty($url)) {
  624. return cms_lang_url(addon_url('cms/index/shows', [$field => $cat, ':id' => $id], $suffix, $domain));
  625. }
  626. $parsedUrl = parse_url($url);
  627. if (isset($parsedUrl['scheme']) && strpos($url, '://') !== false) {
  628. return $url;
  629. }
  630. $queryParams = $parsedUrl['query'] ?? [];
  631. return cms_lang_url(addon_url($parsedUrl['path'], $queryParams, $suffix, $domain));
  632. }
  633. function cms_highlightKeyword($text, $keyword, $highlightStyle = 'color: red;')
  634. {
  635. if (empty($keyword)) {
  636. return $text;
  637. }
  638. $pattern = '/' . preg_quote($keyword, '/') . '/i';
  639. return preg_replace($pattern, '<span style="' . $highlightStyle . '">$0</span>', $text);
  640. }