Passed
Pull Request — master (#218)
by Robbie
02:40
created

BaseElement::getHistoryFields()   B

Complexity

Conditions 3
Paths 2

Size

Total Lines 40
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 25
nc 2
nop 1
dl 0
loc 40
rs 8.8571
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
A BaseElement::getController() 0 16 3
A BaseElement::Top() 0 3 2
1
<?php
2
3
namespace DNADesign\Elemental\Models;
4
5
use DNADesign\Elemental\Controllers\ElementController;
6
use DNADesign\Elemental\Forms\TextCheckboxGroupField;
7
use Exception;
8
use SilverStripe\CMS\Controllers\CMSPageEditController;
9
use SilverStripe\CMS\Model\SiteTree;
10
use SilverStripe\Control\Controller;
11
use SilverStripe\Control\Director;
12
use SilverStripe\Core\ClassInfo;
13
use SilverStripe\Core\Injector\Injector;
14
use SilverStripe\Forms\CheckboxField;
15
use SilverStripe\Forms\DropdownField;
16
use SilverStripe\Forms\FieldList;
17
use SilverStripe\Forms\HiddenField;
18
use SilverStripe\Forms\NumericField;
19
use SilverStripe\Forms\TextField;
20
use SilverStripe\ORM\DataObject;
21
use SilverStripe\ORM\FieldType\DBField;
22
use SilverStripe\ORM\FieldType\DBHTMLText;
23
use SilverStripe\Security\Member;
24
use SilverStripe\Security\Permission;
25
use SilverStripe\Versioned\Versioned;
26
use SilverStripe\VersionedAdmin\Forms\HistoryViewerField;
27
use SilverStripe\View\ArrayData;
28
use SilverStripe\View\Parsers\URLSegmentFilter;
29
use SilverStripe\View\Requirements;
30
31
/**
32
 * Class BaseElement
33
 * @package DNADesign\Elemental\Models
34
 *
35
 * @property string $Title
36
 * @property bool $ShowTitle
37
 * @property int $Sort
38
 * @property string $ExtraClass
39
 * @property string $Style
40
 *
41
 * @method ElementalArea Parent()
42
 */
43
class BaseElement extends DataObject
44
{
45
    /**
46
     * Override this on your custom elements to specify a CSS icon class
47
     *
48
     * @var string
49
     */
50
    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...
51
52
    /**
53
     * Describe the purpose of this element
54
     *
55
     * @config
56
     * @var string
57
     */
58
    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...
59
60
    private static $db = [
0 ignored issues
show
introduced by
The private property $db is not used, and could be removed.
Loading history...
61
        'Title' => 'Varchar(255)',
62
        'ShowTitle' => 'Boolean',
63
        'Sort' => 'Int',
64
        'ExtraClass' => 'Varchar(255)',
65
        'Style' => 'Varchar(255)'
66
    ];
67
68
    private static $has_one = [
0 ignored issues
show
introduced by
The private property $has_one is not used, and could be removed.
Loading history...
69
        'Parent' => ElementalArea::class
70
    ];
71
72
    private static $extensions = [
0 ignored issues
show
introduced by
The private property $extensions is not used, and could be removed.
Loading history...
73
        Versioned::class
74
    ];
75
76
    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...
77
78
    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...
79
80
    /**
81
     * @var string
82
     */
83
    private static $controller_class = ElementController::class;
84
85
    /**
86
     * @var string
87
     */
88
    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...
89
90
    /**
91
     * @var ElementController
92
     */
93
    protected $controller;
94
95
    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...
96
97
    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...
98
99
    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...
100
101
    private static $summary_fields = [
0 ignored issues
show
introduced by
The private property $summary_fields is not used, and could be removed.
Loading history...
102
        'EditorPreview' => 'Summary'
103
    ];
104
105
    /**
106
     * @config
107
     * @var array
108
     */
109
    private static $styles = [];
0 ignored issues
show
introduced by
The private property $styles is not used, and could be removed.
Loading history...
110
111
    private static $searchable_fields = [
0 ignored issues
show
introduced by
The private property $searchable_fields is not used, and could be removed.
Loading history...
112
        'ID' => [
113
            'field' => NumericField::class,
114
        ],
115
        'Title',
116
        'LastEdited'
117
    ];
118
119
    /**
120
     * Enable for backwards compatibility
121
     *
122
     * @var boolean
123
     */
124
    private static $disable_pretty_anchor_name = false;
125
126
    /**
127
     * Store used anchor names, this is to avoid title clashes
128
     * when calling 'getAnchor'
129
     *
130
     * @var array
131
     */
132
    protected static $_used_anchors = [];
133
134
    /**
135
     * For caching 'getAnchor'
136
     *
137
     * @var string
138
     */
139
    protected $_anchor = null;
140
141
    /**
142
     * Basic permissions, defaults to page perms where possible.
143
     *
144
     * @param Member $member
145
     * @return boolean
146
     */
147
    public function canView($member = null)
148
    {
149
        $extended = $this->extendedCan(__FUNCTION__, $member);
150
        if ($extended !== null) {
151
            return $extended;
152
        }
153
154
        if ($this->hasMethod('getPage')) {
155
            if ($page = $this->getPage()) {
156
                return $page->canView($member);
157
            }
158
        }
159
160
        return (Permission::check('CMS_ACCESS', 'any', $member)) ? true : null;
161
    }
162
163
    /**
164
     * Basic permissions, defaults to page perms where possible.
165
     *
166
     * @param Member $member
167
     *
168
     * @return boolean
169
     */
170
    public function canEdit($member = null)
171
    {
172
        $extended = $this->extendedCan(__FUNCTION__, $member);
173
        if ($extended !== null) {
174
            return $extended;
175
        }
176
177
        if ($this->hasMethod('getPage')) {
178
            if ($page = $this->getPage()) {
179
                return $page->canEdit($member);
180
            }
181
        }
182
183
        return (Permission::check('CMS_ACCESS', 'any', $member)) ? true : null;
184
    }
185
186
    /**
187
     * Basic permissions, defaults to page perms where possible.
188
     *
189
     * Uses archive not delete so that current stage is respected i.e if a
190
     * element is not published, then it can be deleted by someone who doesn't
191
     * have publishing permissions.
192
     *
193
     * @param Member $member
194
     *
195
     * @return boolean
196
     */
197
    public function canDelete($member = null)
198
    {
199
        $extended = $this->extendedCan(__FUNCTION__, $member);
200
        if ($extended !== null) {
201
            return $extended;
202
        }
203
204
        if ($this->hasMethod('getPage')) {
205
            if ($page = $this->getPage()) {
206
                return $page->canArchive($member);
207
            }
208
        }
209
210
        return (Permission::check('CMS_ACCESS', 'any', $member)) ? true : null;
211
    }
212
213
    /**
214
     * Basic permissions, defaults to page perms where possible.
215
     *
216
     * @param Member $member
217
     * @param array $context
218
     *
219
     * @return boolean
220
     */
221
    public function canCreate($member = null, $context = array())
222
    {
223
        $extended = $this->extendedCan(__FUNCTION__, $member);
224
        if ($extended !== null) {
225
            return $extended;
226
        }
227
228
        return (Permission::check('CMS_ACCESS', 'any', $member)) ? true : null;
229
    }
230
231
    /**
232
     * @throws \SilverStripe\ORM\ValidationException
233
     */
234
    public function onBeforeWrite()
235
    {
236
        parent::onBeforeWrite();
237
238
        if ($areaID = $this->ParentID) {
0 ignored issues
show
Bug Best Practice introduced by
The property ParentID does not exist on DNADesign\Elemental\Models\BaseElement. Since you implemented __get, consider adding a @property annotation.
Loading history...
239
            if ($elementalArea = ElementalArea::get()->byID($areaID)) {
240
                $elementalArea->write();
241
            }
242
        }
243
244
        if (!$this->Sort) {
245
            $parentID = ($this->ParentID) ? $this->ParentID : 0;
0 ignored issues
show
Unused Code introduced by
The assignment to $parentID is dead and can be removed.
Loading history...
246
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'))
0 ignored issues
show
Bug introduced by
'ExtraClass' of type string is incompatible with the type array expected by parameter $args of SilverStripe\View\ViewableData::create(). ( Ignorable by Annotation )

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

260
                TextField::create(/** @scrutinizer ignore-type */ 'ExtraClass', _t(__CLASS__ . '.ExtraCssClassesLabel', 'Custom CSS classes'))
Loading history...
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())),
0 ignored issues
show
Bug introduced by
false of type false is incompatible with the type array expected by parameter $args of SilverStripe\View\ViewableData::create(). ( Ignorable by Annotation )

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

283
                HiddenField::create('AbsoluteLink', /** @scrutinizer ignore-type */ false, Director::absoluteURL($this->PreviewLink())),
Loading history...
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')->addExtraClass('elemental-block__history-tab');
308
            }
309
        });
