BaseElementExtension::updateCMSFields()   B
last analyzed

Complexity

Conditions 7
Paths 8

Size

Total Lines 49
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

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