Completed
Push — master ( 05226f...f09009 )
by Robbie
39s queued 36s
created

BaseElement::getStyleVariant()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 8
nc 2
nop 0
dl 0
loc 14
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace DNADesign\Elemental\Models;
4
5
use DNADesign\Elemental\ORM\FieldType\DBObjectType;
6
use DNADesign\Elemental\Controllers\ElementController;
7
use DNADesign\Elemental\Forms\TextCheckboxGroupField;
8
use Exception;
9
use SilverStripe\CMS\Controllers\CMSPageEditController;
10
use SilverStripe\CMS\Model\SiteTree;
11
use SilverStripe\Control\Controller;
12
use SilverStripe\Control\Director;
13
use SilverStripe\Core\ClassInfo;
14
use SilverStripe\Core\Injector\Injector;
15
use SilverStripe\Forms\CheckboxField;
16
use SilverStripe\Forms\DropdownField;
17
use SilverStripe\Forms\FieldList;
18
use SilverStripe\Forms\HiddenField;
19
use SilverStripe\Forms\NumericField;
20
use SilverStripe\Forms\TextField;
21
use SilverStripe\ORM\DataObject;
22
use SilverStripe\ORM\FieldType\DBField;
23
use SilverStripe\ORM\FieldType\DBHTMLText;
24
use SilverStripe\Security\Member;
25
use SilverStripe\Security\Permission;
26
use SilverStripe\Versioned\Versioned;
27
use SilverStripe\VersionedAdmin\Forms\HistoryViewerField;
28
use SilverStripe\View\ArrayData;
29
use SilverStripe\View\Parsers\URLSegmentFilter;
30
use SilverStripe\View\Requirements;
31
32
/**
33
 * Class BaseElement
34
 * @package DNADesign\Elemental\Models
35
 *
36
 * @property string $Title
37
 * @property bool $ShowTitle
38
 * @property int $Sort
39
 * @property string $ExtraClass
40
 * @property string $Style
41
 *
42
 * @method ElementalArea Parent()
43
 */
