Completed
Push — master ( 98a062...441031 )
by Ryan
10:10
created

Image::getCachePath()   D

Complexity

Conditions 9
Paths 25

Size

Total Lines 28
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 16
nc 25
nop 0
dl 0
loc 28
rs 4.909
c 0
b 0
f 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 Collective\Html\HtmlBuilder;
9
use Illuminate\Contracts\Config\Repository;
10
use Illuminate\Filesystem\Filesystem;
11
use Illuminate\Http\Request;
12
use Intervention\Image\Constraint;
13
use Intervention\Image\ImageManager;
14
use League\Flysystem\File;
15
use League\Flysystem\MountManager;
16
use Mobile_Detect;
17
use Robbo\Presenter\Presenter;
18
19
/**
20
 * Class Image
21
 *
22
 * @link    http://pyrocms.com/
23
 * @author  PyroCMS, Inc. <[email protected]>
24
 * @author  Ryan Thompson <[email protected]>
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 original filename.
66
     *
67
     * @var null|string
68
     */
69
    protected $original = null;
70
71
    /**
72
     * The version flag.
73
     *
74
     * @var null|boolean
75
     */
76
    protected $version = null;
77
78
    /**
79
     * The default output method.
80
     *
81
     * @var string
82
     */
83
    protected $output = 'url';
84
85
    /**
86
     * The image attributes.
87
     *
88
     * @var array
89
     */
90
    protected $attributes = [];
91
92
    /**
93
     * Applied alterations.
94
     *
95
     * @var array
96
     */
97
    protected $alterations = [];
98
99
    /**
100
     * Image srcsets.
101
     *
102
     * @var array
103
     */
104
    protected $srcsets = [];
105
106
    /**
107
     * Image sources.
108
     *
109
     * @var array
110
     */
111
    protected $sources = [];
112
113
    /**
114
     * Allowed methods.
115
     *
116
     * @var array
117
     */
118
    protected $allowedMethods = [
119
        'blur',
120
        'brightness',
121
        'colorize',
122
        'resizeCanvas',
123
        'contrast',
124
        'crop',
125
        'encode',
126
        'fit',
127
        'flip',
128
        'gamma',
129
        'greyscale',
130
        'heighten',
131
        'insert',
132
        'interlace',
133
        'invert',
134
        'limitColors',
135
        'pixelate',
136
        'opacity',
137
        'resize',
138
        'rotate',
139
        'amount',
140
        'widen',
141
        'orientate',
142
    ];
143
144
    /**
145
     * The quality of the output.
146
     *
147
     * @var null|int
148
     */
149
    protected $quality = null;
150
151
    /**
152
     * The image width.
153
     *
154
     * @var null|int
155
     */
156
    protected $width = null;
157
158
    /**
159
     * The image height.
160
     *
161
     * @var null|int
162
     */
163
    protected $height = null;
164
165
    /**
166
     * The URL generator.
167
     *
168
     * @var UrlGenerator
169
     */
170
    protected $url;
171
172
    /**
173
     * The HTML builder.
174
     *
175
     * @var HtmlBuilder
176
     */
177
    protected $html;
178
179
    /**
180
     * Image path hints by namespace.
181
     *
182
     * @var ImagePaths
183
     */
184
    protected $paths;
185
186
    /**
187
     * The image macros.
188
     *
189
     * @var ImageMacros
190
     */
191
    protected $macros;
192
193
    /**
194
     * The file system.
195
     *
196
     * @var Filesystem
197
     */
198
    protected $files;
199
200
    /**
201
     * The user agent utility.
202
     *
203
     * @var Mobile_Detect
204
     */
205
    protected $agent;
206
207
    /**
208
     * The config repository.
209
     *
210
     * @var Repository
211
     */
212
    protected $config;
213
214
    /**
215
     * The request object.
216
     *
217
     * @var Request
218
     */
219
    protected $request;
220
221
    /**
222
     * The image manager.
223
     *
224
     * @var ImageManager
225
     */
