ImagesPerFieldReport   A
last analyzed

Complexity

Total Complexity 25

Size/Duplication

Total Lines 228
Duplicated Lines 0 %

Importance

Changes 6
Bugs 1 Features 0
Metric Value
eloc 79
c 6
b 1
f 0
dl 0
loc 228
rs 10
wmc 25

12 Methods

Rating   Name   Duplication   Size   Complexity  
A TreeTitle() 0 3 1
A parameterFields() 0 23 1
A records() 0 15 3
A getCMSFields() 0 6 1
A dataClass() 0 3 1
A getClassNameFieldCombos() 0 3 1
A getSourceParams() 0 12 4
A sourceQuery() 0 9 2
A getBreadcrumbs() 0 3 1
A getCount() 0 3 1
A columns() 0 6 1
B sourceRecords() 0 38 8
1
<?php
2
3
namespace Sunnysideup\AssetsOverview\Reports;
4
5
use SilverStripe\Control\HTTPRequest;
6
use SilverStripe\Core\Injector\Injector;
7
use SilverStripe\Forms\DropdownField;
8
use SilverStripe\Forms\FieldList;
9
use SilverStripe\Forms\FormField;
10
use SilverStripe\Forms\OptionsetField;
11
use SilverStripe\ORM\ArrayList;
12
use SilverStripe\ORM\DataList;
13
use SilverStripe\ORM\DataObject;
14
use SilverStripe\ORM\DataQuery;
15
use SilverStripe\ORM\SS_List;
16
use SilverStripe\Reports\Report;
17
use SilverStripe\SiteConfig\SiteConfig;
18
use SilverStripe\View\ArrayData;
19
use Sunnysideup\AssetsOverview\Api\ImageFieldFinder;
20
21
/**
22
 * Base "abstract" class creating reports on your data.
23
 *
24
 * Creating reports
25
 * ================
26
 *
27
 * Creating a new report is a matter overloading a few key methods
28
 *
29
 *  {@link title()}: Return the title - i18n is your responsibility
30
 *  {@link description()}: Return the description - i18n is your responsibility
31
 *  {@link sourceQuery()}: Return a SS_List of the search results
32
 *  {@link columns()}: Return information about the columns in this report.
33
 *  {@link parameterFields()}: Return a FieldList of the fields that can be used to filter this
34
 *  report.
35
 *
36
 * If you wish to modify the report in more extreme ways, you could overload these methods instead.
37
 *
38
 * {@link getReportField()}: Return a FormField in the place where your report's TableListField
39
 * usually appears.
40
 * {@link getCMSFields()}: Return the FieldList representing the complete right-hand area of the
41
 * report, including the title, description, parameter fields, and results.
42
 *
43
 * Showing reports to the user
44
 * ===========================
45
 *
46
 * Right now, all subclasses of SS_Report will be shown in the ReportAdmin. In SS3 there is only
47
 * one place where reports can go, so this class is greatly simplifed from its version in SS2.
48
 *
49
 * @method DataList|SS_List sourceRecords($params = [], $sort = null, $limit = null) List of records to show for this report
50
 */