44
class BaseElement extends DataObject
45
{
46
    /**
47
     * Override this on your custom elements to specify a CSS icon class
48
     *
49
     * @var string
50
     */
51
    private static $icon = 'font-icon-block-layout';
0 ignored issues
show
introduced by
The private property $icon is not used, and could be removed.
Loading history...
52
53
    /**
54
     * Describe the purpose of this element
55
     *
56
     * @config
57
     * @var string
58
     */
59
    private static $description = 'Base element class';
0 ignored issues
show
introduced by
The private property $description is not used, and could be removed.
Loading history...
60
61
    private static $db = [
0 ignored issues
show
introduced by
The private property $db is not used, and could be removed.
Loading history...
62
        'Title' => 'Varchar(255)',
63
        'ShowTitle' => 'Boolean',
64
        'Sort' => 'Int',
65
        'ExtraClass' => 'Varchar(255)',
66
        'Style' => 'Varchar(255)'
67
    ];
68
69
    private static $has_one = [
0 ignored issues
show
introduced by
The private property $has_one is not used, and could be removed.
Loading history...
70
        'Parent' => ElementalArea::class
71
    ];
72
73
    private static $extensions = [
0 ignored issues
show
introduced by
The private property $extensions is not used, and could be removed.
Loading history...
74
        Versioned::class
75
    ];
76
77
    private static $casting = [
0 ignored issues
show
introduced by
The private property $casting is not used, and could be removed.
Loading history...
78
        'BlockSchema' => DBObjectType::class,
79
    ];
80
81
    private static $versioned_gridfield_extensions = true;
0 ignored issues
show
introduced by
The private property $versioned_gridfield_extensions is not used, and could be removed.
Loading history...
82
83
    private static $table_name = 'Element';
0 ignored issues
show
introduced by
The private property $table_name is not used, and could be removed.
Loading history...
84
85
    /**
86
     * @var string
87
     */
88
    private static $controller_class = ElementController::class;
89
90
    /**
91
     * @var string
92
     */
93
    private static $controller_template = 'ElementHolder';
0 ignored issues
show
introduced by
The private property $controller_template is not used, and could be removed.
Loading history...
94
95
    /**
96
     * @var ElementController
97
     */
98
    protected $controller;
99
100
    private static $default_sort = 'Sort';
0 ignored issues
show
introduced by
The private property $default_sort is not used, and could be removed.
Loading history...
101
102
    private static $singular_name = 'block';
0 ignored issues
show
introduced by
The private property $singular_name is not used, and could be removed.
Loading history...
103
104
    private static $plural_name = 'blocks';
0 ignored issues
show
introduced by
The private property $plural_name is not used, and could be removed.
Loading history...
105
106
    private static $summary_fields = [
0 ignored issues
show
introduced by
The private property $summary_fields is not used, and could be removed.
Loading history...
107
        'EditorPreview' => 'Summary'
108
    ];
109
110
    /**
111
     * @config
112
     * @var array
113
     */
114
    private static $styles = [];
0 ignored issues
show
introduced by
The private property $styles is not used, and could be removed.
Loading history...
115
116
    private static $searchable_fields = [
0 ignored issues
show
introduced by
The private property $searchable_fields is not used, and could be removed.
Loading history...
117
        'ID' => [
118
            'field' => NumericField::class,
119
        ],
120
        'Title',
121
        'LastEdited'
122
    ];
123
124
    /**
125
     * Enable for backwards compatibility
126
     *
127
     * @var boolean
128
     */
129
    private static $disable_pretty_anchor_name = false;
130
131
    /**
132
     * Store used anchor names, this is to avoid title clashes
133
     * when calling 'getAnchor'
134
     *
135
     * @var array
136
     */
137
    protected static $used_anchors = [];
138
139
    /**
140
     * For caching 'getAnchor'
141
     *
142
     * @var string
143
     */
144
    protected $anchor = null;
145
146
    /**
147
     * Basic permissions, defaults to page perms where possible.
148
     *
149
     * @param Member $member
150
     * @return boolean
151
     */
152
    public function canView($member = null)
153
    {
154
        $extended = $this->extendedCan(__FUNCTION__, $member);
155
        if ($extended !== null) {
156
            return $extended;
157
        }
158
159
        if ($this->hasMethod('getPage')) {
160
            if ($page = $this->getPage()) {
161
                return $page->canView($member);
162
            }
163
        }
164
165
        return (Permission::check('CMS_ACCESS', 'any', $member)) ? true : null;
166
    }
167
168
    /**
169
     * Basic permissions, defaults to page perms where possible.
170
     *
171
     * @param Member $member
172
     *
173
     * @return boolean
174
     */
175
    public function canEdit($member = null)
176
    {
177
        $extended = $this->extendedCan(__FUNCTION__, $member);
178
        if ($extended !== null) {
179
            return $extended;
180
        }
181
182
        if ($this->hasMethod('getPage')) {
183
            if ($page = $this->getPage()) {
184
                return $page->canEdit($member);
185
            }
186
        }
187
188
        return (Permission::check('CMS_ACCESS', 'any', $member)) ? true : null;
189
    }
190
191
    /**
192
     * Basic permissions, defaults to page perms where possible.
193
     *
194
     * Uses archive not delete so that current stage is respected i.e if a
195
     * element is not published, then it can be deleted by someone who doesn't
196
     * have publishing permissions.
197
     *
198
     * @param Member $member
199
     *
200
     * @return boolean
201
     */
202
    public function canDelete($member = null)
203
    {
204
        $extended = $this->extendedCan(__FUNCTION__, $member);
205
        if ($extended !== null) {
206
            return $extended;
207
        }
208
209
        if ($this->hasMethod('getPage')) {
210
            if ($page = $this->getPage()) {
211
                return $page->canArchive($member);
212
            }
213
        }
214
215
        return (Permission::check('CMS_ACCESS', 'any', $member)) ? true : null;
216
    }
217
218
    /**
219
     * Basic permissions, defaults to page perms where possible.
220
     *
221
     * @param Member $member
222
     * @param array $context
223
     *
224
     * @return boolean
225
     */
226
    public function canCreate($member = null, $context = array())
227
    {
228
        $extended = $this->extendedCan(__FUNCTION__, $member);
229
        if ($extended !== null) {
230
            return $extended;
231
        }
232
233
        return (Permission::check('CMS_ACCESS', 'any', $member)) ? true : null;
234
    }
235
236
    /**
237
     * Increment the sort order if one hasn't been already defined. This ensures that new elements are created
238
     * at the end of the list by default.
239
     *
240
     * {@inheritDoc}
241
     */
242
    public function onBeforeWrite()
243
    {
244
        parent::onBeforeWrite();
245
246
        if (!$this->Sort) {
247
            $this->Sort = static::get()->max('Sort') + 1;
248
        }
249
    }
250
251
    public function getCMSFields()
252
    {
253
        $this->beforeUpdateCMSFields(function (FieldList $fields) {
254
            // Remove relationship fields
255
            $fields->removeByName('ParentID');
256
            $fields->removeByName('Sort');
257
258
            $fields->addFieldToTab(
259
                'Root.Settings',
260
                TextField::create('ExtraClass', _t(__CLASS__ . '.ExtraCssClassesLabel', 'Custom CSS classes'))
261
                    ->setAttribute(
262
                        'placeholder',
263
                        _t(__CLASS__ . '.ExtraCssClassesPlaceholder', 'my_class another_class')
264
                    )
265
            );
266
267
            // Add a combined field for "Title" and "Displayed" checkbox in a Bootstrap input group
268
            $fields->removeByName('ShowTitle');
269
            $fields->replaceField(
270
                'Title',
271
                TextCheckboxGroupField::create(
272
                    TextField::create('Title', _t(__CLASS__ . '.TitleLabel', 'Title (displayed if checked)')),
273
                    CheckboxField::create('ShowTitle', _t(__CLASS__ . '.ShowTitleLabel', 'Displayed'))
274
                )
275
                    ->setName('TitleAndDisplayed')
276
            );
277
278
            // Rename the "Main" tab
279
            $fields->fieldByName('Root.Main')
280
                ->setTitle(_t(__CLASS__ . '.MainTabLabel', 'Content'));
281
282
            $fields->addFieldsToTab('Root.Main', [
283
                HiddenField::create('AbsoluteLink', false, Director::absoluteURL($this->PreviewLink())),
284
                HiddenField::create('LiveLink', false, Director::absoluteURL($this->Link())),
285
                HiddenField::create('StageLink', false, Director::absoluteURL($this->PreviewLink())),
286
            ]);
287
288
            $styles = $this->config()->get('styles');
289
290
            if ($styles && count($styles) > 0) {
291
                $styleDropdown = DropdownField::create('Style', _t(__CLASS__.'.STYLE', 'Style variation'), $styles);
292
293
                $fields->insertBefore($styleDropdown, 'ExtraClass');
0 ignored issues
show
Bug introduced by
'ExtraClass' of type string is incompatible with the type SilverStripe\Forms\FormField expected by parameter $item of SilverStripe\Forms\FieldList::insertBefore(). ( Ignorable by Annotation )

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

293
                $fields->insertBefore($styleDropdown, /** @scrutinizer ignore-type */ 'ExtraClass');
Loading history...
294
295
                $styleDropdown->setEmptyString(_t(__CLASS__.'.CUSTOM_STYLES', 'Select a style..'));
296
            } else {
297
                $fields->removeByName('Style');
298
            }
299
300
            // Support for new history viewer in SS 4.2+
301
            if (class_exists(HistoryViewerField::class)) {
302
                Requirements::javascript('dnadesign/silverstripe-elemental:client/dist/js/bundle.js');
303
304
                $historyViewer = HistoryViewerField::create('ElementHistory');
305
                $fields->addFieldToTab('Root.History', $historyViewer);
306
307
                $fields->fieldByName('Root.History')
308
                    ->addExtraClass('elemental-block__history-tab tab--history-viewer');
309
            }
310
        });
311
312
        return parent::getCMSFields();
313
    }
314
315
    /**
316
     * Get the type of the current block, for use in GridField summaries, block
317
     * type dropdowns etc. Examples are "Content", "File", "Media", etc.
318
     *
319
     * @return string
320
     */
321
    public function getType()
322
    {
323
        return _t(__CLASS__ . '.BlockType', 'Block');
324
    }
325
326
    /**
327
     * @param ElementController $controller
328
     *
329
     * @return $this
330
     */
331
    public function setController($controller)
332
    {
333
        $this->controller = $controller;
334
335
        return $this;
336
    }
337
338
    /**
339
     * @throws Exception If the specified controller class doesn't exist
340
     *
341
     * @return ElementController
342
     */
343
    public function getController()
344
    {
345
        if ($this->controller) {
346
            return $this->controller;
347
        }
348
349
        $controllerClass = self::config()->controller_class;
350
351
        if (!class_exists($controllerClass)) {
352
            throw new Exception(
353
                'Could not find controller class ' . $controllerClass . ' as defined in ' . static::class
354
            );
355
        }
356
357
        $this->controller = Injector::inst()->create($controllerClass, $this);
358
        $this->controller->doInit();
359
360
        return $this->controller;
361
    }
362
363
    /**
364
     * @return Controller
365
     */
366
    public function Top()
367
    {
368
        return (Controller::has_curr()) ? Controller::curr() : null;
369
    }
370
371
    /**
372
     * Default way to render element in templates. Note that all blocks should
373
     * be rendered through their {@link ElementController} class as this
374
     * contains the holder styles.
375
     *
376
     * @return string|null HTML
377
     */
378
    public function forTemplate($holder = true)
379
    {
380
        $templates = $this->getRenderTemplates();
381
382
        if ($templates) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $templates of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
383
            return $this->renderWith($templates);
384
        }
385
386
        return null;
387
    }