226
    protected $manager;
227
228
    /**
229
     * The stream application.
230
     *
231
     * @var Application
232
     */
233
    protected $application;
234
235
    /**
236
     * Create a new Image instance.
237
     *
238
     * @param UrlGenerator  $url
239
     * @param HtmlBuilder   $html
240
     * @param Filesystem    $files
241
     * @param Mobile_Detect $agent
242
     * @param Repository    $config
243
     * @param ImageManager  $manager
244
     * @param Request       $request
245
     * @param Application   $application
246
     * @param ImagePaths    $paths
247
     * @param ImageMacros   $macros
248
     */
249 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...
250
        UrlGenerator $url,
251
        HtmlBuilder $html,
252
        Filesystem $files,
253
        Mobile_Detect $agent,
254
        Repository $config,
255
        ImageManager $manager,
256
        Request $request,
0 ignored issues
show
Bug introduced by
You have injected the Request via parameter $request. This is generally not recommended as there might be multiple instances during a request cycle (f.e. when using sub-requests). Instead, it is recommended to inject the RequestStack and retrieve the current request each time you need it via getCurrentRequest().
Loading history...
257
        Application $application,
258
        ImagePaths $paths,
259
        ImageMacros $macros
260
    ) {
261
        $this->url         = $url;
262
        $this->html        = $html;
263
        $this->files       = $files;
264
        $this->agent       = $agent;
265
        $this->paths       = $paths;
266
        $this->config      = $config;
267
        $this->macros      = $macros;
268
        $this->manager     = $manager;
269
        $this->request     = $request;
270
        $this->application = $application;
271
    }
272
273
    /**
274
     * Make a new image instance.
275
     *
276
     * @param  mixed $image
277
     * @param  null  $output
278
     * @return $this
279
     */
280
    public function make($image, $output = null)
281
    {
282
        if ($image instanceof Image) {
283
            return $image;
284
        }
285
286
        if ($output) {
287
            $this->setOutput($output);
288
        }
289
290
        $clone = clone($this);
291
292
        $clone->setAlterations([]);
293
        $clone->setSources([]);
294
        $clone->setSrcsets([]);
295
        $clone->setImage(null);
296
297
        try {
298
            return $clone->setImage($image);
299
        } catch (\Exception $e) {
300
            return $this;
301
        }
302
    }
303
304
    /**
305
     * Return the path to an image.
306
     *
307
     * @return string
308
     */
309
    public function path()
310
    {
311
        $path = $this->getCachePath();
312
313
        return $this->request->getBasePath() . $path;
314
    }
315
316
    /**
317
     * Return the asset path to an image.
318
     *
319
     * @return string
320
     */
321
    public function asset()
322
    {
323
        $path = $this->getCachePath();
324
325
        return $this->url->asset($path);
326
    }
327
328
    /**
329
     * Run a macro on the image.
330
     *
331
     * @param $macro
332
     * @return Image
333
     * @throws \Exception
334
     */
335
    public function macro($macro)
336
    {
337
        return $this->macros->run($macro, $this);
338
    }
339
340
    /**
341
     * Return the URL to an image.
342
     *
343
     * @param  array $parameters
344
     * @param  null  $secure
345
     * @return string
346
     */
347
    public function url(array $parameters = [], $secure = null)
348
    {
349
        return $this->url->asset($this->getCachePath(), $parameters, $secure);
350
    }
351
352
    /**
353
     * Return the image tag to an image.
354
     *
355
     * @param  null  $alt
356
     * @param  array $attributes
357
     * @return string
358
     */
359
    public function image($alt = null, array $attributes = [])
