Passed
Push — master ( b4725e...edcc7a )
by Nicolaas
02:25
created

PerfectCmsImageDataExtension::onBeforeUnpublish()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
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\Control\Director;
8
use SilverStripe\Core\Config\Config;
9
use SilverStripe\Core\Convert;
10
use SilverStripe\ORM\DataExtension;
11
use SilverStripe\ORM\DB;
12
use SilverStripe\ORM\FieldType\DBField;
13
use SilverStripe\ORM\FieldType\DBHTMLText;
14
use SilverStripe\View\ArrayData;
15
use Sunnysideup\PerfectCmsImages\Api\ImageManipulations;
16
use Sunnysideup\PerfectCmsImages\Api\PerfectCMSImages;
17
use Sunnysideup\PerfectCmsImages\Model\PerfectCMSImageCache;
18
19
/**
20
 * defines the image sizes
21
 * and default upload folder.
22
 */
23
class PerfectCmsImageDataExtension extends DataExtension
24
{
25
    /**
26
     * background image for padded images...
27
     *
28
     * @var string
29
     */
30
    private static $perfect_cms_images_background_padding_color = '#cccccc';
31
32
    /*
33
     * details of the images
34
     *     - width: 3200
35
     *     - height: 3200
36
     *     - folder: "myfolder"
37
     *     - filetype: "try jpg"
38
     *     - enforce_size: false
39
     *     - folder: my-image-folder-a
40
     *     - filetype: "jpg or a png with a transparant background"
41
     *     - use_retina: true
42
     *     - padding_bg_colour: '#dddddd'
43
     *     - crop: true
44
     *     - move_to_right_folder: true
45
     *     - loading_style: 'eager'
46
     *     - used_by:
47
     *       - MyClass.MyHasOne
48
     *       - MyOtherClass.MyHasManyMethod
49
     *       - MyOtherClass.MyManyManyRel
50
     * @var array
51
     */
52
    private static $perfect_cms_images_image_definitions = [];
53
54
    private static $casting = [
55
        'PerfectCMSImageTag' => 'HTMLText',
56
    ];
57
58
    private static $has_many = [
59
        'CachedImges' => PerfectCMSImageCache::class,
60
    ];
61
62
    private static $cascade_deletes = [
63
        'CachedImges',
64
    ];
65
66
    /**
67
     * @param string $name       PerfectCMSImages name
68
     * @param bool   $inline     for use within existing image tag - optional
69
     * @param string $alt        alt tag for image -optional
70
     * @param string $attributes additional attributes
71
     *
72
     * @return string (HTML)
73
     */
74
    public function getPerfectCMSImageTag(string $name, $inline = false, ?string $alt = '', ?string $attributes = '')
75
    {
76
        return $this->PerfectCMSImageTag($name, $inline, $alt, $attributes);
77
    }
78
79
    /**
80
     * @param string $name       PerfectCMSImages name
81
     * @param bool   $inline     for use within existing image tag - optional. can be TRUE, "TRUE" or 1 also...
82
     * @param string $alt        alt tag for image -optional
83
     * @param string $attributes additional attributes
84
     *
85
     * @return string (HTML)
86
     */
87
    public function PerfectCMSImageTag(string $name, $inline = false, ?string $alt = '', ?string $attributes = '')
88
    {
89
        $arrayData = $this->getPerfectCMSImageTagArrayData($name, $inline, $alt, $attributes);
90
        $template = 'Includes/PerfectCMSImageTag';
91
        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

91
        if (true === $inline || 1 === (int) $inline || 'true' === strtolower(/** @scrutinizer ignore-type */ $inline)) {
Loading history...
92
            $template .= 'Inline';
93
        }
94
95
        return DBField::create_field('HTMLText', $arrayData->renderWith($template));
96
    }
97
98
    /**
99
     * @param string $name       PerfectCMSImages name
100
     * @param bool   $inline     for use within existing image tag - optional. can be TRUE, "TRUE" or 1 also...
101
     * @param string $alt        alt tag for image -optional
102
     * @param string $attributes additional attributes
103
     *
104
     * @return ArrayData
105
     */
106
    public function PerfectCMSImageTagArrayData(string $name, $inline = false, ?string $alt = '', ?string $attributes = '')
107
    {
108
        return $this->getPerfectCMSImageTagArrayData($name, $inline, $alt, $attributes);
109
    }
110
111
    /**
112
     * @param string $name       PerfectCMSImages name
113
     * @param bool   $inline     for use within existing image tag - optional. can be TRUE, "TRUE" or 1 also...
114
     * @param string $alt        alt tag for image -optional
115
     * @param string $attributes additional attributes
116
     *
117
     * @return ArrayData
118
     */
119
    public function getPerfectCMSImageTagArrayData(string $name, $inline = false, ?string $alt = '', ?string $attributes = '')
0 ignored issues
show
Unused Code introduced by
The parameter $inline is not used and could be removed. ( Ignorable by Annotation )

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

119
    public function getPerfectCMSImageTagArrayData(string $name, /** @scrutinizer ignore-unused */ $inline = false, ?string $alt = '', ?string $attributes = '')

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

Loading history...
120
    {
121
        $retinaLink = $this->PerfectCMSImageLinkRetina($name);
122
        $nonRetinaLink = $this->PerfectCMSImageLinkNonRetina($name);
123
124
        $width = PerfectCMSImages::get_width($name, true);
125
        $height = PerfectCMSImages::get_height($name, true);
126
127
        $hasWebP = (bool) Config::inst()->get(ImageManipulations::class, 'webp_enabled');
128
        $hasMobile = PerfectCMSImages::has_mobile($name);
129
130
        // mobile links
131
        $mobileRetinaLink = '';
132
        $mobileNonRetinaLink = '';
133
134
        // mobile media query
135
        $mobileMediaWidth = '';
136
137
        if ($hasMobile) {
138
            $mobileRetinaLink = $this->PerfectCMSImageLinkRetinaForMobile($name);
139
            $mobileNonRetinaLink = $this->PerfectCMSImageLinkNonRetinaForMobile($name);
140
        }
141
        if ($hasWebP) {
142
            $retinaLinkWebP = $this->PerfectCMSImageLinkRetinaWebP($name);
143
            $nonRetinaLinkWebP = $this->PerfectCMSImageLinkNonRetinaWebP($name);
144
            if ($hasMobile) {
145
                $mobileRetinaLinkWebP = $this->PerfectCMSImageLinkRetinaWebPForMobile($name);
146
                $mobileNonRetinaLinkWebP = $this->PerfectCMSImageLinkNonRetinaWebPForMobile($name);
147
            }
148
        }
149
150
        if ($hasMobile) {
151
            $mobileMediaWidth = PerfectCMSImages::get_mobile_media_width($name);
152
        }
153
154
        if (!$alt) {
155
            $alt = $this->getOwner()->Title;
156
        }
157
158
        return ArrayData::create(
159
            [
160
                'MobileMediaWidth' => $mobileMediaWidth,
161
                'Width' => $width,
162
                'Height' => $height,
163
                'Alt' => Convert::raw2att($alt),
164
                'MobileRetinaLink' => $mobileRetinaLink,
165
                'MobileNonRetinaLink' => $mobileNonRetinaLink,
166
                'RetinaLink' => $retinaLink,
167
                'NonRetinaLink' => $nonRetinaLink,
168
                '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...
169
                '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...
170
                'RetinaLinkWebP' => $retinaLinkWebP,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $retinaLinkWebP does not seem to be defined for all execution paths leading up to this point.
Loading history...
171
                'NonRetinaLinkWebP' => $nonRetinaLinkWebP,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $nonRetinaLinkWebP does not seem to be defined for all execution paths leading up to this point.
Loading history...
172
                'Type' => $this->owner->getMimeType(),
173
                'HasWebP' => $hasWebP,
174
                'Attributes' => DBField::create_field('HTMLText', $attributes),
175
            ]
176
        );
177
    }
178
179
    /**
180
     * @param string $name of Image Field template
181
     *
182
     * @return string (link)
183
     */
184
    public function PerfectCMSImageLinkNonRetina(string $name): string
185
    {
186
        return $this->PerfectCMSImageLink($name);
187
    }
188
189
    /**
190
     * @param string $name of Image Field template
191
     *
192
     * @return string (link)
193
     */
194
    public function PerfectCMSImageLinkRetina(string $name): string
195
    {
196
        return $this->PerfectCMSImageLink($name, true);
197
    }
198
199
    /**
200
     * @param string $name of Image Field template
201
     *
202
     * @return string (link)
203
     */
204
    public function PerfectCMSImageLinkNonRetinaWebP(string $name): string
205
    {
206
        return $this->PerfectCMSImageLink($name, false, true);
207
    }
208
209
    /**
210
     * @param string $name of Image Field template
211
     *
212
     * @return string (link)
213
     */
214
    public function PerfectCMSImageLinkRetinaWebP(string $name): string
215
    {
216
        return $this->PerfectCMSImageLink($name, true, true);
217
    }
218
219
    /**
220
     * @param string $name of Image Field template
221
     *
222
     * @return string (link)
223
     */
224
    public function PerfectCMSImageLinkNonRetinaForMobile(string $name): string
225
    {
226
        return $this->PerfectCMSImageLink($name, false, false, true);
227
    }
228
229
    /**
230
     * @param string $name of Image Field template
231
     *
232
     * @return string (link)
233
     */
234
    public function PerfectCMSImageLinkRetinaForMobile(string $name): string
235
    {
236
        return $this->PerfectCMSImageLink($name, true, false, true);
237
    }
238
239
    /**
240
     * @param string $name of Image Field template
241
     *
242
     * @return string (link)
243
     */
244
    public function PerfectCMSImageLinkNonRetinaWebPForMobile(string $name): string
245
    {
246
        return $this->PerfectCMSImageLink($name, false, true, true);
247
    }
248
249
    /**
250
     * @param string $name of Image Field template
251
     *
252
     * @return string (link)
253
     */
254
    public function PerfectCMSImageLinkRetinaWebPForMobile(string $name): string
255
    {
256
        return $this->PerfectCMSImageLink($name, true, true, true);
257
    }
258
259
    /**
260
     * @return string (link)
261
     */
262
    public function getPerfectCMSImageAbsoluteLink(string $link): string
263
    {
264
        return Director::absoluteURL($link);
265
    }
266
267
    /**
268
     * returns image link (if any).
269
     */
270
    public function PerfectCMSImageLink(string $name, ?bool $useRetina = false, ?bool $isWebP = false, ?bool $forMobile = false): string
271
    {
272
        /** @var null|Image $image */
273
        $image = $this->owner;
274
        $allOk = false;
275
        if ($image && $image->exists() && $image instanceof Image) {
276
            $allOk = true;
277
            //we are all good ...
278
        } else {
279
            $image = ImageManipulations::get_backup_image($name);
280
            if ($image && $image->exists() && $image instanceof Image) {
281
                $allOk = true;
282
            }
283
        }
284
285
        if ($allOk) {
286
            // $backEndString = Image::get_backend();
287
            // $backend = Injector::inst()->get($backEndString);
288
            $link = ImageManipulations::get_image_link($image, $name, $useRetina, $forMobile);
289
290
            if ($isWebP) {
291
                $link = ImageManipulations::web_p_link($link);
292
            }
293
294
            return $link ? ImageManipulations::add_fake_parts($image, $link) : '';
295
        } else {
296
            // no image -> provide placeholder if in DEV MODE only!!!
297
            if (Director::isDev()) {
298
                return ImageManipulations::get_placeholder_image_tag($name);
299
            }
300
        }
301
302
        // no image -> provide placeholder if in DEV MODE only!!!
303
        if (Director::isDev()) {
304
            return ImageManipulations::get_placeholder_image_tag($name);
305
        }
306
307
        return '';
308
    }
309
310
    public function PerfectCMSImageFixFolder($name, ?string $folderName = ''): ?Folder
311
    {
312
        $folder = null;
313
        if (PerfectCMSImages::move_to_right_folder($name) || $folderName) {
314
            $image = $this->getOwner();
315
            if ($image) {
0 ignored issues
show
introduced by
$image is of type object, thus it always evaluated to true.
Loading history...
316
                if (!$folderName) {
317
                    $folderName = PerfectCMSImages::get_folder($name);
318
                }
319
                $folder = Folder::find_or_make($folderName);
320
                if (!$folder->ID) {
321
                    $folder->write();
322
                }
323
                if ($image->ParentID !== $folder->ID) {
324
                    $wasPublished = $image->isPublished() && !$image->isModifiedOnDraft();
325
                    $image->ParentID = $folder->ID;
326
                    $image->write();
327
                    if ($wasPublished) {
328
                        $image->publishRecursive();
329
                    }
330
                }
331
            }
332
            // user_error('could not find image');
333
        }
334
335
        return $folder;
336
    }
337
338
    public function getCMSThumbnail()
339
    {
340
        if ($this->owner->ID) {
341
            if ('svg' === $this->owner->getExtension()) {
342
                $obj = DBHTMLText::create();
343
                $obj->setValue(file_get_contents(BASE_PATH . $this->owner->Link()));
344
345
                return $obj;
346
            }
347
348
            return $this->owner->CMSThumbnail();
349
        }
350
351
        return $this->owner->CMSThumbnail();
352
    }
353
354
    public function updatePreviewLink(&$link, $action)
0 ignored issues
show
Unused Code introduced by
The parameter $action is not used and could be removed. ( Ignorable by Annotation )

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

354
    public function updatePreviewLink(&$link, /** @scrutinizer ignore-unused */ $action)

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

Loading history...
355
    {
356
        $owner = $this->getOwner();
357
        if ('svg' === $this->owner->getExtension()) {
358
            return $owner->Link();
359
        }
360
361
        return $link;
362
    }
363
364
    public function onBeforeUnpublish()
365
    {
366
        DB::query('DELETE FROM "PerfectCMSImageCache" WHERE "ImageID" = ' . $this->getOwner()->ID);
367
    }
368
}
369