Completed
Push — master ( c57572...957f36 )
by Ryan
07:40
created

Image::getCachePath()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 18
rs 8.8571
cc 5
eloc 10
nc 5
nop 0
1
<?php namespace Anomaly\Streams\Platform\Image;
2
3
use Anomaly\FilesModule\File\Contract\FileInterface;
4
use Anomaly\FilesModule\File\FilePresenter;
5
use Anomaly\Streams\Platform\Addon\FieldType\FieldType;
6
use Anomaly\Streams\Platform\Application\Application;
7
use Anomaly\Streams\Platform\Routing\UrlGenerator;
8
use Closure;
9
use Collective\Html\HtmlBuilder;
10
use Illuminate\Contracts\Config\Repository;
11
use Illuminate\Filesystem\Filesystem;
12
use Intervention\Image\Constraint;
13
use Intervention\Image\ImageManager;
14
use League\Flysystem\File;
15
use Mobile_Detect;
16
use Robbo\Presenter\Presenter;
17
18
/**
19
 * Class Image
20
 *
21
 * @link    http://anomaly.is/streams-platform
22
 * @author  AnomalyLabs, Inc. <[email protected]>
23
 * @author  Ryan Thompson <[email protected]>
24
 * @package Anomaly\Streams\Platform\Image
25
 */
