Completed
Push — master ( 2b1919...c5b8da )
by Will
13s queued 10s
created

BaseElementExtension::getVirtualLinkedSummary()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace DNADesign\ElementalVirtual\Extensions;
4
5
use DNADesign\ElementalVirtual\Forms\ElementalGridFieldDeleteAction;
6
use DNADesign\ElementalVirtual\Model\ElementVirtual;
7
use SilverStripe\ORM\DataExtension;
8
use SilverStripe\Forms\FieldList;
9
use SilverStripe\Versioned\Versioned;
10
use SilverStripe\Forms\LiteralField;
11
use SilverStripe\Forms\GridField\GridFieldConfig_Base;
12
use SilverStripe\Forms\GridField\GridFieldDataColumns;
13
use SilverStripe\Forms\GridField\GridFieldAddNewButton;
14
use SilverStripe\Forms\GridField\GridFieldAddExistingAutocompleter;
15
use SilverStripe\Forms\GridField\GridFieldDetailForm;
16
17
class BaseElementExtension extends DataExtension
18
{
19
    /**
20
     * @var mixed
21
     */
22
    protected $virtualOwner;
23
24
    /**
25
     * @config
26
     *
27
     * @var boolean
28
     */
29
    private static $default_global_elements = true;
0 ignored issues
show
introduced by
The private property $default_global_elements is not used, and could be removed.
Loading history...
30
31
    /**
32
     * @var array
33
     */
34
    private static $db = [
0 ignored issues
show
introduced by
The private property $db is not used, and could be removed.
Loading history...
35
        'AvailableGlobally' => 'Boolean(1)'
36
    ];
37
38
    /**
39
     * @var array $has_many
40
     */
41
    private static $has_many = [
0 ignored issues
show
introduced by
The private property $has_many is not used, and could be removed.
Loading history...
42
        'VirtualClones' => ElementVirtual::class
43
    ];
44
45
    public function populateDefaults()
46
    {
47
        $default = $this->owner->config()->get('default_global_elements');
48
49
        $this->AvailableGlobally = $default;
0 ignored issues
show
Bug Best Practice introduced by
The property AvailableGlobally does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
50
    }
51
52
    /**
53
     * @param ElementVirtual
54
     *
55
     * @return $this
56
     */
57
    public function setVirtualOwner(ElementVirtual $owner)
58
    {
59
        $this->virtualOwner = $owner;
60
        return $this;
61
    }
62
63
    /**
64
     * @return ElementVirtual
65
     */
66
    public function getVirtualOwner()
67
    {
68
        return $this->virtualOwner;
69
    }
70
71
    /**
72
     * Finds and returns elements that are virtual elements which link to this
73
     * element.
74
     *
75
     * @return DataList
0 ignored issues
show
Bug introduced by
The type DNADesign\ElementalVirtual\Extensions\DataList 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...
76
     */
77
    public function getVirtualElements()
78
    {
79
        return ElementVirtual::get()->filter([
0 ignored issues
show
Bug Best Practice introduced by
The expression return DNADesign\Element...' => $this->owner->ID)) returns the type SilverStripe\ORM\DataList which is incompatible with the documented return type DNADesign\ElementalVirtual\Extensions\DataList.
Loading history...
80
            'LinkedElementID' => $this->owner->ID
81
        ]);
82
    }
83
84
    /**
85
     * @return string
86
     */
87
    public function getVirtualLinkedSummary()
88
    {
89
        return sprintf('%s (%s #%s)', $this->owner->Title, $this->owner->getType(), $this->owner->ID);
90
    }
91
92
    /**
93
     * @return DataList
94
     */
95
    public function getPublishedVirtualElements()
96
    {
97
        return ElementVirtual::get()->filter([
0 ignored issues
show
Bug Best Practice introduced by
The expression return DNADesign\Element...oned.stage' => 'Live')) returns the type SilverStripe\ORM\DataList which is incompatible with the documented return type DNADesign\ElementalVirtual\Extensions\DataList.
Loading history...
98
            'LinkedElementID' => $this->owner->ID
99
        ])->setDataQueryParam([
100
            'Versioned.mode' => 'stage',
101
            'Versioned.stage' => 'Live'
102
        ]);
103
    }
104
105
    /**
106
     * @param FieldList $fields
107
     *
108
     * @return FieldList
109
     */
110
    public function updateCMSFields(FieldList $fields)
111
    {
112
        $global = $fields->dataFieldByName('AvailableGlobally');
113
114
        if ($global) {
0 ignored issues
show
introduced by
$global is of type SilverStripe\Forms\FormField, thus it always evaluated to true.
Loading history...
115
            $fields->removeByName('AvailableGlobally');
116
            $fields->addFieldToTab('Root.Settings', $global);
117
        }
118
119
        if ($virtual = $fields->dataFieldByName('VirtualClones')) {
120
            if ($this->owner->VirtualClones()->Count() > 0) {
121
                $tab = $fields->findOrMakeTab('Root.VirtualClones');
122
                $tab->setTitle(_t(__CLASS__ . '.LinkedTo', 'Linked To'));
123
124
                if ($ownerPage = $this->owner->getPage()) {
125
                    $fields->addFieldToTab(
126
                        'Root.VirtualClones',
127
                        LiteralField::create(
128
                            'DisplaysOnPage',
129
                            sprintf(
130
                                "<p>"
131
                                . _t(__CLASS__ . '.OriginalContentFrom', 'The original content element appears on')
132
                                . " <a href='%s'>%s</a></p>",
133
                                ($ownerPage->hasMethod('CMSEditLink') && $ownerPage->canEdit()) ? $ownerPage->CMSEditLink() : $ownerPage->Link(),
134
                                $ownerPage->MenuTitle
135
                            )
136
                        ),
137
                        'VirtualClones'
138
                    );
139
                }
140
141
                $virtual->setConfig(new GridFieldConfig_Base());
142
                $virtual
143
                    ->setTitle(_t(__CLASS__ . '.OtherPages', 'Other pages'))
144
                    ->getConfig()
145
                        ->removeComponentsByType(GridFieldAddExistingAutocompleter::class)
146
                        ->removeComponentsByType(GridFieldAddNewButton::class)
147
                        ->removeComponentsByType(GridFieldDeleteAction::class)
0 ignored issues
show
Bug introduced by
The type DNADesign\ElementalVirtu...s\GridFieldDeleteAction 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...
148
                        ->removeComponentsByType(GridFieldDetailForm::class)
149
                        ->addComponent(new ElementalGridFieldDeleteAction());
150
151
                $virtual->getConfig()
152
                    ->getComponentByType(GridFieldDataColumns::class)
153
                    ->setDisplayFields([
154
                        'getPage.Title' => _t(__CLASS__ . '.GridFieldTitle', 'Title'),
155
                        'ParentCMSEditLink' => _t(__CLASS__ . '.GridFieldUsedOn', 'Used on'),
156
                    ]);
157
            } else {
158
                $fields->removeByName('VirtualClones');
159
            }
160
        }
161
    }
162
163
    /**
164
     * Ensure that if there are elements that are virtualised from this element
165
     * that we move the original element to replace one of the virtual elements
166
     *
167
     * But only if it's a delete not an unpublish
168
     */
169
    public function onBeforeDelete()
170
    {
171
        if (Versioned::get_reading_mode() == 'Stage.Stage') {
172
            $firstVirtual = false;
173
            $allVirtual = $this->getVirtualElements();
174
175
            if ($this->getPublishedVirtualElements()->Count() > 0) {
176
                // choose the first one
177
                $firstVirtual = $this->getPublishedVirtualElements()->First();
178
                $wasPublished = true;
179
            } elseif ($allVirtual->Count() > 0) {
180
                // choose the first one
181
                $firstVirtual = $this->getVirtualElements()->First();
182
                $wasPublished = false;
183
            }
184
            if ($firstVirtual) {
185
                $clone = $this->owner->duplicate(false);
186
187
                // set clones values to first virtual's values
188
                $clone->ParentID = $firstVirtual->ParentID;
189
                $clone->Sort = $firstVirtual->Sort;
190
191
                $clone->write();
192
                if ($wasPublished) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $wasPublished does not seem to be defined for all execution paths leading up to this point.
Loading history...
193
                    $clone->doPublish();
194
                    $firstVirtual->doUnpublish();
195
                }
196
197
                // clone has a new ID, so need to repoint
198
                // all the other virtual elements
199
                foreach ($allVirtual as $virtual) {
200
                    if ($virtual->ID == $firstVirtual->ID) {
201
                        continue;
202
                    }
203
                    $pub = false;
204
                    if ($virtual->isPublished()) {
205
                        $pub = true;
206
                    }
207
                    $virtual->LinkedElementID = $clone->ID;
208
                    $virtual->write();
209
                    if ($pub) {
210
                        $virtual->doPublish();
211
                    }
212
                }
213
214
                $firstVirtual->delete();
215
            }
216
        }
217
    }
