ElementSiteTreeFilterSearch   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 99
Duplicated Lines 0 %

Importance

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

2 Methods

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