Issues (144)

src/Pages/SubsitesVirtualPage.php (12 issues)

1
<?php
2
3
namespace SilverStripe\Subsites\Pages;
4
5
use SilverStripe\CMS\Controllers\CMSPageEditController;
6
use SilverStripe\CMS\Model\SiteTree;
7
use SilverStripe\CMS\Model\VirtualPage;
8
use SilverStripe\Control\Controller;
9
use SilverStripe\Core\Config\Config;
10
use SilverStripe\Forms\DropdownField;
11
use SilverStripe\Forms\LiteralField;
12
use SilverStripe\Forms\TextareaField;
13
use SilverStripe\Forms\TextField;
14
use SilverStripe\Forms\TreeDropdownField;
15
use SilverStripe\ORM\ArrayList;
16
use SilverStripe\ORM\DataObject;
17
use SilverStripe\Subsites\Forms\SubsitesTreeDropdownField;
18
use SilverStripe\Subsites\Model\Subsite;
19
use SilverStripe\Subsites\State\SubsiteState;
20
use SilverStripe\View\ArrayData;
21
22
class SubsitesVirtualPage extends VirtualPage
23
{
24
25
    private static $table_name = 'SubsitesVirtualPage';
26
27
    private static $description = 'Displays the content of a page on another subsite';
28
29
    private static $db = [
30
        'CustomMetaTitle' => 'Varchar(255)',
31
        'CustomMetaKeywords' => 'Varchar(255)',
32
        'CustomMetaDescription' => 'Text',
33
        'CustomExtraMeta' => 'HTMLText'
34
    ];
35
36
    private static $non_virtual_fields = [
37
        'SubsiteID'
38
    ];
39
40
    public function getCMSFields()
41
    {
42
        $fields = parent::getCMSFields();
43
44
        $subsites = DataObject::get(Subsite::class);
45
        if (!$subsites) {
46
            $subsites = new ArrayList();
47
        } else {
48
            $subsites = ArrayList::create($subsites->toArray());
49
        }
50
51
        $subsites->push(new ArrayData(['Title' => 'Main site', 'ID' => 0]));
52
53
        $fields->addFieldToTab(
54
            'Root.Main',
55
            DropdownField::create(
56
                'CopyContentFromID_SubsiteID',
57
                _t(__CLASS__ . '.SubsiteField', 'Subsite'),
58
                $subsites->map('ID', 'Title')
59
            )->addExtraClass('subsitestreedropdownfield-chooser no-change-track'),
60
            'CopyContentFromID'
61
        );
62
63
        // Setup the linking to the original page.
64
        $pageSelectionField = SubsitesTreeDropdownField::create(
65
            'CopyContentFromID',
66
            _t('SilverStripe\\CMS\\Model\\VirtualPage.CHOOSE', 'Linked Page'),
67
            SiteTree::class,
68
            'ID',
69
            'MenuTitle'
70
        );
71
72
        $fields->addFieldToTab(
73
            'Root.Main',
74
            TreeDropdownField::create('CopyContentFromID', 'Linked Page', SiteTree::class)
75
        );
76
77
        if (Controller::has_curr() && Controller::curr()->getRequest()) {
78
            $subsiteID = (int) Controller::curr()->getRequest()->requestVar('CopyContentFromID_SubsiteID');
79
            $pageSelectionField->setSubsiteID($subsiteID);
80
        }
81
        $fields->replaceField('CopyContentFromID', $pageSelectionField);
82
83
        // Create links back to the original object in the CMS
84
        if ($this->CopyContentFromID) {
85
            $editLink = Controller::join_links(
86
                CMSPageEditController::singleton()->Link('show'),
87
                $this->CopyContentFromID
88
            );
89
90
            $linkToContent = "
91
				<a class=\"cmsEditlink\" href=\"$editLink\">" .
92
                _t('SilverStripe\\CMS\\Model\\VirtualPage.EDITCONTENT', 'Click here to edit the content') .
93
                '</a>';
94
            $fields->removeByName('VirtualPageContentLinkLabel');
95
            $fields->addFieldToTab(
96
                'Root.Main',
97
                $linkToContentLabelField = LiteralField::create('VirtualPageContentLinkLabel', $linkToContent),
98
                'Title'
99
            );
100
        }
101
102
103
        $fields->addFieldToTab(
104
            'Root.Main',
105
            TextField::create(
106
                'CustomMetaTitle',
107
                $this->fieldLabel('CustomMetaTitle')
108
            )->setDescription(_t(__CLASS__ . '.OverrideNote', 'Overrides inherited value from the source')),
109
            'MetaTitle'
110
        );
111
        $fields->addFieldToTab(
112
            'Root.Main',
113
            TextareaField::create(
114
                'CustomMetaKeywords',
115
                $this->fieldLabel('CustomMetaKeywords')
116
            )->setDescription(_t(__CLASS__ . '.OverrideNote', 'Overrides inherited value from the source')),
117
            'MetaKeywords'
118
        );
119
        $fields->addFieldToTab(
120
            'Root.Main',
121
            TextareaField::create(
122
                'CustomMetaDescription',
123
                $this->fieldLabel('CustomMetaDescription')
124
            )->setDescription(_t(__CLASS__ . '.OverrideNote', 'Overrides inherited value from the source')),
125
            'MetaDescription'
126
        );
127
        $fields->addFieldToTab(
128
            'Root.Main',
129
            TextField::create(
130
                'CustomExtraMeta',
131
                $this->fieldLabel('CustomExtraMeta')
132
            )->setDescription(_t(__CLASS__ . '.OverrideNote', 'Overrides inherited value from the source')),
133
            'ExtraMeta'
134
        );
135
136
        return $fields;
137
    }
138
139
    public function fieldLabels($includerelations = true)
140
    {
141
        $labels = parent::fieldLabels($includerelations);
142
        $labels['CustomMetaTitle'] = _t('SilverStripe\\Subsites\\Model\\Subsite.CustomMetaTitle', 'Title');
143
        $labels['CustomMetaKeywords'] = _t(
144
            'SilverStripe\\Subsites\\Model\\Subsite.CustomMetaKeywords',
145
            'Keywords'
146
        );
147
        $labels['CustomMetaDescription'] = _t(
148
            'SilverStripe\\Subsites\\Model\\Subsite.CustomMetaDescription',
149
            'Description'
150
        );
151
        $labels['CustomExtraMeta'] = _t(
152
            'SilverStripe\\Subsites\\Model\\Subsite.CustomExtraMeta',
153
            'Custom Meta Tags'
154
        );
155
156
        return $labels;
157
    }
158
159
    public function getCopyContentFromID_SubsiteID()
160
    {
161
        if ($this->CopyContentFromID) {
162
            return (int) $this->CopyContentFrom()->SubsiteID;
163
        }
164
        return SubsiteState::singleton()->getSubsiteId();
165
    }
166
167
    public function getVirtualFields()
168
    {
169
        $fields = parent::getVirtualFields();
170
        foreach ($fields as $k => $v) {
171
            if ($v == 'SubsiteID') {
172
                unset($fields[$k]);
173
            }
174
        }
175
176
        foreach (self::$db as $field => $type) {
177
            if (in_array($field, $fields)) {
178
                unset($fields[array_search($field, $fields)]);
179
            }
180
        }
181
182
        return $fields;
183
    }
184
185
    public function syncLinkTracking()
186
    {
187
        $oldState = Subsite::$disable_subsite_filter;
188
        Subsite::$disable_subsite_filter = true;
189
        if ($this->CopyContentFromID) {
190
            $this->HasBrokenLink = DataObject::get_by_id(SiteTree::class, $this->CopyContentFromID) ? false : true;
0 ignored issues
show
Bug Best Practice introduced by
The property HasBrokenLink does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
191
        }
192
        Subsite::$disable_subsite_filter = $oldState;
193
    }
194
195
    public function onBeforeWrite()
196
    {
197
        parent::onBeforeWrite();
198
199
        if ($this->CustomMetaTitle) {
0 ignored issues
show
Bug Best Practice introduced by
The property CustomMetaTitle does not exist on SilverStripe\Subsites\Pages\SubsitesVirtualPage. Since you implemented __get, consider adding a @property annotation.
Loading history...
200
            $this->MetaTitle = $this->CustomMetaTitle;
0 ignored issues
show
Bug Best Practice introduced by
The property MetaTitle does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
201
        } else {
202
            $this->MetaTitle = $this->ContentSource()->MetaTitle ?: $this->MetaTitle;
203
        }
204
        if ($this->CustomMetaKeywords) {
0 ignored issues
show
Bug Best Practice introduced by
The property CustomMetaKeywords does not exist on SilverStripe\Subsites\Pages\SubsitesVirtualPage. Since you implemented __get, consider adding a @property annotation.
Loading history...
205
            $this->MetaKeywords = $this->CustomMetaKeywords;
0 ignored issues
show
Bug Best Practice introduced by
The property MetaKeywords does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
206
        } else {
207
            $this->MetaKeywords = $this->ContentSource()->MetaKeywords ?: $this->MetaKeywords;
208
        }
209
        if ($this->CustomMetaDescription) {
0 ignored issues
show
Bug Best Practice introduced by
The property CustomMetaDescription does not exist on SilverStripe\Subsites\Pages\SubsitesVirtualPage. Since you implemented __get, consider adding a @property annotation.
Loading history...
210
            $this->MetaDescription = $this->CustomMetaDescription;
0 ignored issues
show
Bug Best Practice introduced by
The property MetaDescription does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
211
        } else {
212
            $this->MetaDescription = $this->ContentSource()->MetaDescription ?: $this->MetaDescription;
213
        }
214
        if ($this->CustomExtraMeta) {
0 ignored issues
show
Bug Best Practice introduced by
The property CustomExtraMeta does not exist on SilverStripe\Subsites\Pages\SubsitesVirtualPage. Since you implemented __get, consider adding a @property annotation.
Loading history...
215
            $this->ExtraMeta = $this->CustomExtraMeta;
0 ignored issues
show
Bug Best Practice introduced by
The property ExtraMeta does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
216
        } else {
217
            $this->ExtraMeta = $this->ContentSource()->ExtraMeta ?: $this->ExtraMeta;
218
        }
219
    }
220
221
    public function validURLSegment()
222
    {
223
        $isValid = parent::validURLSegment();
224
225
        // Veto the validation rules if its false. In this case, some logic
226
        // needs to be duplicated from parent to find out the exact reason the validation failed.
227
        if (!$isValid) {
228
            $filters = [
229
                'URLSegment' => $this->URLSegment,
0 ignored issues
show
Bug Best Practice introduced by
The property URLSegment does not exist on SilverStripe\Subsites\Pages\SubsitesVirtualPage. Since you implemented __get, consider adding a @property annotation.
Loading history...
230
                'ID:not' => $this->ID,
0 ignored issues
show
Bug Best Practice introduced by
The property ID does not exist on SilverStripe\Subsites\Pages\SubsitesVirtualPage. Since you implemented __get, consider adding a @property annotation.
Loading history...
231
            ];
232
233
            if (Config::inst()->get(SiteTree::class, 'nested_urls')) {
234
                $filters['ParentID'] = $this->ParentID ?: 0;
0 ignored issues
show
Bug Best Practice introduced by
The property ParentID does not exist on SilverStripe\Subsites\Pages\SubsitesVirtualPage. Since you implemented __get, consider adding a @property annotation.
Loading history...
235
            }
236
237
            $origDisableSubsiteFilter = Subsite::$disable_subsite_filter;
238
            Subsite::disable_subsite_filter();
239
            $existingPage = SiteTree::get()->filter($filters)->first();
240
            Subsite::disable_subsite_filter($origDisableSubsiteFilter);
241
            $existingPageInSubsite = SiteTree::get()->filter($filters)->first();
242
243
            // If URL has been vetoed because of an existing page,
244
            // be more specific and allow same URLSegments in different subsites
245
            $isValid = !($existingPage && $existingPageInSubsite);
246
        }
247
248
        return $isValid;
249
    }
250
}
251