310
311
        return parent::getCMSFields();
312
    }
313
314
    /**
315
     * Get the type of the current block, for use in GridField summaries, block
316
     * type dropdowns etc. Examples are "Content", "File", "Media", etc.
317
     *
318
     * @return string
319
     */
320
    public function getType()
321
    {
322
        return _t(__CLASS__ . '.BlockType', 'Block');
323
    }
324
325
    /**
326
     * @param ElementController $controller
327
     *
328
     * @return $this
329
     */
330
    public function setController($controller)
331
    {
332
        $this->controller = $controller;
333
334
        return $this;
335
    }
336
337
    /**
338
     * @throws Exception If the specified controller class doesn't exist
339
     *
340
     * @return ElementController
341
     */
342
    public function getController()
343
    {
344
        if ($this->controller) {
345
            return $this->controller;
346
        }
347
348
        $controllerClass = self::config()->controller_class;
349
350
        if (!class_exists($controllerClass)) {
351
            throw new Exception('Could not find controller class ' . $controllerClass . ' as defined in ' . static::class);
352
        }
353
354
        $this->controller = Injector::inst()->create($controllerClass, $this);
355
        $this->controller->doInit();
356
357
        return $this->controller;
358
    }
359
360
    /**
361
     * @return Controller
362
     */
