diff --git a/app/Http/Controllers/Api/UserPreferenceController.php b/app/Http/Controllers/Api/UserPreferenceController.php index f5ca024..be66fe7 100644 --- a/app/Http/Controllers/Api/UserPreferenceController.php +++ b/app/Http/Controllers/Api/UserPreferenceController.php @@ -32,10 +32,36 @@ public function list(Request $request) * mediaType="multipart/form-data", * @OA\Schema( * type="object", - * @OA\Property(property="preferences[source]", type="string"), - * @OA\Property(property="preferences[published_at][from]", type="string"), - * @OA\Property(property="preferences[published_at][to]", type="string"), - * @OA\Property(property="preferences[category]", type="string"), + * @OA\Property( + * property="preferences[authors][0]", + * description="Author 1", + * type="string" + * ), + * @OA\Property( + * property="preferences[authors][1]", + * description="Author 2", + * type="string" + * ), + * @OA\Property( + * property="preferences[categories][0]", + * description="sport", + * type="string" + * ), + * @OA\Property( + * property="preferences[categories][1]", + * description="art", + * type="string" + * ), + * @OA\Property( + * property="preferences[sources][0]", + * description="bbc-news", + * type="string" + * ), + * @OA\Property( + * property="preferences[sources][1]", + * description="bbc-news", + * type="string" + * ), * @OA\Property(property="name", type="string") * ) * ) @@ -67,10 +93,37 @@ public function store(UserPreferenceStoreRequest $request) * @OA\MediaType( * mediaType="application/x-www-form-urlencoded", * @OA\Schema( - * type="object", - * @OA\Property(property="preferences[source]", type="string"), - * @OA\Property(property="preferences[published_at][from]", type="string"), - * @OA\Property(property="preferences[category]", type="string"), + * type="object", + * @OA\Property( + * property="preferences[authors][0]", + * description="Author 1", + * type="string" + * ), + * @OA\Property( + * property="preferences[authors][1]", + * description="Author 2", + * type="string" + * ), + * @OA\Property( + * property="preferences[categories][0]", + * description="sport", + * type="string" + * ), + * @OA\Property( + * property="preferences[categories][1]", + * description="art", + * type="string" + * ), + * @OA\Property( + * property="preferences[sources][0]", + * description="bbc-news", + * type="string" + * ), + * @OA\Property( + * property="preferences[sources][1]", + * description="bbc-news", + * type="string" + * ), * @OA\Property(property="name", type="string") * ) * ) diff --git a/app/Http/Requests/UserPreferenceStoreRequest.php b/app/Http/Requests/UserPreferenceStoreRequest.php index d43c3b4..b52e35f 100644 --- a/app/Http/Requests/UserPreferenceStoreRequest.php +++ b/app/Http/Requests/UserPreferenceStoreRequest.php @@ -24,11 +24,9 @@ public function authorize(): bool public function rules(): array { return [ - 'preferences.source' => 'required_without_all:preferences.published_at,preferences.category', - 'preferences.published_at' => [ - 'from' => 'required_without_all:preferences.source,preferences.category', - ], - 'preferences.category' => 'required_without_all:preferences.source,preferences.published_at', + 'preferences.sources' => 'required_without_all:preferences.categories,preferences.authors', + 'preferences.categories' => 'required_without_all:preferences.source,preferences.authors', + 'preferences.authors' => 'required_without_all:preferences.source,preferences.categories', 'name' => 'required|string|unique:user_preferences,name', ]; } diff --git a/app/Http/Requests/UserPreferenceUpdateRequest.php b/app/Http/Requests/UserPreferenceUpdateRequest.php index 19ab406..cf867ca 100644 --- a/app/Http/Requests/UserPreferenceUpdateRequest.php +++ b/app/Http/Requests/UserPreferenceUpdateRequest.php @@ -24,11 +24,9 @@ public function authorize(): bool public function rules(): array { return [ - 'preferences.source' => 'required_without_all:preferences.published_at,preferences.category', - 'preferences.published_at' => [ - 'from' => 'required_without_all:preferences.source,preferences.category', - ], - 'preferences.category' => 'required_without_all:preferences.source,preferences.published_at', + 'preferences.sources' => 'required_without_all:preferences.categories,preferences.authors', + 'preferences.categories' => 'required_without_all:preferences.source,preferences.authors', + 'preferences.authors' => 'required_without_all:preferences.source,preferences.categories', 'name' => 'required|string', ]; } diff --git a/app/Logic/Service/NewsService.php b/app/Logic/Service/NewsService.php index 7fd72e5..111014a 100644 --- a/app/Logic/Service/NewsService.php +++ b/app/Logic/Service/NewsService.php @@ -31,14 +31,32 @@ public function getFilteredNews($data, int $limit = 10): LengthAwarePaginator if (!empty($data['preference'])) { $UserPreferenceData = $this->UserPreferenceService->findOrFailByName($data['preference']); $data = $UserPreferenceData['preferences']; - } - $this->filterNewsByData($data); + $this->filterNewsByPreferenceData($data); + + } else { + $this->filterNewsByData($data); + } $out = $this->newsRepo->getFilteredDataPaginate(['Source.DataSource'], $limit); return $out; } + /** + * @param mixed $data + * @return void + */ + private function filterNewsByPreferenceData(mixed $data): void + { + collect($data)->filter()->each(function ($item, $key) { + match ($key) { + 'sources' => $this->newsRepo->getFilteredBySource($item), + 'categories' => $this->newsRepo->getFilteredByCategory($item), + 'authors' => $this->newsRepo->getFilteredByAuthor($item), + }; + }); + } + /** * @param mixed $data * @return void diff --git a/app/Models/News.php b/app/Models/News.php index a5fbb4d..e7c606e 100644 --- a/app/Models/News.php +++ b/app/Models/News.php @@ -44,7 +44,7 @@ public function Source() public function scopeGetSource($query, $value) { return $query->whereHas('Source', function ($q) use ($value) { - $q->where('name', $value); + $q->whereIn('name', $value); }); } @@ -62,15 +62,24 @@ public function scopeGetPublishedAt($query, string $fromDate, ?string $toDate = } + /** + * @param $query + * @param $category + * @return mixed + */ + public function scopeGetCategory($query, $category) + { + return $query->whereIn('category', $category); + } /** * @param $query - * @param string|null $category + * @param $author * @return mixed */ - public function scopeGetCategory($query, ?string $category = null) + public function scopeGetAuthor($query, $author) { - return $query->where('category', $category); + return $query->whereIn('author', $author); } /** diff --git a/app/Repositories/News/EloquentNewsRepository.php b/app/Repositories/News/EloquentNewsRepository.php index 23edb0e..c2ee3a8 100644 --- a/app/Repositories/News/EloquentNewsRepository.php +++ b/app/Repositories/News/EloquentNewsRepository.php @@ -104,21 +104,30 @@ public function getFilteredByPublishedAt($from_published_at, $to_published_at): } /** - * @param $category + * @param string $category * @return void */ - public function getFilteredByCategory($category): void + public function getFilteredByCategory(string $category): void { $this->setBuilder($this->getBuilder()->getCategory($category)); } /** - * @param $category + * @param $author * @return void */ - public function searchByText($category): void + public function getFilteredByAuthor($author): void { - $this->setBuilder($this->getBuilder()->search($category)); + $this->setBuilder($this->getBuilder()->getAuthor($author)); + } + + /** + * @param string $text + * @return void + */ + public function searchByText(string $text): void + { + $this->setBuilder($this->getBuilder()->search($text)); } /** diff --git a/app/Repositories/News/NewsRepository.php b/app/Repositories/News/NewsRepository.php index d648e2b..9c662da 100644 --- a/app/Repositories/News/NewsRepository.php +++ b/app/Repositories/News/NewsRepository.php @@ -59,16 +59,22 @@ public function getFilteredBySource($source); public function getFilteredByPublishedAt($from_published_at, $to_published_at): void; /** - * @param $category + * @param string $category * @return void */ - public function getFilteredByCategory($category): void; + public function getFilteredByCategory(string $category): void; /** - * @param $category + * @param string $author * @return void */ - public function searchByText($category): void; + public function getFilteredByAuthor(string $author): void; + + /** + * @param string $text + * @return void + */ + public function searchByText(string $text): void; /** * @param array $relations diff --git a/storage/api-docs/api-docs.json b/storage/api-docs/api-docs.json index 407db49..7d142c8 100644 --- a/storage/api-docs/api-docs.json +++ b/storage/api-docs/api-docs.json @@ -29,7 +29,7 @@ "name": "published_at[to]", "in": "query", "description": "published_at to", - "example": "2023-12-04" + "example": "2023-12-05" }, { "name": "category", @@ -89,16 +89,28 @@ "multipart/form-data": { "schema": { "properties": { - "preferences[source]": { + "preferences[authors][0]": { + "description": "Author 1", "type": "string" }, - "preferences[published_at][from]": { + "preferences[authors][1]": { + "description": "Author 2", "type": "string" }, - "preferences[published_at][to]": { + "preferences[categories][0]": { + "description": "sport", "type": "string" }, - "preferences[category]": { + "preferences[categories][1]": { + "description": "art", + "type": "string" + }, + "preferences[sources][0]": { + "description": "bbc-news", + "type": "string" + }, + "preferences[sources][1]": { + "description": "bbc-news", "type": "string" }, "name": { @@ -139,13 +151,28 @@ "application/x-www-form-urlencoded": { "schema": { "properties": { - "preferences[source]": { + "preferences[authors][0]": { + "description": "Author 1", + "type": "string" + }, + "preferences[authors][1]": { + "description": "Author 2", + "type": "string" + }, + "preferences[categories][0]": { + "description": "sport", + "type": "string" + }, + "preferences[categories][1]": { + "description": "art", "type": "string" }, - "preferences[published_at][from]": { + "preferences[sources][0]": { + "description": "bbc-news", "type": "string" }, - "preferences[category]": { + "preferences[sources][1]": { + "description": "bbc-news", "type": "string" }, "name": {