| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- <?php
- namespace addons\cms\model;
- use addons\cms\library\Service;
- use think\facade\Db;
- use think\Model;
- class Cms extends Model
- {
- protected $autoWriteTimestamp = true;
- protected $ext_table = '_data';
- protected $name = 'cms_field';
- protected static $config = [];
- protected static function init()
- {
- self::$config = get_addon_config('cms');
- }
- protected function currentLang()
- {
- return cms_current_lang();
- }
- protected function langFields()
- {
- return ['title', 'keywords', 'description', 'tags', 'content'];
- }
- protected function getLangRow($tableName, $id, $currentLang, $defaultLang, $strictLang = false)
- {
- $extTable = $tableName . $this->ext_table;
- $columns = array_map('strtolower', array_keys(Db::name($extTable)->getFields()));
- if (!in_array('did', $columns, true)) {
- return [null, $columns];
- }
- $query = Db::name($extTable)->where(['did' => $id]);
- if (in_array('lang', $columns, true)) {
- $langRow = (clone $query)->where(['lang' => $currentLang])->find();
- if (!$langRow && !$strictLang && $currentLang !== $defaultLang) {
- $langRow = (clone $query)->where(['lang' => $defaultLang])->find();
- }
- } else {
- $langRow = $query->find();
- }
- return [$langRow, $columns];
- }
- protected function mergeLangData($modeId, array $row, array $langRow = null, $currentLang = '', $defaultLang = '', array $extColumns = [])
- {
- $currentLang = strtolower((string) $currentLang);
- $defaultLang = strtolower((string) $defaultLang);
- $extColumns = array_map('strtolower', $extColumns);
- if ($langRow) {
- foreach ($langRow as $field => $value) {
- $fieldLower = strtolower((string) $field);
- if (!in_array($fieldLower, $extColumns, true) || in_array($fieldLower, ['did', 'lang'], true)) {
- continue;
- }
- // 附表独有字段,直接并入结果(如 title1、title2、自定义副标题等)
- if (!array_key_exists($field, $row)) {
- $row[$field] = $value;
- continue;
- }
- // 同名字段:附表非空优先,空值回退主表,保证多语言字段覆盖主表默认值
- if ($value !== null && $value !== '') {
- $row[$field] = $value;
- }
- }
- // 再做一次附表自定义字段兜底,避免后续格式化过程中丢失
- foreach ($langRow as $field => $value) {
- $fieldLower = strtolower((string) $field);
- if (in_array($fieldLower, ['did', 'lang'], true)) {
- continue;
- }
- if (preg_match('/^(title\d+|subtitle\d*|desc\d+|description\d+|button(_text)?\d*|link\d+|image\d+|video\d+)$/i', $field)) {
- $row[$field] = $value;
- }
- }
- $row['lang'] = $currentLang ?: ($langRow['lang'] ?? ($row['lang'] ?? ''));
- } else {
- $row['lang'] = $currentLang ?: ($row['lang'] ?? '');
- }
- return Service::dealModelShowData(cms_cache('ModelField')[$modeId], $row);
- }
- public function getList($modeId, $where, $moreifo, $field = '*', $order = '', $limit = 10, $page = null, $simple = false, $config = [])
- {
- $url_mode = self::$config['site_url_mode'];
- $config['query'] = array_merge($config['query'] ?? [], request()->get());
- $config['list_rows'] = $limit;
- $tableName = cms_cache('Model')[$modeId]['tablename'] ?? '';
- if (empty($tableName)) {
- return [];
- }
- $defaultLang = cms_default_lang();
- $currentLang = $this->currentLang();
- $strictLang = !empty($config['strict_lang']);
- $cmsModel = Db::name($tableName)->where($where)->order($order)->field($field);
- if ($page) {
- $result = $cmsModel->paginate($config, $simple);
- $items = $result->items();
- } else {
- list($offset, $length) = $this->parseLimit($limit);
- $items = $cmsModel->limit($offset, $length)->select()->toArray();
- $result = $items;
- }
- if (!empty($items)) {
- $Category = cms_cache('Category');
- foreach ($items as $key => $vo) {
- if (getModel($modeId, 'type') == 2 && $moreifo) {
- [$langRow, $extColumns] = $this->getLangRow($tableName, $vo['id'], $currentLang, $defaultLang, $strictLang);
- if ($strictLang && !$langRow) {
- unset($items[$key]);
- continue;
- }
- $vo = $this->mergeLangData($modeId, $vo, $langRow ?: null, $currentLang, $defaultLang, $extColumns);
- } else {
- $vo = Service::dealModelShowData(cms_cache('ModelField')[$modeId], $vo);
- }
- $cat = $url_mode == 1 ? $vo['catid'] : ($Category[$vo['catid']]['catdir'] ?? getCategory($vo['catid'], 'catdir'));
- $vo['url'] = buildContentUrl($cat, $vo['id'], $vo['url']);
- $items[$key] = $vo;
- }
- if ($page) {
- foreach ($items as $idx => $item) {
- $result[$idx] = $item;
- }
- } else {
- $result = $items;
- }
- }
- return $result;
- }
- public function getContent($modeId, $where, $moreifo = false, $field = '*', $order = '', $cacheKey = false, $cacheExpire = null)
- {
- $url_mode = self::$config['site_url_mode'];
- $tableName = cms_cache('Model')[$modeId]['tablename'] ?? '';
- if (empty($tableName)) {
- return [];
- }
- $defaultLang = cms_default_lang();
- $currentLang = $this->currentLang();
- $dataInfo = Db::name($tableName)
- ->field($field)
- ->cache($cacheKey, $cacheExpire, 'cms')
- ->where($where)
- ->order($order)
- ->find();
- if (!empty($dataInfo)) {
- if (getModel($modeId, 'type') == 2 && $moreifo) {
- [$langRow, $extColumns] = $this->getLangRow($tableName, $dataInfo['id'], $currentLang, $defaultLang);
- $dataInfo = $this->mergeLangData($modeId, $dataInfo, $langRow ?: null, $currentLang, $defaultLang, $extColumns);
- } else {
- $dataInfo = Service::dealModelShowData(cms_cache('ModelField')[$modeId], $dataInfo);
- }
- $Category = cms_cache('Category');
- $cat = $url_mode == 1 ? $dataInfo['catid'] : ($Category[$dataInfo['catid']]['catdir'] ?? getCategory($dataInfo['catid'], 'catdir'));
- $dataInfo['url'] = buildContentUrl($cat, $dataInfo['id'], $dataInfo['url']);
- }
- return $dataInfo;
- }
- protected function parseLimit($limit): array
- {
- if (is_string($limit) && strpos($limit, ',') !== false) {
- return array_map('intval', explode(',', $limit));
- }
- return [0, (int) $limit];
- }
- }
|