360
    {
361
        $attributes = array_merge($this->getAttributes(), $attributes);
362
363
        $attributes['src'] = $this->asset();
364
365
        if ($srcset = $this->srcset()) {
366
            $attributes['srcset'] = $srcset;
367
        }
368
369
        if (!$alt && $this->config->get('streams::images.auto_alt', true)) {
370
371
            $attributes['alt'] = array_get(
372
                $this->getAttributes(),
373
                'alt',
374
                ucwords(
375
                    str_humanize(
376
                        trim(basename($this->getOriginal(), $this->getExtension()), '.'),
377
                        '^a-zA-Z0-9'
378
                    )
379
                )
380
            );
381
        }
382
383
        return '<img ' . $this->html->attributes($attributes) . '>';
384
    }
385
386
    /**
387
     * Return the image tag to an image.
388
     *
389
     * @param  null  $alt
390
     * @param  array $attributes
391
     * @return string
392
     */
393
    public function img($alt = null, array $attributes = [])
394
    {
395
        return $this->image($alt, $attributes);
396
    }
397
398
    /**
399
     * Return a picture tag.
400
     *
401
     * @return string
402
     */
403
    public function picture(array $attributes = [])
404
    {
405
        $sources = [];
406
407
        $attributes = array_merge($this->getAttributes(), $attributes);
408
409
        /* @var Image $image */
410
        foreach ($this->getSources() as $media => $image) {
411
            if ($media != 'fallback') {
412
                $sources[] = $image->source();
413
            } else {
414
                $sources[] = $image->image();
415
            }
416
        }
417
418
        $sources = implode("\n", $sources);
419
420
        $attributes = $this->html->attributes($attributes);
421
422
        return "<picture {$attributes}>\n{$sources}\n</picture>";
423
    }
424
425
    /**
426
     * Return a source tag.
427
     *
428
     * @return string
429
     */
430
    public function source()
431
    {
432
        $this->addAttribute('srcset', $this->srcset() ?: $this->asset() . ' 2x, ' . $this->asset() . ' 1x');
433
434
        $attributes = $this->html->attributes($this->getAttributes());
435
436
        if ($srcset = $this->srcset()) {
437
            $attributes['srcset'] = $srcset;
438
        }
439
440
        return "<source {$attributes}>";
441
    }
442
443
    /**
444
     * Return the image response.
445
     *
446
     * @param  null $format
447
     * @param  int  $quality
448
     * @return String
449
     */
450
    public function encode($format = null, $quality = null)
451
    {
452
        return $this->manager->make($this->getCachePath())->encode($format, $quality ?: $this->getQuality());
453
    }
454
455
    /**
456
     * Return the image contents.
457
     *
458
     * @return string
459
     */
460
    public function data()
461
    {
462
        return $this->dumpImage();
463
    }
464
465
    /**
466
     * Return the output.
467
     *
468
     * @return string
469
     */
470
    public function output()
471
    {
472
        return $this->{$this->output}();
473
    }
474
475
    /**
476
     * Set the filename.
477
     *
478
     * @param $filename
479
     * @return $this
480
     */
481
    public function rename($filename = null)
482
    {
483
        return $this->setFilename($filename);
484
    }
485
486
    /**
487
     * Set the version flag.
488
     *
489
     * @param bool $version
490
     * @return $this
491
     */
492
    public function version($version = true)
493
    {
494
        return $this->setVersion($version);
495
    }
496
497
    /**
498
     * Set the quality.
499
     *
500
     * @param $quality
501
     * @return $this
502
     */
503
    public function quality($quality)
504
    {
505
        return $this->setQuality($quality);
506
    }
507
508
    /**
509
     * Set the width attribute.
510
     *
511
     * @param  null $width
512
     * @return Image
513
     */
514
    public function width($width = null)
515
    {
516
        return $this->addAttribute('width', $width ?: $this->getWidth());
517
    }
518
519
    /**
520
     * Set the height attribute.
521
     *
522
     * @param  null $height
523
     * @return Image
524
     */
525
    public function height($height = null)
526
    {
527
        return $this->addAttribute('height', $height ?: $this->getHeight());
528
    }
529
530
    /**
531
     * Set the quality.
532
     *
533
     * @param $quality
534
     * @return $this
535
     */
536
    public function setQuality($quality)
