DatedUpdateHolderController::doDateReset()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 0
dl 0
loc 11
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace CWP\CWP\PageTypes;
4
5
use CWP\Core\Feed\CwpAtomFeed;
6
use InvalidArgumentException;
7
use PageController;
0 ignored issues
show
Bug introduced by
The type PageController 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 SilverStripe\Control\Director;
9
use SilverStripe\Control\HTTP;
10
use SilverStripe\Control\RSS\RSSFeed;
11
use SilverStripe\Core\Config\Config;
12
use SilverStripe\Forms\DateField;
13
use SilverStripe\Forms\FieldList;
14
use SilverStripe\Forms\Form;
15
use SilverStripe\Forms\FormAction;
16
use SilverStripe\Forms\HiddenField;
17
use SilverStripe\ORM\ArrayList;
18
use SilverStripe\ORM\FieldType\DBDatetime;
19
use SilverStripe\ORM\FieldType\DBField;
20
use SilverStripe\ORM\PaginatedList;
21
use SilverStripe\ORM\ValidationResult;
22
use SilverStripe\Taxonomy\TaxonomyTerm;
23
24
/**
25
 * The parameters apply in the following preference order:
26
 *  - Highest priority: Tag & date (or date range)
27
 *  - Month (and Year)
28
 *  - Pagination
29
 *
30
 * So, when the user click on a tag link, the pagination, and month will be reset, but not the date filter. Also,
31
 * changing the date will not affect the tag, but will reset the month and pagination.
32
 *
33
 * When the user clicks on a month, pagination will be reset, but tags retained. Pagination retains all other
34
 * parameters.
35
 */