388
389
    /**
390
     * @param string $suffix
391
     *
392
     * @return array
393
     */
394
    public function getRenderTemplates($suffix = '')
395
    {
396
        $classes = ClassInfo::ancestry($this->ClassName);
397
        $classes[static::class] = static::class;
398
        $classes = array_reverse($classes);
399
        $templates = [];
400
401
        foreach ($classes as $key => $class) {
402
            if ($class == BaseElement::class) {
403
                continue;
404
            }
405
406
            if ($class == DataObject::class) {
407
                break;
408
            }
409
410
            if ($style = $this->Style) {
411
                $templates[$class][] = $class . $suffix . '_'. $this->getAreaRelationName() . '_' . $style;
412
                $templates[$class][] = $class . $suffix . '_' . $style;
413
            }
414
            $templates[$class][] = $class . $suffix . '_'. $this->getAreaRelationName();
415
            $templates[$class][] = $class . $suffix;
416
        }
417
418
        $this->extend('updateRenderTemplates', $templates, $suffix);
419
420
        $templateFlat = [];
421
        foreach ($templates as $class => $variations) {
422
            $templateFlat = array_merge($templateFlat, $variations);
423
        }
424
425
        return $templateFlat;
426
    }
427
428
    /**
429
     * Strip all namespaces from class namespace.
430
     *
431
     * @param string $classname e.g. "\Fully\Namespaced\Class"
432
     *
433
     * @return string following the param example, "Class"
434
     */
