SitewideContentReport::parameterFields()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 11
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 18
rs 9.9
1
<?php
2
3
namespace SilverStripe\SiteWideContentReport;
4
5
use Page;
0 ignored issues
show
Bug introduced by
The type Page 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...
6
use SilverStripe\AssetAdmin\Controller\AssetAdmin;
0 ignored issues
show
Bug introduced by
The type SilverStripe\AssetAdmin\Controller\AssetAdmin 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...
7
use SilverStripe\Assets\File;
8
use SilverStripe\Assets\Folder;
9
use SilverStripe\CMS\Controllers\CMSPageEditController;
10
use SilverStripe\CMS\Model\SiteTree;
11
use SilverStripe\Control\Controller;
12
use SilverStripe\Forms\DropdownField;
13
use SilverStripe\Forms\FieldList;
14
use SilverStripe\Forms\GridField\GridField;
15
use SilverStripe\Forms\GridField\GridFieldButtonRow;
16
use SilverStripe\Forms\GridField\GridFieldComponent;
17
use SilverStripe\Forms\GridField\GridFieldConfig;
18
use SilverStripe\Forms\GridField\GridFieldDataColumns;
19
use SilverStripe\Forms\GridField\GridFieldExportButton;
20
use SilverStripe\Forms\GridField\GridFieldPaginator;
21
use SilverStripe\Forms\GridField\GridFieldPrintButton;
22
use SilverStripe\Forms\GridField\GridFieldSortableHeader;
23
use SilverStripe\Forms\GridField\GridFieldToolbarHeader;
24
use SilverStripe\Forms\HeaderField;
25
use SilverStripe\Reports\Report;
26
use SilverStripe\SiteWideContentReport\Form\GridFieldBasicContentReport;
27
use SilverStripe\Subsites\Model\Subsite;
0 ignored issues
show
Bug introduced by
The type SilverStripe\Subsites\Model\Subsite 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...
28
use SilverStripe\Versioned\Versioned;
29
use SilverStripe\View\Requirements;
30
31
/**
32
 * Content side-report listing all pages and files from all sub sites.
33
 *
34
 * Class SitewideContentReport
35
 * @package SilverStripe\SiteWideContentReport
36
 */