26
class Image
27
{
28
29
    /**
30
     * The publish flag.
31
     *
32
     * @var bool
33
     */
34
    protected $publish = false;
35
36
    /**
37
     * The publishable base directory.
38
     *
39
     * @var null
40
     */
41
    protected $directory = null;
42
43
    /**
44
     * The image object.
45
     *
46
     * @var null|string
47
     */
48
    protected $image = null;
49
50
    /**
51
     * The file extension.
52
     *
53
     * @var null|string
54
     */
55
    protected $extension = null;
56
57
    /**
58
     * The desired filename.
59
     *
60
     * @var null|string
61
     */
62
    protected $filename = null;
63
64
    /**
65
     * The default output method.
66
     *
67
     * @var string
68
     */
69
    protected $output = 'url';
70
71
    /**
72
     * The image attributes.
73
     *
74
     * @var array
75
     */
76
    protected $attributes = [];
77
78
    /**
79
     * Applied alterations.
80
     *
81
     * @var array
82
     */
83
    protected $alterations = [];
84
85
    /**
86
     * Image srcsets.
87
     *
88
     * @var array
89
     */
90
    protected $srcsets = [];
91
92
    /**
93
     * Image sources.
94
     *
95
     * @var array
96
     */
97
    protected $sources = [];
98
99
    /**
100
     * Allowed methods.
101
     *
102
     * @var array
103
     */
104
    protected $allowedMethods = [
105
        'blur',
106
        'brightness',
107
        'colorize',
108
        'contrast',
109
        'crop',
110
        'encode',
111
        'fit',
112
        'flip',
113
        'gamma',
114
        'greyscale',
115
        'heighten',
116
        'invert',
117
        'limitColors',
118
        'pixelate',
119
        'opacity',
120
        'resize',
121
        'rotate',
122
        'amount',
123
        'widen',
124
        'orientate'
125
    ];
126
127
    /**
128
     * The quality of the output.
129
     *
130
     * @var null|int
131
     */
132
    protected $quality = null;
133
134
    /**
135
     * The image width.
136
     *
137
     * @var null|int
138
     */
139
    protected $width = null;
140
141
    /**
142
     * The image height.
143
     *
144
     * @var null|int
145
     */
146
    protected $height = null;
147
148
    /**
149
     * The URL generator.
150
     *
151
     * @var UrlGenerator
152
     */
153
    protected $url;
154
155
    /**
156
     * The HTML builder.
157
     *
158
     * @var HtmlBuilder
159
     */
160
    protected $html;
161
162
    /**
163
     * Image path hints by namespace.
164
     *
165
     * @var ImagePaths
166
     */
167
    protected $paths;
168
169
    /**
170
     * The image macros.
171
     *
172
     * @var ImageMacros
173
     */
174
    protected $macros;
175
176
    /**
177
     * The file system.
178
     *
179
     * @var Filesystem
180
     */
181
    protected $files;
182
183
    /**
184
     * The user agent utility.
185
     *
186
     * @var Mobile_Detect
187
     */
188
    protected $agent;
189
190
    /**
191
     * The config repository.
192
     *
193
     * @var Repository
194
     */
195
    protected $config;
196
197
    /**
198
     * The image manager.
199
     *
200
     * @var ImageManager
201
     */
202
    protected $manager;
203
204
    /**
205
     * The stream application.
206
     *
207
     * @var Application
208
     */
209
    protected $application;
210
211
    /**
212
     * Create a new Image instance.
213
     *
214
     * @param UrlGenerator  $url
215
     * @param HtmlBuilder   $html
216
     * @param Filesystem    $files
217
     * @param Mobile_Detect $agent
218
     * @param Repository    $config
219
     * @param ImageManager  $manager
220
     * @param Application   $application
221
     * @param ImagePaths    $paths
222
     * @param ImageMacros   $macros
223
     */
224 View Code Duplication
    public function __construct(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
225
        UrlGenerator $url,
226
        HtmlBuilder $html,
227
        Filesystem $files,
228
        Mobile_Detect $agent,
229
        Repository $config,
230
        ImageManager $manager,
231
        Application $application,
232
        ImagePaths $paths,
233
        ImageMacros $macros
234
    ) {
235
        $this->url         = $url;
236
        $this->html        = $html;
237
        $this->files       = $files;
238
        $this->agent       = $agent;
239
        $this->paths       = $paths;
240
        $this->config      = $config;
241
        $this->macros      = $macros;
242
        $this->manager     = $manager;
243
        $this->application = $application;
244
    }
245
246
    /**
247
     * Make a new image instance.
248
     *
249
     * @param mixed $image
250
     * @param null  $output
251
     * @return $this
252
     */
253
    public function make($image, $output = null)
254
    {
255
        if ($image instanceof Image) {
256
            return $image;
257
        }
258
259
        if ($output) {
260
            $this->setOutput($output);
261
        }
262
263
        $clone = clone($this);
264
265
        $clone->setAlterations([]);
266
        $clone->setSources([]);
267
        $clone->setSrcsets([]);
268
        $clone->setImage(null);
269
270
        try {
271
            return $clone->setImage($image);
272
        } catch (\Exception $e) {
273
            return $this;
274
        }
275
    }
276
277
    /**
278
     * Return the path to an image.
279
     *
280
     * @return string
281
     */
282
    public function path()
283
    {
284
        $path = $this->getCachePath();
285
286
        return $path;
287
    }
288
289
    /**
290
     * Run a macro on the image.
291
     *
292
     * @param $macro
293
     * @return Image
294
     * @throws \Exception
295
     */
296
    public function macro($macro)
297
    {
298
        return $this->macros->run($macro, $this);
299
    }
300
301
    /**
302
     * Return the URL to an image.
303
     *
304
     * @param array $parameters
305
     * @param null  $secure
306
     * @return string
307
     */
308
    public function url(array $parameters = [], $secure = null)
309
    {
310
        return $this->url->asset($this->path(), $parameters, $secure);
311
    }
312
313
    /**
314
     * Return the image tag to an image.
315
     *
316
     * @param null  $alt
317
     * @param array $attributes
318
     * @return string
319
     */
320
    public function image($alt = null, array $attributes = [])
321
    {
322
        if (!$alt) {
323
            $alt = array_get($this->getAttributes(), 'alt');
324
        }
325
326
        $attributes = array_merge($this->getAttributes(), $attributes);
327
328
        if ($srcset = $this->srcset()) {
329
            $attributes['srcset'] = $srcset;
330
        }
331
332
        return $this->html->image($this->path(), $alt, $attributes);
333
    }
334
335
    /**
336
     * Return the image tag to an image.
337
     *
338
     * @param null  $alt
339
     * @param array $attributes
340
     * @return string
341
     */
342
    public function img($alt = null, array $attributes = [])
343
    {
344
        return $this->image($alt, $attributes);
345
    }
346
347
    /**
348
     * Return a picture tag.
349
     *
350
     * @return string
351
     */
352
    public function picture(array $attributes = [])
353
    {
354
        $sources = [];
355
356
        $attributes = array_merge($this->getAttributes(), $attributes);
357
358
        /* @var Image $image */
359
        foreach ($this->getSources() as $media => $image) {
360
            if ($media != 'fallback') {
361
                $sources[] = $image->source();
362
            } else {
363
                $sources[] = $image->image();
364
            }
365
        }
366
367
        $sources = implode("\n", $sources);
368
369
        $attributes = $this->html->attributes($attributes);
370
371
        return "<picture {$attributes}>\n{$sources}\n</picture>";
372
    }
373
374
    /**
375
     * Return a source tag.
376
     *
377
     * @return string
378
     */
379
    public function source()
380
    {
381
        $this->addAttribute('srcset', $this->srcset() ?: $this->url() . ' 2x, ' . $this->url() . ' 1x');
382
383
        $attributes = $this->html->attributes($this->getAttributes());
384
385
        if ($srcset = $this->srcset()) {
386
            $attributes['srcset'] = $srcset;
387
        }
388
389
        return "<source {$attributes}>";
390
    }
391
392
    /**
393
     * Return the image response.
394
     *
395
     * @param null $format
396
     * @param int  $quality
397
     * @return String
398
     */
399
    public function encode($format = null, $quality = null)
400
    {
401
        return $this->manager->make($this->getCachePath())->encode($format, $quality ?: $this->getQuality());
402
    }
403
404
    /**
405
     * Return the output.
406
     *
407
     * @return string
408
     */
409
    public function output()
410
    {
411
        return $this->{$this->output}();
412
    }
413
414
    /**
415
     * Set the filename.
416
     *
417
     * @param $filename
418
     * @return $this
419
     */
420
    public function rename($filename = null)
421
    {
422
        return $this->setFilename($filename);
423
    }
424
425
    /**
426
     * Set the quality.
427
     *
428
     * @param $quality
429
     * @return $this
430
     */
431
    public function quality($quality)
432
    {
433
        return $this->setQuality($quality);
434
    }
435
436
    /**
437
     * Set the width attribute.
438
     *
439
     * @param null $width
440
     * @return Image
441
     */
442
    public function width($width = null)
443
    {
444
        return $this->addAttribute('width', $width ?: $this->getWidth());
445
    }
446
447
    /**
448
     * Set the height attribute.
449
     *
450
     * @param null $height
451
     * @return Image
452
     */
453
    public function height($height = null)
454
    {
455
        return $this->addAttribute('height', $height ?: $this->getHeight());
456
    }
457
458
    /**
459
     * Set the quality.
460
     *
461
     * @param $quality
462
     * @return $this
463
     */
464
    public function setQuality($quality)
465
    {
466
        $this->quality = (int)$quality;
467
468
        return $this;
469
    }
470
471
    /**
472
     * Get the cache path of the image.
473
     *
474
     * @return string
475
     */
476
    protected function getCachePath()
477
    {
478
        if (starts_with($this->getImage(), ['http://', 'https://', '//'])) {
479
            return $this->getImage();
480
        }
481
482
        $path = $this->paths->outputPath($this);
483
484
        if ($this->shouldPublish($path)) {
485
            try {
486
                $this->publish($path);
487
            } catch (\Exception $e) {
488
                return $this->config->get('app.debug', false) ? $e->getMessage() : null;
489
            }
490
        }
491
492
        return $path;
493
    }
494
495
    /**
496
     * Determine if the image needs to be published
497
     *
498
     * @param $path
499
     * @return bool
500
     */
501
    private function shouldPublish($path)
502
    {
503
        $path = ltrim($path, '/');
504
505
        if (!$this->files->exists($path)) {
506
            return true;
507
        }
508
509 View Code Duplication
        if (is_string($this->image) && !str_is('*://*', $this->image) && filemtime($path) < filemtime($this->image)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
510
            return true;
511
        }
512
513 View Code Duplication
        if (is_string($this->image) && str_is('*://*', $this->image) && filemtime($path) < app(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
514
                'League\Flysystem\MountManager'
515
            )->getTimestamp($this->image)
516
        ) {
517
            return true;
518
        }
519
520
        if ($this->image instanceof File && filemtime($path) < $this->image->getTimestamp()) {
521
            return true;
522
        }
523
524
        if ($this->image instanceof FileInterface && filemtime($path) < $this->image->lastModified()->format('U')) {
0 ignored issues
show
Bug introduced by
The class Anomaly\FilesModule\File\Contract\FileInterface does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
525
            return true;
526
        }
527
528
        return false;
529
    }
530
531
    /**
532
     * Publish an image to the publish directory.
533
     *
534
     * @param $path
535
     */
536
    protected function publish($path)
537
    {
538
        $path = ltrim($path, '/');
539
540
        $this->files->makeDirectory((new \SplFileInfo($path))->getPath(), 0777, true, true);
541
542
        if ($this->files->extension($path) == 'svg') {
543
544
            $this->files->put($path, $this->dumpImage());
545
546
            return;
547
        }
548
549
        if (!$image = $this->makeImage()) {
550
            return;
551
        }
552
553
        if (function_exists('exif_read_data') && $image->exif('Orientation') && $image->exif('Orientation') > 1) {
554
            $this->addAlteration('orientate');
555
        }
556
557
        if (!$this->getAlterations() && $content = $this->dumpImage()) {
558
559
            $this->files->put($this->directory . $path, $content);
560
561
            return;
562
        }
563
564
        if (is_callable('exif_read_data') && in_array('orientate', $this->getAlterations())) {
565
            $this->setAlterations(array_unique(array_merge(['orientate'], $this->getAlterations())));
566
        }
567
568
        foreach ($this->getAlterations() as $method => $arguments) {
569
570
            if ($method == 'resize') {
571
                $this->guessResizeArguments($arguments);
572
            }
573
574
            if (in_array($method, $this->getAllowedMethods())) {
575
                if (is_array($arguments)) {
576
                    call_user_func_array([$image, $method], $arguments);
577
                } else {
578
                    call_user_func([$image, $method], $arguments);
579
                }
580
            }
581
        }
582
583
        $image->save($this->directory . $path, $this->getQuality());
584
    }
585
586
    /**
587
     * Set an attribute value.
588
     *
589
     * @param $attribute
590
     * @param $value
591
     * @return $this
592
     */
593
    public function attr($attribute, $value)
594
    {
595
        array_set($this->attributes, $attribute, $value);
596
597
        return $this;
598
    }
599
600
    /**
601
     * Return the image srcsets by set.
602
     *
603
     * @return array
604
     */
605
    public function srcset()
606
    {
607
        $sources = [];
608
609
        /* @var Image $image */
610
        foreach ($this->getSrcsets() as $descriptor => $image) {
611
            $sources[] = $image->url() . ' ' . $descriptor;
612
        }
613
614
        return implode(', ', $sources);
615
    }
616
617
    /**
618
     * Set the srcsets/alterations.
619
     *
620
     * @param array $srcsets
621
     */
622
    public function srcsets(array $srcsets)
623
    {
624
        foreach ($srcsets as $descriptor => &$alterations) {
625
626
            $image = $this->make(array_pull($alterations, 'image', $this->getImage()))->setOutput('url');
627
628 View Code Duplication
            foreach ($alterations as $method => $arguments) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
629
                if (is_array($arguments)) {
630
                    call_user_func_array([$image, $method], $arguments);
631
                } else {
632
                    call_user_func([$image, $method], $arguments);
633
                }
634
            }
635
636
            $alterations = $image;
637
        }
638
639
        $this->setSrcsets($srcsets);
640
641
        return $this;
642
    }