435
    protected function stripNamespacing($classname)
436
    {
437
        $classParts = explode('\\', $classname);
438
        return array_pop($classParts);
439
    }
440
441
    /**
442
     * @return string
443
     */
444
    public function getSimpleClassName()
445
    {
446
        return strtolower($this->sanitiseClassName($this->ClassName, '__'));
447
    }
448
449
    /**
450
     * @return null|DataObject
451
     * @throws \Psr\Container\NotFoundExceptionInterface
452
     * @throws \SilverStripe\ORM\ValidationException
453
     */
454
    public function getPage()
455
    {
456
        $area = $this->Parent();
457
458
        if ($area instanceof ElementalArea && $area->exists()) {
459
            return $area->getOwnerPage();
460
        }
461
462
        return null;
463
    }
464
465
    /**
466
     * Get a unique anchor name
467
     *
468
     * @return string
469
     */
470
    public function getAnchor()
471
    {
472
        if ($this->anchor !== null) {
473
            return $this->anchor;
474
        }
475
476
        $anchorTitle = '';
477
478
        if (!$this->config()->disable_pretty_anchor_name) {
479
            if ($this->hasMethod('getAnchorTitle')) {
480
                $anchorTitle = $this->getAnchorTitle();
0 ignored issues
show
Bug introduced by
The method getAnchorTitle() does not exist on DNADesign\Elemental\Models\BaseElement. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

480
                /** @scrutinizer ignore-call */ 
481
                $anchorTitle = $this->getAnchorTitle();
Loading history...
481
            } elseif ($this->config()->enable_title_in_template) {
482
                $anchorTitle = $this->getField('Title');
483
            }
484
        }
485
486
        if (!$anchorTitle) {
487
            $anchorTitle = 'e'.$this->ID;
488
        }
489
490
        $filter = URLSegmentFilter::create();
491
        $titleAsURL = $filter->filter($anchorTitle);
492
493
        // Ensure that this anchor name isn't already in use
494
        // ie. If two elemental blocks have the same title, it'll append '-2', '-3'
495
        $result = $titleAsURL;
496
        $count = 1;
497
        while (isset(self::$used_anchors[$result]) && self::$used_anchors[$result] !== $this->ID) {
498
            ++$count;
499
            $result = $titleAsURL . '-' . $count;
500
        }
501
        self::$used_anchors[$result] = $this->ID;
502
        return $this->anchor = $result;
503
    }
