Passed
Push — master ( 3c6afc...60fb92 )
by Robbie
01:46
created

SitewideContentReport::getCount()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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

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

177
                HeaderField::create('PagesTitle', _t(__CLASS__ . '.Pages', 'Pages'), /** @scrutinizer ignore-type */ 3),
Loading history...
Bug introduced by
'PagesTitle' of type string is incompatible with the type array expected by parameter $args of SilverStripe\View\ViewableData::create(). ( Ignorable by Annotation )

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

177
                HeaderField::create(/** @scrutinizer ignore-type */ 'PagesTitle', _t(__CLASS__ . '.Pages', 'Pages'), 3),
Loading history...
178
                'Report-Pages'
0 ignored issues
show
Bug introduced by
'Report-Pages' of type string is incompatible with the type SilverStripe\Forms\FormField expected by parameter $item of SilverStripe\Forms\FieldList::insertBefore(). ( Ignorable by Annotation )

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

178
                /** @scrutinizer ignore-type */ 'Report-Pages'
Loading history...
179
            );
180
            $fields->insertBefore(
181
                DropdownField::create('AllSubsites', _t(__CLASS__ . '.FilterBy', 'Filter by:'), $subsites)
182
                    ->addExtraClass('subsite-filter no-change-track')
183
                    ->setEmptyString('All Subsites'),
184
                'Report-Pages'
185
            );
186
        }
187
188
        $fields->push(HeaderField::create('FilesTitle', _t(__CLASS__ . '.Files', 'Files'), 3));
189
        $fields->push($this->getReportField('Files'));
190
191
192
        return $fields;
193
    }
194
195
    /**
196
     * Creates a GridField for pages and another one for files with different columns.
197
     * Grid fields have an export and a print button.
198
     *
199
     * @param string $itemType (i.e 'Pages' or 'Files')
200
     *
201
     * @return GridField
202
     */
203
    public function getReportField($itemType = 'Pages')
204
    {
205
        $params = isset($_REQUEST['filters']) ? $_REQUEST['filters'] : array();
206
        $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 $params. ( Ignorable by Annotation )

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

206
        /** @scrutinizer ignore-call */ 
207
        $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...
207
208
        $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

208
        $gridField = new GridFieldBasicContentReport('Report-' . $itemType, /** @scrutinizer ignore-type */ false, $items[$itemType]);
Loading history...
209
210
        $gridFieldConfig = GridFieldConfig::create()->addComponents(
211
            new GridFieldToolbarHeader(),
212
            new GridFieldSortableHeader(),
213
            new GridFieldDataColumns(),
214
            new GridFieldPaginator(),
215
            new GridFieldButtonRow('after'),
216
            $printButton = new GridFieldPrintButton('buttons-after-left'),
217
            $exportButton = new GridFieldExportButton('buttons-after-left')
218
        );
219
220
        $gridField->setConfig($gridFieldConfig);
221
222
        /* @var $columns GridFieldDataColumns */
223
        $columns = $gridField->getConfig()->getComponentByType(GridFieldDataColumns::class);
224
225
        $exportFields = [];
226
        $displayFields = [];
227
        $fieldCasting = [];
228
        $fieldFormatting = [];
229
        $dataFields = [];
230
231
        // Parse the column information
232
        foreach ($this->columns($itemType) as $source => $info) {
233
            if (is_string($info)) {
234
                $info = ['title' => $info];
235
            }
236
237
            if (isset($info['formatting'])) {
238
                $fieldFormatting[$source] = $info['formatting'];
239
            }
240
            if (isset($info['casting'])) {
241
                $fieldCasting[$source] = $info['casting'];
242
            }
243
244
            if (isset($info['link']) && $info['link']) {
245
                $fieldFormatting[$source] = function ($value, &$item) {
246
                    if ($item instanceof Page) {
247
                        return sprintf(
248
                            "<a href='%s'>%s</a>",
249
                            Controller::join_links(singleton(CMSPageEditController::class)->Link('show'), $item->ID),
250
                            $value
251
                        );
252
                    }
253
254
                    return sprintf(
255
                        "<a href='%s'>%s</a>",
256
                        Controller::join_links(
257
                            singleton(AssetAdmin::class)->Link('EditForm'),
258
                            'field/File/item',
259
                            $item->ID,
260
                            'edit'
261
                        ),
262
                        $value
263
                    );
264
                };
265
            }
266
267
            // Set custom datasource
268
            if (isset($info['datasource'])) {
269
                $dataFields[$source] = $info['datasource'];
270
            }
271
272
            // Set field name for export
273
            $fieldTitle = isset($info['title']) ? $info['title'] : $source;
274
275
            // If not print-only, then add to display list
276
            if (empty($info['printonly'])) {
277
                $displayFields[$source] = $fieldTitle;
278
            }
279
280
            // Assume that all displayed fields are printed also
281
            $exportFields[$source] = $fieldTitle;
282
        }
283
284
        // Set custom evaluated columns
285
        $gridField->addDataFields($dataFields);
286
287
        // Set visible fields
288
        $columns->setDisplayFields($displayFields);
289
        $columns->setFieldCasting($fieldCasting);
290
        $columns->setFieldFormatting($fieldFormatting);
291
292
        // Get print columns, and merge with print-only columns
293
        $printExportColumns = $this->getPrintExportColumns($gridField, $itemType, $exportFields);
294
295
        $printButton->setPrintColumns($printExportColumns);
296
        $exportButton->setExportColumns($printExportColumns);
297
298
        return $gridField;
299
    }
300
301
    /**
302
     * Returns the columns for the export and print functionality.
303
     *
304
     * @param GridField $gridField
305
     * @param string $itemType (i.e 'Pages' or 'Files')
306
     * @param array $exportColumns
307
     *
308
     * @return array
309
     */
310
    public function getPrintExportColumns($gridField, $itemType, $exportColumns)
311
    {
312
        // Swap RelativeLink for AbsoluteLink for export
313
        $exportColumns['AbsoluteLink'] = _t(__CLASS__ . '.Link', 'Link');
314
        unset($exportColumns['RelativeLink']);
315
316
        $this->extend('updatePrintExportColumns', $gridField, $itemType, $exportColumns);
317
318
        return $exportColumns;
319
    }
320
}
321