51
class ImagesPerFieldReport extends Report
52
{
53
    /**
54
     * This is the title of the report,
55
     * used by the ReportAdmin templates.
56
     *
57
     * @var string
58
     */
59
    protected $title = 'Images per field';
60
61
    /**
62
     * This is a description about what this
63
     * report does. Used by the ReportAdmin
64
     * templates.
65
     *
66
     * @var string
67
     */
68
    protected $description = 'Choose an image field and see what images have been added';
69
70
    /**
71
     * The class of object being managed by this report.
72
     * Set by overriding in your subclass.
73
     */
74
    protected $dataClass = DataObject::class;
75
76
    /**
77
     * A field that specifies the sort order of this report.
78
     *
79
     * @var int
80
     */
81
    protected $sort = 999;
82
83
    protected $classNameUsed = '';
84
85
    protected $fieldUsed = '';
86
87
    protected $typeUsed = '';
88
89
    public function getCMSFields()
90
    {
91
        $fields = parent::getCMSFields();
92
        $fields->renameField('updatereport', 'Show Images');
93
94
        return $fields;
95
    }
96
97
    public function sourceRecords($params = [], $sort = null, $limit = null)
98
    {
99
        $classNameFieldComboString = $params['ClassNameFieldCombo'] ?? ',,';
100
        $situation = $params['Situation'] ?? '';
101
        list($classNameUsed, $fieldUsed, $typeUsed) = explode(',', $classNameFieldComboString);
102
103
        if ($classNameUsed && $fieldUsed && class_exists($classNameUsed)) {
104
            $this->classNameUsed = $classNameUsed;
105
            $this->fieldUsed = $fieldUsed;
106
            $this->typeUsed = $typeUsed;
107
            $isSingularRel = 'has_one' === $typeUsed || 'belongs_to' === $typeUsed;
108
            // create list
109
            $list = $classNameUsed::get();
110
            if ($situation) {
111
                if ('WithImage' === $situation) {
112
                    $filterMethod = 'exclude';
113
                    $existsValue = true;
114
                } else {
115
                    $existsValue = false;
116
                    $filterMethod = 'filter';
117
                }
118
119
                if ($isSingularRel) {
120
                    $field = $fieldUsed . 'ID';
121
                    $list = $list->{$filterMethod}([$field => 0]);
122
                } else {
123
                    $list = $list->filterByCallBack(
124
                        function ($item) use ($fieldUsed, $existsValue) {
125
                            return (bool) $item->{$fieldUsed}()->exists() === $existsValue;
126
                        }
127
                    );
128
                }
129
            }
130
131
            return $list;
132
        }
133
134
        return SiteConfig::get()->filter(['ID' => 0]);
135
    }
136
137
    /**
138
     * Return the {@link DataQuery} that provides your report data.
139
     *
140
     * @param array $params
141
     *
142
     * @return DataQuery
143
     */
144
    public function sourceQuery($params)
145
    {
146
        if (! $this->hasMethod('sourceRecords')) {
147
            throw new \RuntimeException(
148
                'Please override sourceQuery()/sourceRecords() and columns() or, if necessary, override getReportField()'
149
            );
150
        }
151
152
        return $this->sourceRecords($params)->dataQuery();
153
    }
154
155
    /**
156
     * Return a SS_List records for this report.
157
     *
158
     * @param array $params
159
     *
160
     * @return SS_List
161
     */
162
    public function records($params)
163
    {
164
        if ($this->hasMethod('sourceRecords')) {
165
            return $this->sourceRecords($params);
166
        }
167
168
        $query = $this->sourceQuery($params);
169
        $results = ArrayList::create();
170
        foreach ($query->execute() as $data) {
171
            $class = $this->dataClass();
172
            $result = Injector::inst()->create($class, $data);
173
            $results->push($result);
174
        }
175
176
        return $results;
177
    }
178
179
    public function columns()
180
    {
181
        return [
182
            'Title' => ['title' => 'Title', 'link' => 'CMSEditLink'],
183
            $this->fieldUsed . '.Link' => ['title' => 'Link', 'link' => $this->fieldUsed . '.URL'],
184
            $this->fieldUsed . '.CMSThumbnail' => 'Image',
185
        ];
186
    }
187
188
    /**
189
     * Return the data class for this report.
190
     */
191
    public function dataClass()
192
    {
193
        return $this->dataClass;
194
    }
195
196
    /**
197
     * counts the number of objects returned.
198
     *
199
     * @param array      $params - any parameters for the sourceRecords
200
     * @param null|mixed $limit
201
     *
202
     * @return int
203
     */
204
    public function getCount($params = [], $limit = null)
205
    {
206
        return count($this->getClassNameFieldCombos());
207
    }
208
209
    /////////////////////// UI METHODS ///////////////////////
210
211
    /**
212
     * Return the name of this report, which is used by the templates to render the name of the report in the report
213
     * tree, the left hand pane inside ReportAdmin.
214
     *
215
     * @return string
216
     */
217
    public function TreeTitle()
218
    {
219
        return $this->title();
220
    }
221
222
    /**
223
     * Return additional breadcrumbs for this report. Useful when this report is a child of another.
224
     *
225
     * @return ArrayData[]
226
     */
227
    public function getBreadcrumbs()
228
    {
229
        return [];
230
    }
231
232
    /**
233
     * Get source params for the report to filter by.
234
     *
235
     * @return array
236
     */
237
    protected function getSourceParams()
238
    {
239
        $params = [];
240
        if (Injector::inst()->has(HTTPRequest::class)) {
241
            /** @var HTTPRequest $request */
242
            $request = Injector::inst()->get(HTTPRequest::class);
243
            $params = $request->param('filters') ?: $request->requestVar('filters') ?: [];
244
        }
245
246
        $this->extend('updateSourceParams', $params);
247
248
        return $params;
249
    }
250
251
    protected function parameterFields()
252
    {
253
        $params = new FieldList();
254
255
        $params->push(
256
            DropdownField::create(
257
                'ClassNameFieldCombo',
258
                'Classname and Field',
259
                $this->getClassNameFieldCombos()
260
            )->setEmptyString('--- select record list and image field ---')
261
        );
262
        $params->push(
263
            OptionsetField::create(
264
                'Situation',
265
                'Situation',
266
                [
267
                    'WithImage' => 'With Image(s)',
268
                    'Without' => 'Without Image(s)',
269
                ]
270
            )->setEmptyString('(Any)')
271
        );
272
273
        return $params;
274
    }
275
276
    protected function getClassNameFieldCombos(): array
277
    {
278
        return (new ImageFieldFinder())->Fields();
279
    }
280
}
281