504
505
    /**
506
     * @param string|null $action
507
     * @return string|null
508
     * @throws \Psr\Container\NotFoundExceptionInterface
509
     * @throws \SilverStripe\ORM\ValidationException
510
     */
511
    public function AbsoluteLink($action = null)
512
    {
513
        if ($page = $this->getPage()) {
514
            $link = $page->AbsoluteLink($action) . '#' . $this->getAnchor();
515
516
            return $link;
517
        }
518
519
        return null;
520
    }
521
522
    /**
523
     * @param string|null $action
524
     * @return string
525
     * @throws \Psr\Container\NotFoundExceptionInterface
526
     * @throws \SilverStripe\ORM\ValidationException
527
     */
528
    public function Link($action = null)
529
    {
530
        if ($page = $this->getPage()) {
531
            $link = $page->Link($action) . '#' . $this->getAnchor();
532
533
            $this->extend('updateLink', $link);
534
535
            return $link;
536
        }
537
538
        return null;
539
    }
540
541
    /**
542
     * @param string|null $action
543
     * @return string
544
     * @throws \Psr\Container\NotFoundExceptionInterface
545
     * @throws \SilverStripe\ORM\ValidationException
546
     */
547
    public function PreviewLink($action = null)
548
    {
549
        $action = $action . '?ElementalPreview=' . mt_rand();
550
        $link = $this->Link($action);
551
        $this->extend('updatePreviewLink', $link);
552
553
        return $link;
554
    }
555
556
    /**
557
     * @return boolean
558
     */
559
    public function isCMSPreview()
560
    {
561
        if (Controller::has_curr()) {
562
            $controller = Controller::curr();
563
564
            if ($controller->getRequest()->requestVar('CMSPreview')) {
565
                return true;
566
            }
567
        }
568
569
        return false;
570
    }
571
572
    /**
573
     * @return null|string
574
     * @throws \Psr\Container\NotFoundExceptionInterface
575
     * @throws \SilverStripe\ORM\ValidationException
576
     */
577
    public function CMSEditLink()