36
class DatedUpdateHolderController extends PageController
37
{
38
    private static $allowed_actions = [
0 ignored issues
show
introduced by
The private property $allowed_actions is not used, and could be removed.
Loading history...
39
        'rss',
40
        'atom',
41
        'DateRangeForm',
42
    ];
43
44
    private static $casting = [
0 ignored issues
show
introduced by
The private property $casting is not used, and could be removed.
Loading history...
45
        'MetaTitle' => 'Text',
46
        'FilterDescription' => 'Text',
47
    ];
48
49
    /**
50
     * The session key for storing temporary form messages
51
     *
52
     * @var string
53
     */
54
    const TEMP_FORM_MESSAGE = __CLASS__ . '.TempFormMessage';
55
56
    /**
57
     * Get the meta title for the current action
58
     *
59
     * @return string
60
     */
61
    public function getMetaTitle()
62
    {
63
        $title = $this->data()->getTitle();
64
        $filter = $this->FilterDescription();
65
        if ($filter) {
66
            $title = "{$title} - {$filter}";
67
        }
68
69
        $this->extend('updateMetaTitle', $title);
70
        return $title;
71
    }
72
73
    /**
74
     * Returns a description of the current filter
75
     *
76
     * @return string
77
     */
78
    public function FilterDescription()
79
    {
80
        $params = $this->parseParams();
81
82
        $filters = array();
83
        if ($params['tag']) {
84
            $term = TaxonomyTerm::get_by_id(TaxonomyTerm::class, $params['tag']);
85
            if ($term) {
0 ignored issues
show
introduced by
$term is of type SilverStripe\Taxonomy\TaxonomyTerm, thus it always evaluated to true.
Loading history...
86
                $filters[] = _t(
87
                    'CWP\\CWP\\PageTypes\\DatedUpdateHolder.FILTER_WITHIN',
88
                    'within'
89
                ) . ' "' . $term->Name . '"';
90
            }
91
        }
92
93
        if ($params['from'] || $params['to']) {
94
            if ($params['from']) {
95
                $from = strtotime($params['from']);
96
                if ($params['to']) {
97
                    $to = strtotime($params['to']);
98
                    $filters[] = _t('CWP\\CWP\\PageTypes\\DatedUpdateHolder.FILTER_BETWEEN', 'between') . ' '
99
                        . date('j/m/Y', $from) . ' and ' . date('j/m/Y', $to);
100
                } else {
101
                    $filters[] = _t('CWP\\CWP\\PageTypes\\DatedUpdateHolder.FILTER_ON', 'on')
102
                        . ' ' . date('j/m/Y', $from);
103
                }
104
            } else {
105
                $to = strtotime($params['to']);
106
                $filters[] = _t('CWP\\CWP\\PageTypes\\DatedUpdateHolder.FILTER_ON', 'on')
107
                    . ' ' . date('j/m/Y', $to);
108
            }
109
        }
110
111
        if ($params['year'] && $params['month']) {
112
            $timestamp = mktime(1, 1, 1, $params['month'], 1, $params['year']);
113
            $filters[] = _t('CWP\\CWP\\PageTypes\\DatedUpdateHolder.FILTER_IN', 'in')
114
                . ' ' . date('F', $timestamp) . ' ' . $params['year'];
115
        }
116
117
        if ($filters) {
118
            return $this->getUpdateName() . ' ' . implode(' ', $filters);
119
        }
120
    }
121
122
    public function getUpdateName()
123
    {
124
        return Config::inst()->get($this->data()->ClassName, 'update_name');
125
    }
126
127
    protected function init()
128
    {
129
        parent::init();
130
        RSSFeed::linkToFeed($this->Link() . 'rss', $this->getSubscriptionTitle());
131
    }
132
133
    /**
134
     * Parse URL parameters.
135
     *
136
     * @param bool $produceErrorMessages Set to false to omit session messages.
137
     */
138
    public function parseParams($produceErrorMessages = true)
139
    {
140
        $tag = $this->request->getVar('tag');
141
        $from = $this->request->getVar('from');
142
        $to = $this->request->getVar('to');
143
        $year = $this->request->getVar('year');
144
        $month = $this->request->getVar('month');
145
146
        if ($tag == '') {
147
            $tag = null;
148
        }
149
        if ($from == '') {
150
            $from = null;
151
        }
152
        if ($to == '') {
153
            $to = null;
154
        }
155
        if ($year == '') {
156
            $year = null;
157
        }
158
        if ($month == '') {
159
            $month = null;
160
        }
161
162
        if (isset($tag)) {
163
            $tag = (int)$tag;
164
        }
165
        try {
166
            if (isset($from)) {
167
                $from = urldecode($from);
168
                $parser = DBDatetime::create();
169
                $parser->setValue($from);
170
                $from = $parser->Format('y-MM-dd');
171
            }
172
            if (isset($to)) {
173
                $to = urldecode($to);
174
                $parser = DBDatetime::create();
175
                $parser->setValue($to);
176
                $to = $parser->Format('y-MM-dd');
177
            }
178
        } catch (InvalidArgumentException $e) {
179
            if ($produceErrorMessages) {
180
                $this->getRequest()->getSession()->set(self::TEMP_FORM_MESSAGE, _t(
181
                    __CLASS__ . '.InvalidDateFormat',
182
                    'Dates must be in "y-MM-dd" format.'
183
                ));
184
            }
185
        }
186
        if (isset($year)) {
187
            $year = (int)$year;
188
        }
189
        if (isset($month)) {
190
            $month = (int)$month;
191
        }
192
193
        // If only "To" has been provided filter by single date. Normalise by swapping with "From".
194
        if (isset($to) && !isset($from)) {
195
            list($to, $from) = [$from, $to];
196
        }
197
198
        // Flip the dates if the order is wrong.
199
        if (isset($to) && isset($from) && strtotime($from) > strtotime($to)) {
200
            list($to, $from) = [$from, $to];
201
202
            if ($produceErrorMessages) {
203
                $this->getRequest()->getSession()->set(self::TEMP_FORM_MESSAGE, _t(
204
                    __CLASS__ . '.FilterAppliedMessage',
205
                    'Filter has been applied with the dates reversed.'
206
                ));
207
            }
208
        }
209
210
        // Notify the user that filtering by single date is taking place.
211
        if (isset($from) && !isset($to)) {
212
            if ($produceErrorMessages) {
213
                $this->getRequest()->getSession()->set(self::TEMP_FORM_MESSAGE, _t(
214
                    __CLASS__ . '.DateRangeFilterMessage',
215
                    'Filtered by a single date.'
216
                ));
217
            }
218
        }
219
220
        return [
221
            'tag' => $tag,
222
            'from' => $from,
223
            'to' => $to,
224
            'year' => $year,
225
            'month' => $month,
226
        ];
227
    }
228
229
    /**
230
     * Build the link - keep the date range, reset the rest.
231
     */
232
    public function AllTagsLink()
233
    {
234
        $link = HTTP::setGetVar('tag', null, null, '&');
235
        $link = HTTP::setGetVar('month', null, $link, '&');
236
        $link = HTTP::setGetVar('year', null, $link, '&');
237
        $link = HTTP::setGetVar('start', null, $link, '&');
238
239
        return $link;
240
    }
241
242
    /**
243
     * List tags and attach links.
244
     */
245
    public function UpdateTagsWithLinks()
246
    {
247
        $tags = $this->UpdateTags();
248
249
        $processed = ArrayList::create();
250
251
        foreach ($tags as $tag) {
252
            // Build the link - keep the tag, and date range, but reset month, year and pagination.
253
            $link = HTTP::setGetVar('tag', $tag->ID, null, '&');
254
            $link = HTTP::setGetVar('month', null, $link, '&');
255
            $link = HTTP::setGetVar('year', null, $link, '&');
256
            $link = HTTP::setGetVar('start', null, $link, '&');
257
258
            $tag->Link = $link;
259
            $processed->push($tag);
260
        }
261
262
        return $processed;
263
    }
264
265
    /**
266
     * Get the TaxonomyTerm related to the current tag GET parameter.
267
     */
268
    public function CurrentTag()
269
    {
270
        $tagID = $this->request->getVar('tag');
271
272
        if (isset($tagID)) {
273
            return TaxonomyTerm::get_by_id(TaxonomyTerm::class, (int)$tagID);
274
        }
275
    }
276
277
    /**
278
     * Extract the available months based on the current query.
279
     * Only tag is respected. Pagination and months are ignored.
280
     */
281
    public function AvailableMonths()
282
    {
283
        $params = $this->parseParams();
284
285
        return DatedUpdateHolder::ExtractMonths(
286
            $this->Updates($params['tag'], $params['from'], $params['to']),
287
            Director::makeRelative($_SERVER['REQUEST_URI']),
288
            $params['year'],
289
            $params['month']
290
        );
291
    }
292
293
    /**
294
     * Get the updates based on the current query.
295
     */
296
    public function FilteredUpdates($pageSize = 20)
297
    {
298
        $params = $this->parseParams();
299
300
        $items = $this->Updates(
301
            $params['tag'],
302
            $params['from'],
303
            $params['to'],
304
            $params['year'],
305
            $params['month']
306
        );
307
308
        // Apply pagination
309
        $list = PaginatedList::create($items, $this->getRequest());
310
        $list->setPageLength($pageSize);
311
        return $list;
312
    }
313
314
    /**
315
     * @return Form
316
     */
317
    public function DateRangeForm()
318
    {
319
        $dateFromTitle = DBField::create_field('HTMLText', sprintf(
320
            '%s <span class="field-note">%s</span>',
321
            _t('CWP\\CWP\\PageTypes\\DatedUpdateHolder.FROM_DATE', 'From date'),
322
            _t('CWP\\CWP\\PageTypes\\DatedUpdateHolder.DATE_EXAMPLE', '(example: 30/12/2017)')
323
        ));
324
        $dateToTitle = DBField::create_field('HTMLText', sprintf(
325
            '%s <span class="field-note">%s</span>',
326
            _t('CWP\\CWP\\PageTypes\\DatedUpdateHolder.TO_DATE', 'To date'),
327
            _t('CWP\\CWP\\PageTypes\\DatedUpdateHolder.DATE_EXAMPLE', '(example: 30/12/2017)')
328
        ));
329
330
        $fields = FieldList::create(
331
            DateField::create('from', $dateFromTitle),
332
            DateField::create('to', $dateToTitle),
333
            HiddenField::create('tag')
334
        );
335
336
        $actions = FieldList::create(
337
            FormAction::create("doDateFilter")
338
                ->setTitle(_t(__CLASS__ . '.Filter', 'Filter'))
339
                ->addExtraClass('btn btn-primary primary'),
340
            FormAction::create("doDateReset")
341
                ->setTitle(_t(__CLASS__ . '.Clear', 'Clear'))
342
                ->addExtraClass('btn')
343
        );
344
345
        $form = Form::create($this, 'DateRangeForm', $fields, $actions);
346
        $form->loadDataFrom($this->request->getVars());
347
        $form->setFormMethod('get');
348
349
        // Add any locally stored form messages before returning
350
        if ($formMessage = $this->getRequest()->getSession()->get(self::TEMP_FORM_MESSAGE)) {
351
            $form->setMessage($formMessage, ValidationResult::TYPE_WARNING);
352
            $this->getRequest()->getSession()->clear(self::TEMP_FORM_MESSAGE);
353
        }
354
355
        return $form;
356
    }
357
358
    public function doDateFilter()
359
    {
360
        $params = $this->parseParams();
361
362
        // Build the link - keep the tag, but reset month, year and pagination.
363
        $link = HTTP::setGetVar('from', $params['from'], $this->AbsoluteLink(), '&');
364
        $link = HTTP::setGetVar('to', $params['to'], $link, '&');
365
        if (isset($params['tag'])) {
366
            $link = HTTP::setGetVar('tag', $params['tag'], $link, '&');
367
        }
368
369
        $this->redirect($link);
370
    }
371
372
    public function doDateReset()
373
    {
374
        $params = $this->parseParams(false);
375
376
        // Reset the link - only include the tag.
377
        $link = $this->AbsoluteLink();
378
        if (isset($params['tag'])) {
379
            $link = HTTP::setGetVar('tag', $params['tag'], $link, '&');
380
        }
381
382
        $this->redirect($link);
383
    }
384
385
    public function rss()
386
    {
387
        $rss = RSSFeed::create(
388
            $this->Updates()->sort('Created DESC')->limit(20),
389
            $this->Link('rss'),
390
            $this->getSubscriptionTitle()
391
        );
392
        return $rss->outputToBrowser();
393
    }
394
395
    public function atom()
396
    {
397
        $atom = CwpAtomFeed::create(
398
            $this->Updates()->sort('Created DESC')->limit(20),
399
            $this->Link('atom'),
400
            $this->getSubscriptionTitle()
401
        );
402
        return $atom->outputToBrowser();
403
    }
404
}
405