userService = $userService; } public function fetch(Request $request) { $request->validate([ 'id' => 'nullable|sometimes|integer|min:1', 'language' => 'nullable|sometimes|string|max:10', 'keyword' => 'nullable|sometimes|string|max:255', ]); return $request->input('id') ? $this->fetchSingle($request) : $this->fetchList($request); } private function fetchSingle(Request $request) { $knowledge = $this->buildKnowledgeQuery() ->where('id', $request->input('id')) ->first(); if (!$knowledge) { return $this->fail([500, __('Article does not exist')]); } $knowledge = $knowledge->toArray(); $knowledge = $this->processKnowledgeContent($knowledge, $request->user()); return $this->success(KnowledgeResource::make($knowledge)); } private function fetchList(Request $request) { $builder = $this->buildKnowledgeQuery(['id', 'category', 'title', 'updated_at', 'body']) ->where('language', $request->input('language')) ->orderBy('sort', 'ASC'); $keyword = $request->input('keyword'); if ($keyword) { $builder = $builder->where(function ($query) use ($keyword) { $query->where('title', 'LIKE', "%{$keyword}%") ->orWhere('body', 'LIKE', "%{$keyword}%"); }); } $knowledges = $builder->get() ->map(function ($knowledge) use ($request) { $knowledge = $knowledge->toArray(); $knowledge = $this->processKnowledgeContent($knowledge, $request->user()); return KnowledgeResource::make($knowledge); }) ->groupBy('category'); return $this->success($knowledges); } private function buildKnowledgeQuery(array $select = ['*']) { return Knowledge::select($select)->where('show', 1); } private function processKnowledgeContent(array $knowledge, User $user): array { if (!isset($knowledge['body'])) { return $knowledge; } if (!$this->userService->isAvailable($user)) { $this->formatAccessData($knowledge['body']); } $subscribeUrl = Helper::getSubscribeUrl($user['token']); $knowledge['body'] = $this->replacePlaceholders($knowledge['body'], $subscribeUrl); return $knowledge; } private function formatAccessData(&$body): void { $rules = [ [ 'type' => 'regex', 'pattern' => '/(.*?)/s', 'replacement' => '