578
    {
579
        $relationName = $this->getAreaRelationName();
580
        $page = $this->getPage(true);
0 ignored issues
show
Unused Code introduced by
The call to DNADesign\Elemental\Models\BaseElement::getPage() has too many arguments starting with true. ( Ignorable by Annotation )

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

580
        /** @scrutinizer ignore-call */ 
581
        $page = $this->getPage(true);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
581
582
        if (!$page) {
583
            return null;
584
        }
585
586
        $editLinkPrefix = '';
587
        if (!$page instanceof SiteTree && method_exists($page, 'CMSEditLink')) {
588
            $editLinkPrefix = Controller::join_links($page->CMSEditLink(), 'ItemEditForm');
589
        } else {
590
            $editLinkPrefix = Controller::join_links(
591
                singleton(CMSPageEditController::class)->Link('EditForm'),
592
                $page->ID
593
            );
594
        }
595
596
        $link = Controller::join_links(
597
            $editLinkPrefix,
598
            'field/' . $relationName . '/item/',
599
            $this->ID
600
        );
601
602
        $link = Controller::join_links(
603
            $link,
604
            'edit'
605
        );
606
607
        $this->extend('updateCMSEditLink', $link);
608
609
        return $link;
610
    }
611
612
    /**
613
     * Retrieve a elemental area relation for creating cms links
614
     *
615
     * @return int|string The name of a valid elemental area relation
616
     * @throws \Psr\Container\NotFoundExceptionInterface
617
     * @throws \SilverStripe\ORM\ValidationException
618
     */
619
    public function getAreaRelationName()
620
    {
621
        $page = $this->getPage();
622
623
        if ($page) {
624
            $has_one = $page->config()->get('has_one');
625
            $area = $this->Parent();
626
627
            foreach ($has_one as $relationName => $relationClass) {
628
                if ($page instanceof BaseElement && $relationName === 'Parent') {
629
                    continue;
630
                }
631
                if ($relationClass === $area->ClassName && $page->{$relationName}()->ID === $area->ID) {
632
                    return $relationName;
633
                }
634
            }
635
        }
636
637
        return 'ElementalArea';
638
    }
639
640
    /**
641
     * Sanitise a model class' name for inclusion in a link.
642
     *
643
     * @return string
644
     */
645
    public function sanitiseClassName($class, $delimiter = '-')
646
    {
647
        return str_replace('\\', $delimiter, $class);
648
    }
649
650
    public function unsanitiseClassName($class, $delimiter = '-')
651
    {
652
        return str_replace($delimiter, '\\', $class);
653
    }
654
655
    /**
656
     * @return null|string
657
     * @throws \Psr\Container\NotFoundExceptionInterface
658
     * @throws \SilverStripe\ORM\ValidationException
659
     */
660
    public function getEditLink()
661
    {
662
        return $this->CMSEditLink();
663
    }
664
665
    /**
666
     * @return DBField|null
667
     * @throws \Psr\Container\NotFoundExceptionInterface
668
     * @throws \SilverStripe\ORM\ValidationException
669
     */
670
    public function PageCMSEditLink()
671
    {
672
        if ($page = $this->getPage()) {
673
            return DBField::create_field('HTMLText', sprintf(
674
                '<a href="%s">%s</a>',
675
                $page->CMSEditLink(),
676
                $page->Title
677
            ));
678
        }
679
680
        return null;
681
    }
682
683
    /**
684
     * @return string
685
     */
686
    public function getMimeType()
687
    {
688
        return 'text/html';
689
    }
690
691
    /**
692
     * This can be overridden on child elements to create a summary for display
693
     * in GridFields.
694
     *
695
     * @return string
696
     */
697
    public function getSummary()
698
    {
699
        return '';
700
    }
701
702
703
    /**
704
     * @return array
705
     */
706
    public function getBlockSchema()
707
    {
708
        $blockSchema = [
709
            'iconClass' => $this->config()->get('icon'),
710
            'type' => $this->getType(),
711
        ];
712
713
        return $blockSchema;
714
    }
715
716
    /**
717
     * Generate markup for element type icons suitable for use in GridFields.
718
     *
719
     * @return null|DBHTMLText
720
     */
721
    public function getIcon()
