diff --git a/app/Http/Controllers/V1/User/KnowledgeController.php b/app/Http/Controllers/V1/User/KnowledgeController.php index 00f28b3..e3646c9 100644 --- a/app/Http/Controllers/V1/User/KnowledgeController.php +++ b/app/Http/Controllers/V1/User/KnowledgeController.php @@ -4,50 +4,58 @@ namespace App\Http\Controllers\V1\User; use App\Exceptions\ApiException; use App\Http\Controllers\Controller; +use App\Http\Resources\KnowledgeResource; use App\Models\Knowledge; use App\Models\User; +use App\Services\Plugin\HookManager; use App\Services\UserService; use App\Utils\Helper; use Illuminate\Http\Request; class KnowledgeController extends Controller { + private UserService $userService; + + public function __construct(UserService $userService) + { + $this->userService = $userService; + } + public function fetch(Request $request) { - if ($request->input('id')) { - $knowledge = Knowledge::where('id', $request->input('id')) - ->where('show', 1) - ->first(); - - if (!$knowledge) { - return $this->fail([500, __('Article does not exist')]); - } - - $knowledge = $knowledge->toArray(); - $user = User::find($request->user()->id); - $userService = new UserService(); - if (!$userService->isAvailable($user)) { - $this->formatAccessData($knowledge['body']); - } - $subscribeUrl = Helper::getSubscribeUrl($user['token']); - $knowledge['body'] = str_replace('{{siteName}}', admin_setting('app_name', 'XBoard'), $knowledge['body']); - $knowledge['body'] = str_replace('{{subscribeUrl}}', $subscribeUrl, $knowledge['body']); - $knowledge['body'] = str_replace('{{urlEncodeSubscribeUrl}}', urlencode($subscribeUrl), $knowledge['body']); - $knowledge['body'] = str_replace( - '{{safeBase64SubscribeUrl}}', - str_replace( - array('+', '/', '='), - array('-', '_', ''), - base64_encode($subscribeUrl) - ), - $knowledge['body'] - ); - return $this->success($knowledge); + $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')]); } - $builder = Knowledge::select(['id', 'category', 'title', 'updated_at']) + + $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')) - ->where('show', 1) ->orderBy('sort', 'ASC'); + $keyword = $request->input('keyword'); if ($keyword) { $builder = $builder->where(function ($query) use ($keyword) { @@ -57,14 +65,86 @@ class KnowledgeController extends Controller } $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 formatAccessData(&$body) + private function buildKnowledgeQuery(array $select = ['*']) { - $pattern = '/(.*?)/s'; - $replacement = '
' . __('You must have a valid subscription to view content in this area') . '
'; - $body = preg_replace($pattern, $replacement, $body); + 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' => '
' . __('You must have a valid subscription to view content in this area') . '
' + ] + ]; + + $this->applyReplacementRules($body, $rules); + } + + private function replacePlaceholders(string $body, string $subscribeUrl): string + { + $rules = [ + [ + 'type' => 'string', + 'search' => '{{siteName}}', + 'replacement' => admin_setting('app_name', 'XBoard') + ], + [ + 'type' => 'string', + 'search' => '{{subscribeUrl}}', + 'replacement' => $subscribeUrl + ], + [ + 'type' => 'string', + 'search' => '{{urlEncodeSubscribeUrl}}', + 'replacement' => urlencode($subscribeUrl) + ], + [ + 'type' => 'string', + 'search' => '{{safeBase64SubscribeUrl}}', + 'replacement' => str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($subscribeUrl)) + ] + ]; + + $this->applyReplacementRules($body, $rules); + return $body; + } + + private function applyReplacementRules(string &$body, array $rules): void + { + foreach ($rules as $rule) { + if ($rule['type'] === 'regex') { + $body = preg_replace($rule['pattern'], $rule['replacement'], $body); + } else { + $body = str_replace($rule['search'], $rule['replacement'], $body); + } + } } } diff --git a/app/Http/Resources/KnowledgeResource.php b/app/Http/Resources/KnowledgeResource.php new file mode 100644 index 0000000..cda796c --- /dev/null +++ b/app/Http/Resources/KnowledgeResource.php @@ -0,0 +1,28 @@ + + */ + public function toArray(Request $request): array + { + $data = [ + 'id' => $this['id'], + 'category' => $this['category'], + 'title' => $this['title'], + 'body' => $this->when(isset($this['body']), $this['body']), + 'updated_at' => $this['updated_at'], + ]; + + return HookManager::filter('user.knowledge.resource', $data, $request, $this); + } +}