363
    public function Top()
364
    {
365
        return (Controller::has_curr()) ? Controller::curr() : null;
366
    }
367
368
    /**
369
     * Default way to render element in templates. Note that all blocks should
370
     * be rendered through their {@link ElementController} class as this
371
     * contains the holder styles.
372
     *
373
     * @return string|null HTML
374
     */
375
    public function forTemplate($holder = true)
376
    {
377
        $templates = $this->getRenderTemplates();
378
379
        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...
380
            return $this->renderWith($templates);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->renderWith($templates) returns the type SilverStripe\ORM\FieldType\DBHTMLText which is incompatible with the documented return type null|string.
Loading history...
381
        }
382
383
        return null;
384
    }
385
386
    /**
387
     * @param string $suffix
388
     *
389
     * @return array
390
     */
391
    public function getRenderTemplates($suffix = '')
392
    {
393
        $classes = ClassInfo::ancestry($this->ClassName);
394
        $classes[static::class] = static::class;
395
        $classes = array_reverse($classes);
396
        $templates = array();
397
398
        foreach ($classes as $key => $value) {
399
            if ($value == BaseElement::class) {
400
                continue;
401
            }
402
403
            if ($value == DataObject::class) {
404
                break;
405
            }
406
407
            $templates[] = $value . $suffix . '_'. $this->getAreaRelationName();
408
            $templates[] = $value . $suffix;
409
        }
410
411
        return $templates;
412
    }