537
    {
538
        $this->quality = (int)$quality;
539
540
        return $this;
541
    }
542
543
    /**
544
     * Get the cache path of the image.
545
     *
546
     * @return string
547
     */
548
    protected function getCachePath()
549
    {
550
        if (starts_with($this->getImage(), ['http://', 'https://', '//'])) {
551
            return $this->getImage();
552
        }
553
554
        if ($this->agent->isTablet()) {
555
            $this->macro('tablet_optimized');
556
        } elseif ($this->agent->isMobile()) {
557
            $this->macro('mobile_optimized');
558
        }
559
560
        $path = $this->paths->outputPath($this);
561
562
        try {
563
            if ($this->shouldPublish($path)) {
564
                $this->publish($path);
565
            }
566
        } catch (\Exception $e) {
567
            return $this->config->get('app.debug', false) ? $e->getMessage() : null;
568
        }
569
570
        if ($this->config->get('streams::images.version') || $this->getVersion() == true) {
571
            $path .= '?v=' . filemtime(public_path(trim($path, '/\\')));
572
        }
573
574
        return $path;
575
    }
576
577
    /**
578
     * Determine if the image needs to be published
579
     *
580
     * @param $path
581
     * @return bool
582
     */
583
    private function shouldPublish($path)
584
    {
585
        $path = ltrim($path, '/');
586
587
        if (!$this->files->exists($path)) {
588
            return true;
589
        }
590
591 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...
592
            return true;
593
        }
594
595 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...
596
                'League\Flysystem\MountManager'
597
            )->getTimestamp($this->image)
598
        ) {
599
            return true;
600
        }
601
602
        if ($this->image instanceof File && filemtime($path) < $this->image->getTimestamp()) {
603
            return true;
604
        }
605
606
        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...
607
            return true;
608
        }
609
610
        return false;
611
    }
612
613
    /**
614
     * Publish an image to the publish directory.
615
     *
616
     * @param $path
617
     */
618
    protected function publish($path)
619
    {
620
        $path = $this->directory . DIRECTORY_SEPARATOR . ltrim($path, '/');
621
622
        $this->files->makeDirectory((new \SplFileInfo($path))->getPath(), 0777, true, true);
623
624
        if (!$this->supportsType($this->getExtension())) {
625
626
            $this->files->put($path, $this->dumpImage());
627
628
            return;
629
        }
630
631
        if (!$image = $this->makeImage()) {
632
            return;
633
        }
634
635
        if (function_exists('exif_read_data') && $image->exif('Orientation') && $image->exif('Orientation') > 1) {
636
            $this->addAlteration('orientate');
637
        }
638
639
        if (in_array($this->getExtension(), ['jpeg', 'jpg']) && $this->config->get('streams::images.interlace')) {
640
            $this->addAlteration('interlace');
641
        }
642
643
        if (!$this->getAlterations() && $content = $this->dumpImage()) {
644
            $this->files->put($path, $content);
645
646
            return;
647
        }
648
649
        if (is_callable('exif_read_data') && in_array('orientate', $this->getAlterations())) {
650
            $this->setAlterations(array_unique(array_merge(['orientate'], $this->getAlterations())));
651
        }
652
653
        foreach ($this->getAlterations() as $method => $arguments) {
654
            if ($method == 'resize') {
655
                $this->guessResizeArguments($arguments);
656
            }
657
658
            if (in_array($method, $this->getAllowedMethods())) {
659
                if (is_array($arguments)) {
660
                    call_user_func_array([$image, $method], $arguments);
661
                } else {
662
                    call_user_func([$image, $method], $arguments);
663
                }
664
            }
665
        }
666
667
        $image->save($path, $this->getQuality());
668
    }
669
670
    /**
671
     * Set an attribute value.
672
     *
673
     * @param $attribute
674
     * @param $value
675
     * @return $this
676
     */
677
    public function attr($attribute, $value)
678
    {
679
        array_set($this->attributes, $attribute, $value);
680
681
        return $this;
682
    }
