Passed
Pull Request — master (#19)
by
unknown
02:29
created

BaseElementExtension   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 263
Duplicated Lines 0 %

Importance

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