add Anime/Manga Advanced Search

Pagination, Limit
Order By + Sort
Query
Letter
This commit is contained in:
Irfan 2020-07-10 20:58:07 +05:00
parent 7bb1c99b44
commit d20d0ef5da
9 changed files with 311 additions and 11 deletions

54
app/GenreAnime.php Normal file
View File

@ -0,0 +1,54 @@
<?php
namespace App;
use Jenssegers\Mongodb\Eloquent\Model;
use Jikan\Request\Genre\AnimeGenresRequest;
/**
* Class Magazine
* @package App
*/
class GenreAnime extends Model
{
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'mal_id', 'name', 'url', 'count'
];
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'genres_anime';
/**
* The attributes excluded from the model's JSON form.
*
* @var array
*/
protected $hidden = [
'_id', 'expiresAt'
];
/**
* @return array
*/
public static function scrape() : array
{
$data = app('JikanParser')->getAnimeGenres(new AnimeGenresRequest());
return json_decode(
app('SerializerV4')
->serialize($data, 'json'),
true
);
}
}

54
app/GenreManga.php Normal file
View File

@ -0,0 +1,54 @@
<?php
namespace App;
use Jenssegers\Mongodb\Eloquent\Model;
use Jikan\Request\Genre\AnimeGenresRequest;
/**
* Class Magazine
* @package App
*/
class GenreManga extends Model
{
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'mal_id', 'name', 'url', 'count'
];
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'genres_manga';
/**
* The attributes excluded from the model's JSON form.
*
* @var array
*/
protected $hidden = [
'_id', 'expiresAt'
];
/**
* @return array
*/
public static function scrape() : array
{
$data = app('JikanParser')->getAnimeGenres(new AnimeGenresRequest());
return json_decode(
app('SerializerV4')
->serialize($data, 'json'),
true
);
}
}

View File

@ -3,7 +3,14 @@
namespace App\Http\Controllers\V4DB;
use App\Anime;
use App\GenreAnime;
use App\GenreManga;
use App\Http\QueryBuilder\SearchQueryBuilderGenre;
use App\Http\QueryBuilder\SearchQueryBuilderProducer;
use App\Http\Resources\V4\AnimeCollection;
use App\Http\Resources\V4\GenreCollection;
use App\Http\Resources\V4\ProducerCollection;
use App\Producer;
use Illuminate\Http\Request;
use Jikan\Request\Genre\AnimeGenreRequest;
use Jikan\Request\Genre\AnimeGenresRequest;
@ -43,15 +50,73 @@ class GenreController extends Controller
return response($this->serializer->serialize($person, 'json'));
}
public function animeListing()
public function mainAnime(Request $request)
{
$results = $this->jikan->getAnimeGenres(new AnimeGenresRequest());
return response($this->serializer->serialize($results, 'json'));
$page = $request->get('page') ?? 1;
$limit = $request->get('limit') ?? self::MAX_RESULTS_PER_PAGE;
if (!empty($limit)) {
$limit = (int) $limit;
if ($limit <= 0) {
$limit = 1;
}
if ($limit > self::MAX_RESULTS_PER_PAGE) {
$limit = self::MAX_RESULTS_PER_PAGE;
}
}
$results = SearchQueryBuilderGenre::query(
$request,
GenreAnime::query()
);
$results = $results
->paginate(
$limit,
['*'],
null,
$page
);
return new GenreCollection(
$results
);
}
public function mangaListing()
public function mainManga(Request $request)
{
$results = $this->jikan->getAnimeGenres(new AnimeGenresRequest());
return response($this->serializer->serialize($results, 'json'));
$page = $request->get('page') ?? 1;
$limit = $request->get('limit') ?? self::MAX_RESULTS_PER_PAGE;
if (!empty($limit)) {
$limit = (int) $limit;
if ($limit <= 0) {
$limit = 1;
}
if ($limit > self::MAX_RESULTS_PER_PAGE) {
$limit = self::MAX_RESULTS_PER_PAGE;
}
}
$results = SearchQueryBuilderGenre::query(
$request,
GenreManga::query()
);
$results = $results
->paginate(
$limit,
['*'],
null,
$page
);
return new GenreCollection(
$results
);
}
}

View File

@ -0,0 +1,64 @@
<?php
namespace App\Http\QueryBuilder;
use Illuminate\Http\Request;
use Jenssegers\Mongodb\Eloquent\Builder;
class SearchQueryBuilderGenre implements SearchQueryBuilderInterface
{
const MAX_RESULTS_PER_PAGE = 50;
const ORDER_BY = [
'mal_id', 'title', 'count'
];
public static function query(Request $request, Builder $results) : Builder
{
$query = $request->get('q');
$orderBy = $request->get('order_by');
$sort = self::mapSort($request->get('sort'));
$letter = $request->get('letter');
if (!empty($query) && is_null($letter)) {
$results = $results
->where('name', 'like', "%{$query}%");
}
if (!is_null($letter)) {
$results = $results
->where('name', 'like', "{$letter}%");
}
if (empty($query)) {
$results = $results
->orderBy('mal_id');
}
if (!is_null($orderBy)) {
$results = $results
->orderBy($orderBy, $sort ?? 'asc');
}
return $results;
}
/**
* @param string|null $sort
* @return string|null
*/
public static function mapSort(?string $sort = null) : ?string
{
if (!is_null($sort)) {
return null;
}
$sort = strtolower($sort);
return $sort === 'desc' ? 'desc' : 'asc';
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace App\Http\Resources\V4;
use Illuminate\Http\Resources\Json\ResourceCollection;
class GenreCollection extends ResourceCollection
{
/**
* The resource that this resource collects.
*
* @var string
*/
public $collects = 'App\Http\Resources\V4\GenreResource';
/**
* Transform the resource collection into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'data' => $this->collection,
'links' => [
'self' => 'link-value',
],
];
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace App\Http\Resources\V4;
use Illuminate\Http\Resources\Json\JsonResource;
class GenreResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'mal_id' => $this->mal_id,
'name' => $this->name,
'url' => $this->url,
'count' => $this->count
];
}
}

View File

@ -193,7 +193,7 @@ class SearchQueryBuilder
}
}
// Genre
// GenreAnime
if (isset($_GET['genre']) && \is_string($_GET['genre']) && strpos($_GET['genre'], ',')) {
$_GET['genre'] = explode(',', $_GET['genre']);
}

View File

@ -147,8 +147,14 @@ return [
'UserController@reviews' => 'users_reviews',
'UserController@clubs' => 'users_clubs',
'GenreController@animeListing' => 'genres',
'GenreController@mangaListing' => 'genres',
'GenreController@mainAnime' => [
'table_name' => 'common',
'ttl' => env('CACHE_GENRE_EXPIRE')
],
'GenreController@mainManga' => [
'table_name' => 'common',
'ttl' => env('CACHE_GENRE_EXPIRE')
],
'GenreController@anime' => 'genres_anime',
'GenreController@manga' => 'genres_manga',

View File

@ -315,11 +315,11 @@ $router->group(
],
function () use ($router) {
$router->get('/anime', [
'uses' => 'GenreController@animeListing'
'uses' => 'GenreController@mainAnime'
]);
$router->get('/manga', [
'uses' => 'GenreController@mangaListing'
'uses' => 'GenreController@mainManga'
]);
$router->get('/anime/{id:[0-9]+}[/{page:[0-9]+}]', [