683
684
    /**
685
     * Return the image srcsets by set.
686
     *
687
     * @return array
688
     */
689
    public function srcset()
690
    {
691
        $sources = [];
692
693
        /* @var Image $image */
694
        foreach ($this->getSrcsets() as $descriptor => $image) {
695
            $sources[] = $image->asset() . ' ' . $descriptor;
696
        }
697
698
        return implode(', ', $sources);
699
    }
700
701
    /**
702
     * Set the srcsets/alterations.
703
     *
704
     * @param array $srcsets
705
     */
706
    public function srcsets(array $srcsets)
707
    {
708
        foreach ($srcsets as $descriptor => &$alterations) {
709
            $image = $this->make(array_pull($alterations, 'image', $this->getImage()))->setOutput('url');
710
711 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...
712
                if (is_array($arguments)) {
713
                    call_user_func_array([$image, $method], $arguments);
714
                } else {
715
                    call_user_func([$image, $method], $arguments);
716
                }
717
            }
718
719
            $alterations = $image;
720
        }
721
722
        $this->setSrcsets($srcsets);
723
724
        return $this;
725
    }
726
727
    /**
728
     * Set the sources/alterations.
729
     *
730
     * @param  array $sources
731
     * @param  bool  $merge
732
     * @return $this
733
     */
734
    public function sources(array $sources, $merge = true)
735
    {
736
        foreach ($sources as $media => &$alterations) {
737
            if ($merge) {
738
                $alterations = array_merge($this->getAlterations(), $alterations);
739
            }
740
741
            $image = $this->make(array_pull($alterations, 'image', $this->getImage()))->setOutput('source');
742
743
            if ($media != 'fallback') {
744
                call_user_func([$image, 'media'], $media);
745
            }
746
747 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...
748
                if (is_array($arguments)) {
749
                    call_user_func_array([$image, $method], $arguments);
750
                } else {
751
                    call_user_func([$image, $method], $arguments);
752
                }
753
            }
754
755
            $alterations = $image;
756
        }
757
758
        $this->setSources($sources);
759
760
        return $this;
761
    }
762
763
    /**
764
     * Alter the image based on the user agents.
765
     *
766
     * @param  array $agents
767
     * @param  bool  $exit
768
     * @return $this
769
     */
770
    public function agents(array $agents, $exit = false)
771
    {
772
        foreach ($agents as $agent => $alterations) {
773
            if (
774
                $this->agent->is($agent)
775
                || ($agent == 'phone' && $this->agent->isPhone())
776
                || ($agent == 'mobile' && $this->agent->isMobile())
777
                || ($agent == 'tablet' && $this->agent->isTablet())
778
                || ($agent == 'desktop' && $this->agent->isDesktop())
779
            ) {
780 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...
781
                    if (is_array($arguments)) {
782
                        call_user_func_array([$this, $method], $arguments);
783
                    } else {
784
                        call_user_func([$this, $method], $arguments);
785
                    }
786
                }
787
788
                if ($exit) {
789
                    return $this;
790
                }
791
            }
792
        }
793
794
        return $this;
795
    }
796
797
    /**
798
     * Return if an extension is supported.
799
     *
800
     * @param $extension
801
     * @return bool
802
     */
803
    protected function supportsType($extension)
804
    {
805
        return !in_array($extension, ['svg', 'webp']);
806
    }
807
808
    /**
809
     * Set the image.
810
     *
811
     * @param  $image
812
     * @return $this
813
     */
814
    public function setImage($image)
