Passed
Pull Request — master (#221)
by Ingo
03:53
created

ElementSiteTreeFilterSearch   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 99
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 99
rs 10
c 0
b 0
f 0
wmc 13

2 Methods

Rating   Name   Duplication   Size   Complexity  
D applyWithExtraTermFilters() 0 44 9
B applyDefaultFilters() 0 26 4
1
<?php
2
3
namespace DNADesign\Elemental\Controllers;
4
5
use DNADesign\Elemental\Extensions\ElementalPageExtension;
6
use SilverStripe\CMS\Controllers\CMSSiteTreeFilter_Search;
7
use SilverStripe\CMS\Model\SiteTree;
8
use SilverStripe\Forms\DateField;
9
use SilverStripe\ORM\ArrayList;
10
use SilverStripe\ORM\DataList;
11
12
class ElementSiteTreeFilterSearch extends CMSSiteTreeFilter_Search
13
{
14
    /**
15
     * @var array
16
     */
17
    private $extraTermFilters = [];
18
19
    /**
20
     * We can't use ORM filtering for PHP methods, so we'll perform our own PHP "search" and get a list of
21
     * matching SiteTree record IDs, then add that to the original ORM query.
22
     *
23
     * @param DataList $query Unfiltered query
24
     * @return DataList
25
     */
26
    protected function applyDefaultFilters($query)
27
    {
28
        // If not filtering by a Term then skip this altogether
29
        if (empty($this->params['Term'])) {
30
            return parent::applyDefaultFilters($query);
31
        }
32
33
        // Get an array of SiteTree record IDs that match the search term in nested element data
34
        /** @var ArrayList $siteTrees */
35
        $siteTrees = $query->filterByCallback(function (SiteTree $siteTree) {
36
            // Filter by elemental PHP
37
            if (!$siteTree->hasExtension(ElementalPageExtension::class)) {
38
                return false;
39
            }
40
41
            // Check whether the search term exists in the nested page content
42
            $pageContent = $siteTree->getElementsForSearch();
43
            return (bool) stripos($pageContent, $this->params['Term']) !== false;
44
        });
45
46
        if ($siteTrees->count()) {
47
            // Apply the list of IDs as an extra filter
48
            $this->extraTermFilters['ID:ExactMatch'] = $siteTrees->column('ID');
49
        }
50
51
        return $this->applyWithExtraTermFilters($query);
52
    }
53
54
    /**
55
     * Method is a copy of {@link CMSSiteTreeFilter::applyDefaultFilters} with one line added to the Term
56
     * filter array to merge in a custom array of "extra term filters", since we cannot modify the list
57
     * after the filters have been applied by the parent class.
58
     *
59
     * PLEASE NOTE: This method is likely to be removed in a future minor version of the module. Do not rely
60
     * on it.
61
     *
62
     * @internal
63
     *
64
     * @param DataList $query
65
     * @return DataList
66
     */
67
    private function applyWithExtraTermFilters($query)
68
    {
69
        $sng = SiteTree::singleton();
70
        foreach ($this->params as $name => $val) {
71
            if (empty($val)) {
72
                continue;
73
            }
74
75
            switch ($name) {
76
                case 'Term':
77
                    $query = $query->filterAny([
78
                        'URLSegment:PartialMatch' => $val,
79
                        'Title:PartialMatch' => $val,
80
                        'MenuTitle:PartialMatch' => $val,
81
                        'Content:PartialMatch' => $val
82
                        ] + $this->extraTermFilters); // NB: only modified line
83
                    break;
84
85
                case 'LastEditedFrom':
86
                    $fromDate = DateField::create(null, null, $val);
87
                    $query = $query->filter("LastEdited:GreaterThanOrEqual", $fromDate->dataValue().' 00:00:00');
88
                    break;
89
90
                case 'LastEditedTo':
91
                    $toDate = DateField::create(null, null, $val);
92
                    $query = $query->filter("LastEdited:LessThanOrEqual", $toDate->dataValue().' 23:59:59');
93
                    break;
94
95
                case 'ClassName':
96
                    if ($val != 'All') {
97
                        $query = $query->filter('ClassName', $val);
98
                    }
99
                    break;
100
101
                default:
102
                    $field = $sng->dbObject($name);
103
                    if ($field) {
104
                        $filter = $field->defaultSearchFilter();
105
                        $filter->setValue($val);
106
                        $query = $query->alterDataQuery([$filter, 'apply']);
107
                    }
108
            }
109
        }
110
        return $query;
111
    }
112
}
113