218
219
    /**
220
     * @param array $classes
221
     */
222
    public function updateAllowedElementClasses(&$classes)
223
    {
224
        if (isset($classes[ElementVirtual::class])) {
225
            unset($classes[ElementVirtual::class]);
226
        }
227
    }
228
229
230
    /**
231
     * get all pages where this element is used
232
     *
233
     * @return ArrayList
234
     */
235
    public function getUsage()
236
    {
237
        $usage = new ArrayList();
0 ignored issues
show
Bug introduced by
The type DNADesign\ElementalVirtual\Extensions\ArrayList 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...
238
239
        if ($page = $this->getPage()) {
0 ignored issues
show
Bug introduced by
The method getPage() does not exist on DNADesign\ElementalVirtu...ns\BaseElementExtension. Did you maybe mean getUsage()? ( Ignorable by Annotation )

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

239
        if ($page = $this->/** @scrutinizer ignore-call */ getPage()) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
240
            $usage->push($page);
241
            if ($this->virtualOwner) {
242
                $page->setField('ElementType', 'Linked');
243
            } else {
244
                $page->setField('ElementType', 'Master');
245
            }
246
        }
247
248
        $linkedElements = ElementVirtual::get()->filter('LinkedElementID', $this->ID);
0 ignored issues
show
Bug Best Practice introduced by
The property ID does not exist on DNADesign\ElementalVirtu...ns\BaseElementExtension. Did you maybe forget to declare it?
Loading history...
249
250
        foreach ($linkedElements as $element) {
251
            $area = $element->Parent();
252
253
            if ($area instanceof ElementalArea && $page = $area->getOwnerPage()) {
0 ignored issues
show
Bug introduced by
The type DNADesign\ElementalVirtu...xtensions\ElementalArea 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...
254
                $page->setField('ElementType', 'Linked');
255
                $usage->push($page);
256
            }
257
        }
258
259
        $usage->removeDuplicates();
260
        return $usage;
261
    }
262
263
    /**
264
     * @return DBHTMLText
265
     */
266
    public function UsageSummary()
267
    {
268
        $usage = $this->getUsage();
269
        $arr = array();
270
        foreach ($usage as $page) {
271
            $type = ($page->ElementType) ? sprintf("<em> - %s</em>", $page->ElementType) : null;
272
            $arr[] = sprintf("<a href=\"%s\" target=\"blank\">%s</a> %s", $page->CMSEditLink(), $page->Title, $type);
273
        }
274
        $html = DBHTMLText::create('UsageSummary');
0 ignored issues
show
Bug introduced by
The type DNADesign\ElementalVirtual\Extensions\DBHTMLText 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...
275
        $html->setValue(implode('<br>', $arr));
276
277
        return $html;
278
    }
279
}
280