815
    {
816
        if ($image instanceof Presenter) {
817
            $image = $image->getObject();
818
        }
819
820
        if ($image instanceof FieldType) {
821
            $image = $image->getValue();
822
        }
823
824
        // Replace path prefixes.
825
        if (is_string($image) && str_contains($image, '::')) {
826
            $image = $this->paths->realPath($image);
827
828
            $this->setOriginal(basename($image));
829
            $this->setExtension(pathinfo($image, PATHINFO_EXTENSION));
830
831
            $size = getimagesize($image);
832
833
            $this->setWidth(array_get($size, 0));
834
            $this->setHeight(array_get($size, 1));
835
        }
836
837
        if (is_string($image) && str_is('*://*', $image) && !starts_with($image, ['http', 'https'])) {
838
            $this->setOriginal(basename($image));
839
            $this->setExtension(pathinfo($image, PATHINFO_EXTENSION));
840
        }
841
842 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...
843
844
            /* @var FileInterface $image */
845
            $this->setOriginal($image->getName());
846
            $this->setExtension($image->getExtension());
847
848
            $this->setWidth($image->getWidth());
849
            $this->setHeight($image->getHeight());
850
        }
851
852 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...
853
854
            /* @var FilePresenter|FileInterface $image */
855
            $image = $image->getObject();
856
857
            $this->setOriginal($image->getName());
858
            $this->setExtension($image->getExtension());
859
860
            $this->setWidth($image->getWidth());
861
            $this->setHeight($image->getHeight());
862
        }
863
864
        $this->image = $image;
865
866
        return $this;
867
    }
868
869
    /**
870
     * Make an image instance.
871
     *
872
     * @return \Intervention\Image\Image
873
     */
874
    protected function makeImage()
875
    {
876
        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...
877
            return $this->manager->make(app(MountManager::class)->read($this->image->location()));
878
        }
879
880
        if (is_string($this->image) && str_is('*://*', $this->image)) {
881
            return $this->manager->make(app(MountManager::class)->read($this->image));
882
        }
883
884
        if ($this->image instanceof File) {
885
            return $this->manager->make($this->image->read());
886
        }
887
888
        if (is_string($this->image) && file_exists($this->image)) {
889
            return $this->manager->make($this->image);
890
        }
891
892
        if ($this->image instanceof Image) {
893
            return $this->image;
894
        }
895
896
        return null;
897
    }
898
899
    /**
900
     * Dump an image instance's data.
901
     *
902
     * @return string
903
     */
904
    protected function dumpImage()
905
    {
906
        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...
907
            return app('League\Flysystem\MountManager')->read($this->image->location());
908
        }
909
910 View Code Duplication
        if (is_string($this->image) && str_is('*://*', $this->image) && !starts_with($this->image, ['http', '//'])) {
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...
911
            return app('League\Flysystem\MountManager')->read($this->image);
912
        }
913
914 View Code Duplication
        if (is_string($this->image) && (file_exists($this->image) || starts_with($this->image, ['http', '//']))) {
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...
915
            return file_get_contents($this->image);
916
        }
917
918
        if (is_string($this->image) && file_exists($this->image)) {
919
            return file_get_contents($this->image);
920
        }
921
922
        if ($this->image instanceof File) {
923
            return $this->image->read();
924
        }
925
926
        if ($this->image instanceof Image) {
927
            return $this->image->encode();
928
        }
929
930
        if (is_string($this->image) && file_exists($this->image)) {
931
            return file_get_contents($this->image);
932
        }
933
934
        return null;
935
    }
936
937
    /**
938
     * Get the image instance.
939
     *
940
     * @return \Intervention\Image\Image
941
     */
942
    public function getImage()
943
    {
944
        return $this->image;
945
    }
946
947
    /**
948
     * Get the file name.
949
     *
950
     * @return null|string
951
     */
952
    public function getFilename()
953
    {
954
        return $this->filename;
955
    }
956
957
    /**
958
     * Set the file name.
959
     *
960
     * @param $filename
961
     * @return $this
962
     */
963
    public function setFilename($filename = null)
964
    {
965
        $this->filename = $filename;
966
967
        return $this;
968
    }
969
970
    /**
971
     * Get the original name.
972
     *
973
     * @return null|string
974
     */
975
    public function getOriginal()
976
    {
977
        return $this->original;
978
    }
979
980
    /**
981
     * Set the original name.
982
     *
983
     * @param $original
984
     * @return $this
985
     */