643
644
    /**
645
     * Set the sources/alterations.
646
     *
647
     * @param array $sources
648
     * @param bool  $merge
649
     * @return $this
650
     */
651
    public function sources(array $sources, $merge = true)
652
    {
653
        foreach ($sources as $media => &$alterations) {
654
655
            if ($merge) {
656
                $alterations = array_merge($this->getAlterations(), $alterations);
657
            }
658
659
            $image = $this->make(array_pull($alterations, 'image', $this->getImage()))->setOutput('source');
660
661
            if ($media != 'fallback') {
662
                call_user_func([$image, 'media'], $media);
663
            }
664
665 View Code Duplication
            foreach ($alterations as $method => $arguments) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
666
                if (is_array($arguments)) {
667
                    call_user_func_array([$image, $method], $arguments);
668
                } else {
669
                    call_user_func([$image, $method], $arguments);
670
                }
671
            }
672
673
            $alterations = $image;
674
        }
675
676
        $this->setSources($sources);
677
678
        return $this;
679
    }
680
681
    /**
682
     * Alter the image based on the user agents.
683
     *
684
     * @param array $agents
685
     * @param bool  $exit
686
     * @return $this
687
     */
688
    public function agents(array $agents, $exit = false)
689
    {
690
        foreach ($agents as $agent => $alterations) {
691
            if (
692
                $this->agent->is($agent)
693
                || ($agent == 'phone' && $this->agent->isPhone())
694
                || ($agent == 'mobile' && $this->agent->isMobile())
695
                || ($agent == 'tablet' && $this->agent->isTablet())
696
                || ($agent == 'desktop' && $this->agent->isDesktop())
697
            ) {
698 View Code Duplication
                foreach ($alterations as $method => $arguments) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
699
                    if (is_array($arguments)) {
700
                        call_user_func_array([$this, $method], $arguments);
701
                    } else {
702
                        call_user_func([$this, $method], $arguments);
703
                    }
704
                }
705
706
                if ($exit) {
707
                    return $this;
708
                }
709
            }
710
        }
