InfluxOW/laravel_ddd_ecommerce

View on GitHub
app/Interfaces/Http/Controllers/Controller.php

Summary

Maintainability
A
0 mins
Test Coverage
F
0%
<?php

namespace App\Interfaces\Http\Controllers;

use App\Components\Queryable\Abstracts\Filter\FilterService;
use App\Components\Queryable\Abstracts\Sort\SortService;
use App\Components\Queryable\Enums\QueryKey;
use App\Components\Queryable\Services\Filter\FilterQueryResourceBuilder;
use App\Components\Queryable\Services\Sort\SortQueryResourceBuilder;
use App\Domains\Common\Enums\Response\ResponseKey;
use App\Domains\Common\Http\Requests\IndexRequest;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Routing\Controller as BaseController;
use OpenApi\Annotations as OA;
use Spatie\QueryBuilder\QueryBuilder;

/**
 * @OA\OpenApi(
 *
 *    @OA\Info(
 *       title="E-Commerce App API",
 *       description="E-Commerce App",
 *       version="1.0.0",
 *
 *       @OA\Contact(
 *          email="krochak_n@mail.ru",
 *          url="https://github.com/InfluxOW"
 *       ),
 *    ),
 *
 *    @OA\Server(
 *       url=L5_SWAGGER_CONST_HOST,
 *       description="E-Commerce App API Server",
 *
 *       @OA\ServerVariable(
 *          serverVariable="schema",
 *          enum={"https", "http"},
 *          default="https",
 *       ),
 *    ),
 * )
 */
abstract class Controller extends BaseController
{
    use AuthorizesRequests;
    use DispatchesJobs;
    use ValidatesRequests;
    use ResponseTrait;

    /**
     * @param class-string<JsonResource> $resource
     */
    protected function respondPaginated(string $resource, QueryBuilder|Builder $query, IndexRequest $request, ?FilterService $filterService = null, ?SortService $sortService = null): AnonymousResourceCollection
    {
        if ($query instanceof Builder) {
            $query = QueryBuilder::for($query);
        }

        $validated = $request->validated();
        $additional = [];
        $searchFilterIsApplied = false;

        if (isset($filterService)) {
            $filterService->build();

            $query->allowedFilters($filterService->callbacks()->toArray());

            $filterQueryResourceBuilder = (new FilterQueryResourceBuilder($filterService));
            $searchFilterIsApplied = $filterQueryResourceBuilder->hasAppliedSearchFilter($request);

            $additional[ResponseKey::QUERY->value][QueryKey::FILTER->value] = $filterQueryResourceBuilder->resource($request);
        }

        if (isset($sortService)) {
            $sortService->build();

            $query
                ->allowedSorts($sortService->callbacks()->toArray())
                ->defaultSort($sortService->getDefaultCallback($searchFilterIsApplied));

            $additional[ResponseKey::QUERY->value][QueryKey::SORT->value] = (new SortQueryResourceBuilder($sortService))->resource($request, $searchFilterIsApplied);
        }

        $items = $query
            ->paginate($validated[QueryKey::PER_PAGE->value], ['*'], QueryKey::PAGE->value, $validated[QueryKey::PAGE->value])
            ->appends($request->append());

        return $this->respondWithCollection($resource, $items, $additional);
    }
}