986
    public function setOriginal($original = null)
987
    {
988
        $this->original = $original;
989
990
        return $this;
991
    }
992
993
    /**
994
     * Get the file name.
995
     *
996
     * @return null|string
997
     */
998
    public function getVersion()
999
    {
1000
        return $this->version;
1001
    }
1002
1003
    /**
1004
     * Set the file name.
1005
     *
1006
     * @param $version
1007
     * @return $this
1008
     */
1009
    public function setVersion($version = true)
1010
    {
1011
        $this->version = $version;
1012
1013
        return $this;
1014
    }
1015
1016
    /**
1017
     * Get the alterations.
1018
     *
1019
     * @return array
1020
     */
1021
    public function getAlterations()
1022
    {
1023
        return $this->alterations;
1024
    }
1025
1026
    /**
1027
     * Set the alterations.
1028
     *
1029
     * @param  array $alterations
1030
     * @return $this
1031
     */
1032
    public function setAlterations(array $alterations)
1033
    {
1034
        $this->alterations = $alterations;
1035
1036
        return $this;
1037
    }
1038
1039
    /**
1040
     * Add an alteration.
1041
     *
1042
     * @param  $method
1043
     * @param  $arguments
1044
     * @return $this
1045
     */
1046
    public function addAlteration($method, $arguments = [])
1047
    {
1048
        $this->alterations[$method] = $arguments;
1049
1050
        return $this;
1051
    }
1052
1053
    /**
1054
     * Get the attributes.
1055
     *
1056
     * @return array
1057
     */
1058
    public function getAttributes()
1059
    {
1060
        return $this->attributes;
1061
    }
1062
1063
    /**
1064
     * Set the attributes.
1065
     *
1066
     * @param  array $attributes
1067
     * @return $this
1068
     */
1069
    public function setAttributes(array $attributes)
1070
    {
1071
        $this->attributes = $attributes;
1072
1073
        return $this;
1074
    }
1075
1076
    /**
1077
     * Add an attribute.
1078
     *
1079
     * @param  $attribute
1080
     * @param  $value
1081
     * @return $this
1082
     */
1083
    protected function addAttribute($attribute, $value)
1084
    {
1085
        $this->attributes[$attribute] = $value;
1086
1087
        return $this;
1088
    }
1089
1090
    /**
1091
     * Get the srcsets.
1092
     *
1093
     * @return array
1094
     */
1095
    public function getSrcsets()
1096
    {
1097
        return $this->srcsets;
1098
    }
1099
1100
    /**
1101
     * Set the srcsets.
1102
     *
1103
     * @param  array $srcsets
1104
     * @return $this
1105
     */
1106
    public function setSrcsets(array $srcsets)
1107
    {
1108
        $this->srcsets = $srcsets;
1109
1110
        return $this;
1111
    }
1112
1113
    /**
1114
     * Get the sources.
1115
     *
1116
     * @return array
1117
     */
1118
    public function getSources()
1119
    {
1120
        return $this->sources;
1121
    }
1122
1123
    /**
1124
     * Set the sources.
1125
     *
1126
     * @param  array $sources
1127
     * @return $this
1128
     */
1129
    public function setSources(array $sources)
1130
    {
1131
        $this->sources = $sources;
1132
1133
        return $this;
1134
    }
1135
1136
    /**
1137
     * Get the quality.
1138
     *
1139
     * @param  null $default
1140
     * @return int
1141
     */
1142
    public function getQuality($default = null)
1143
    {
1144
        if (!$default) {
1145
            $this->config->get('streams::images.quality', 80);
1146
        }
1147
1148
        return $this->quality ?: $default;
1149
    }
1150
1151
    /**
1152
     * Set the output mode.
1153
     *
1154
     * @param $output
1155
     * @return $this
1156
     */
1157
    public function setOutput($output)
1158
    {
1159
        $this->output = $output;
1160
1161
        return $this;
1162
    }