711
712
        return $this;
713
    }
714
715
    /**
716
     * Set the image.
717
     *
718
     * @param  $image
719
     * @return $this
720
     */
721
    public function setImage($image)
722
    {
723
        if ($image instanceof Presenter) {
724
            $image = $image->getObject();
725
        }
726
727
        if ($image instanceof FieldType) {
728
            $image = $image->getValue();
729
        }
730
731
        // Replace path prefixes.
732
        if (is_string($image) && str_contains($image, '::')) {
733
734
            $image = $this->paths->realPath($image);
735
736
            $this->setExtension(pathinfo($image, PATHINFO_EXTENSION));
737
738
            $size = getimagesize($image);
739
740
            $this->setWidth(array_get($size, 0));
741
            $this->setHeight(array_get($size, 1));
742
        }
743
744
        if (is_string($image) && str_is('*://*', $image) && !starts_with($image, ['http', 'https'])) {
745
746
            $this->setExtension(pathinfo($image, PATHINFO_EXTENSION));
747
748
            $size = getimagesize($image);
749
750
            $this->setWidth(array_get($size, 0));
751
            $this->setHeight(array_get($size, 1));
752
        }
753
754 View Code Duplication
        if ($image instanceof FileInterface) {
0 ignored issues
show
Bug introduced by
The class Anomaly\FilesModule\File\Contract\FileInterface does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
755
756
            /* @var FileInterface $image */
757
            $this->setExtension($image->getExtension());
758
759
            $this->setWidth($image->getWidth());
760
            $this->setHeight($image->getHeight());
761
        }
762
763 View Code Duplication
        if ($image instanceof FilePresenter) {
0 ignored issues
show
Bug introduced by
The class Anomaly\FilesModule\File\FilePresenter does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
764
765
            /* @var FilePresenter|FileInterface $image */
766
            $image = $image->getObject();
767
768
            $this->setExtension($image->getExtension());
769
770
            $this->setWidth($image->getWidth());
771
            $this->setHeight($image->getHeight());
772
        }
773
774
        $this->image = $image;
775
776
        return $this;
777
    }
