HasMedias::findMedia()   C
last analyzed

Complexity

Conditions 12
Paths 4

Size

Total Lines 31
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 45.561

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 12
eloc 15
nc 4
nop 2
dl 0
loc 31
ccs 5
cts 13
cp 0.3846
crap 45.561
rs 6.9666
c 1
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace A17\Twill\Models\Behaviors;
4
5
use A17\Twill\Exceptions\MediaCropNotFoundException;
6
use A17\Twill\Models\Media;
7
use Illuminate\Database\Eloquent\Model;
8
use Illuminate\Support\Arr;
9
use A17\Twill\Services\MediaLibrary\ImageService;
10
11
trait HasMedias
12
{
13
    protected $cropParamsKeys = [
14
        'crop_x',
15
        'crop_y',
16
        'crop_w',
17
        'crop_h',
18 22
    ];
19
20 22
    public static function bootHasMedias(): void
21 22
    {
22 22
        self::deleted(static function (Model $model) {
23 22
            if (!method_exists($model, 'isForceDeleting') || $model->isForceDeleting()) {
24 22
                /** @var \A17\Twill\Models\Behaviors\HasMedias $model */
25 22
                $model->medias()->detach();
26
            }
27
        });
28
    }
29
30
    /**
31
     * Defines the many-to-many relationship for media objects.
32
     *
33
     * @return \Illuminate\Database\Eloquent\Relations\MorphToMany
34 22
     */
35 22
    public function medias()
36
    {
37
        return $this->morphToMany(
0 ignored issues
show
Bug introduced by
It seems like morphToMany() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

37
        return $this->/** @scrutinizer ignore-call */ morphToMany(
Loading history...
38 2
            Media::class,
39
            'mediable',
40 2
            config('twill.mediables_table', 'twill_mediables')
41
        )->withPivot(array_merge([
42
            'crop',
43
            'role',
44
            'crop_w',
45
            'crop_h',
46 2
            'crop_x',
47
            'crop_y',
48 2
            'lqip_data',
49
            'ratio',
50
            'metadatas',
51
        ], config('twill.media_library.translated_form_fields', false) ? ['locale'] : []))
52
            ->withTimestamps()->orderBy(config('twill.mediables_table', 'twill_mediables') . '.id', 'asc');
53
    }
54 2
55
    private function findMedia($role, $crop = "default")
56
    {
57
        $foundMedia = false;
58
        $media = $this->medias->first(function ($media) use ($role, $crop, &$foundMedia) {
59
            if (config('twill.media_library.translated_form_fields', false)) {
60
                $localeScope = $media->pivot->locale === app()->getLocale();
0 ignored issues
show
introduced by
The method getLocale() does not exist on Illuminate\Container\Container. Are you sure you never get this type here, but always one of the subclasses? ( Ignorable by Annotation )

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

60
                $localeScope = $media->pivot->locale === app()->/** @scrutinizer ignore-call */ getLocale();
Loading history...
61
            }
62
63
            if (!$foundMedia) {
64 2
                $foundMedia = $media->pivot->role === $role && ($localeScope ?? true);
65
            }
66
67 2
            return $foundMedia && $media->pivot->crop === $crop;
68 2
        });
69
70
        if (!$media && config('twill.media_library.translated_form_fields', false)) {
71 2
            $media = $this->medias->first(function ($media) use ($role, $crop, &$foundMedia) {
72
                if (!$foundMedia) {
73
                    $foundMedia = $media->pivot->role === $role;
74
                }
75
76
                return $foundMedia && $media->pivot->crop === $crop;
77
            });
78
        }
79
80
        if ($foundMedia && !$media && config('app.debug')) {
81
            // In this case we found the media but not the crop because our result is still empty.
82
            throw new MediaCropNotFoundException($crop);
83 2
        }
84
85
        return $media;
86
    }
87 2
88
    /**
89
     * Checks if an image has been attached for a role and crop.
90
     *
91
     * @param string $role Role name.
92
     * @param string $crop Crop name.
93
     * @return bool
94
     */
95
    public function hasImage($role, $crop = "default")
96
    {
97
        $media = $this->findMedia($role, $crop);
98
99
        return !empty($media);
100
    }
101
102
    /**
103
     * Returns the URL of the attached image for a role and crop.
104
     *
105
     * @param string $role Role name.
106
     * @param string $crop Crop name.
107
     * @param array $params Parameters compatible with the current image service, like `w` or `h`.
108
     * @param bool $has_fallback Indicate that you can provide a fallback. Will return `null` instead of the default image fallback.
109
     * @param bool $cms Indicate that you are displaying this image in the CMS views.
110
     * @param Media|null $media Provide a media object if you already retrieved one to prevent more SQL queries.
111
     * @return string|null
112
     */
113
    public function image($role, $crop = "default", $params = [], $has_fallback = false, $cms = false, $media = null)
114
    {
115
116
        if (!$media) {
117
            $media = $this->findMedia($role, $crop);
118
        }
119
120
        if ($media) {
121
122
            $crop_params = Arr::only($media->pivot->toArray(), $this->cropParamsKeys);
123
124
            if ($cms) {
125
126
                return ImageService::getCmsUrl($media->uuid, $crop_params + $params);
0 ignored issues
show
Bug introduced by
The method getCmsUrl() does not exist on A17\Twill\Services\MediaLibrary\ImageService. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

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

126
                return ImageService::/** @scrutinizer ignore-call */ getCmsUrl($media->uuid, $crop_params + $params);
Loading history...
127
            }
128
129
            return ImageService::getUrlWithCrop($media->uuid, $crop_params, $params);
0 ignored issues
show
Bug introduced by
The method getUrlWithCrop() does not exist on A17\Twill\Services\MediaLibrary\ImageService. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

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

129
            return ImageService::/** @scrutinizer ignore-call */ getUrlWithCrop($media->uuid, $crop_params, $params);
Loading history...
130
        }
131
132
        if ($has_fallback) {
133
            return null;
134
        }
135
136
        return ImageService::getTransparentFallbackUrl();
0 ignored issues
show
Bug introduced by
The method getTransparentFallbackUrl() does not exist on A17\Twill\Services\MediaLibrary\ImageService. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

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

136
        return ImageService::/** @scrutinizer ignore-call */ getTransparentFallbackUrl();
Loading history...
137
    }
138
139
    /**
140
     * Returns an array of URLs of all attached images for a role and crop.
141
     *
142
     * @param string $role Role name.
143
     * @param string $crop Crop name.
144
     * @param array $params Parameters compatible with the current image service, like `w` or `h`.
145
     * @return array
146
     */
147
    public function images($role, $crop = "default", $params = [])
148
    {
149
        $medias = $this->medias->filter(function ($media) use ($role, $crop) {
150
            return $media->pivot->role === $role && $media->pivot->crop === $crop;
151
        });
152
153
        $urls = [];
154
155
        foreach ($medias as $media) {
156
            $urls[] = $this->image($role, $crop, $params, false, false, $media);
157
        }
158
159
        return $urls;
160
    }
161
162
    /**
163
     * Returns an array of URLs of all attached images for a role, including all crops.
164
     *
165
     * @param string $role Role name.
166
     * @param array $params Parameters compatible with the current image service, like `w` or `h`.
167
     * @return array
168
     */
169
    public function imagesWithCrops($role, $params = [])
170
    {
171
        $medias = $this->medias->filter(function ($media) use ($role) {
172
            return $media->pivot->role === $role;
173
        });
174
175
        $urls = [];
176
177
        foreach ($medias as $media) {
178
            $paramsForCrop = $params[$media->pivot->crop] ?? [];
179
            $urls[$media->id][$media->pivot->crop] = $this->image($role, $media->pivot->crop, $paramsForCrop, false, false, $media);
180
        }
181
182
        return $urls;
183
    }
184
185
    /**
186
     * Returns an array of meta information for the image attached for a role and crop.
187
     *
188
     * @param string $role Role name.
189
     * @param string $crop Crop name.
190
     * @param array $params Parameters compatible with the current image service, like `w` or `h`.
191
     * @param Media|null $media Provide a media object if you already retrieved one to prevent more SQL queries.
192
     * @return array
193
     */
194
    public function imageAsArray($role, $crop = "default", $params = [], $media = null)
195
    {
196
        if (!$media) {
197
            $media = $this->findMedia($role, $crop);
198
        }
199
200
        if ($media) {
201
            return [
202
                'src' => $this->image($role, $crop, $params, false, false, $media),
203
                'width' => $media->pivot->crop_w ?? $media->width,
204
                'height' => $media->pivot->crop_h ?? $media->height,
205
                'alt' => $this->imageAltText($role, $media),
206
                'caption' => $this->imageCaption($role, $media),
207
                'video' => $this->imageVideo($role, $media),
208
            ];
209
        }
210
211
        return [];
212
    }
213
214
    /**
215
     * Returns an array of meta information for all images attached for a role and crop.
216
     *
217
     * @param string $role Role name.
218
     * @param string $crop Crop name.
219
     * @param array $params Parameters compatible with the current image service, like `w` or `h`.
220
     * @return array
221
     */
222
    public function imagesAsArrays($role, $crop = "default", $params = [])
223
    {
224
        $medias = $this->medias->filter(function ($media) use ($role, $crop) {
225
            return $media->pivot->role === $role && $media->pivot->crop === $crop;
226
        });
227
228
        $arrays = [];
229
230
        foreach ($medias as $media) {
231
            $arrays[] = $this->imageAsArray($role, $crop, $params, $media);
232
        }
233
234
        return $arrays;
235
    }
236
237 2
    /**
238
     * Returns an array of meta information for all images attached for a role, including all crops.
239 2
     *
240
     * @param string $role Role name.
241
     * @param array $params Parameters compatible with the current image service, like `w` or `h`.
242 3
     * @return array
243
     */
244 3
    public function imagesAsArraysWithCrops($role, $params = [])
245
    {
246 3
        $medias = $this->medias->filter(function ($media) use ($role) {
247
            return $media->pivot->role === $role;
248
        });
249
250 3
        $arrays = [];
251
252
        foreach ($medias as $media) {
253
            $paramsForCrop = $params[$media->pivot->crop] ?? [];
254
            $arrays[$media->id][$media->pivot->crop] = $this->imageAsArray($role, $media->pivot->crop, $paramsForCrop, $media);
255
        }
256
257
        return $arrays;
258
    }
259
260
    /**
261
     * Returns the alt text of the image attached for a role.
262
     *
263
     * @param string $role Role name.
264
     * @param Media|null $media Provide a media object if you already retrieved one to prevent more SQL queries.
265
     * @return string
266
     */
267
    public function imageAltText($role, $media = null)
268
    {
269
        if (!$media) {
270
            $media = $this->medias->first(function ($media) use ($role) {
271
                if (config('twill.media_library.translated_form_fields', false)) {
272
                    $localeScope = $media->pivot->locale === app()->getLocale();
273
                }
274
275
                return $media->pivot->role === $role && ($localeScope ?? true);;
276
            });
277
        }
278
279
        if ($media) {
280
            return $media->getMetadata('altText', 'alt_text');
281
        }
282
283
        return '';
284
    }
285
286
    /**
287
     * Returns the caption of the image attached for a role.
288
     *
289
     * @param string $role Role name.
290
     * @param Media|null $media Provide a media object if you already retrieved one to prevent more SQL queries.
291
     * @return string
292
     */
293
    public function imageCaption($role, $media = null)
294
    {
295
        if (!$media) {
296
            $media = $this->medias->first(function ($media) use ($role) {
297
                if (config('twill.media_library.translated_form_fields', false)) {
298
                    $localeScope = $media->pivot->locale === app()->getLocale();
299
                }
300
301
                return $media->pivot->role === $role && ($localeScope ?? true);;
302
            });
303
        }
304
305
        if ($media) {
306
            return $media->getMetadata('caption');
307
        }
308
309
        return '';
310
    }
311
312
    /**
313
     * Returns the video URL of the image attached for a role.
314
     *
315
     * @param string $role Role name.
316
     * @param Media|null $media Provide a media object if you already retrieved one to prevent more SQL queries.
317
     * @return string
318
     */
319
    public function imageVideo($role, $media = null)
320
    {
321
        if (!$media) {
322
            $media = $this->medias->first(function ($media) use ($role) {
323
                if (config('twill.media_library.translated_form_fields', false)) {
324
                    $localeScope = $media->pivot->locale === app()->getLocale();
325
                }
326
327
                return $media->pivot->role === $role && ($localeScope ?? true);;
328
            });
329
        }
330
331
        if ($media) {
332
            $metadatas = (object) json_decode($media->pivot->metadatas);
333
            $language = app()->getLocale();
334
            return $metadatas->video->$language ?? (is_object($metadatas->video) ? '' : ($metadatas->video ?? ''));
335
        }
336
337
        return '';
338
    }
339
340
    /**
341
     * Returns the media object attached for a role and crop.
342
     *
343
     * @param string $role Role name.
344
     * @param string $crop Crop name.
345
     * @return Media|null
346
     */
347
    public function imageObject($role, $crop = "default")
348
    {
349
        return $this->findMedia($role, $crop);
350
    }
351
352
    /**
353
     * Returns the LQIP base64 encoded string for a role.
354
     * Use this in conjunction with the `RefreshLQIP` Artisan command.
355
     *
356
     * @param string $role Role name.
357
     * @param string $crop Crop name.
358
     * @param array $params Parameters compatible with the current image service, like `w` or `h`.
359
     * @param bool $has_fallback Indicate that you can provide a fallback. Will return `null` instead of the default image fallback.
360
     * @return string|null
361
     * @see \A17\Twill\Commands\RefreshLQIP
362
     */
363
    public function lowQualityImagePlaceholder($role, $crop = "default", $params = [], $has_fallback = false)
0 ignored issues
show
Unused Code introduced by
The parameter $params is not used and could be removed. ( Ignorable by Annotation )

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

363
    public function lowQualityImagePlaceholder($role, $crop = "default", /** @scrutinizer ignore-unused */ $params = [], $has_fallback = false)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
364
    {
365
        $media = $this->findMedia($role, $crop);
366
367
        if ($media) {
368
            return $media->pivot->lqip_data ?? ImageService::getTransparentFallbackUrl();
369
        }
370
371
        if ($has_fallback) {
372
            return null;
373
        }
374
375
        return ImageService::getTransparentFallbackUrl();
376
377
    }
378
379
    /**
380
     * Returns the URL of the social image for a role and crop.
381
     *
382
     * @param string $role Role name.
383
     * @param string $crop Crop name.
384
     * @param array $params Parameters compatible with the current image service, like `w` or `h`.
385
     * @param bool $has_fallback Indicate that you can provide a fallback. Will return `null` instead of the default image fallback.
386
     * @return string|null
387
     */
388
    public function socialImage($role, $crop = "default", $params = [], $has_fallback = false)
389
    {
390
        $media = $this->findMedia($role, $crop);
391
392
        if ($media) {
393
            $crop_params = Arr::only($media->pivot->toArray(), $this->cropParamsKeys);
394
395
            return ImageService::getSocialUrl($media->uuid, $crop_params + $params);
0 ignored issues
show
Bug introduced by
The method getSocialUrl() does not exist on A17\Twill\Services\MediaLibrary\ImageService. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

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

395
            return ImageService::/** @scrutinizer ignore-call */ getSocialUrl($media->uuid, $crop_params + $params);
Loading history...
396
        }
397
398
        if ($has_fallback) {
399
            return null;
400
        }
401
402
        return ImageService::getSocialFallbackUrl();
0 ignored issues
show
Bug introduced by
The method getSocialFallbackUrl() does not exist on A17\Twill\Services\MediaLibrary\ImageService. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

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

402
        return ImageService::/** @scrutinizer ignore-call */ getSocialFallbackUrl();
Loading history...
403
    }
404
405
    /**
406
     * Returns the URL of the CMS image for a role and crop.
407
     *
408
     * @param string $role Role name.
409
     * @param string $crop Crop name.
410
     * @param array $params Parameters compatible with the current image service, like `w` or `h`.
411
     * @return string
412
     */
413
    public function cmsImage($role, $crop = "default", $params = [])
414
    {
415
        return $this->image($role, $crop, $params, false, true, false) ?? ImageService::getTransparentFallbackUrl($params);
0 ignored issues
show
Bug introduced by
false of type false is incompatible with the type A17\Twill\Models\Media|null expected by parameter $media of A17\Twill\Models\Behaviors\HasMedias::image(). ( Ignorable by Annotation )

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

415
        return $this->image($role, $crop, $params, false, true, /** @scrutinizer ignore-type */ false) ?? ImageService::getTransparentFallbackUrl($params);
Loading history...
416
    }
417
418
    /**
419
     * Returns the URL of the default CMS image for this model.
420
     *
421
     * @param array $params Parameters compatible with the current image service, like `w` or `h`.
422
     * @return string
423
     */
424
    public function defaultCmsImage($params = [])
425
    {
426
        $media = $this->medias->first();
427
428
        if ($media) {
429
            return $this->image(null, null, $params, true, true, $media) ?? ImageService::getTransparentFallbackUrl($params);
430
        }
431
432
        return ImageService::getTransparentFallbackUrl($params);
433
    }
434
435
    /**
436
     * Returns the media objects associated with a role and crop.
437
     *
438
     * @param string $role Role name.
439
     * @param string $crop Crop name.
440
     * @return \Illuminate\Database\Eloquent\Collection
441
     */
442
    public function imageObjects($role, $crop = "default")
443
    {
444
        return $this->medias->filter(function ($media) use ($role, $crop) {
445
            return $media->pivot->role === $role && $media->pivot->crop === $crop;
446
        });
447
    }
448
}
449