1163
1164
    /**
1165
     * Get the extension.
1166
     *
1167
     * @return null|string
1168
     */
1169
    public function getExtension()
1170
    {
1171
        return $this->extension;
1172
    }
1173
1174
    /**
1175
     * Set the extension.
1176
     *
1177
     * @param $extension
1178
     * @return $this
1179
     */
1180
    public function setExtension($extension)
1181
    {
1182
        $this->extension = $extension;
1183
1184
        return $this;
1185
    }
1186
1187
    /**
1188
     * Get the allowed methods.
1189
     *
1190
     * @return array
1191
     */
1192
    public function getAllowedMethods()
1193
    {
1194
        return $this->allowedMethods;
1195
    }
1196
1197
    /**
1198
     * Add a path by it's namespace hint.
1199
     *
1200
     * @param $namespace
1201
     * @param $path
1202
     * @return $this
1203
     */
1204
    public function addPath($namespace, $path)
1205
    {
1206
        $this->paths->addPath($namespace, $path);
1207
1208
        return $this;
1209
    }
1210
1211
1212
    /**
1213
     * Get the width.
1214
     *
1215
     * @return int|null
1216
     */
1217
    public function getWidth()
1218
    {
1219
        return $this->width;
1220
    }
1221
1222
    /**
1223
     * Set the width.
1224
     *
1225
     * @param $width
1226
     * @return $this
1227
     */
1228
    public function setWidth($width)
1229
    {
1230
        $this->width = $width;
1231
1232
        return $this;
1233
    }
1234
1235
    /**
1236
     * Get the height.
1237
     *
1238
     * @return int|null
1239
     */
1240
    public function getHeight()
1241
    {
1242
        return $this->height;
1243
    }
1244
1245
    /**
1246
     * Set the height.
1247
     *
1248
     * @param $height
1249
     * @return $this
1250
     */
1251
    public function setHeight($height)
1252
    {
1253
        $this->height = $height;
1254
1255
        return $this;
1256
    }
1257
1258
    /**
1259
     * Guess the resize callback value
1260
     * from a boolean.
1261
     *
1262
     * @param array $arguments
1263
     */
1264
    protected function guessResizeArguments(array &$arguments)
1265
    {
1266
        $arguments = array_pad($arguments, 3, null);
1267
1268
        if (end($arguments) instanceof \Closure) {
1269
            return;
1270
        }
1271
1272
        if (array_pop($arguments) !== false && (is_null($arguments[0]) || is_null($arguments[1]))) {
1273
            $arguments[] = function (Constraint $constraint) {
1274
                $constraint->aspectRatio();
1275
                $constraint->upsize();
1276
            };
1277
        }
1278
    }
1279
1280
    /**
1281
     * Set the public base directory.
1282
     *
1283
     * @param  $directory
1284
     * @return $this
1285
     */
1286
    public function setDirectory($directory)
1287
    {
1288
        $this->directory = $directory;
1289
1290
        return $this;
1291
    }
1292
1293
    /**
1294
     * Return the output.
1295
     *
1296
     * @return string
1297
     */
1298
    public function __toString()
1299
    {
1300
        return (string)$this->output();
1301
    }
1302
1303
    /**
1304
     * If the method does not exist then
1305
     * add an attribute and return.
1306
     *
1307
     * @param $name
1308
     * @param $arguments
1309
     * @return $this|mixed
1310
     */
1311
    public function __call($name, $arguments)
1312
    {
1313
        if (in_array($name, $this->getAllowedMethods())) {
1314
            return $this->addAlteration($name, $arguments);
1315
        }
1316
1317
        if ($this->macros->isMacro($macro = snake_case($name))) {
1318
            return $this->macro($macro);
1319
        }
1320
1321
        if (!method_exists($this, $name)) {
1322
            array_set($this->attributes, $name, array_shift($arguments));
1323
1324
            return $this;
1325
        }
1326
1327
        return call_user_func_array([$this, $name], $arguments);
1328
    }
1329
}
1330