778
779
    /**
780
     * Make an image instance.
781
     *
782
     * @return \Intervention\Image\Image
783
     */
784
    protected function makeImage()
785
    {
786
        if ($this->image instanceof FileInterface) {
0 ignored issues
show
Bug introduced by
The class Anomaly\FilesModule\File\Contract\FileInterface does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
787
            return $this->manager->make(app('League\Flysystem\MountManager')->read($this->image->location()));
788
        }
789
790 View Code Duplication
        if (is_string($this->image) && str_is('*://*', $this->image)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
791
            return $this->manager->make(app('League\Flysystem\MountManager')->read($this->image));
792
        }
793
794
        if ($this->image instanceof File) {
795
            return $this->manager->make($this->image->read());
796
        }
797
798
        if (is_string($this->image) && file_exists($this->image)) {
799
            return $this->manager->make($this->image);
800
        }
801
802
        if ($this->image instanceof Image) {
803
            return $this->image;
804
        }
805
806
        return null;
807
    }
808
809
    /**
810
     * Dump an image instance's data.
811
     *
812
     * @return string
813
     */
814
    protected function dumpImage()
815
    {
816
        if ($this->image instanceof FileInterface) {
0 ignored issues
show
Bug introduced by
The class Anomaly\FilesModule\File\Contract\FileInterface does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
817
            return app('League\Flysystem\MountManager')->read($this->image->location());
818
        }
819
820 View Code Duplication
        if (is_string($this->image) && str_is('*://*', $this->image)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
821
            return app('League\Flysystem\MountManager')->read($this->image);
822
        }
823
824
        if ($this->image instanceof File) {
825
            return $this->image->read();
826
        }
827
828
        if (is_string($this->image) && file_exists($this->image)) {
829
            return file_get_contents($this->image);
830
        }
831
832
        if ($this->image instanceof Image) {
833
            return $this->image->encode();
834
        }
835
836
        if (is_string($this->image) && file_exists($this->image)) {
837
            return file_get_contents($this->image);
838
        }
839
840
        return null;
841
    }