413
414
    /**
415
     * Strip all namespaces from class namespace.
416
     *
417
     * @param string $classname e.g. "\Fully\Namespaced\Class"
418
     *
419
     * @return string following the param example, "Class"
420
     */
421
    protected function stripNamespacing($classname)
422
    {
423
        $classParts = explode('\\', $classname);
424
        return array_pop($classParts);
425
    }
426
427
    /**
428
     * @return string
429
     */
430
    public function getSimpleClassName()
431
    {
432
        return strtolower($this->sanitiseClassName($this->ClassName, '__'));
433
    }
434
435
    /**
436
     * @return null|DataObject
437
     * @throws \Psr\Container\NotFoundExceptionInterface
438
     * @throws \SilverStripe\ORM\ValidationException
439
     */
440
    public function getPage()
441
    {
442
        $area = $this->Parent();
443
444
        if ($area instanceof ElementalArea && $area->exists()) {
445
            return $area->getOwnerPage();
446
        }
447
448
        return null;
449
    }
450
451
    /**
452
     * Get a unique anchor name
453
     *
454
     * @return string
455
     */
456
    public function getAnchor()
457
    {
458
        if ($this->_anchor !== null) {
459
            return $this->_anchor;
460
        }
461
462
        $anchorTitle = '';
463
464
        if (!$this->config()->disable_pretty_anchor_name) {
465
            if ($this->hasMethod('getAnchorTitle')) {
466
                $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

466
                /** @scrutinizer ignore-call */ 
467
                $anchorTitle = $this->getAnchorTitle();
Loading history...
467
            } elseif ($this->config()->enable_title_in_template) {
468
                $anchorTitle = $this->getField('Title');
469
            }
470
        }
471
472
        if (!$anchorTitle) {
473
            $anchorTitle = 'e'.$this->ID;
474
        }
475
476
        $filter = URLSegmentFilter::create();
477
        $titleAsURL = $filter->filter($anchorTitle);
478
479
        // Ensure that this anchor name isn't already in use
480
        // ie. If two elemental blocks have the same title, it'll append '-2', '-3'
481
        $result = $titleAsURL;
482
        $count = 1;
483
        while (isset(self::$_used_anchors[$result]) && self::$_used_anchors[$result] !== $this->ID) {
484
            ++$count;
485
            $result = $titleAsURL.'-'.$count;
486
        }
487
        self::$_used_anchors[$result] = $this->ID;
488
        return $this->_anchor = $result;
489
    }
490
491
    /**
492
     * @param string|null $action
493
     * @return string|null
494
     * @throws \Psr\Container\NotFoundExceptionInterface
495
     * @throws \SilverStripe\ORM\ValidationException
496
     */
497
    public function AbsoluteLink($action = null)
498
    {
499
        if ($page = $this->getPage()) {
500
            $link = $page->AbsoluteLink($action) . '#' . $this->getAnchor();
501
502
            return $link;
503
        }
504
505
        return null;
506
    }
507
508
    /**
509
     * @param string|null $action
510
     * @return string
511
     * @throws \Psr\Container\NotFoundExceptionInterface
512
     * @throws \SilverStripe\ORM\ValidationException
513
     */
514
    public function Link($action = null)
515
    {
516
        if ($page = $this->getPage()) {
517
            $link = $page->Link($action) . '#' . $this->getAnchor();
518
519
            $this->extend('updateLink', $link);
520
521
            return $link;
522
        }
523
524
        return null;
525
    }
526
527
    /**
528
     * @param string|null $action
529
     * @return string
530
     * @throws \Psr\Container\NotFoundExceptionInterface
531
     * @throws \SilverStripe\ORM\ValidationException
532
     */
533
    public function PreviewLink($action = null)
534
    {
535
        $action = $action . '?ElementalPreview=' . mt_rand();
536
        $link = $this->Link($action);
537
        $this->extend('updatePreviewLink', $link);
538
539
        return $link;
540
    }
