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]; } }