842
843
    /**
844
     * Get the image instance.
845
     *
846
     * @return \Intervention\Image\Image
847
     */
848
    public function getImage()
849
    {
850
        return $this->image;
851
    }
852
853
    /**
854
     * Get the file name.
855
     *
856
     * @return null|string
857
     */
858
    public function getFilename()
859
    {
860
        return $this->filename;
861
    }
862
863
    /**
864
     * Set the file name.
865
     *
866
     * @param $filename
867
     * @return $this
868
     */
869
    public function setFilename($filename = null)
870
    {
871
        if (!$filename) {
872
            $filename = $this->getImageFilename();
0 ignored issues
show
Documentation Bug introduced by
The method getImageFilename does not exist on object<Anomaly\Streams\Platform\Image\Image>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
873
        }
874
875
        $this->filename = $filename;
876
877
        return $this;
878
    }
879
880
    /**
881
     * Get the alterations.
882
     *
883
     * @return array
884
     */
885
    public function getAlterations()
886
    {
887
        return $this->alterations;
888
    }
889
890
    /**
891
     * Set the alterations.
892
     *
893
     * @param array $alterations
894
     * @return $this
895
     */
896
    public function setAlterations(array $alterations)
897
    {
898
        $this->alterations = $alterations;
899
900
        return $this;
901
    }
902
903
    /**
904
     * Add an alteration.
905
     *
906
     * @param  $method
907
     * @param  $arguments
908
     * @return $this
909
     */
910
    public function addAlteration($method, $arguments = [])
911
    {
912
        $this->alterations[$method] = $arguments;
913
914
        return $this;
915
    }
916
917
    /**
918
     * Get the attributes.
919
     *
920
     * @return array
921
     */
922
    public function getAttributes()
923
    {
924
        return $this->attributes;
925
    }
926
927
    /**
928
     * Set the attributes.
929
     *
930
     * @param array $attributes
931
     * @return $this
932
     */
933
    public function setAttributes(array $attributes)
934
    {
935
        $this->attributes = $attributes;
936
937
        return $this;
938
    }
939
940
    /**
941
     * Add an attribute.
942
     *
943
     * @param  $attribute
944
     * @param  $value
945
     * @return $this
946
     */
947
    protected function addAttribute($attribute, $value)
948
    {
949
        $this->attributes[$attribute] = $value;
950
951
        return $this;
952
    }
953
954
    /**
955
     * Get the srcsets.
956
     *
957
     * @return array
958
     */
959
    public function getSrcsets()
960
    {
961
        return $this->srcsets;
962
    }
963
964
    /**
965
     * Set the srcsets.
966
     *
967
     * @param array $srcsets
968
     * @return $this
969
     */
970
    public function setSrcsets(array $srcsets)
971
    {
972
        $this->srcsets = $srcsets;
973
974
        return $this;
975
    }
976
977
    /**
978
     * Get the sources.
979
     *
980
     * @return array
981
     */
982
    public function getSources()
983
    {
984
        return $this->sources;
985
    }
986
987
    /**
988
     * Set the sources.
989
     *
990
     * @param array $sources
991
     * @return $this
992
     */
993
    public function setSources(array $sources)
994
    {
995
        $this->sources = $sources;
996
997
        return $this;
998
    }
