Completed
Pull Request — master (#13)
by Scott
03:29
created

CWPSiteConfigExtension::getThemeOptionsExcluding()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 10
nc 4
nop 1
dl 0
loc 18
rs 9.9332
c 0
b 0
f 0
1
<?php
2
3
namespace CWP\AgencyExtensions\Extensions;
4
5
use Heyday\ColorPalette\Fields\ColorPaletteField;
0 ignored issues
show
Bug introduced by
The type Heyday\ColorPalette\Fields\ColorPaletteField was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use SilverStripe\Assets\File;
7
use SilverStripe\Assets\Image;
8
use SilverStripe\Core\Injector\Injector;
9
use SilverStripe\Forms\DropdownField;
10
use SilverStripe\Forms\FieldList;
11
use SilverStripe\Forms\FileHandleField;
12
use SilverStripe\Forms\TextField;
13
use SilverStripe\ORM\DataExtension;
14
use SilverStripe\Versioned\Versioned;
15
16
/**
17
 * Class CWPCleanupSiteConfigExtension
18
 */
19
class CWPSiteConfigExtension extends DataExtension
20
{
21
    private static $db = array(
0 ignored issues
show
introduced by
The private property $db is not used, and could be removed.
Loading history...
22
        'FooterLogoLink' => 'Varchar(255)',
23
        'FooterLogoDescription' => 'Varchar(255)',
24
        'FooterLogoSecondaryLink' => 'Varchar(255)',
25
        'FooterLogoSecondaryDescription' => 'Varchar(255)',
26
        'EmptySearch' => 'Varchar(255)',
27
        'NoSearchResults' => 'Varchar(255)',
28
        'MainFontFamily' => 'Varchar(50)',
29
        'HeaderBackground' => 'Varchar(50)',
30
        'NavigationBarBackground' => 'Varchar(50)',
31
        'CarouselBackground' => 'Varchar(50)',
32
        'FooterBackground' => 'Varchar(50)',
33
        'AccentColor' => 'Varchar(50)',
34
        'TextLinkColor' => 'Varchar(50)',
35
    );
36
37
    private static $has_one = array(
0 ignored issues
show
introduced by
The private property $has_one is not used, and could be removed.
Loading history...
38
        'Logo' => Image::class,
39
        'LogoRetina' => Image::class,
40
        'FooterLogo' => Image::class,
41
        'FooterLogoRetina' => Image::class,
42
        'FooterLogoSecondary' => Image::class,
43
        'FavIcon' => File::class,
44
        'AppleTouchIcon144' => File::class,
45
        'AppleTouchIcon114' => File::class,
46
        'AppleTouchIcon72' => File::class,
47
        'AppleTouchIcon57' => File::class
48
    );
49
50
    private static $owns = [
0 ignored issues
show
introduced by
The private property $owns is not used, and could be removed.
Loading history...
51
        'Logo',
52
        'LogoRetina',
53
        'FooterLogo',
54
        'FooterLogoRetina',
55
        'FooterLogoSecondary',
56
        'FavIcon',
57
        'AppleTouchIcon144',
58
        'AppleTouchIcon114',
59
        'AppleTouchIcon72',
60
        'AppleTouchIcon57'
61
    ];
62
63
    private static $defaults = [
0 ignored issues
show
introduced by
The private property $defaults is not used, and could be removed.
Loading history...
64
        'MainFontFamily' => 'nunito-sans',
65
        'HeaderBackground' => 'default-background',
66
        'NavigationBarBackground' => 'default-background',
67
        'CarouselBackground' => 'default-background',
68
        'FooterBackground' => 'default-background',
69
        'AccentColor' => 'default-accent',
70
        'TextLinkColor' => 'default-accent',
71
    ];
72
73
    /**
74
     * Defines whether to use the ColorPaletteField to render theme colour picker
75
     * @var boolean
76
     */
77
    private $useColorPaletteField = true;
78
79
    /**
80
     * Defines if the theme colour picker is enabled in the CMS
81
     *
82
     * @config
83
     * @var boolean
84
     */
85
    private static $enable_theme_color_picker = false;
0 ignored issues
show
introduced by
The private property $enable_theme_color_picker is not used, and could be removed.
Loading history...
86
87
    /**
88
     * Defines the theme fonts that can be selected via the CMS
89
     *
90
     * @config
91
     * @var array
92
     */
93
    private static $theme_fonts = [
0 ignored issues
show
introduced by
The private property $theme_fonts is not used, and could be removed.
Loading history...
94
        'nunito-sans' => 'Nunito Sans',
95
        'fira-sans' => 'Fira Sans',
96
        'merriweather' => 'Merriweather',
97
    ];
98
99
    /**
100
     * Defines the theme colours that can be selected via the CMS
101
     *
102
     * @config
103
     * @var array
104
     */
105
    private static $theme_colors = [
0 ignored issues
show
introduced by
The private property $theme_colors is not used, and could be removed.
Loading history...
106
        'default-accent' => [
107
            'Title' => 'Default accent',
108
            'CSSClass' => 'default-accent',
109
            'Color' => '#0F7EB2',
110
        ],
111
        'default-background' => [
112
            'Title' => 'Default background',
113
            'CSSClass' => 'default-background',
114
            'Color' => '#001F2C',
115
        ],
116
        'red' => [
117
            'Title' => 'Red',
118
            'CSSClass' => 'red',
119
            'Color' => '#E51016',
120
        ],
121
        'dark-red' => [
122
            'Title' => 'Dark red',
123
            'CSSClass' => 'dark-red',
124
            'Color' => '#AD161E',
125
        ],
126
        'pink' => [
127
            'Title' => 'Pink',
128
            'CSSClass' => 'pink',
129
            'Color' => '#B32A95',
130
        ],
131
        'purple' => [
132
            'Title' => 'Purple',
133
            'CSSClass' => 'purple',
134
            'Color' => '#6239C8',
135
        ],
136
        'blue' => [
137
            'Title' => 'Blue',
138
            'CSSClass' => 'blue',
139
            'Color' => '#1F6BFE',
140
        ],
141
        'dark-blue' => [
142
            'Title' => 'Dark blue',
143
            'CSSClass' => 'dark-blue',
144
            'Color' => '#123581',
145
        ],
146
        'teal' => [
147
            'Title' => 'Teal',
148
            'CSSClass' => 'teal',
149
            'Color' => '#00837A',
150
        ],
151
        'green' => [
152
            'Title' => 'Green',
153
            'CSSClass' => 'green',
154
            'Color' => '#298436',
155
        ],
156
        'dark-orange' => [
157
            'Title' => 'Dark orange',
158
            'CSSClass' => 'dark-orange',
159
            'Color' => '#D34300',
160
        ],
161
        'dark-ochre' => [
162
            'Title' => 'Dark ochre',
163
            'CSSClass' => 'dark-ochre',
164
            'Color' => '#947200',
165
        ],
166
        'black' => [
167
            'Title' => 'Black',
168
            'CSSClass' => 'black',
169
            'Color' => '#111111',
170
        ],
171
        'dark-grey' => [
172
            'Title' => 'Dark grey',
173
            'CSSClass' => 'dark-grey',
174
            'Color' => '#555555',
175
        ],
176
        'light-grey' => [
177
            'Title' => 'Light grey',
178
            'CSSClass' => 'light-grey',
179
            'Color' => '#EAEAEA',
180
        ],
181
        'white' => [
182
            'Title' => 'White',
183
            'CSSClass' => 'white',
184
            'Color' => '#FFFFFF',
185
        ],
186
    ];
187
188
    public function __construct()
189
    {
190
        $this->useColorPaletteField = class_exists(ColorPaletteField::class);
191
    }
192
193
    /**
194
     * @param FieldList $fields
195
     */
196
    public function updateCMSFields(FieldList $fields)
197
    {
198
        $this
199
            ->addLogosAndIcons($fields)
200
            ->addSearchOptions($fields)
201
            ->addThemeColorPicker($fields);
202
    }
203
204
    /**
205
     * Add fields for logo and icon uploads
206
     *
207
     * @param  FieldList $fields
208
     * @return $this
209
     */
210
    protected function addLogosAndIcons(FieldList $fields)
211
    {
212
        $logoTypes = array('jpg', 'jpeg', 'png', 'gif');
213
        $iconTypes = array('ico');
214
        $appleTouchTypes = array('png');
215
216
        $fields->findOrMakeTab(
217
            'Root.LogosIcons',
218
            _t(__CLASS__ . '.LogosIconsTab', 'Logos/Icons')
219
        );
220
221
        $fields->addFieldToTab(
222
            'Root.LogosIcons',
223
            $logoField = Injector::inst()->create(
224
                FileHandleField::class,
225
                'Logo',
226
                _t(__CLASS__ . '.LogoUploadField', 'Logo, to appear in the top left')
227
            )
228
        );
229
        $logoField->getValidator()->setAllowedExtensions($logoTypes);
230
231
        $fields->addFieldToTab(
232
            'Root.LogosIcons',
233
            $logoRetinaField = Injector::inst()->create(
234
                FileHandleField::class,
235
                'LogoRetina',
236
                _t(
237
                    'CwpConfig.LogoRetinaUploadField',
238
                    'High resolution logo, to appear in the top left ' .
239
                    '(recommended to be twice the height and width of the standard logo)'
240
                )
241
            )
242
        );
243
        $logoRetinaField->getValidator()->setAllowedExtensions($logoTypes);
244
245
        $fields->addFieldToTab(
246
            'Root.LogosIcons',
247
            $footerLogoField = Injector::inst()->create(
248
                FileHandleField::class,
249
                'FooterLogo',
250
                _t(__CLASS__ . '.FooterLogoField', 'Footer logo, to appear in the footer')
251
            )
252
        );
253
        $footerLogoField->getValidator()->setAllowedExtensions($logoTypes);
254
255
        $fields->addFieldToTab(
256
            'Root.LogosIcons',
257
            $footerLogoRetinaField = Injector::inst()->create(
258
                FileHandleField::class,
259
                'FooterLogoRetina',
260
                _t(
261
                    'CwpConfig.FooterLogoRetinaField',
262
                    'High resolution footer logo (recommended twice the height and width of the standard footer logo)'
263
                )
264
            )
265
        );
266
        $footerLogoRetinaField->getValidator()->setAllowedExtensions($logoTypes);
267
268
        $fields->addFieldToTab(
269
            'Root.LogosIcons',
270
            $footerLink = TextField::create(
271
                'FooterLogoLink',
272
                _t(__CLASS__ . '.FooterLogoLinkField', 'Footer Logo link')
273
            )
274
        );
275
        $footerLink->setRightTitle(
276
            _t(
277
                'CwpConfig.FooterLogoLinkDesc',
278
                'Please include the protocol (ie, http:// or https://) unless it is an internal link.'
279
            )
280
        );
281
282
        $fields->addFieldToTab(
283
            'Root.LogosIcons',
284
            TextField::create(
285
                'FooterLogoDescription',
286
                _t(__CLASS__ . '.FooterLogoDescField', 'Footer Logo description')
287
            )
288
        );
289
290
        $fields->addFieldToTab(
291
            'Root.LogosIcons',
292
            $footerLogoSecondaryField = Injector::inst()->create(
293
                FileHandleField::class,
294
                'FooterLogoSecondary',
295
                _t(__CLASS__ . '.FooterLogoSecondaryField', 'Secondary Footer Logo, to appear in the footer.')
296
            )
297
        );
298
        $footerLogoSecondaryField->getValidator()->setAllowedExtensions($logoTypes);
299
300
        $fields->addFieldToTab('Root.LogosIcons', $footerSecondaryLink = TextField::create(
301
            'FooterLogoSecondaryLink',
302
            _t(__CLASS__ . '.FooterLogoSecondaryLinkField', 'Secondary Footer Logo link.')
303
        ));
304
        $footerSecondaryLink->setRightTitle(_t(
305
            'CwpConfig.FooterLogoSecondaryLinkDesc',
306
            'Please include the protocol (ie, http:// or https://) unless it is an internal link.'
307
        ));
308
        $fields->addFieldToTab('Root.LogosIcons', TextField::create(
309
            'FooterLogoSecondaryDescription',
310
            _t(__CLASS__ . '.FooterLogoSecondaryDescField', 'Secondary Footer Logo description')
311
        ));
312
313
        $fields->addFieldToTab(
314
            'Root.LogosIcons',
315
            $favIconField = Injector::inst()->create(
316
                FileHandleField::class,
317
                'FavIcon',
318
                _t(__CLASS__ . '.FavIconField', 'Favicon, in .ico format, dimensions of 16x16, 32x32, or 48x48')
319
            )
320
        );
321
        $favIconField->getValidator()->setAllowedExtensions($iconTypes);
322
323
        $fields->addFieldToTab(
324
            'Root.LogosIcons',
325
            $atIcon144 = Injector::inst()->create(
326
                FileHandleField::class,
327
                'AppleTouchIcon144',
328
                _t(
329
                    'CwpConfig.AppleIconField144',
330
                    'Apple Touch Web Clip and Windows 8 Tile Icon (dimensions of 144x144, PNG format)'
331
                )
332
            )
333
        );
334
        $atIcon144->getValidator()->setAllowedExtensions($appleTouchTypes);
335
336
        $fields->addFieldToTab(
337
            'Root.LogosIcons',
338
            $atIcon114 = Injector::inst()->create(
339
                FileHandleField::class,
340
                'AppleTouchIcon114',
341
                _t(__CLASS__ . '.AppleIconField114', 'Apple Touch Web Clip Icon (dimensions of 114x114, PNG format)')
342
            )
343
        );
344
        $atIcon114->getValidator()->setAllowedExtensions($appleTouchTypes);
345
346
        $fields->addFieldToTab(
347
            'Root.LogosIcons',
348
            $atIcon72 = Injector::inst()->create(
349
                FileHandleField::class,
350
                'AppleTouchIcon72',
351
                _t(__CLASS__ . '.AppleIconField72', 'Apple Touch Web Clip Icon (dimensions of 72x72, PNG format)')
352
            )
353
        );
354
        $atIcon72->getValidator()->setAllowedExtensions($appleTouchTypes);
355
356
        $fields->addFieldToTab(
357
            'Root.LogosIcons',
358
            $atIcon57 = Injector::inst()->create(
359
                FileHandleField::class,
360
                'AppleTouchIcon57',
361
                _t(__CLASS__ . '.AppleIconField57', 'Apple Touch Web Clip Icon (dimensions of 57x57, PNG format)')
362
            )
363
        );
364
        $atIcon57->getValidator()->setAllowedExtensions($appleTouchTypes);
365
366
        return $this;
367
    }
368
369
    /**
370
     * Add user configurable search field labels
371
     *
372
     * @param  FieldList $fields
373
     * @return $this
374
     */
375
    protected function addSearchOptions(FieldList $fields)
376
    {
377
        $fields->findOrMakeTab('Root.SearchOptions');
378
379
        $fields->addFieldToTab(
380
            'Root.SearchOptions',
381
            TextField::create(
382
                'EmptySearch',
383
                _t(
384
                    'CWP.SITECONFIG.EmptySearch',
385
                    'Text to display when there is no search query'
386
                )
387
            )
388
        );
389
        $fields->addFieldToTab(
390
            'Root.SearchOptions',
391
            TextField::create(
392
                'NoSearchResults',
393
                _t(
394
                    'CWP.SITECONFIG.NoResult',
395
                    'Text to display when there are no results'
396
                )
397
            )
398
        );
399
400
        return $this;
401
    }
402
403
    /**
404
     * Add field for selecting the theme colour for different areas of the site. Will create fields
405
     * with ColorPaletteField if the ColorPalette modules exists, falling back to DropdownField.
406
     *
407
     * @param  FieldList $fields
408
     * @return $this
409
     */
410
    protected function addThemeColorPicker(FieldList $fields)
411
    {
412
        // Only show theme colour selector if enabled
413
        if (!$this->owner->config()->get('enable_theme_color_picker')) {
414
            return $this;
415
        }
416
417
        $themeColors = $this->owner->config()->get('theme_colors');
0 ignored issues
show
Unused Code introduced by
The assignment to $themeColors is dead and can be removed.
Loading history...
418
        $fieldType = DropdownField::class;
419
        $allThemeColors = $this->getThemeOptionsExcluding();
0 ignored issues
show
Unused Code introduced by
The assignment to $allThemeColors is dead and can be removed.
Loading history...
420
421
        if ($this->useColorPaletteField) {
422
            $fieldType = ColorPaletteField::class;
423
        }
424
425
        $fields->addFieldsToTab(
426
            'Root.ThemeOptions',
427
            [
428
                DropdownField::create(
429
                    'MainFontFamily',
430
                    _t(
431
                        __CLASS__ . '.MainFontFamily',
432
                        'Main font family'
433
                    ),
434
                    $this->owner->config()->get('theme_fonts')
435
                ),
436
                $fieldType::create(
437
                    'HeaderBackground',
438
                    _t(
439
                        __CLASS__ . '.HeaderBackground',
440
                        'Header background'
441
                    ),
442
                    $this->getThemeOptionsExcluding([
443
                        'default-accent',
444
                    ])
445
                ),
446
                $fieldType::create(
447
                    'NavigationBarBackground',
448
                    _t(
449
                        __CLASS__ . '.NavigationBarBackground',
450
                        'Navigation bar background'
451
                    ),
452
                    $this->getThemeOptionsExcluding([
453
                        'default-accent',
454
                    ])
455
                ),
456
                $fieldType::create(
457
                    'CarouselBackground',
458
                    _t(
459
                        __CLASS__ . '.CarouselBackground',
460
                        'Carousel background'
461
                    ),
462
                    $this->getThemeOptionsExcluding([
463
                        'default-accent',
464
                    ])
465
                )->setDescription(
466
                    _t(
467
                        __CLASS__ . '.CarouselBackgroundDescription',
468
                        'The background colour of the carousel when there is no image set.'
469
                    )
470
                ),
471
                $fieldType::create(
472
                    'FooterBackground',
473
                    _t(
474
                        __CLASS__ . '.FooterBackground',
475
                        'Footer background'
476
                    ),
477
                    $this->getThemeOptionsExcluding([
478
                        'light-grey',
479
                        'white',
480
                        'default-accent',
481
                    ])
482
                ),
483
                $fieldType::create(
484
                    'AccentColor',
485
                    _t(
486
                        __CLASS__ . '.AccentColor',
487
                        'Accent colour'
488
                    ),
489
                    $this->getThemeOptionsExcluding([
490
                        'light-grey',
491
                        'white',
492
                        'default-background',
493
                    ])
494
                )->setDescription(
495
                    _t(
496
                        __CLASS__ . '.AccentColorDescription',
497
                        'Affects colour of buttons, current navigation items etc.'
498
                    )
499
                ),
500
                $fieldType::create(
501
                    'TextLinkColor',
502
                    _t(
503
                        __CLASS__ . '.TextLinkColor',
504
                        'Text link colour'
505
                    ),
506
                    $this->getThemeOptionsExcluding([
507
                        'black',
508
                        'light-grey',
509
                        'dark-grey',
510
                        'white',
511
                        'default-background',
512
                    ])
513
                ),
514
            ]
515
        );
516
517
        return $this;
518
    }
519
520
    /**
521
     * Returns theme_colors in a format consumable by a DropdownField/ColorPaletteField.
522
     *
523
     * @param  array  $excludedColors list of colours to exclude from the returned options
524
     *                                based on the theme colour's 'CSSClass' value
525
     * @return array
526
     */
527
    public function getThemeOptionsExcluding($excludedColors = [])
528
    {
529
        $themeColors = $this->owner->config()->get('theme_colors');
530
        $options = [];
531
532
        foreach ($themeColors as $themeColor) {
533
            if (in_array($themeColor['CSSClass'], $excludedColors)) {
534
                continue;
535
            }
536
537
            if ($this->useColorPaletteField) {
538
                $options[$themeColor['CSSClass']] = $themeColor['Color'];
539
            } else {
540
                $options[$themeColor['CSSClass']] = $themeColor['Title'];
541
            }
542
        }
543
544
        return $options;
545
    }
546
547
    /**
548
     * Setter for the useColorPaletteField property
549
     * @param boolean $useColorPaletteField
550
     */
551
    public function setUseColorPaletteField($useColorPaletteField)
552
    {
553
        $this->useColorPaletteField = $useColorPaletteField;
554
    }
555
556
    /**
557
     * Auto-publish any images attached to the SiteConfig object if it's not versioned. Versioned objects will
558
     * handle their related objects via the "owns" API by default.
559
     */
560
    public function onAfterWrite()
561
    {
562
        if (!$this->owner->hasExtension(Versioned::class)) {
563
            $this->owner->publishRecursive();
564
        }
565
    }
566
567
    /**
568
     * If HeaderBackground is not set, assume no theme colours exist and call populateDefaults if the color picker is enabled.
569
     * This is done as SiteConfig won't call populateDefaults() on existing sites, so would
570
     * not have any default theme_colors
571
     */
572
    public function onBeforeWrite()
573
    {
574
        $colorPickerEnabled = $this->owner->config()->get('enable_theme_color_picker');
575
576
        if ($colorPickerEnabled && !isset($this->owner->record['HeaderBackground'])) {
577
            $this->owner->populateDefaults();
578
        }
579
    }
580
}
581