physicalTableName($tableName); if (!isset($cache[$tableName])) { $columns = Db::getFields($tableName); $cache[$tableName] = array_map('strtolower', array_keys($columns)); } return $cache[$tableName]; } protected function hasColumn($tableName, $column) { return in_array(strtolower($column), $this->getTableColumns($tableName), true); } protected function filterDataByColumns(array $data, array $columns) { $result = []; foreach ($data as $key => $value) { if (in_array(strtolower($key), $columns, true)) { $result[$key] = $value; } } return $result; } protected function getLangWhere($extTableName, $id, $lang) { $where = ['did' => $id]; if ($this->hasColumn($extTableName, 'lang')) { $where['lang'] = $lang; } return $where; } protected function isChineseLang($lang) { return in_array(strtolower((string) $lang), ['cn', 'zh', 'zh-cn'], true); } protected function getChineseTitleFromExtTable($extTableName, $id, $lang, array $dataExt, array $extColumns) { if ($this->isChineseLang($lang) && array_key_exists('title', $dataExt)) { return $dataExt['title']; } if (!in_array('lang', $extColumns, true)) { return null; } $row = Db::table($extTableName)->where('did', $id)->where('lang', 'in', ['cn', 'zh', 'zh-cn'])->orderRaw("field(lang,'cn','zh','zh-cn')")->find(); return $row && array_key_exists('title', $row) ? $row['title'] : null; } protected function splitLangFields(array $data, array $dataExt = [], $lang = 'cn', array $mainColumns = [], array $extColumns = []) { $defaultLang = Db::name('lang')->where('is_default', 1)->value('mark') ?: 'cn'; $langFields = ['title', 'keywords', 'description', 'tags']; foreach ($langFields as $field) { if (!array_key_exists($field, $data)) { continue; } $value = $data[$field]; $mainHas = in_array(strtolower($field), $mainColumns, true); $extHas = in_array(strtolower($field), $extColumns, true); if ($extHas) { $dataExt[$field] = $value; } if (!$mainHas || $lang !== $defaultLang) { unset($data[$field]); } } return [$data, $dataExt]; } public function addModelData($data, $dataExt = [], $lang = 'cn') { $catid = (int) $data['catid']; $category = Category::find($catid); $modelid = $category['modelid']; $eventResult = Event::trigger('cms_content_add', [$data, $dataExt]); if ($eventResult) { [$data, $dataExt] = array_map('array_merge', [$data, $dataExt], ...$eventResult); } $tablename = $this->physicalTableName(Models::where('id', $modelid)->value('tablename')); $extTableName = $tablename . $this->ext_table; $mainColumns = $this->getTableColumns($tablename); $extColumns = $this->getTableColumns($extTableName); Service::getAfterText($data, $dataExt); [$data, $dataExt] = $this->splitLangFields($data, $dataExt, $lang, $mainColumns, $extColumns); $data['admin_id'] = session('admin.id') ?: 0; [$data, $dataExt] = Service::dealModelPostData($modelid, $data, $dataExt); $data = $this->filterDataByColumns($data, $mainColumns); $dataExt = $this->filterDataByColumns($dataExt, $extColumns); if (!isset($data['publish_time'])) { $data['publish_time'] = request()->time(); } $data['create_time'] = request()->time(); $data['update_time'] = request()->time(); try { $id = Db::table($tablename)->insertGetId($data); if (!empty($dataExt['tags'])) { $this->tagDispose($dataExt['tags'], $id, $catid, $modelid); } if (!empty($dataExt)) { $dataExt['did'] = $id; if (in_array('lang', $extColumns, true)) { $dataExt['lang'] = $lang; $whereExt = $this->getLangWhere($extTableName, $id, $lang); $exists = Db::table($extTableName)->where($whereExt)->find(); if ($exists) { Db::table($extTableName)->where($whereExt)->update($dataExt); } else { Db::table($extTableName)->insert($dataExt); } } else { $exists = Db::table($extTableName)->where(['did' => $id])->find(); if ($exists) { Db::table($extTableName)->where(['did' => $id])->update($dataExt); } else { Db::table($extTableName)->insert($dataExt); } } } } catch (\Exception $e) { throw new \Exception($e->getMessage()); } $category->inc('items')->save(); if (self::$config['site_weburlpush']) { hook('weburlpush', buildContentUrl($catid, $id, $data['url'] ?? '', true, true)); } if (self::$config['site_searchtype'] === 'xunsearch') { FulltextSearch::update($modelid, $catid, $id, $data, $dataExt); } if (self::$config['site_searchtype'] === 'meilisearch') { MeiliSearch::update($modelid, $catid, $id, $data, $dataExt); } return $id; } public function editModelData($data, $dataExt = [], $lang = 'cn') { $catid = (int) $data['catid']; $id = (int) $data['id']; $category = Category::find($catid); $modelid = $category['modelid']; $eventResult = Event::trigger('cms_content_edit', [$data, $dataExt]); if ($eventResult) { [$data, $dataExt] = array_map('array_merge', [$data, $dataExt], ...$eventResult); } $tablename = $this->physicalTableName(Models::where('id', $modelid)->value('tablename')); $extTableName = $tablename . $this->ext_table; $mainColumns = $this->getTableColumns($tablename); $extColumns = $this->getTableColumns($extTableName); Service::getAfterText($data, $dataExt); [$data, $dataExt] = $this->splitLangFields($data, $dataExt, $lang, $mainColumns, $extColumns); $defaultLang = Db::name('lang')->where('is_default', 1)->value('mark') ?: 'cn'; if (!empty($dataExt['tags'])) { $this->tagDispose($dataExt['tags'], $id, $catid, $modelid); } else { $this->tagDispose([], $id, $catid, $modelid); } [$data, $dataExt] = Service::dealModelPostData($modelid, $data, $dataExt); $data = $this->filterDataByColumns($data, $mainColumns); $dataExt = $this->filterDataByColumns($dataExt, $extColumns); if (in_array('title', $mainColumns, true) && in_array('title', $extColumns, true)) { $chineseTitle = $this->getChineseTitleFromExtTable($extTableName, $id, $lang, $dataExt, $extColumns); if ($chineseTitle !== null) { $data['title'] = $chineseTitle; } } if ($lang !== $defaultLang) { foreach (['keywords', 'description', 'tags'] as $field) { unset($data[$field]); } } if (!isset($data['update_time'])) { $data['update_time'] = request()->time(); } $info = Db::table($tablename)->where('id', $id)->find(); if (empty($info)) { throw new \Exception('该信息不存在!'); } Db::table($tablename)->where('id', $id)->update($data); if (!empty($dataExt)) { $whereExt = $this->getLangWhere($extTableName, $id, $lang); $exists = Db::table($extTableName)->where($whereExt)->find(); if ($exists) { Db::table($extTableName)->where($whereExt)->update($dataExt); } else { $dataExt['did'] = $id; if (in_array('lang', $extColumns, true)) { $dataExt['lang'] = $lang; } Db::table($extTableName)->insert($dataExt); } } if ($info['sysadd'] == 0) { CmsContent::where('catid', $catid)->where('content_id', $id)->update(['status' => $data['status']]); } if (self::$config['site_searchtype'] === 'xunsearch') { FulltextSearch::update($modelid, $catid, $id, $data, $dataExt); } if (self::$config['site_searchtype'] === 'meilisearch') { MeiliSearch::update($modelid, $catid, $id, $data, $dataExt); } } public function deleteModelData($catid, $id, $no_delete = false) { $category = Category::find($catid); if (empty($category)) { throw new \Exception('栏目不存在!'); } $modelid = $category['modelid']; $model = Models::where('id', $modelid)->find(); $tableName = $this->physicalTableName($model['tablename']); $data = Db::table($tableName)->where('id', $id)->find(); if (empty($data)) { throw new \Exception('该信息不存在!'); } if (!empty($data['tags'])) { $this->tagDispose([], $data['id'], $data['catid'], $modelid); } if ($no_delete) { Db::table($tableName)->where('id', $id)->update(['status' => -1]); } else { Db::table($tableName)->where('id', $id)->delete(); if (2 == $model['type']) { Db::table($tableName . $this->ext_table)->where('did', $id)->delete(); } if ($category['items']) { $category->dec('items')->save(); } } if ($data['sysadd'] == 0) { CmsContent::where('catid', $data['catid'])->where('content_id', $data['id'])->delete(); } if (self::$config['site_searchtype'] === 'xunsearch') { FulltextSearch::del($data['catid'], $id); } if (self::$config['site_searchtype'] === 'meilisearch') { MeiliSearch::del($data['catid'], $id); } } private function tagDispose($tags, $id, $catid, $modelid) { if (!empty($tags)) { $keyword = strpos($tags, ',') === false ? explode(' ', $tags) : explode(',', $tags); $keyword = array_unique($keyword); if ('add' == request()->action()) { (new Tags)->addTag($keyword, $id, $catid); } else { (new Tags)->updata($keyword, $id, $catid); } } else { (new Tags)->deleteAll($id, $catid); } } }