999
1000
    /**
1001
     * Get the quality.
1002
     *
1003
     * @param null $default
1004
     * @return int
1005
     */
1006
    public function getQuality($default = null)
1007
    {
1008
        if (!$default) {
1009
            $this->config->get('streams::images.quality', 80);
1010
        }
1011
1012
        return $this->quality ?: $default;
1013
    }
1014
1015
    /**
1016
     * Set the output mode.
1017
     *
1018
     * @param $output
1019
     * @return $this
1020
     */
1021
    public function setOutput($output)
1022
    {
1023
        $this->output = $output;
1024
1025
        return $this;
1026
    }
1027
1028
    /**
1029
     * Get the extension.
1030
     *
1031
     * @return null|string
1032
     */
1033
    public function getExtension()
1034
    {
1035
        return $this->extension;
1036
    }
1037
1038
    /**
1039
     * Set the extension.
1040
     *
1041
     * @param $extension
1042
     * @return $this
1043
     */
1044
    public function setExtension($extension)
1045
    {
1046
        $this->extension = $extension;
1047
1048
        return $this;
1049
    }
1050
1051
    /**
1052
     * Get the allowed methods.
1053
     *
1054
     * @return array
1055
     */
1056
    public function getAllowedMethods()
1057
    {
1058
        return $this->allowedMethods;
1059
    }
1060
1061
    /**
1062
     * Add a path by it's namespace hint.
1063
     *
1064
     * @param $namespace
1065
     * @param $path
1066
     * @return $this
1067
     */
1068
    public function addPath($namespace, $path)
1069
    {
1070
        $this->paths->addPath($namespace, $path);
1071
1072
        return $this;
1073
    }
1074
1075
    /**
1076
     * Get the width.
1077
     *
1078
     * @return int|null
1079
     */
1080
    public function getWidth()
1081
    {
1082
        return $this->width;
1083
    }
1084
1085
    /**
1086
     * Set the width.
1087
     *
1088
     * @param $width
1089
     * @return $this
1090
     */
1091
    public function setWidth($width)
1092
    {
1093
        $this->width = $width;
1094
1095
        return $this;
1096
    }
1097
1098
    /**
1099
     * Get the height.
1100
     *
1101
     * @return int|null
1102
     */
1103
    public function getHeight()
1104
    {
1105
        return $this->height;
1106
    }
1107
1108
    /**
1109
     * Set the height.
1110
     *
1111
     * @param $height
1112
     * @return $this
1113
     */
1114
    public function setHeight($height)
1115
    {
1116
        $this->height = $height;
1117
1118
        return $this;
1119
    }
1120
1121
    /**
1122
     * Guess the resize callback value
1123
     * from a boolean.
1124
     *
1125
     * @param array $arguments
1126
     */
1127
    protected function guessResizeArguments(array &$arguments)
1128
    {
1129
        $arguments = array_pad($arguments, 3, null);
1130
1131
        if (end($arguments) instanceof \Closure) {
1132
            return;
1133
        }
1134
1135
        if (array_pop($arguments) !== false && (is_null($arguments[0]) || is_null($arguments[1]))) {
1136
            $arguments[] = function (Constraint $constraint) {
1137
                $constraint->aspectRatio();
1138
            };
1139
        }
1140
    }
1141
1142
    /**
1143
     * Return the output.
1144
     *
1145
     * @return string
1146
     */
1147
    public function __toString()
1148
    {
1149
        return $this->output();
1150
    }
1151
1152
    /**
1153
     * If the method does not exist then
1154
     * add an attribute and return.
1155
     *
1156
     * @param $name
1157
     * @param $arguments
1158
     * @return $this|mixed
1159
     */
1160
    function __call($name, $arguments)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1161
    {
1162
        if (in_array($name, $this->getAllowedMethods())) {
1163
            return $this->addAlteration($name, $arguments);
1164
        }
1165
1166
        if ($this->macros->isMacro($macro = snake_case($name))) {
1167
            return $this->macro($macro);
1168
        }
1169
1170
        if (!method_exists($this, $name)) {
1171
1172
            array_set($this->attributes, $name, array_shift($arguments));
1173
1174
            return $this;
1175
        }
1176
1177
        return call_user_func_array([$this, $name], $arguments);
1178
    }
1179
}
1180