Passed
Pull Request — master (#13)
by Scott
03:07
created

CWPSiteConfigExtension::getThemeOptionsExcluding()   A

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