PerfectCmsImageDataExtension::getCMSThumbnail()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 3
nop 0
dl 0
loc 14
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Sunnysideup\PerfectCmsImages\Model\File;
4
5
use SilverStripe\Assets\Folder;
6
use SilverStripe\Assets\Image;
7
use SilverStripe\Assets\Storage\AssetStore;
8
use SilverStripe\Control\Director;
9
use SilverStripe\Core\Config\Config;
10
use SilverStripe\Core\Convert;
11
use SilverStripe\Core\Injector\Injector;
12
use SilverStripe\ORM\DataExtension;
13
use SilverStripe\ORM\DB;
14
use SilverStripe\ORM\FieldType\DBField;
15
use SilverStripe\ORM\FieldType\DBHTMLText;
16
use SilverStripe\View\ArrayData;
17
use Sunnysideup\PerfectCmsImages\Api\ImageManipulations;
18
use Sunnysideup\PerfectCmsImages\Api\PerfectCMSImages;
19
20
/**
21
 * defines the image sizes
22
 * and default upload folder.
23
 *
24
 * @property \SilverStripe\Assets\Image|\Sunnysideup\PerfectCmsImages\Model\File\PerfectCmsImageDataExtension $owner
25
 */
26
class PerfectCmsImageDataExtension extends DataExtension
27
{
28
    /**
29
     * background image for padded images...
30
     *
31
     * @var string
32
     */
33
    private static $perfect_cms_images_background_padding_color = '#cccccc';
34
35
    /*
36
     * details of the images
37
     *     - width: 3200
38
     *     - height: 3200
39
     *     - folder: "myfolder"
40
     *     - filetype: "try jpg"
41
     *     - enforce_size: false
42
     *     - folder: my-image-folder-a
43
     *     - filetype: "jpg or a png with a transparant background"
44
     *     - use_retina: true
45
     *     - padding_bg_colour: '#dddddd'
46
     *     - crop: true
47
     *     - move_to_right_folder: true
48
     *     - loading_style: 'eager'
49
     *     - used_by:
50
     *       - MyClass.MyHasOne
51
     *       - MyOtherClass.MyHasManyMethod
52
     *       - MyOtherClass.MyManyManyRel
53
     * @var array
54
     */
55
    private static $perfect_cms_images_image_definitions = [];
56
57
    private static $casting = [
58
        'PerfectCMSImageTag' => 'HTMLText',
59
    ];
60
61
    /**
62
     * you can provide as many arguments as needed here
63
     *
64
     * @param string $method
65
     * @param [mixed] $args- zero to many arguments
66
     * @return void
67
     */
68
    public function getImageLinkCachedIfExists($method, $args = null): string
69
    {
70
        $args = func_get_args();
71
        //remove the method argument
72
        array_shift($args);
73
74
        $image = $this->owner;
75
        $variant = $image->variantName($method, ...$args);
0 ignored issues
show
Bug introduced by
The method variantName() does not exist on Sunnysideup\PerfectCmsIm...ctCmsImageDataExtension. ( Ignorable by Annotation )

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

75
        /** @scrutinizer ignore-call */ 
76
        $variant = $image->variantName($method, ...$args);

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

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

Loading history...
76
        $store = Injector::inst()->get(AssetStore::class);
77
        $closeToOutOfMemory = (memory_get_peak_usage(false) / memory_get_usage(true)) > 0.8;
78
        if ($closeToOutOfMemory) {
79
            return $image->Link();
0 ignored issues
show
Bug introduced by
The method Link() does not exist on Sunnysideup\PerfectCmsIm...ctCmsImageDataExtension. ( Ignorable by Annotation )

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

79
            return $image->/** @scrutinizer ignore-call */ Link();

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

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

Loading history...
Bug Best Practice introduced by
The expression return $image->Link() returns the type string which is incompatible with the documented return type void.
Loading history...
80
        }
81
        if ($store->exists($image->getFilename(), $image->getHash(), $variant)) {
0 ignored issues
show
Bug introduced by
The method getFilename() does not exist on Sunnysideup\PerfectCmsIm...ctCmsImageDataExtension. ( Ignorable by Annotation )

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

81
        if ($store->exists($image->/** @scrutinizer ignore-call */ getFilename(), $image->getHash(), $variant)) {

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

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

Loading history...
Bug introduced by
The method getHash() does not exist on Sunnysideup\PerfectCmsIm...ctCmsImageDataExtension. ( Ignorable by Annotation )

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

81
        if ($store->exists($image->getFilename(), $image->/** @scrutinizer ignore-call */ getHash(), $variant)) {

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

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

Loading history...
82
            return $store->getAsURL($image->getFilename(), $image->getHash(), $variant);
83
        } else {
84
            return $image->$method(
85
                ...$args
86
            )->Link();
87
        }
88
    }
89
    /**
90
     * @param string $name       PerfectCMSImages name
91
     * @param bool   $inline     for use within existing image tag - optional
92
     * @param string $alt        alt tag for image -optional
93
     * @param string $attributes additional attributes
94
     *
95
     * @return string (HTML)
96
     */
97
    public function getPerfectCMSImageTag(string $name, $inline = false, ?string $alt = '', ?string $attributes = '')
98
    {
99
        return $this->PerfectCMSImageTag($name, $inline, $alt, $attributes);
100
    }
101
102
    /**
103
     * @param string $name       PerfectCMSImages name
104
     * @param bool   $inline     for use within existing image tag - optional. can be TRUE, "TRUE" or 1 also...
105
     * @param string $alt        alt tag for image -optional
106
     * @param string $attributes additional attributes
107
     *
108
     * @return string (HTML)
109
     */
110
    public function PerfectCMSImageTag(string $name, $inline = false, ?string $alt = '', ?string $attributes = '')
111
    {
112
        $arrayData = $this->getPerfectCMSImageTagArrayData($name, $alt, $attributes);
113
        $template = 'Includes/PerfectCMSImageTag';
114
        if (true === $inline || 1 === (int) $inline || 'true' === strtolower($inline)) {
0 ignored issues
show
Bug introduced by
$inline of type false is incompatible with the type string expected by parameter $string of strtolower(). ( Ignorable by Annotation )

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

114
        if (true === $inline || 1 === (int) $inline || 'true' === strtolower(/** @scrutinizer ignore-type */ $inline)) {
Loading history...
115
            $template .= 'Inline';
116
        }
117
118
        return DBField::create_field('HTMLText', $arrayData->renderWith($template));
119
    }
120
121
    /**
122
     * @param string $name       PerfectCMSImages name
123
     * @param string $alt        alt tag for image -optional
124
     * @param string $attributes additional attributes
125
     *
126
     * @return ArrayData
127
     */
128
    private function PerfectCMSImageTagArrayData(string $name, ?string $alt = '', ?string $attributes = '')
129
    {
130
        return $this->getPerfectCMSImageTagArrayData($name, $alt, $attributes);
131
    }
132
133
    /**
134
     * @param string $name       PerfectCMSImages name
135
     * @param string $alt        alt tag for image -optional
136
     * @param string $attributes additional attributes
137
     *
138
     * @return ArrayData
139
     */
140
    private function getPerfectCMSImageTagArrayData(string $name, ?string $alt = '', ?string $attributes = '')
141
    {
142
        $retinaLink = $this->PerfectCMSImageLinkRetina($name);
143
        $nonRetinaLink = $this->PerfectCMSImageLinkNonRetina($name);
144
        $retinaLinkWebP = '';
145
        $nonRetinaLinkWebP = '';
146
147
        $width = PerfectCMSImages::get_width($name, true);
148
        $height = PerfectCMSImages::get_height($name, true);
149
150
        $hasWebP = (bool) Config::inst()->get(ImageManipulations::class, 'webp_enabled');
151
        $hasMobile = PerfectCMSImages::has_mobile($name);
152
153
        if ($hasMobile) {
154
            $mobileRetinaLink = $this->PerfectCMSImageLinkRetinaForMobile($name);
155
            $mobileNonRetinaLink = $this->PerfectCMSImageLinkNonRetinaForMobile($name);
156
            $mobileMediaWidth = PerfectCMSImages::get_mobile_media_width($name);
157
        }
158
        if ($hasWebP) {
159
            $retinaLinkWebP = $this->PerfectCMSImageLinkRetinaWebP($name);
160
            $nonRetinaLinkWebP = $this->PerfectCMSImageLinkNonRetinaWebP($name);
161
        }
162
163
        if ($hasMobile && $hasWebP) {
164
            $mobileRetinaLinkWebP = $this->PerfectCMSImageLinkRetinaWebPForMobile($name);
165
            $mobileNonRetinaLinkWebP = $this->PerfectCMSImageLinkNonRetinaWebPForMobile($name);
166
        }
167
168
        if (!$alt) {
169
            $alt = $this->getOwner()->Title;
170
        }
171
        $myArray = [
172
            'Width' => $width,
173
            'Height' => $height,
174
            'Alt' => Convert::raw2att($alt),
175
            'RetinaLink' => $retinaLink,
176
            'NonRetinaLink' => $nonRetinaLink,
177
            'Type' => $this->owner->getMimeType(),
0 ignored issues
show
Bug introduced by
The method getMimeType() does not exist on Sunnysideup\PerfectCmsIm...ctCmsImageDataExtension. ( Ignorable by Annotation )

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

177
            'Type' => $this->owner->/** @scrutinizer ignore-call */ getMimeType(),

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

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

Loading history...
178
            'HasWebP' => $hasWebP,
179
            'Attributes' => DBField::create_field('HTMLText', $attributes),
180
        ];
181
        if ($hasMobile) {
182
            $myArray = $myArray + [
183
                'MobileMediaWidth' => $mobileMediaWidth,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $mobileMediaWidth does not seem to be defined for all execution paths leading up to this point.
Loading history...
184
                'MobileRetinaLink' => $mobileRetinaLink,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $mobileRetinaLink does not seem to be defined for all execution paths leading up to this point.
Loading history...
185
                'MobileNonRetinaLink' => $mobileNonRetinaLink,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $mobileNonRetinaLink does not seem to be defined for all execution paths leading up to this point.
Loading history...
186
187
            ];
188
        }
189
        if ($hasWebP) {
190
            $myArray = $myArray + [
191
                'RetinaLinkWebP' => $retinaLinkWebP,
192
                'NonRetinaLinkWebP' => $nonRetinaLinkWebP,
193
            ];
194
        }
195
        if ($hasWebP && $hasMobile) {
196
            $myArray = $myArray + [
197
                'MobileRetinaLinkWebP' => $mobileRetinaLinkWebP,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $mobileRetinaLinkWebP does not seem to be defined for all execution paths leading up to this point.
Loading history...
198
                'MobileNonRetinaLinkWebP' => $mobileNonRetinaLinkWebP,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $mobileNonRetinaLinkWebP does not seem to be defined for all execution paths leading up to this point.
Loading history...
199
            ];
200
        }
201
        return ArrayData::create(
202
            $myArray
203
        );
204
    }
205
206
    /**
207
     * @param string $name of Image Field template
208
     *
209
     * @return string (link)
210
     */
211
    public function PerfectCMSImageLinkNonRetina(string $name): string
212
    {
213
        return $this->PerfectCMSImageLink($name);
214
    }
215
216
    /**
217
     * @param string $name of Image Field template
218
     *
219
     * @return string (link)
220
     */
221
    public function PerfectCMSImageLinkRetina(string $name): string
222
    {
223
        return $this->PerfectCMSImageLink($name, true);
224
    }
225
226
    /**
227
     * @param string $name of Image Field template
228
     *
229
     * @return string (link)
230
     */
231
    public function PerfectCMSImageLinkNonRetinaWebP(string $name): string
232
    {
233
        return $this->PerfectCMSImageLink($name, false, true);
234
    }
235
236
    /**
237
     * @param string $name of Image Field template
238
     *
239
     * @return string (link)
240
     */
241
    public function PerfectCMSImageLinkRetinaWebP(string $name): string
242
    {
243
        return $this->PerfectCMSImageLink($name, true, true);
244
    }
245
246
    /**
247
     * @param string $name of Image Field template
248
     *
249
     * @return string (link)
250
     */
251
    public function PerfectCMSImageLinkNonRetinaForMobile(string $name): string
252
    {
253
        return $this->PerfectCMSImageLink($name, false, false, true);
254
    }
255
256
    /**
257
     * @param string $name of Image Field template
258
     *
259
     * @return string (link)
260
     */
261
    public function PerfectCMSImageLinkRetinaForMobile(string $name): string
262
    {
263
        return $this->PerfectCMSImageLink($name, true, false, true);
264
    }
265
266
    /**
267
     * @param string $name of Image Field template
268
     *
269
     * @return string (link)
270
     */
271
    public function PerfectCMSImageLinkNonRetinaWebPForMobile(string $name): string
272
    {
273
        return $this->PerfectCMSImageLink($name, false, true, true);
274
    }
275
276
    /**
277
     * @param string $name of Image Field template
278
     *
279
     * @return string (link)
280
     */
281
    public function PerfectCMSImageLinkRetinaWebPForMobile(string $name): string
282
    {
283
        return $this->PerfectCMSImageLink($name, true, true, true);
284
    }
285
286
    /**
287
     * @return string (link)
288
     */
289
    public function getPerfectCMSImageAbsoluteLink(string $link): string
290
    {
291
        return Director::absoluteURL($link);
292
    }
293
294
    /**
295
     * returns image link (if any).
296
     */
297
    public function PerfectCMSImageLink(string $name, ?bool $useRetina = false, ?bool $isWebP = false, ?bool $forMobile = false): string
298
    {
299
        /** @var null|Image $image */
300
        $image = $this->owner;
301
        $allOk = false;
302
        if ($image && $image->exists() && $image instanceof Image) {
303
            $allOk = true;
304
            //we are all good ...
305
        } else {
306
            $image = ImageManipulations::get_backup_image($name);
307
            if ($image && $image->exists() && $image instanceof Image) {
308
                $allOk = true;
309
            }
310
        }
311
312
        if ($allOk) {
313
            // $backEndString = Image::get_backend();
314
            // $backend = Injector::inst()->get($backEndString);
315
            $link = ImageManipulations::get_image_link($image, $name, $useRetina, $forMobile);
316
317
            if ($isWebP) {
318
                $link = ImageManipulations::web_p_link($link);
319
            }
320
321
            return $link ? ImageManipulations::add_fake_parts($image, $link) : '';
322
        } else {
323
            // no image -> provide placeholder if in DEV MODE only!!!
324
            if (Director::isDev()) {
325
                return ImageManipulations::get_placeholder_image_tag($name);
326
            }
327
        }
328
329
        // no image -> provide placeholder if in DEV MODE only!!!
330
        if (Director::isDev()) {
331
            return ImageManipulations::get_placeholder_image_tag($name);
332
        }
333
334
        return '';
335
    }
336
337
    public function PerfectCMSImageFixFolder($name, ?string $folderName = ''): ?Folder
338
    {
339
        $folder = null;
340
        if (PerfectCMSImages::move_to_right_folder($name) || $folderName) {
341
            $image = $this->getOwner();
342
            if ($image) {
0 ignored issues
show
introduced by
$image is of type object, thus it always evaluated to true.
Loading history...
343
                if (!$folderName) {
344
                    $folderName = PerfectCMSImages::get_folder($name);
345
                }
346
                $folder = Folder::find_or_make($folderName);
347
                if (!$folder->ID) {
348
                    $folder->write();
349
                }
350
                if ($image->ParentID !== $folder->ID) {
351
                    $wasPublished = $image->isPublished() && !$image->isModifiedOnDraft();
352
                    $image->ParentID = $folder->ID;
353
                    $image->write();
354
                    if ($wasPublished) {
355
                        $image->publishRecursive();
356
                    }
357
                }
358
            }
359
            // user_error('could not find image');
360
        }
361
362
        return $folder;
363
    }
364
365
    public function getCMSThumbnail()
366
    {
367
        if ($this->owner->ID) {
0 ignored issues
show
Bug Best Practice introduced by
The property ID does not exist on Sunnysideup\PerfectCmsIm...ctCmsImageDataExtension. Did you maybe forget to declare it?
Loading history...
368
            if ('svg' === $this->owner->getExtension()) {
0 ignored issues
show
Bug introduced by
The method getExtension() does not exist on Sunnysideup\PerfectCmsIm...ctCmsImageDataExtension. ( Ignorable by Annotation )

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

368
            if ('svg' === $this->owner->/** @scrutinizer ignore-call */ getExtension()) {

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

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

Loading history...
369
                $obj = DBHTMLText::create();
370
                $obj->setValue(file_get_contents(BASE_PATH . $this->owner->Link()));
371
372
                return $obj;
373
            }
374
375
            return $this->owner->CMSThumbnail();
0 ignored issues
show
Bug introduced by
The method CMSThumbnail() does not exist on Sunnysideup\PerfectCmsIm...ctCmsImageDataExtension. Did you maybe mean getCMSThumbnail()? ( Ignorable by Annotation )

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

375
            return $this->owner->/** @scrutinizer ignore-call */ CMSThumbnail();

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

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

Loading history...
376
        }
377
378
        return $this->owner->CMSThumbnail();
379
    }
380
381
    public function updatePreviewLink(&$link, $action)
382
    {
383
        $owner = $this->getOwner();
384
        if ('svg' === $this->owner->getExtension()) {
385
            return $owner->Link();
386
        }
387
388
        return $link;
389
    }
390
}
391