Completed
Pull Request — master (#97)
by Robbie
02:29
created

SiteSummary   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 212
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 212
rs 10
c 0
b 0
f 0
wmc 15

10 Methods

Rating   Name   Duplication   Size   Complexity  
A title() 0 3 1
A columns() 0 11 1
A sourceRecords() 0 12 2
A getCMSFields() 0 9 2
A getAlerts() 0 5 1
A getLastUpdated() 0 9 2
A getInfoLink() 0 9 1
B getDropdownFilter() 0 24 1
A resolveCmsVersion() 0 23 3
A getReportField() 0 47 1
1
<?php
2
3
namespace BringYourOwnIdeas\Maintenance\Reports;
4
5
use BringYourOwnIdeas\Maintenance\Forms\GridFieldDropdownFilter;
6
use BringYourOwnIdeas\Maintenance\Forms\GridFieldHtmlFragment;
7
use BringYourOwnIdeas\Maintenance\Forms\GridFieldLinkButton;
8
use BringYourOwnIdeas\Maintenance\Forms\GridFieldRefreshButton;
9
use BringYourOwnIdeas\Maintenance\Model\Package;
10
use BringYourOwnIdeas\Maintenance\Tasks\UpdatePackageInfoTask;
11
use SilverStripe\Core\Config\Config;
12
use SilverStripe\Core\Injector\Injector;
13
use SilverStripe\Forms\GridField\GridField;
14
use SilverStripe\Forms\GridField\GridFieldConfig;
15
use SilverStripe\Forms\GridField\GridFieldExportButton;
16
use SilverStripe\Forms\GridField\GridFieldPaginator;
17
use SilverStripe\Forms\GridField\GridFieldPrintButton;
18
use SilverStripe\Forms\LiteralField;
19
use SilverStripe\ORM\FieldType\DBDatetime;
20
use SilverStripe\ORM\FieldType\DBField;
21
use SilverStripe\Reports\Report;
22
use SilverStripe\View\ArrayData;
23
use SilverStripe\View\Requirements;
24
25
/**
26
 * A report listing all installed modules used in this site (from a cache).
27
 */
28
class SiteSummary extends Report
29
{
30
    public function title()
31
    {
32
        return _t(__CLASS__ . '.TITLE', 'Installed modules');
33
    }
34
35
    public function sourceRecords()
36
    {
37
        $packageList = Package::get();
38
        $typeFilters = Config::inst()->get(UpdatePackageInfoTask::class, 'allowed_types');
39
40
        if (!empty($typeFilters)) {
41
            $packageList = $packageList->filter('Type', $typeFilters);
42
        }
43
44
        $this->extend('updateSourceRecords', $packageList);
45
46
        return $packageList;
47
    }
48
49
    /**
50
     * Provide column selection and formatting rules for the CMS report. You can extend data columns by extending
51
     * {@link Package::summary_fields}, or you can extend this method to adjust the formatting rules, or to provide
52
     * composite fields (such as Summary below) for the CMS report but not the CSV export.
53
     *
54
     * {@inheritDoc}
55
     */
56
    public function columns()
57
    {
58
        $columns = Package::create()->summaryFields();
59
60
        // Remove the default Title and Description and create Summary as a composite of both for the CMS report only
61
        unset($columns['Title'], $columns['Description']);
62
        $columns = ['Summary' => 'Summary'] + $columns;
63
64
        $this->extend('updateColumns', $columns);
65
66
        return $columns;
67
    }
68
69
    /**
70
     * Add a button row, including link out to the SilverStripe addons repository, and export button
71
     *
72
     * {@inheritdoc}
73
     */
74
    public function getReportField()
75
    {
76
        Requirements::css('bringyourownideas/silverstripe-maintenance: client/dist/styles/bundle.css');
77
        Requirements::javascript('bringyourownideas/silverstripe-maintenance: client/dist/js/bundle.js');
78
79
        /** @var GridField $grid */
80
        $grid = parent::getReportField();
81
82
        /** @var GridFieldConfig $config */
83
        $config = $grid->getConfig();
84
85
        $grid->addExtraClass('site-summary');
86
87
        /** @var GridFieldExportButton $exportButton */
88
        $exportButton = $config->getComponentByType(GridFieldExportButton::class);
89
        $exportButton->setExportColumns(Package::create()->summaryFields());
90
91
        $versionHtml = ArrayData::create([
92
            'Title' => _t(__CLASS__ . '.VERSION', 'Version'),
93
            'Version' => $this->resolveCmsVersion(),
94
            'LastUpdated' => $this->getLastUpdated(),
95
        ])->renderWith(__CLASS__ . '/VersionHeader');
96
97
        $config->addComponents(
98
            Injector::inst()->create(GridFieldRefreshButton::class, 'buttons-before-left'),
99
            Injector::inst()->create(
100
                GridFieldLinkButton::class,
101
                'https://addons.silverstripe.org',
102
                _t(__CLASS__ . '.LINK_TO_ADDONS', 'Explore Addons'),
103
                'buttons-before-left'
104
            ),
105
            $this->getDropdownFilter(),
106
            $this->getInfoLink(),
107
            Injector::inst()->create(GridFieldHtmlFragment::class, 'header', $versionHtml)
108
        );
109
110
        // Re-order the paginator to ensure it counts correctly, and reorder the buttons
111
        $paginator = $config->getComponentByType(GridFieldPaginator::class);
112
        $config->removeComponent($paginator)->addComponent($paginator);
113
114
        $exportButton = $config->getComponentByType(GridFieldExportButton::class);
115
        $config->removeComponent($exportButton)->addComponent($exportButton);
116
117
        $printButton = $config->getComponentByType(GridFieldPrintButton::class);
118
        $config->removeComponentsByType($printButton)->addComponent($printButton);
0 ignored issues
show
Bug introduced by
$printButton of type SilverStripe\Forms\GridField\GridFieldComponent is incompatible with the type string|string[] expected by parameter $types of SilverStripe\Forms\GridF...emoveComponentsByType(). ( Ignorable by Annotation )

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

118
        $config->removeComponentsByType(/** @scrutinizer ignore-type */ $printButton)->addComponent($printButton);
Loading history...
119
120
        return $grid;
121
    }
122
123
    /**
124
     * Returns a dropdown filter with user configurable options in it
125
     *
126
     * @return GridFieldDropdownFilter
127
     */
128
    protected function getDropdownFilter()
129
    {
130
        /** @var GridFieldDropdownFilter $dropdownFilter */
131
        $dropdownFilter = Injector::inst()->create(
132
            GridFieldDropdownFilter::class,
133
            'addonFilter',
134
            'buttons-before-right',
135
            _t(__CLASS__ . '.ShowAllModules', 'Show all modules')
136
        );
137
138
        $dropdownFilter->addFilterOption(
139
            'supported',
140
            _t(__CLASS__ . '.FilterSupported', 'Supported modules'),
141
            ['Supported' => true]
142
        );
143
        $dropdownFilter->addFilterOption(
144
            'unsupported',
145
            _t(__CLASS__ . '.FilterUnsupported', 'Unsupported modules'),
146
            ['Supported' => false]
147
        );
148
149
        $this->extend('updateDropdownFilterOptions', $dropdownFilter);
150
151
        return $dropdownFilter;
152
    }
153
154
    /**
155
     * Returns a link to more information on this module on the addons site
156
     *
157
     * @return GridFieldHtmlFragment
158
     */
159
    protected function getInfoLink()
160
    {
161
        return Injector::inst()->create(
162
            GridFieldHtmlFragment::class,
163
            'buttons-before-right',
164
            DBField::create_field('HTMLFragment', ArrayData::create([
165
                'Link' => 'https://addons.silverstripe.org/add-ons/bringyourownideas/silverstripe-maintenance',
166
                'Label' => _t(__CLASS__ . '.MORE_INFORMATION', 'More information'),
167
            ])->renderWith(__CLASS__ . '/MoreInformationLink'))
168
        );
169
    }
170
171
    public function getCMSFields()
172
    {
173
        $fields = parent::getCMSFields();
174
        $alerts = $this->getAlerts();
175
        if ($alerts) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $alerts of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
176
            $summaryInfo = '<div class="site-summary message warning">' . implode("\n", $alerts) . '</div>';
177
            $fields->unshift(LiteralField::create('AlertSummary', $summaryInfo));
178
        }
179
        return $fields;
180
    }
181
182
    /**
183
     * Return a list of alerts to display in a message box above the report
184
     * A combination of free text fields - combined alerts as opposed to a message box per alert.
185
     *
186
     * @return array
187
     */
188
    protected function getAlerts()
189
    {
190
        $alerts = [];
191
        $this->extend('updateAlerts', $alerts);
192
        return $alerts;
193
    }
194
195
    /**
196
     * Extract CMS and Framework version details from the records in the report
197
     *
198
     * @return string
199
     */
200
    protected function resolveCmsVersion()
201
    {
202
        $versionModules = [
203
            'silverstripe/framework' => 'Framework',
204
            'silverstripe/cms' => 'CMS',
205
        ];
206
        $this->extend('updateVersionModules', $versionModules);
207
208
        $records = $this->sourceRecords()->filter('Name', array_keys($versionModules));
209
        $versionParts = [];
210
211
        foreach ($versionModules as $name => $label) {
212
            $record = $records->find('Name', $name);
213
            if (!$record) {
214
                $version = _t(__CLASS__.'.VersionUnknown', 'Unknown');
215
            } else {
216
                $version = $record->Version;
217
            }
218
219
            $versionParts[] = "$label $version";
220
        }
221
222
        return implode(', ', $versionParts);
223
    }
224
225
    /**
226
     * Get the "last updated" date for the report. This is based on the modified date of any of the records, since
227
     * they are regenerated when the report is generated.
228
     *
229
     * @return string
230
     */
231
    public function getLastUpdated()
232
    {
233
        $packages = Package::get()->limit(1);
234
        if (!$packages->count()) {
235
            return '';
236
        }
237
        /** @var DBDatetime $datetime */
238
        $datetime = $packages->first()->dbObject('LastEdited');
239
        return $datetime->Date() . ' ' . $datetime->Time12();
240
    }
241
}
242