Passed
Pull Request — master (#123)
by Will
01:40
created

BaseElement::canView()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 9
Code Lines 4

Duplication

Lines 9
Ratio 100 %

Importance

Changes 0
Metric Value
dl 9
loc 9
rs 9.2
c 0
b 0
f 0
cc 4
eloc 4
nc 5
nop 1
1
<?php
2
3
namespace DNADesign\Elemental\Models;
4
5
use Exception;
6
use DNADesign\Elemental\Controllers\ElementController;
7
use SilverStripe\CMS\Controllers\CMSPageEditController;
8
use SilverStripe\Control\Controller;
9
use SilverStripe\Control\Director;
10
use SilverStripe\Core\ClassInfo;
11
use SilverStripe\Core\Config\Config;
12
use SilverStripe\Core\Injector\Injector;
13
use SilverStripe\Core\Manifest\ModuleResourceLoader;
14
use SilverStripe\Forms\CheckboxField;
15
use SilverStripe\Forms\DropdownField;
16
use SilverStripe\Forms\FieldGroup;
17
use SilverStripe\Forms\FieldList;
18
use SilverStripe\Forms\HiddenField;
19
use SilverStripe\Forms\NumericField;
20
use SilverStripe\Forms\ReadonlyField;
21
use SilverStripe\Forms\TextField;
22
use SilverStripe\Forms\GridField\GridField;
23
use SilverStripe\Forms\GridField\GridFieldConfig_RecordViewer;
24
use SilverStripe\Forms\GridField\GridFieldDataColumns;
25
use SilverStripe\Forms\GridField\GridFieldVersionedState;
26
use SilverStripe\Forms\GridField\GridFieldPageCount;
27
use SilverStripe\ORM\ArrayList;
28
use SilverStripe\ORM\CMSPreviewable;
29
use SilverStripe\ORM\DataObject;
30
use SilverStripe\ORM\DB;
31
use SilverStripe\ORM\FieldType\DBField;
32
use SilverStripe\ORM\Search\SearchContext;
33
use SilverStripe\Security\Permission;
34
use SilverStripe\Security\Member;
35
use SilverStripe\SiteConfig\SiteConfig;
36
use SilverStripe\Versioned\Versioned;
37
use SilverStripe\View\Parsers\URLSegmentFilter;
38
use SilverStripe\View\SSViewer;
39
40
class BaseElement extends DataObject implements CMSPreviewable
41
{
42
    /**
43
     * Override this on your custom elements to specify a cms icon
44
     *
45
     * @var string
46
     */
47
    private static $icon = 'dnadesign/silverstripe-elemental:images/base.svg';
0 ignored issues
show
Unused Code introduced by
The property $icon is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
48
49
    private static $db = [
0 ignored issues
show
Unused Code introduced by
The property $db is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
50
        'Title' => 'Varchar(255)',
51
        'ShowTitle' => 'Boolean',
52
        'Sort' => 'Int',
53
        'ExtraClass' => 'Varchar(255)',
54
        'Style' => 'Varchar(255)'
55
    ];
56
57
    private static $has_one = [
0 ignored issues
show
Unused Code introduced by
The property $has_one is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
58
        'Parent' => ElementalArea::class
59
    ];
60
61
    private static $extensions = [
0 ignored issues
show
Unused Code introduced by
The property $extensions is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
62
        Versioned::class
63
    ];
64
65
    private static $table_name = 'Element';
0 ignored issues
show
Unused Code introduced by
The property $table_name is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
66
67
    /**
68
     * @var string
69
     */
70
    private static $controller_class = ElementController::class;
0 ignored issues
show
Unused Code introduced by
The property $controller_class is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
71
72
    /**
73
     * @var string
74
     */
75
    private static $controller_template = 'ElementHolder';
0 ignored issues
show
Unused Code introduced by
The property $controller_template is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
76
77
    /**
78
     * @var ElementController
79
     */
80
    protected $controller;
81
82
    private static $default_sort = 'Sort';
0 ignored issues
show
Unused Code introduced by
The property $default_sort is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
83
84
    private static $singular_name = 'block';
0 ignored issues
show
Unused Code introduced by
The property $singular_name is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
85
86
    private static $plural_name = 'blocks';
0 ignored issues
show
Unused Code introduced by
The property $plural_name is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
87
88
    private static $summary_fields = [
0 ignored issues
show
Unused Code introduced by
The property $summary_fields is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
89
        'EditorPreview' => 'Summary'
90
    ];
91
92
    /**
93
     * @var array
94
     */
95
    private static $styles = [];
0 ignored issues
show
Unused Code introduced by
The property $styles is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
96
97
    private static $searchable_fields = [
0 ignored issues
show
Unused Code introduced by
The property $searchable_fields is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
98
        'ID' => [
99
            'field' => NumericField::class,
100
        ],
101
        'Title',
102
        'LastEdited'
103
    ];
104
105
    /**
106
     * Enable for backwards compatibility
107
     *
108
     * @var boolean
109
     */
110
    private static $disable_pretty_anchor_name = false;
0 ignored issues
show
Unused Code introduced by
The property $disable_pretty_anchor_name is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
111
112
    /**
113
     * Store used anchor names, this is to avoid title clashes
114
     * when calling 'getAnchor'
115
     *
116
     * @var array
117
     */
118
    protected static $_used_anchors = [];
119
120
    /**
121
     * For caching 'getAnchor'
122
     *
123
     * @var string
124
     */
125
    protected $_anchor = null;
126
127
    /**
128
     * Basic permissions, defaults to page perms where possible.
129
     *
130
     * @param Member $member
131
     *
132
     * @return boolean
133
     */
134 View Code Duplication
    public function canView($member = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
135
    {
136
        if ($this->hasMethod('getPage')) {
137
            if ($page = $this->getPage()) {
138
                return $page->canView($member);
139
            }
140
        }
141
142
        return (Permission::check('CMS_ACCESS', 'any', $member)) ? true : null;
143
    }
144
145
    /**
146
     * Basic permissions, defaults to page perms where possible.
147
     *
148
     * @param Member $member
149
     *
150
     * @return boolean
151
     */
152 View Code Duplication
    public function canEdit($member = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
153
    {
154
        if ($this->hasMethod('getPage')) {
155
            if ($page = $this->getPage()) {
156
                return $page->canEdit($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
     * Uses archive not delete so that current stage is respected i.e if a
167
     * element is not published, then it can be deleted by someone who doesn't
168
     * have publishing permissions.
169
     *
170
     * @param Member $member
171
     *
172
     * @return boolean
173
     */
174 View Code Duplication
    public function canDelete($member = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
175
    {
176
        if ($this->hasMethod('getPage')) {
177
            if ($page = $this->getPage()) {
178
                return $page->canArchive($member);
179
            }
180
        }
181
182
        return (Permission::check('CMS_ACCESS', 'any', $member)) ? true : null;
183
    }
184
185
    /**
186
     * Basic permissions, defaults to page perms where possible.
187
     *
188
     * @param Member $member
189
     * @param array $context
190
     *
191
     * @return boolean
192
     */
193
    public function canCreate($member = null, $context = array())
194
    {
195
        return (Permission::check('CMS_ACCESS', 'any', $member)) ? true : null;
196
    }
197
198
    /**
199
     *
200
     */
201
    public function onBeforeWrite()
202
    {
203
        parent::onBeforeWrite();
204
205
        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...
206
            if ($elementalArea = ElementalArea::get()->byID($areaID)) {
207
                $elementalArea->write();
208
            }
209
        }
210
211
        if (!$this->Sort) {
212
            $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...
213
214
            $this->Sort = static::get()->max('Sort') + 1;
0 ignored issues
show
Bug Best Practice introduced by
The property Sort does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
215
        }
216
    }
217
218
    public function getCMSFields()
219
    {
220
        $this->beforeUpdateCMSFields(function (FieldList $fields) {
221
            // Remove relationship fields
222
            $fields->removeByName('ParentID');
223
            $fields->removeByName('Sort');
224
225
            $fields->addFieldToTab(
226
                'Root.Settings',
227
                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

227
                TextField::create(/** @scrutinizer ignore-type */ 'ExtraClass', _t(__CLASS__ . '.ExtraCssClassesLabel', 'Custom CSS classes'))
Loading history...
228
                    ->setAttribute(
229
                        'placeholder',
230
                        _t(__CLASS__ . '.ExtraCssClassesPlaceholder', 'my_class another_class')
231
                    )
232
            );
233
234
            // Add a combined field for "Title" and "Displayed" checkbox in a Bootstrap input group
235
            $fields->removeByName('ShowTitle');
236
            $fields->replaceField(
237
                'Title',
238
                FieldGroup::create(
239
                    TextField::create('Title', ''),
240
                    CheckboxField::create('ShowTitle', _t(__CLASS__ . '.ShowTitleLabel', 'Displayed'))
241
                )
242
                    ->setTemplate(__CLASS__ . '\\FieldGroup')
243
                    ->setTitle(_t(__CLASS__ . '.TitleLabel', 'Title (not displayed unless specified)'))
244
            );
245
246
            // Rename the "Main" tab
247
            $fields->fieldByName('Root.Main')
248
                ->setTitle(_t(__CLASS__ . '.MainTabLabel', 'Content'));
249
250
            // Remove divider lines on all block forms
251
            $fields->fieldByName('Root')->addExtraClass('form--no-dividers');
252
253
            $fields->addFieldsToTab('Root.Main', [
254
                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

254
                HiddenField::create('AbsoluteLink', /** @scrutinizer ignore-type */ false, Director::absoluteURL($this->PreviewLink())),
Loading history...
255
                HiddenField::create('LiveLink', false, Director::absoluteURL($this->Link())),
256
                HiddenField::create('StageLink', false, Director::absoluteURL($this->PreviewLink())),
257
            ]);
258
259
            $styles = $this->config()->get('styles');
260
261
            if ($styles && count($styles) > 0) {
262
                $styleDropdown = new DropdownField(
263
                    'Style',
264
                    _t(__CLASS__.'.STYLE', 'Style variation'),
265
                    $styles
266
                );
267
268
                $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

268
                $fields->insertBefore($styleDropdown, /** @scrutinizer ignore-type */ 'ExtraClass');
Loading history...
269
270
                $styleDropdown->setEmptyString(_t(__CLASS__.'.CUSTOM_STYLES', 'Select a style..'));
271
            } else {
272
                $fields->removeByName('Style');
273
            }
274
275
            $fields->addFieldsToTab('Root.History', $this->getHistoryFields());
0 ignored issues
show
Bug introduced by
$this->getHistoryFields() of type SilverStripe\Forms\FieldList is incompatible with the type array expected by parameter $fields of SilverStripe\Forms\FieldList::addFieldsToTab(). ( Ignorable by Annotation )

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

275
            $fields->addFieldsToTab('Root.History', /** @scrutinizer ignore-type */ $this->getHistoryFields());
Loading history...
276
        });
277
278
        return parent::getCMSFields();
279
    }
280
281
    /**
282
     * Returns the history fields for this element.
283
     *
284
     * @return FieldList
285
     */
286
    public function getHistoryFields()
287
    {
288
        $config = GridFieldConfig_RecordViewer::create();
289
        $config->removeComponentsByType(GridFieldPageCount::class);
290
291
        $config->getComponentByType(GridFieldDataColumns::class)->setDisplayFields([
292
            'Version' => '#',
293
            'LastEdited' => _t(__CLASS__ . '.LastEdited', 'Last Edited'),
294
            'getAuthor.Name' => _t(__CLASS__ . '.Author', 'Author')
295
        ]);
296
297
        $history = Versioned::get_all_versions(__CLASS__, $this->ID);
298
        $history = $history->sort('Version', 'DESC');
299
300
        return new FieldList(
301
            GridField::create(
302
                'History',
0 ignored issues
show
Bug introduced by
'History' 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

302
                /** @scrutinizer ignore-type */ 'History',
Loading history...
303
                '',
304
                $history,
0 ignored issues
show
Bug introduced by
$history of type SilverStripe\ORM\DataList 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

304
                /** @scrutinizer ignore-type */ $history,
Loading history...
305
                $config
306
            )
307
        );
308
    }
309
310
    /**
311
     * Get the type of the current block, for use in GridField summaries, block
312
     * type dropdowns etc. Examples are "Content", "File", "Media", etc.
313
     *
314
     * @return string
315
     */
316
    public function getType()
317
    {
318
        return _t(__CLASS__ . '.BlockType', 'Block');
319
    }
320
321
    /**
322
     * @param ElementController
323
     *
324
     * @return $this
325
     */
326
    public function setController($controller)
327
    {
328
        $this->controller = $controller;
329
330
        return $this;
331
    }
332
333
    /**
334
     * @throws Exception
335
     *
336
     * @return ElementController
337
     */
338
    public function getController()
339
    {
340
        if ($this->controller) {
341
            return $this->controller;
342
        }
343
344
        $controllerClass = self::config()->controller_class;
345
346
        if (!class_exists($controllerClass)) {
347
            throw new Exception('Could not find controller class ' . $controllerClass . ' as defined in ' . static::class);
348
        }
349
350
        $this->controller = Injector::inst()->create($controllerClass, $this);
351
        $this->controller->doInit();
352
353
        return $this->controller;
354
    }
355
356
    /**
357
     * @return Controller
358
     */
359
    public function Top()
360
    {
361
        return (Controller::has_curr()) ? Controller::curr() : null;
362
    }
363
364
    /**
365
     * Default way to render element in templates. Note that all blocks should
366
     * be rendered through their {@link ElementController} class as this
367
     * contains the holder styles.
368
     *
369
     * @return string HTML
370
     */
371
    public function forTemplate($holder = true)
0 ignored issues
show
Unused Code introduced by
The parameter $holder is not used and could be removed. ( Ignorable by Annotation )

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

371
    public function forTemplate(/** @scrutinizer ignore-unused */ $holder = true)

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

Loading history...
372
    {
373
        $templates = $this->getRenderTemplates();
374
375
        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...
376
            return $this->renderWith($templates);
377
        }
378
    }
379
380
    /**
381
     * @param string $suffix
382
     *
383
     * @return array
384
     */
385
    public function getRenderTemplates($suffix = '')
386
    {
387
        $classes = ClassInfo::ancestry($this->ClassName);
388
        $classes[static::class] = static::class;
389
        $classes = array_reverse($classes);
390
        $templates = array();
391
392
        foreach ($classes as $key => $value) {
393
            if ($value == BaseElement::class) {
394
                continue;
395
            }
396
397
            if ($value == DataObject::class) {
398
                break;
399
            }
400
401
            $templates[] = $value . $suffix;
402
        }
403
404
        return $templates;
405
    }
406
407
    /**
408
     * Strip all namespaces from class namespace.
409
     *
410
     * @param string $classname e.g. "\Fully\Namespaced\Class"
411
     *
412
     * @return string following the param example, "Class"
413
     */
414
    protected function stripNamespacing($classname)
415
    {
416
        $classParts = explode('\\', $classname);
417
        return array_pop($classParts);
418
    }
419
420
    /**
421
     * @return string
422
     */
423
    public function getSimpleClassName()
424
    {
425
        return strtolower($this->sanitiseClassName($this->ClassName, '__'));
426
    }
427
428
    /**
429
     * @return SiteTree
0 ignored issues
show
Bug introduced by
The type DNADesign\Elemental\Models\SiteTree 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...
430
     */
431
    public function getPage()
432
    {
433
        $area = $this->Parent();
0 ignored issues
show
Bug introduced by
The method Parent() 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

433
        /** @scrutinizer ignore-call */ 
434
        $area = $this->Parent();
Loading history...
434
435
        if ($area instanceof ElementalArea) {
436
            return $area->getOwnerPage();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $area->getOwnerPage() could also return false which is incompatible with the documented return type DNADesign\Elemental\Models\SiteTree. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
437
        }
438
439
        return null;
440
    }
441
442
    /**
443
     * Get a unique anchor name
444
     *
445
     * @return string
446
     */
447
    public function getAnchor()
448
    {
449
        if ($this->_anchor !== null) {
450
            return $this->_anchor;
451
        }
452
453
        $anchorTitle = '';
454
455
        if (!$this->config()->disable_pretty_anchor_name) {
456
            if ($this->hasMethod('getAnchorTitle')) {
457
                $anchorTitle = $this->getAnchorTitle();
458
            } elseif ($this->config()->enable_title_in_template) {
459
                $anchorTitle = $this->getField('Title');
460
            }
461
        }
462
463
        if (!$anchorTitle) {
464
            $anchorTitle = 'e'.$this->ID;
465
        }
466
467
        $filter = URLSegmentFilter::create();
468
        $titleAsURL = $filter->filter($anchorTitle);
469
470
        // Ensure that this anchor name isn't already in use
471
        // ie. If two elemental blocks have the same title, it'll append '-2', '-3'
472
        $result = $titleAsURL;
473
        $count = 1;
474
        while (isset(self::$_used_anchors[$result]) && self::$_used_anchors[$result] !== $this->ID) {
475
            ++$count;
476
            $result = $titleAsURL.'-'.$count;
477
        }
478
        self::$_used_anchors[$result] = $this->ID;
479
        return $this->_anchor = $result;
480
    }
481
482
    /**
483
     * @param string $action
484
     *
485
     * @return string
486
     */
487
    public function AbsoluteLink($action = null)
488
    {
489
        if ($page = $this->getPage()) {
490
            $link = $page->AbsoluteLink($action) . '#' . $this->getAnchor();
491
492
            return $link;
493
        }
494
    }
495
496
    /**
497
     * @param string $action
498
     *
499
     * @return string
500
     */
501
    public function Link($action = null)
502
    {
503
        if ($page = $this->getPage()) {
504
            $link = $page->Link($action) . '#' . $this->getAnchor();
505
506
            $this->extend('updateLink', $link);
507
508
            return $link;
509
        }
510
    }
511
512
    /**
513
     * @param string $action
514
     *
515
     * @return string
516
     */
517
    public function PreviewLink($action = null)
518
    {
519
        $action = $action . '?ElementalPreview=' . mt_rand();
520
        $link = $this->Link($action);
521
        $this->extend('updatePreviewLink', $link);
522
523
        return $link;
524
    }
525
526
    /**
527
     * @return boolean
528
     */
529
    public function isCMSPreview()
530
    {
531
        if (Controller::has_curr()) {
532
            $c = Controller::curr();
533
534
            if ($c->getRequest()->requestVar('CMSPreview')) {
535
                return true;
536
            }
537
        }
538
539
        return false;
540
    }
541
542
    /**
543
     * @return string
544
     */
545
    public function CMSEditLink()
546
    {
547
        $relationName = $this->getAreaRelationName();
548
549
        $link = Controller::join_links(
550
            singleton(CMSPageEditController::class)->Link('EditForm'),
551
            $this->getPage(true)->ID,
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

551
            $this->/** @scrutinizer ignore-call */ 
552
                   getPage(true)->ID,

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...
552
            'field/' . $relationName . '/item/',
553
            $this->ID
554
        );
555
556
        if ($inList) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $inList seems to be never defined.
Loading history...
557
            return $link;
558
        }
559
560
        return Controller::join_links(
561
            $link,
562
            'edit'
563
        );
564
    }
565
566
    /**
567
     * Retrieve a elemental area relation for creating cms links
568
     *
569
     * @return string - the name of a valid elemental area relation
570
     */
571
    public function getAreaRelationName()
572
    {
573
        $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

573
        /** @scrutinizer ignore-call */ 
574
        $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...
574
        $has_one = $page->config()->get('has_one');
575
        $area = $this->Parent();
576
577
        foreach ($has_one as $relationName => $relationClass) {
578
            if ($relationClass === $area->ClassName) {
579
                return $relationName;
580
            }
581
        }
582
583
        return 'ElementalArea';
584
    }
585
586
    /**
587
     * Sanitise a model class' name for inclusion in a link.
588
     *
589
     * @return string
590
     */
591
    protected function sanitiseClassName($class, $delimiter = '-')
592
    {
593
        return str_replace('\\', $delimiter, $class);
594
    }
595
596
    /**
597
     * @return string
598
     */
599
    public function getEditLink()
600
    {
601
        return $this->CMSEditLink();
602
    }
603
604
    /**
605
     * @return HTMLText
0 ignored issues
show
Bug introduced by
The type DNADesign\Elemental\Models\HTMLText 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...
606
     */
607
    public function PageCMSEditLink()
608
    {
609
        if ($page = $this->getPage()) {
610
            return DBField::create_field('HTMLText', sprintf(
0 ignored issues
show
Bug Best Practice introduced by
The expression return SilverStripe\ORM\...tLink(), $page->Title)) returns the type SilverStripe\ORM\FieldType\DBField which is incompatible with the documented return type DNADesign\Elemental\Models\HTMLText.
Loading history...
611
                '<a href="%s">%s</a>',
612
                $page->CMSEditLink(),
613
                $page->Title
614
            ));
615
        }
616
    }
617
618
    /**
619
     * @return string
620
     */
621
    public function getMimeType()
622
    {
623
        return 'text/html';
624
    }
625
626
    /**
627
     * This can be overridden on child elements to create a summary for display
628
     * in GridFields.
629
     *
630
     * @return string
631
     */
632
    public function getSummary()
633
    {
634
        return '';
635
    }
636
637
638
    /**
639
     * Generate markup for element type icons suitable for use in GridFields.
640
     *
641
     * @return DBField
642
     */
643
    public function getIcon()
644
    {
645
        $icon = $this->config()->get('icon');
646
647
        if ($icon) {
648
            $icon = ModuleResourceLoader::resourceURL($icon);
649
650
            return DBField::create_field('HTMLVarchar', '<img width="16px" src="' . Director::absoluteBaseURL() . $icon . '" alt="" />');
651
        }
652
    }
653
654
    /**
655
     * Generate markup for element type, with description suitable for use in
656
     * GridFields.
657
     *
658
     * @return DBField
659
     */
660
    public function getTypeNice()
661
    {
662
        $description = $this->config()->get('description');
663
664
        return DBField::create_field(
665
            'HTMLVarchar',
666
            $this->getType() . ' <span class="el-description"> &mdash; ' . $description . '</span>'
667
        );
668
    }
669
670
    /**
671
     * @return HTMLText
672
     */
673
    public function getEditorPreview()
674
    {
675
        $templates = $this->getRenderTemplates('_EditorPreview');
676
        $templates[] = BaseElement::class . '_EditorPreview';
677
678
        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 DNADesign\Elemental\Models\HTMLText.
Loading history...
679
    }
680
681
    /**
682
     * @return Member
683
     */
684
    public function getAuthor()
685
    {
686
        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...
687
            return Member::get()->byId($this->AuthorID);
688
        }
689
    }
690
691
    /**
692
     * @return string
693
     */
694
    public function getStyleVariant()
695
    {
696
        $style = $this->Style;
0 ignored issues
show
Bug Best Practice introduced by
The property Style does not exist on DNADesign\Elemental\Models\BaseElement. Since you implemented __get, consider adding a @property annotation.
Loading history...
697
698
        if (isset($styles[$style])) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $styles does not exist. Did you maybe mean $style?
Loading history...
699
            $style = strtolower($styles[$style]);
700
        } else {
701
            $style = '';
702
        }
703
704
        $this->extend('updateStyleVariant', $style);
705
706
        return $style;
707
    }
708
}
709