| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388 |
- <?php
- // +----------------------------------------------------------------------
- // |
- // +----------------------------------------------------------------------
- // |
- // +----------------------------------------------------------------------
- // |
- // +----------------------------------------------------------------------
- // |
- // +----------------------------------------------------------------------
- // +----------------------------------------------------------------------
- // | cms处理类
- // +----------------------------------------------------------------------
- namespace addons\cms\library;
- use addons\cms\model\ModelField;
- use think\facade\Config;
- use think\facade\Db;
- use think\facade\Validate;
- class Service
- {
- private static $ext_table = '_data';
- protected static function physicalTableName($tableName)
- {
- $prefix = Config::get('database.connections.mysql.prefix', '');
- return strpos($tableName, $prefix) === 0 ? $tableName : $prefix . $tableName;
- }
- protected static function tableQuery($tableName)
- {
- return Db::table(self::physicalTableName($tableName));
- }
- //查询解析模型数据用以构造from表单
- public static function getFieldList($modelId, $id = null, $lang = null)
- {
- $list = ModelField::where('modelid', $modelId)->where('status', 1)->order('listorder DESC,id DESC')->select();
- if (!empty($list)) {
- //编辑信息时查询出已有信息
- if ($id) {
- $modelInfo = Db::name('cms_model')->where('id', $modelId)->field('tablename,type')->find();
- $mainTable = $modelInfo['tablename'];
- $dataInfo = self::tableQuery($mainTable)->where('id', $id)->find();
- $currentLang = $lang ?: request()->param('lang/s', '');
- if (!$currentLang && function_exists('cms_current_lang')) {
- $currentLang = cms_current_lang();
- }
- if (!$currentLang) {
- $currentLang = Db::name('lang')->where('is_default', 1)->value('mark') ?: 'cn';
- }
- if ($modelInfo['type'] == 2 && !empty($dataInfo)) {
- $extTable = $modelInfo['tablename'] . self::$ext_table;
- $extFields = array_map('strtolower', array_keys(Db::getFields(self::physicalTableName($extTable))));
- if (in_array('lang', $extFields, true)) {
- $defaultLang = Db::name('lang')->where('is_default', 1)->value('mark') ?: 'cn';
- $dataInfoExt = self::tableQuery($extTable)->where(['did' => $dataInfo['id'], 'lang' => $currentLang])->find();
- if (!$dataInfoExt && $currentLang !== $defaultLang) {
- $dataInfoExt = self::tableQuery($extTable)->where(['did' => $dataInfo['id'], 'lang' => $defaultLang])->find();
- }
- } else {
- $dataInfoExt = self::tableQuery($extTable)->where(['did' => $dataInfo['id']])->find();
- }
- }
- }
- $langMirrorFields = ['title', 'keywords', 'description', 'tags'];
- $defaultLang = Db::name('lang')->where('is_default', 1)->value('mark') ?: 'cn';
- $currentLang = $lang ?: request()->param('lang/s', '');
- if (!$currentLang && function_exists('cms_current_lang')) {
- $currentLang = cms_current_lang();
- }
- $currentLang = $currentLang ?: $defaultLang;
- $fieldBuckets = [];
- foreach ($list as $key => &$value) {
- if ($value['iscore']) {
- unset($list[$key]);
- continue;
- }
- $fieldBuckets[$value['name']][] = $key;
- }
- unset($value);
- foreach ($fieldBuckets as $fieldName => $indexes) {
- if (count($indexes) <= 1) {
- continue;
- }
- $mainIndex = null;
- $extIndex = null;
- foreach ($indexes as $idx) {
- if ((int) $list[$idx]['ifsystem'] === 1) {
- $mainIndex = $idx;
- } else {
- $extIndex = $idx;
- }
- }
- if ($mainIndex === null || $extIndex === null) {
- continue;
- }
- if (in_array($fieldName, $langMirrorFields, true)) {
- $keepIndex = $currentLang === $defaultLang ? $mainIndex : $extIndex;
- } else {
- $keepIndex = $extIndex;
- }
- $dropIndex = $keepIndex === $mainIndex ? $extIndex : $mainIndex;
- unset($list[$dropIndex]);
- }
- foreach ($list as $key => &$value) {
- $isLangMirror = in_array($value['name'], $langMirrorFields, true);
- if ($value['ifsystem'] && !$isLangMirror) {
- $value['fieldArr'] = 'modelField';
- if (isset($dataInfo[$value['name']])) {
- $value['value'] = $dataInfo[$value['name']];
- }
- } else {
- $value['fieldArr'] = 'modelFieldExt';
- if (isset($dataInfoExt[$value['name']])) {
- $value['value'] = $dataInfoExt[$value['name']];
- } elseif ($isLangMirror && isset($dataInfo[$value['name']])) {
- $value['value'] = $dataInfo[$value['name']];
- } elseif (isset($dataInfo[$value['name']])) {
- $value['value'] = $dataInfo[$value['name']];
- }
- }
- //扩展配置
- $value['options'] = $value['setting']['options'] ?? '';
- //在新增时候添加默认值
- if (!$id) {
- $value['value'] = $value['setting']['value'] ?? '';
- }
- if ($value['type'] == 'custom') {
- if ($value['options'] != '') {
- $tpar = explode(".", $value['options'], 2);
- $value['options'] = \think\Response::create('admin@custom/' . $tpar[0], 'view')->assign('vo', $value)->getContent();
- unset($tpar);
- }
- } elseif ($value['options'] != '') {
- $value['options'] = parse_attr($value['options']);
- }
- /*if ('' != $value['options']) {
- $value['options'] = parse_attr($value['options']);
- }*/
- if ($value['type'] == 'checkbox') {
- $value['value'] = empty($value['value']) ? [] : explode(',', $value['value']);
- }
- if ($value['type'] == 'datetime') {
- $value['value'] = empty($value['value']) ? date('Y-m-d H:i:s') : date('Y-m-d H:i:s', $value['value']);
- }
- if ($value['type'] == 'date') {
- $value['value'] = empty($value['value']) ? '' : date('Y-m-d', $value['value']);
- }
- }
- }
- return $list;
- }
- //处理post提交的模型数据
- public static function dealModelPostData($modeId, $data, $dataExt = [], $ignoreField = [])
- {
- //字段类型
- $query = ModelField::where('modelid', $modeId)->where('status', 1);
- if ([] != $ignoreField) {
- $query = $query->where('name', 'not in', $ignoreField);
- }
- $filedTypeList = $query->order('listorder DESC, id DESC')->column('title,type,ifsystem,ifrequire,pattern,errortips', 'name');
- $currentLang = request()->post('modelFieldExt.lang/s', '') ?: request()->param('lang/s', '');
- if (!$currentLang && function_exists('cms_current_lang')) {
- $currentLang = cms_current_lang();
- }
- $defaultLang = Db::name('lang')->where('is_default', 1)->value('mark') ?: 'cn';
- $langMirrorFields = ['title', 'keywords', 'description', 'tags'];
- foreach ($filedTypeList as $name => $vo) {
- $arr = $vo['ifsystem'] ? 'data' : 'dataExt';
- if ($currentLang && $currentLang !== $defaultLang && in_array($name, $langMirrorFields, true)) {
- if ($arr === 'data' && (!isset($data[$name]) || $data[$name] === '') && isset($dataExt[$name]) && $dataExt[$name] !== '') {
- $data[$name] = $dataExt[$name];
- }
- if ($arr === 'dataExt' && (!isset($dataExt[$name]) || $dataExt[$name] === '') && isset($data[$name]) && $data[$name] !== '') {
- $dataExt[$name] = $data[$name];
- }
- }
- if (!isset(${$arr}[$name])) {
- switch ($vo['type']) {
- // 开关
- case 'switch':
- ${$arr}[$name] = 0;
- break;
- case 'checkbox':
- ${$arr}[$name] = '';
- break;
- case 'radio':
- ${$arr}[$name] = '';
- break;
- }
- } else {
- if (is_array(${$arr}[$name])) {
- ${$arr}[$name] = implode(',', ${$arr}[$name]);
- }
- switch ($vo['type']) {
- // 开关
- case 'switch':
- ${$arr}[$name] = 1;
- break;
- // 日期+时间
- case 'datetime':
- //if ($vo['ifeditable']) {
- ${$arr}[$name] = strtotime(${$arr}[$name]);
- //}
- break;
- // 日期
- case 'date':
- ${$arr}[$name] = strtotime(${$arr}[$name]);
- break;
- }
- }
- //数据必填验证
- if ($vo['ifrequire']) {
- $currentValue = ${$arr}[$name] ?? '';
- if (in_array($name, $langMirrorFields, true)) {
- $mirrorValue = $arr === 'data' ? ($dataExt[$name] ?? '') : ($data[$name] ?? '');
- if ($currentValue === '' && $mirrorValue !== '') {
- $currentValue = $mirrorValue;
- }
- }
- if ($currentValue === '') {
- throw new \Exception("'" . $vo['title'] . "'必须填写~");
- }
- }
- //正则校验
- if (isset(${$arr}[$name]) && ${$arr}[$name] && $vo['pattern'] && !Validate::regex(${$arr}[$name], $vo['pattern'])) {
- throw new \Exception("'" . $vo['title'] . "'" . (!empty($vo['errortips']) ? $vo['errortips'] : '正则校验失败') . "");
- }
- //数据格式验证
- if (!empty(${$arr}[$name]) && in_array($vo['type'], ['number']) && !Validate::isNumber(${$arr}[$name])) {
- throw new \Exception("'" . $vo['title'] . "'格式错误~");
- //安全过滤
- } else {
- }
- }
- return [$data, $dataExt];
- }
- /**
- * 数据处理 前端显示
- * @param $fieldinfo
- * @param $data
- */
- public static function dealModelShowData($fieldinfo, $data)
- {
- $newdata = [];
- foreach ($data as $key => $value) {
- if (isset($fieldinfo[$key])) {
- switch ($fieldinfo[$key]['type']) {
- case 'array':
- $newdata[$key] = (array) json_decode($value, true);
- break;
- case 'radio':
- case 'select':
- if (!empty($value)) {
- if (!empty($fieldinfo[$key]['options'])) {
- $optionArr = parse_attr($fieldinfo[$key]['options']);
- $newdata[$key . '_text'] = isset($optionArr[$value]) ? $optionArr[$value] : $value;
- }
- }
- $newdata[$key] = $value;
- break;
- case 'selects':
- case 'checkbox':
- if (!empty($value)) {
- if (!empty($fieldinfo[$key]['options'])) {
- $optionArr = parse_attr($fieldinfo[$key]['options']);
- $valueArr = explode(',', $value);
- foreach ($valueArr as $v) {
- if (isset($optionArr[$v])) {
- $newdata[$key][$v] = $optionArr[$v];
- } elseif ($v) {
- $newdata[$key][$v] = $v;
- }
- }
- //其他表关联
- } else {
- $newdata[$key] = [];
- }
- }
- break;
- case 'files':
- case 'images':
- $newdata[$key] = empty($value) ? [] : explode(',', $value);
- break;
- case 'markdown':
- $parser = new \util\Parser;
- $newdata[$key] = $parser->makeHtml($value);
- break;
- default:
- $newdata[$key] = $value;
- break;
- }
- } else {
- // 允许前台拿到已合并进来的附表自定义字段(如 title1/title2),不要清空
- $newdata[$key] = $value;
- }
- if (!isset($newdata[$key])) {
- $newdata[$key] = '';
- }
- }
- return $newdata;
- }
- /**
- * 文本处理
- */
- public static function getAfterText(&$data, &$dataExt)
- {
- //自动提取摘要,如果有设置自动提取,且description为空,且有内容字段才执行
- if (isset($data['get_introduce']) && (($data['description'] ?? '') == '') && (isset($dataExt['content']) || isset($data['content']))) {
- $content = isset($dataExt['content']) ? $dataExt['content'] : (isset($data['content']) ? $data['content'] : '');
- $data['description'] = mb_substr(str_replace(["\r\n", "\t", '“', '”', ' '], '', strip_tags($content)), 0, 200);
- }
- //自动提取缩略图
- if (isset($data['auto_thumb']) && empty($data['thumb']) && (isset($dataExt['content']) || isset($data['content']))) {
- $thumb = isset($dataExt['content']) ? \util\GetImgSrc::src($dataExt['content']) : (isset($data['content']) ? \util\GetImgSrc::src($data['content']) : false);
- $data['thumb'] = $thumb ? $thumb : '';
- }
- //关键词加链接
- $autolinks = get_addon_config('cms')['autolinks'];
- if (!empty($autolinks) && isset($dataExt['content'])) {
- $kwarray = [];
- if (strpos($autolinks, '|')) {
- //解析关键词数组
- $kwsets = array_filter(preg_split("/(\r|\n|\r\n)/", $autolinks));
- foreach ($kwsets as $kwset) {
- $kwarray[] = explode('|', $kwset);
- }
- }
- foreach ($kwarray as $i => $row) {
- $txt = isset($row[0]) ? trim($row[0]) : '';
- $link = isset($row[1]) ? trim($row[1]) : '';
- $set = isset($row[2]) ? trim($row[2]) : '';
- if ($txt && $link) {
- $rel = '';
- $open = '_blank';
- //处理标记与打开方式
- if ($set) {
- if (false !== stripos($set, 'e')) {
- $rel = ' rel="external nofollow"';
- } elseif (false !== stripos($set, 'n')) {
- $rel = ' rel="nofollow"';
- }
- $open = false !== stripos($set, 'b') ? '_self' : $open;
- }
- $dataExt['content'] = false !== strpos($dataExt['content'], $txt)
- //正则排除参数和链接
- ? preg_replace('/(?!<[^>]*)' . $txt . '(?![^<]*(>|<\/[a|sc]))/s'
- , '<a href="' . $link . '"' . $rel . 'target="' . $open . '" title="' . $txt . '">' . $txt . '</a>', $dataExt['content']) : $dataExt['content'];
- }
- }
- }
- unset($data['get_introduce']);
- unset($data['auto_thumb']);
- }
- /**
- * 获取缓存标签和时长
- */
- public static function getCacheConfig(string $type): array
- {
- $cachetime = get_addon_config('cms')['site_cache_time'] ?? 0;
- if (in_array($cachetime, [true, 'true'], true)) {
- $cacheDuration = 0;
- } elseif (in_array($cachetime, [false, 'false'], true)) {
- $cacheDuration = -1;
- } else {
- $cacheDuration = (int) $cachetime;
- }
- $cacheKey = $cacheDuration !== -1 ? "cms-{$type}" : false;
- $cacheExpire = $cacheDuration !== -1 ? $cacheDuration : null;
- return [$cacheKey, $cacheExpire];
- }
- }
|