541
542
    /**
543
     * @return boolean
544
     */
545
    public function isCMSPreview()
546
    {
547
        if (Controller::has_curr()) {
548
            $controller = Controller::curr();
549
550
            if ($controller->getRequest()->requestVar('CMSPreview')) {
551
                return true;
552
            }
553
        }
554
555
        return false;
556
    }
557
558
    /**
559
     * @return null|string
560
     * @throws \Psr\Container\NotFoundExceptionInterface
561
     * @throws \SilverStripe\ORM\ValidationException
562
     */
563
    public function CMSEditLink()
564
    {
565
        $relationName = $this->getAreaRelationName();
566
        $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

566
        /** @scrutinizer ignore-call */ 
567
        $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...
567
568
        if (!$page) {
569
            return null;
570
        }
571
572
        $editLinkPrefix = '';
573
        if (!$page instanceof SiteTree && method_exists($page, 'CMSEditLink')) {
574
            $editLinkPrefix = Controller::join_links($page->CMSEditLink(), 'ItemEditForm');
575
        } else {
576
            $editLinkPrefix = Controller::join_links(singleton(CMSPageEditController::class)->Link('EditForm'), $page->ID);
577
        }
578
579
        $link = Controller::join_links(
580
            $editLinkPrefix,
581
            'field/' . $relationName . '/item/',
582
            $this->ID
583
        );
584
585
        $link = Controller::join_links(
586
            $link,
587
            'edit'
588
        );
589
590
        $this->extend('updateCMSEditLink', $link);
591
592
        return $link;
593
    }
594
595
    /**
596
     * Retrieve a elemental area relation for creating cms links
597
     *
598
     * @return int|string The name of a valid elemental area relation
599
     * @throws \Psr\Container\NotFoundExceptionInterface
600
     * @throws \SilverStripe\ORM\ValidationException
601
     */
602
    public function getAreaRelationName()
603
    {
604
        $page = $this->getPage();
605
606
        if ($page) {
607
            $has_one = $page->config()->get('has_one');
608
            $area = $this->Parent();
609
610
            foreach ($has_one as $relationName => $relationClass) {
611
                if ($page instanceof BaseElement && $relationName === 'Parent') {
612
                    continue;
613
                }
614
                if ($relationClass === $area->ClassName && $page->{$relationName}()->ID === $area->ID) {
615
                    return $relationName;
616
                }
617
            }
618
        }
619
620
        return 'ElementalArea';
621
    }
622
623
    /**
624
     * Sanitise a model class' name for inclusion in a link.
625
     *
626
     * @return string
627
     */
628
    public function sanitiseClassName($class, $delimiter = '-')
629
    {
630
        return str_replace('\\', $delimiter, $class);
631
    }
632
633
    public function unsanitiseClassName($class, $delimiter = '-')
634
    {
635
        return str_replace($delimiter, '\\', $class);
636
    }
637
638
    /**
639
     * @return null|string
640
     * @throws \Psr\Container\NotFoundExceptionInterface
641
     * @throws \SilverStripe\ORM\ValidationException
642
     */
643
    public function getEditLink()
644
    {
645
        return $this->CMSEditLink();
646
    }
647
648
    /**
649
     * @return DBField|null
650
     * @throws \Psr\Container\NotFoundExceptionInterface
651
     * @throws \SilverStripe\ORM\ValidationException
652
     */
653
    public function PageCMSEditLink()
654
    {
655
        if ($page = $this->getPage()) {
656
            return DBField::create_field('HTMLText', sprintf(
657
                '<a href="%s">%s</a>',
658
                $page->CMSEditLink(),
659
                $page->Title
660
            ));
661
        }
662
663
        return null;
664
    }
665
666
    /**
667
     * @return string
668
     */
669
    public function getMimeType()
670
    {
671
        return 'text/html';
672
    }
673
674
    /**
675
     * This can be overridden on child elements to create a summary for display
676
     * in GridFields.
677
     *
678
     * @return string
679
     */
