These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace PragmaRX\Health\Support; |
||
4 | |||
5 | use Exception; |
||
6 | use Illuminate\Support\Collection; |
||
7 | use PragmaRX\Health\Support\Traits\HandleExceptions; |
||
8 | |||
9 | class ResourceChecker |
||
10 | { |
||
11 | use HandleExceptions; |
||
12 | |||
13 | /** |
||
14 | * Unknown error. |
||
15 | */ |
||
16 | const UNKNOWN_ERROR = 'Unknown error.'; |
||
17 | |||
18 | /** |
||
19 | * The current action. |
||
20 | * |
||
21 | * @var |
||
22 | */ |
||
23 | protected $currentAction = 'check'; |
||
24 | |||
25 | /** |
||
26 | * All resources. |
||
27 | * |
||
28 | * @var |
||
29 | */ |
||
30 | protected $resources; |
||
31 | |||
32 | /** |
||
33 | * Was checked? |
||
34 | * |
||
35 | * @var |
||
36 | */ |
||
37 | protected $checked; |
||
38 | |||
39 | /** |
||
40 | * Services already notified of error. |
||
41 | * |
||
42 | * @var |
||
43 | */ |
||
44 | protected $notified = []; |
||
45 | |||
46 | /** |
||
47 | * The cache service. |
||
48 | * |
||
49 | * @var Cache |
||
50 | */ |
||
51 | protected $cache; |
||
52 | |||
53 | /** |
||
54 | * Resource loader. |
||
55 | * |
||
56 | * @var ResourceLoader |
||
57 | */ |
||
58 | protected $resourceLoader; |
||
59 | |||
60 | /** |
||
61 | * ResourceChecker constructor. |
||
62 | * |
||
63 | * @param ResourceLoader $resourceLoader |
||
64 | * @param Cache $cache |
||
65 | */ |
||
66 | 2 | public function __construct(ResourceLoader $resourceLoader, Cache $cache) |
|
67 | { |
||
68 | 2 | $this->cache = $cache; |
|
69 | |||
70 | 2 | $this->resourceLoader = $resourceLoader; |
|
71 | 2 | } |
|
72 | |||
73 | /** |
||
74 | * Check all resources. |
||
75 | * |
||
76 | * @param bool $force |
||
77 | * @return \Illuminate\Support\Collection |
||
78 | * @throws Exception |
||
79 | */ |
||
80 | public function checkResources($force = false) |
||
81 | { |
||
82 | if (!($resources = $this->getCachedResources($force))->isEmpty()) { |
||
83 | return $resources; |
||
84 | } |
||
85 | |||
86 | if (!$this->allResourcesAreGood()) { |
||
87 | return $this->resources = collect(); |
||
88 | } |
||
89 | |||
90 | $resources = $this->sortResources( |
||
91 | $this->getNonGlobalResources() |
||
92 | ->each(function ($resource) { |
||
93 | $this->checkResource($resource); |
||
94 | }) |
||
95 | ->merge( |
||
96 | $this->getGlobalResources()->each(function ($resource) { |
||
97 | return $resource->checkGlobal($this->getResources()); |
||
98 | }) |
||
99 | ) |
||
100 | ); |
||
101 | |||
102 | $this->checked = true; |
||
103 | |||
104 | return $this->resources = $this->cache->cacheResources($resources); |
||
105 | } |
||
106 | |||
107 | /** |
||
108 | * Check a resource. |
||
109 | * |
||
110 | * @param $resource |
||
111 | * @return array |
||
112 | * @throws Exception |
||
113 | */ |
||
114 | public function checkResource($resource) |
||
115 | { |
||
116 | $resource = |
||
117 | $resource instanceof Resource |
||
118 | ? $resource |
||
119 | : $this->getResourceBySlug($resource); |
||
120 | |||
121 | $checked = $this->cache->remember($resource->slug, function () use ( |
||
122 | $resource |
||
123 | ) { |
||
124 | return $resource->check(); |
||
125 | }); |
||
126 | |||
127 | $resource->targets = $checked->targets; |
||
128 | |||
129 | return $resource; |
||
130 | } |
||
131 | |||
132 | /** |
||
133 | * Get cached resources. |
||
134 | * |
||
135 | * @param bool $force |
||
136 | * @return \Illuminate\Support\Collection |
||
137 | * @throws Exception |
||
138 | */ |
||
139 | protected function getCachedResources($force = false) |
||
140 | { |
||
141 | if ($force) { |
||
142 | return collect(); |
||
143 | } |
||
144 | |||
145 | if ($this->checked) { |
||
146 | return $this->getResources(); |
||
147 | } |
||
148 | |||
149 | return $this->resources = $this->cache->getCachedResources(); |
||
150 | } |
||
151 | |||
152 | /** |
||
153 | * Get current action. |
||
154 | * |
||
155 | * @return mixed |
||
156 | */ |
||
157 | public function getCurrentAction() |
||
158 | { |
||
159 | return $this->currentAction; |
||
160 | } |
||
161 | |||
162 | /** |
||
163 | * Get all non global resources. |
||
164 | * |
||
165 | * @return bool |
||
166 | * @throws Exception |
||
167 | */ |
||
168 | protected function allResourcesAreGood() |
||
169 | { |
||
170 | return !$this->getResources() |
||
171 | ->reject(function ($resource) { |
||
172 | return !$resource instanceof Resource; |
||
173 | }) |
||
174 | ->isEmpty(); |
||
175 | } |
||
176 | |||
177 | /** |
||
178 | * Get all non global resources. |
||
179 | * |
||
180 | * @return Collection |
||
181 | * @throws Exception |
||
182 | */ |
||
183 | protected function getNonGlobalResources() |
||
184 | { |
||
185 | return $this->getResources()->filter(function (Resource $resource) { |
||
186 | return !$resource->isGlobal; |
||
187 | }); |
||
188 | } |
||
189 | |||
190 | /** |
||
191 | * Get all global resources. |
||
192 | * |
||
193 | * @return Collection |
||
194 | * @throws Exception |
||
195 | */ |
||
196 | protected function getGlobalResources() |
||
197 | { |
||
198 | return $this->getResources()->filter(function (Resource $resource) { |
||
199 | return $resource->isGlobal; |
||
200 | }); |
||
201 | } |
||
202 | |||
203 | /** |
||
204 | * Get a resource by slug. |
||
205 | * |
||
206 | * @param $slug |
||
207 | * @return mixed |
||
208 | * @throws Exception |
||
209 | */ |
||
210 | public function getResourceBySlug($slug) |
||
211 | { |
||
212 | return $this->getResources() |
||
213 | ->where('slug', $slug) |
||
214 | ->first(); |
||
215 | } |
||
216 | |||
217 | /** |
||
218 | * Make the result array. |
||
219 | * |
||
220 | * @param $exception |
||
221 | * @param $resourceChecker |
||
222 | * @return array |
||
223 | */ |
||
224 | protected function makeResult($exception, $resourceChecker) |
||
225 | { |
||
226 | $message = $exception->getMessage() |
||
227 | ? $exception->getMessage() |
||
228 | : static::UNKNOWN_ERROR; |
||
229 | |||
230 | if (!isset($resourceChecker)) { |
||
231 | return [ |
||
232 | null, |
||
233 | [ |
||
234 | 'healthy' => false, |
||
235 | 'message' => $message, |
||
236 | ], |
||
237 | ]; |
||
238 | } |
||
239 | |||
240 | $resourceChecker->makeResult(false, $message); |
||
241 | |||
242 | return [$resourceChecker, null]; |
||
243 | } |
||
244 | |||
245 | /** |
||
246 | * Get all resources. |
||
247 | * |
||
248 | * @return \Illuminate\Support\Collection |
||
249 | * @throws Exception |
||
250 | */ |
||
251 | public function getResources() |
||
252 | { |
||
253 | return $this->sortResources($this->loadResources()); |
||
254 | } |
||
255 | |||
256 | /** |
||
257 | * Set the current action. |
||
258 | * |
||
259 | * @param mixed $currentAction |
||
260 | */ |
||
261 | public function setCurrentAction($currentAction) |
||
262 | { |
||
263 | $this->currentAction = $currentAction; |
||
264 | } |
||
265 | |||
266 | /** |
||
267 | * Resources setter. |
||
268 | * |
||
269 | * @param mixed $resources |
||
270 | */ |
||
271 | public function setResources($resources) |
||
272 | { |
||
273 | $this->resources = $resources; |
||
274 | } |
||
275 | |||
276 | /** |
||
277 | * Load all resources. |
||
278 | * |
||
279 | * @return \Illuminate\Support\Collection |
||
280 | * @throws Exception |
||
281 | */ |
||
282 | public function loadResources() |
||
283 | { |
||
284 | if (is_null($this->resources) || $this->resources->isEmpty()) { |
||
285 | $this->resources = $this->resourceLoader->loadResources()->map( |
||
286 | function ($resource) { |
||
287 | return $this->handleExceptions(function () use ($resource) { |
||
288 | return $this->makeResource($resource); |
||
289 | }); |
||
290 | } |
||
291 | ); |
||
292 | } |
||
293 | |||
294 | return $this->resources; |
||
0 ignored issues
–
show
|
|||
295 | } |
||
296 | |||
297 | /** |
||
298 | * Get one resource. |
||
299 | * |
||
300 | * @param resource|Collection $resource |
||
301 | * @return \PragmaRX\Health\Support\Resource |
||
302 | */ |
||
303 | public function makeResource($resource) |
||
304 | { |
||
305 | if ($resource instanceof Resource) { |
||
306 | return $resource; |
||
307 | } |
||
308 | |||
309 | return Resource::factory($resource); |
||
0 ignored issues
–
show
It seems like
$resource defined by parameter $resource on line 303 can also be of type resource ; however, PragmaRX\Health\Support\Resource::factory() does only seem to accept object<Illuminate\Support\Collection> , maybe add an additional type check?
This check looks at variables that have been passed in as parameters and are passed out again to other methods. If the outgoing method call has stricter type requirements than the method itself, an issue is raised. An additional type check may prevent trouble.
Loading history...
|
|||
310 | } |
||
311 | |||
312 | /** |
||
313 | * Sort resources. |
||
314 | * |
||
315 | * @param $resources |
||
316 | * @return \Illuminate\Support\Collection |
||
317 | */ |
||
318 | protected function sortResources($resources) |
||
319 | { |
||
320 | if ($sortBy = config('health.sort_by')) { |
||
321 | return $resources->sortBy(function ($resource) use ($sortBy) { |
||
322 | return $this->handleExceptions(function () use ( |
||
323 | $resource, |
||
324 | $sortBy |
||
325 | ) { |
||
326 | return ( |
||
327 | ($resource->isGlobal ? 'a-' : 'z-') . $resource->$sortBy |
||
328 | ); |
||
329 | }); |
||
330 | }); |
||
331 | } |
||
332 | |||
333 | return $resources; |
||
334 | } |
||
335 | } |
||
336 |
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.
Let’s take a look at an example:
Our function
my_function
expects aPost
object, and outputs the author of the post. The base classPost
returns a simple string and outputting a simple string will work just fine. However, the child classBlogPost
which is a sub-type ofPost
instead decided to return anobject
, and is therefore violating the SOLID principles. If aBlogPost
were passed tomy_function
, PHP would not complain, but ultimately fail when executing thestrtoupper
call in its body.