Passed
Push — main ( 2532b4...65db39 )
by Mohammad
02:36
created

Controller::authorizeAction()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 3
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 5
rs 10
1
<?php
2
3
/** @noinspection PhpMultipleClassDeclarationsInspection */
4
5
namespace Shamaseen\Repository\Utility;
6
7
use Exception;
8
use \Illuminate\Support\Facades\Gate;
9
use Illuminate\Auth\Access\AuthorizationException;
10
use Illuminate\Contracts\View\View;
11
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
12
use Illuminate\Foundation\Bus\DispatchesJobs;
13
use Illuminate\Foundation\Validation\ValidatesRequests;
14
use Illuminate\Http\JsonResponse;
15
use Illuminate\Http\RedirectResponse;
16
use Illuminate\Routing\Controller as LaravelController;
17
use Illuminate\Support\Collection;
18
use Illuminate\Support\Facades\App;
19
use Illuminate\Support\Facades\Route;
20
use Symfony\Component\HttpFoundation\Response;
21
22
/**
23
 * Class BaseController.
24
 */
25
class Controller extends LaravelController
26
{
27
    use AuthorizesRequests;
28
    use DispatchesJobs;
29
    use ValidatesRequests;
30
31
    public AbstractRepository $repository;
32
    public Request $request;
33
34
    public int $limit = 10;
35
    public int $maxLimit = 100;
36
37
    public string $pageTitle = '';
38
    public Collection $breadcrumbs;
39
40
    /**
41
     * Can be either a route name or a URL.
42
     */
43
    public string $routeIndex = '';
44
    public string $createRoute = '';
45
46
    public string $viewIndex = '';
47
    public string $viewCreate = '';
48
    public string $viewEdit = '';
49
    public string $viewShow = '';
50
51
    public bool $isAPI = false;
52
53
    public ?string $paginateType = null;
54
55
    /**
56
     * Allow returning trash if the frontend user request it.
57
     */
58
    public bool $allowTrashRequest = false;
59
60
    public array $params = [];
61
62
    public ResponseDispatcher $responseDispatcher;
63
    public string $requestClass = Request::class;
64
    public ?string $policyClass = null;
65
    public ?string $resourceClass;
66
    public ?string $collectionClass;
67
68
    /**
69
     * BaseController constructor.
70
     */
71
    public function __construct(AbstractRepository $repository)
72
    {
73
        $this->repository = $repository;
74
        $this->breadcrumbs = new Collection();
75
        $this->paginateType = $this->paginateType ?? config('repository.default_pagination');
76
    }
77
78
    /**
79
     * @throws AuthorizationException
80
     */
81
    public function authorizeAction(string $action): void
82
    {
83
        if ($this->policyClass && method_exists($this->policyClass, $action)) {
84
            Gate::policy($this->repository->getModelClass(), $this->policyClass)
85
                ->authorize($action, $this->repository->getModelClass());
86
        }
87
    }
88
89
    /**
90
     * Any data that depend on the request instance should be inside this callback,
91
     * Request instance should be initialized after other middlewares.
92
     *
93
     * @param $method
94
     * @param $parameters
95
     *
96
     * @return Response
97
     *
98
     * @throws AuthorizationException
99
     */
100
    public function callAction($method, $parameters)
101
    {
102
        $this->request = App::make($this->requestClass, ['repository' => $this->repository]);
103
104
        $this->authorizeAction($method);
105
106
        $this->isAPI = $this->request->expectsJson();
107
        $this->limit = min($this->request->get('limit', $this->limit), $this->maxLimit);
108
109
        if ($this->allowTrashRequest) {
110
            if ($this->request->get('with-trash', false)) {
111
                $this->repository->withTrash();
0 ignored issues
show
Bug introduced by
The method withTrash() does not exist on Shamaseen\Repository\Utility\AbstractRepository. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

111
                $this->repository->/** @scrutinizer ignore-call */ 
112
                                   withTrash();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
112
            }
113
114
            if ($this->request->get('only-trash', false)) {
115
                $this->repository->onlyTrash();
0 ignored issues
show
Bug introduced by
The method onlyTrash() does not exist on Shamaseen\Repository\Utility\AbstractRepository. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

115
                $this->repository->/** @scrutinizer ignore-call */ 
116
                                   onlyTrash();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
116
            }
117
        }
118
119
        $this->request->offsetUnset('only-trash');
120
        $this->request->offsetUnset('with-trash');
121
        $this->request->offsetUnset('limit');
122
        $this->responseDispatcher = new ResponseDispatcher($this);
123
124
        return parent::callAction($method, $parameters);
125
    }
126
127
    /**
128
     * Display a listing of the model.
129
     */
130
    public function index(): View|JsonResponse
131
    {
132
        $this->breadcrumbs->put('index', [
133
            'link' => $this->resolveRoute($this->routeIndex),
134
            'text' => $this->pageTitle,
135
        ]);
136
137
        if ('simple' === $this->paginateType) {
138
            $paginate = $this->repository->simplePaginate($this->limit, $this->request->all());
139
        } else {
140
            $paginate = $this->repository->paginate($this->limit, $this->request->all());
141
        }
142
143
        return $this->responseDispatcher->index($paginate);
144
    }
145
146
    /**
147
     * Display the specified resource.
148
     */
149
    public function show(int $entityId): View|JsonResponse
150
    {
151
        $this->breadcrumbs->put('view', [
152
            'link' => '',
153
            'text' => __('repository.show'),
154
        ]);
155
156
        $entity = $this->repository->findOrFail($entityId);
157
158
        return $this->responseDispatcher->show($entity);
159
    }
160
161
    /**
162
     * Show the form to create a new resource, only for web responses.
163
     */
164
    public function create(): View|JsonResponse
165
    {
166
        $this->breadcrumbs->put('create', [
167
            'link' => $this->resolveRoute($this->createRoute),
168
            'text' => trans('repository.create'),
169
        ]);
170
171
        return $this->responseDispatcher->create();
172
    }
173
174
    /**
175
     * Store a newly created resource in storage.
176
     */
177
    public function store(): JsonResponse|RedirectResponse
178
    {
179
        $entity = $this->repository->create($this->request->except(['_token', '_method']));
180
181
        return $this->responseDispatcher->store($entity);
182
    }
183
184
    /**
185
     * Show the form for editing the specified resource.
186
     */
187
    public function edit(int $entityId): View|JsonResponse
188
    {
189
        $this->breadcrumbs->put('edit', [
190
            'link' => '',
191
            'text' => __('repository.edit'),
192
        ]);
193
194
        $entity = $this->repository->findOrFail($entityId);
195
196
        return $this->responseDispatcher->edit($entity);
197
    }
198
199
    /**
200
     * Update the specified resource in storage.
201
     */
202
    public function update(int $entityId): JsonResponse|RedirectResponse
203
    {
204
        $updatedCount = $this->repository->update($entityId, $this->request->except(['_token', '_method']));
205
206
        return $this->responseDispatcher->update($updatedCount);
207
    }
208
209
    /**
210
     * Remove the specified resource from storage.
211
     *
212
     * @throws Exception
213
     */
214
    public function destroy(int $entityId): JsonResponse|RedirectResponse
215
    {
216
        $deletedCount = $this->repository->delete($entityId);
217
218
        return $this->responseDispatcher->destroy($deletedCount);
219
    }
220
221
    /**
222
     * Return a URI from a route or URL.
223
     */
224
    public function resolveRoute(string $route): string
225
    {
226
        return Route::has($route) ? route($route) : $route;
227
    }
228
}
229