722
    {
723
        $data = ArrayData::create([]);
724
725
        $iconClass = $this->config()->get('icon');
726
        if ($iconClass) {
727
            $data->IconClass = $iconClass;
728
729
            // Add versioned states (rendered as a circle over the icon)
730
            if ($this->hasExtension(Versioned::class)) {
731
                $data->IsVersioned = true;
732
                if ($this->isOnDraftOnly()) {
0 ignored issues
show
Bug introduced by
The method isOnDraftOnly() does not exist on DNADesign\Elemental\Models\BaseElement. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

732
                if ($this->/** @scrutinizer ignore-call */ isOnDraftOnly()) {
Loading history...
733
                    $data->VersionState = 'draft';
734
                    $data->VersionStateTitle = _t(
735
                        'SilverStripe\\Versioned\\VersionedGridFieldState\\VersionedGridFieldState.ADDEDTODRAFTHELP',
736
                        'Item has not been published yet'
737
                    );
738
                } elseif ($this->isModifiedOnDraft()) {
0 ignored issues
show
Bug introduced by
The method isModifiedOnDraft() does not exist on DNADesign\Elemental\Models\BaseElement. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

738
                } elseif ($this->/** @scrutinizer ignore-call */ isModifiedOnDraft()) {
Loading history...
739
                    $data->VersionState = 'modified';
740
                    $data->VersionStateTitle = $data->VersionStateTitle = _t(
741
                        'SilverStripe\\Versioned\\VersionedGridFieldState\\VersionedGridFieldState.MODIFIEDONDRAFTHELP',
742
                        'Item has unpublished changes'
743
                    );
744
                }
745
            }
746
747
            return $data->renderWith(__CLASS__ . '/PreviewIcon');
748
        }
749
750
        return null;
751
    }
752
753
    /**
754
     * Get a description for this content element, if available
755
     *
756
     * @return string
757
     */
758
    public function getDescription()
759
    {
760
        $description = $this->config()->uninherited('description');
761
        if ($description) {
762
            return _t(__CLASS__ . '.Description', $description);
763
        }
764
        return '';
765
    }
766
767
    /**
768
     * Generate markup for element type, with description suitable for use in
769
     * GridFields.
770
     *
771
     * @return DBField
772
     */
773
    public function getTypeNice()
774
    {
775
        $description = $this->getDescription();
776
        $desc = ($description) ? ' <span class="element__note"> &mdash; ' . $description . '</span>' : '';
777
778
        return DBField::create_field(
779
            'HTMLVarchar',
780
            $this->getType() . $desc
781
        );
782
    }
783
784
    /**
785
     * @return \SilverStripe\ORM\FieldType\DBHTMLText
786
     */
787
    public function getEditorPreview()
788
    {
789
        $templates = $this->getRenderTemplates('_EditorPreview');
790
        $templates[] = BaseElement::class . '_EditorPreview';
791
792
        return $this->renderWith($templates);
793
    }
794
795
    /**
796
     * @return Member
797
     */
798
    public function getAuthor()
799
    {
800
        if ($this->AuthorID) {
0 ignored issues
show
Bug Best Practice introduced by
The property AuthorID does not exist on DNADesign\Elemental\Models\BaseElement. Since you implemented __get, consider adding a @property annotation.
Loading history...
801
            return Member::get()->byId($this->AuthorID);
802
        }
803
804
        return null;
805
    }
806
807
    /**
808
     * Get a user defined style variant for this element, if available
809
     *
810
     * @return string
811
     */
812
    public function getStyleVariant()
813
    {
814
        $style = $this->Style;
815
        $styles = $this->config()->get('styles');
816
817
        if (isset($styles[$style])) {
818
            $style = strtolower($style);
819
        } else {
820
            $style = '';
821
        }
822
823
        $this->extend('updateStyleVariant', $style);
824
825
        return $style;
826
    }
827
828
    /**
829
     * @return mixed|null
830
     * @throws \Psr\Container\NotFoundExceptionInterface
831
     * @throws \SilverStripe\ORM\ValidationException
832
     */
833
    public function getPageTitle()
834
    {
835
        $page = $this->getPage();
836
837
        if ($page) {
838
            return $page->Title;
839
        }
840
841
        return null;
842
    }
843
}
844