37
class SitewideContentReport extends Report
38
{
39
    /**
40
     * @return string
41
     */
42
    public function title()
43
    {
44
        return _t(__CLASS__ . '.Title', 'Site-wide content report');
45
    }
46
47
    /**
48
     * @return string
49
     */
50
    public function description()
51
    {
52
        if (class_exists(Subsite::class)) {
53
            return _t(__CLASS__ . '.DescriptionIncludingSubsites', 'All pages and files across all Subsites');
54
        } else {
55
            return _t(__CLASS__ . '.Description', 'All pages and files across the system');
56
        }
57
    }
58
59
    /**
60
     * Returns an array with 2 elements, one with a list of Page on the site (and all subsites if
61
     * applicable) and another with files.
62
     *
63
     * @param array $params
64
     * @return array
65
     */
66
    public function sourceRecords($params = [])
67
    {
68
        if (class_exists(Subsite::class) && Subsite::get()->count() > 0) {
69
            $origMode = Versioned::get_reading_mode();
70
            Versioned::set_reading_mode('Stage.Stage');
71
            $items = [
72
                'Pages' => Subsite::get_from_all_subsites(SiteTree::class),
73
                'Files' => Subsite::get_from_all_subsites(File::class),
74
            ];
75
76
            if (array_key_exists('AllSubsites', $params)) {
77
                $items['Pages'] = $items['Pages']->filter(['SubsiteID' => $params['AllSubsites']]);
78
                $items['Files'] = $items['Files']->filter(['SubsiteID' => [0, $params['AllSubsites']]]);
79
            }
80
            Versioned::set_reading_mode($origMode);
81
82
            return $items;
83
        }
84
85
        return [
86
            'Pages' => Versioned::get_by_stage(SiteTree::class, 'Stage'),
87
            'Files' => File::get(),
88
        ];
89
    }
90
91
    public function getCount($params = array())
92
    {
93
        $records = $this->sourceRecords();
94
        return $records['Pages']->count() + $records['Files']->count();
95
    }
96
97
    /**
98
     * Returns columns for the grid fields on this report.
99
     *
100
     * @param string $itemType (i.e 'Pages' or 'Files')
101
     *
102
     * @return array
103
     */
104
    public function columns($itemType = 'Pages')
105
    {
106
        $columns = [
107
            'Title' => [
108
                'title' => _t(__CLASS__ . '.Name', 'Name'),
109
                'link' => true,
110
            ],
111
            'Created' => [
112
                'title' => _t(__CLASS__ . '.Created', 'Date created'),
113
                'formatting' => function ($value, $item) {
114
                    return $item->dbObject('Created')->Nice();
115
                },
116
            ],
117
            'LastEdited' => [
118
                'title' => _t(__CLASS__ . '.LastEdited', 'Date last edited'),
119
                'formatting' => function ($value, $item) {
120
                    return $item->dbObject('LastEdited')->Nice();
121
                },
122
            ],
123
        ];
124
125
        if ($itemType === 'Pages') {
126
            // Page specific fields
127
            $columns['i18n_singular_name'] = _t(__CLASS__ . '.PageType', 'Page type');
128
            $columns['StageState'] = [
129
                'title' => _t(__CLASS__ . '.Stage', 'Stage'),
130
                'formatting' => function ($value, $item) {
131
                    // Stage only
132
                    if (!$item->isPublished()) {
133
                        return _t(__CLASS__ . '.Draft', 'Draft');
134
                    }
135
136
                    // Pending changes
137
                    if ($item->isModifiedOnDraft()) {
138
                        return _t(__CLASS__ . '.PublishedWithChanges', 'Published (with changes)');
139
                    }
140
141
                    // If on live and unmodified
142
                    return _t(__CLASS__ . '.Published', 'Published');
143
                },
144
            ];
145
            $columns['RelativeLink'] = _t(__CLASS__ . '.Link', 'Link');
146
            $columns['MetaDescription'] = [
147
                'title' => _t(__CLASS__ . '.MetaDescription', 'Description'),
148
                'printonly' => true,
149
            ];
150
        } else {
151
            // File specific fields
152
            $columns['FileType'] = [
153
                'title' => _t(__CLASS__ . '.FileType', 'File type'),
154
                'datasource' => function ($record) {
155
                    // Handle folders separately
156
                    if ($record instanceof Folder) {
157
                        return $record->i18n_singular_name();
158
                    }
159
160
                    return $record->getFileType();
161
                }
162
            ];
163
            $columns['Size'] = _t(__CLASS__ . '.Size', 'Size');
164
            $columns['Filename'] = _t(__CLASS__ . '.Directory', 'Directory');
165
        }
166
167
        $this->extend('updateColumns', $itemType, $columns);
168
169
        return $columns;
170
    }
171
172
    /**
173
     * @return FieldList
174
     */
175
    public function getCMSFields()
176
    {
177
        Requirements::css('silverstripe/sitewidecontent-report: css/sitewidecontentreport.css');
178
        $fields = parent::getCMSFields();
179
180
        $fields->push(HeaderField::create('FilesTitle', _t(__CLASS__ . '.Files', 'Files'), 3));
181
        $fields->push($this->getReportField('Files'));
182
183
        return $fields;
184
    }
185
186
    /**
187
     * Creates a GridField for pages and another one for files with different columns.
188
     * Grid fields have an export and a print button.
189
     *
190
     * @param string $itemType (i.e 'Pages' or 'Files')
191
     *
192
     * @return GridField
193
     */
194
    public function getReportField($itemType = 'Pages')
195
    {
196
        $params = isset($_REQUEST['filters']) ? $_REQUEST['filters'] : array();
197
        $items = $this->sourceRecords($params, null, null);
0 ignored issues
show
Unused Code introduced by
The call to SilverStripe\SiteWideCon...Report::sourceRecords() has too many arguments starting with null. ( Ignorable by Annotation )

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

197
        /** @scrutinizer ignore-call */ 
198
        $items = $this->sourceRecords($params, null, null);

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...
198
199
        $gridField = new GridFieldBasicContentReport('Report-' . $itemType, false, $items[$itemType]);
0 ignored issues
show
Bug introduced by
false of type false is incompatible with the type string expected by parameter $title of SilverStripe\SiteWideCon...ntReport::__construct(). ( Ignorable by Annotation )

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

199
        $gridField = new GridFieldBasicContentReport('Report-' . $itemType, /** @scrutinizer ignore-type */ false, $items[$itemType]);
Loading history...
200
201
        $gridFieldConfig = GridFieldConfig::create()->addComponents(
202
            new GridFieldToolbarHeader(),
203
            new GridFieldSortableHeader(),
204
            new GridFieldDataColumns(),
205
            new GridFieldPaginator(),
206
            new GridFieldButtonRow('after'),
207
            $printButton = new GridFieldPrintButton('buttons-after-left'),
208
            $exportButton = $this->getExportButton()
209
        );
210
211
        $gridField->setConfig($gridFieldConfig);
212
213
        /* @var $columns GridFieldDataColumns */
214
        $columns = $gridField->getConfig()->getComponentByType(GridFieldDataColumns::class);
215
216
        $exportFields = [];
217
        $displayFields = [];
218
        $fieldCasting = [];
219
        $fieldFormatting = [];
220
        $dataFields = [];
221
222
        // Parse the column information
223
        foreach ($this->columns($itemType) as $source => $info) {
224
            if (is_string($info)) {
225
                $info = ['title' => $info];
226
            }
227
228
            if (isset($info['formatting'])) {
229
                $fieldFormatting[$source] = $info['formatting'];
230
            }
231
            if (isset($info['casting'])) {
232
                $fieldCasting[$source] = $info['casting'];
233
            }
234
235
            if (isset($info['link']) && $info['link']) {
236
                $fieldFormatting[$source] = function ($value, &$item) {
237
                    if ($item instanceof Page) {
238
                        return sprintf(
239
                            "<a href='%s'>%s</a>",
240
                            Controller::join_links(singleton(CMSPageEditController::class)->Link('show'), $item->ID),
241
                            $value
242
                        );
243
                    }
244
245
                    return sprintf(
246
                        '<a href="%s" target="_blank" rel="noopener">%s</a>',
247
                        Controller::join_links(
248
                            singleton(AssetAdmin::class)->Link('EditForm'),
249
                            'field/File/item',
250
                            $item->ID,
251
                            'edit'
252
                        ),
253
                        $value
254
                    );
255
                };
256
            }
257
258
            // Set custom datasource
259
            if (isset($info['datasource'])) {
260
                $dataFields[$source] = $info['datasource'];
261
            }
262
263
            // Set field name for export
264
            $fieldTitle = isset($info['title']) ? $info['title'] : $source;
265
266
            // If not print-only, then add to display list
267
            if (empty($info['printonly'])) {
268
                $displayFields[$source] = $fieldTitle;
269
            }
270
271
            // Assume that all displayed fields are printed also
272
            $exportFields[$source] = $fieldTitle;
273
        }
274
275
        // Set custom evaluated columns
276
        $gridField->addDataFields($dataFields);
277
278
        // Set visible fields
279
        $columns->setDisplayFields($displayFields);
280
        $columns->setFieldCasting($fieldCasting);
281
        $columns->setFieldFormatting($fieldFormatting);
282
283
        // Get print columns, and merge with print-only columns
284
        $printExportColumns = $this->getPrintExportColumns($gridField, $itemType, $exportFields);
285
286
        $printButton->setPrintColumns($printExportColumns);
287
        $exportButton->setExportColumns($printExportColumns);
0 ignored issues
show
Bug introduced by
The method setExportColumns() does not exist on SilverStripe\Forms\GridField\GridFieldComponent. It seems like you code against a sub-type of SilverStripe\Forms\GridField\GridFieldComponent such as SilverStripe\Forms\GridField\GridFieldPrintButton or SilverStripe\Forms\GridField\GridFieldExportButton or SilverStripe\Forms\GridField\GridFieldPrintButton or SilverStripe\Forms\GridField\GridFieldExportButton or SilverStripe\Forms\GridField\GridFieldPrintButton or SilverStripe\Forms\GridField\GridFieldDetailForm or SilverStripe\Forms\GridField\GridFieldExportButton. ( Ignorable by Annotation )

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

287
        $exportButton->/** @scrutinizer ignore-call */ 
288
                       setExportColumns($printExportColumns);
Loading history...
288
289
        return $gridField;
290
    }
291
292
    /**
293
     * Returns the columns for the export and print functionality.
294
     *
295
     * @param GridField $gridField
296
     * @param string $itemType (i.e 'Pages' or 'Files')
297
     * @param array $exportColumns
298
     *
299
     * @return array
300
     */
301
    public function getPrintExportColumns($gridField, $itemType, $exportColumns)
302
    {
303
        // Swap RelativeLink for AbsoluteLink for export
304
        $exportColumns['AbsoluteLink'] = _t(__CLASS__ . '.Link', 'Link');
305
        unset($exportColumns['RelativeLink']);
306
307
        $this->extend('updatePrintExportColumns', $gridField, $itemType, $exportColumns);
308
309
        return $exportColumns;
310
    }
311
312
    public function parameterFields()
313
    {
314
        if (!class_exists(Subsite::class)) {
315
            return null;
316
        }
317
318
        $subsites = Subsite::all_sites()->map()->toArray();
319
        // Pad the 0 a little so doesn't get treated as the empty string and remove the original
320
        $mainSite = ['000' => $subsites[0]];
321
        unset($subsites[0]);
322
        $subsites = $mainSite + $subsites;
323
324
        $header = HeaderField::create('PagesTitle', _t(__CLASS__ . '.Pages', 'Pages'), 3);
325
        $dropdown = DropdownField::create('AllSubsites', _t(__CLASS__ . '.FilterBy', 'Filter by:'), $subsites);
326
        $dropdown->addExtraClass('subsite-filter no-change-track');
327
        $dropdown->setEmptyString(_t(__CLASS__ . '.ALL_SUBSITES', 'All Subsites'));
328
329
        return FieldList::create($header, $dropdown);
330
    }
331
332
    /**
333
     * @return GridFieldComponent|GridFieldExportButton
334
     */
335
    protected function getExportButton()
336
    {
337
        $exportButton = new GridFieldExportButton('buttons-after-left');
338
        $this->extend('updateExportButton', $exportButton);
339
        return $exportButton;
340
    }
341
}
342