680
    public function getSummary()
681
    {
682
        return '';
683
    }
684
685
686
    /**
687
     * Generate markup for element type icons suitable for use in GridFields.
688
     *
689
     * @return null|DBHTMLText
690
     */
691
    public function getIcon()
692
    {
693
        $data = ArrayData::create([]);
694
695
        $iconClass = $this->config()->get('icon');
696
        if ($iconClass) {
697
            $data->IconClass = $iconClass;
698
699
            // Add versioned states (rendered as a circle over the icon)
700
            if ($this->hasExtension(Versioned::class)) {
701
                $data->IsVersioned = true;
702
                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

702
                if ($this->/** @scrutinizer ignore-call */ isOnDraftOnly()) {
Loading history...
703
                    $data->VersionState = 'draft';
704
                    $data->VersionStateTitle = _t(
705
                        'SilverStripe\\Versioned\\VersionedGridFieldState\\VersionedGridFieldState.ADDEDTODRAFTHELP',
706
                        'Item has not been published yet'
707
                    );
708
                } 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

708
                } elseif ($this->/** @scrutinizer ignore-call */ isModifiedOnDraft()) {
Loading history...
709
                    $data->VersionState = 'modified';
710
                    $data->VersionStateTitle = $data->VersionStateTitle = _t(
711
                        'SilverStripe\\Versioned\\VersionedGridFieldState\\VersionedGridFieldState.MODIFIEDONDRAFTHELP',
712
                        'Item has unpublished changes'
713
                    );
714
                }
715
            }
716
717
            return $data->renderWith(__CLASS__ . '/PreviewIcon');
718
        }
719
720
        return null;
721
    }
722
723
    /**
724
     * Get a description for this content element, if available
725
     *
726
     * @return string
727
     */
728
    public function getDescription()
729
    {
730
        $description = $this->config()->uninherited('description');
731
        if ($description) {
732
            return _t(__CLASS__ . '.Description', $description);
733
        }
734
        return '';
735
    }
736
737
    /**
738
     * Generate markup for element type, with description suitable for use in
739
     * GridFields.
740
     *
741
     * @return DBField
742
     */
743
    public function getTypeNice()
744
    {
745
        $description = $this->getDescription();
746
        $desc = ($description) ? ' <span class="element__note"> &mdash; ' . $description . '</span>' : '';
747
748
        return DBField::create_field(
749
            'HTMLVarchar',
750
            $this->getType() . $desc
751
        );
752
    }
753
754
    /**
755
     * @return \SilverStripe\ORM\FieldType\DBHTMLText
756
     */
757
    public function getEditorPreview()
758
    {
759
        $templates = $this->getRenderTemplates('_EditorPreview');
760
        $templates[] = BaseElement::class . '_EditorPreview';
761
762
        return $this->renderWith($templates);
763
    }
764
765
    /**
766
     * @return Member
767
     */
768
    public function getAuthor()
769
    {
770
        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...
771
            return Member::get()->byId($this->AuthorID);
772
        }
773
774
        return null;
775
    }
776
777
    /**
778
     * Get a user defined style variant for this element, if available
779
     *
780
     * @return string
781
     */
782
    public function getStyleVariant()
783
    {
784
        $style = $this->Style;
785
        $styles = $this->config()->get('styles');
786
787
        if (isset($styles[$style])) {
788
            $style = strtolower($style);
789
        } else {
790
            $style = '';
791
        }
792
793
        $this->extend('updateStyleVariant', $style);
794
795
        return $style;
796
    }
797
798
    /**
799
     * @return mixed|null
800
     * @throws \Psr\Container\NotFoundExceptionInterface
801
     * @throws \SilverStripe\ORM\ValidationException
802
     */
803
    public function getPageTitle()
804
    {
805
        $page = $this->getPage();
806
807
        if ($page) {
808
            return $page->Title;
809
        }
810
811
        return null;
812
    }
813
}
814