QueryComponentFilterTrait   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 93
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 33
dl 0
loc 93
ccs 38
cts 38
cp 1
rs 10
c 0
b 0
f 0
wmc 12

5 Methods

Rating   Name   Duplication   Size   Complexity  
A buildCriteriaFilter() 0 9 2
A buildClassFilter() 0 7 2
A buildFilters() 0 7 2
A buildExcludes() 0 8 2
A buildViewFilter() 0 20 4
1
<?php
2
/**
3
 * Trait QueryComponentFilterTrait|Firesphere\SolrSearch\Traits\QueryComponentFilterTrait Trait to set Filtering on
4
 * fields for the {@link \Firesphere\SolrSearch\Factories\QueryComponentFactory}
5
 *
6
 * @package Firesphere\Solr\Search
7
 * @author Simon `Firesphere` Erkelens; Marco `Sheepy` Hermo
8
 * @copyright Copyright (c) 2018 - now() Firesphere & Sheepy
9
 */
10
11
namespace Firesphere\SolrSearch\Traits;
12
13
use Firesphere\SolrSearch\Queries\BaseQuery;
14
use Minimalcode\Search\Criteria;
15
use SilverStripe\ORM\DataList;
16
use SilverStripe\Security\Group;
17
use SilverStripe\Security\Security;
18
use Solarium\QueryType\Select\Query\Query;
19
20
/**
21
 * Trait QueryComponentFilterTrait
22
 *
23
 * Methods for creating the filters on query time.
24
 *
25
 * @package Firesphere\Solr\Search
26
 */
27
trait QueryComponentFilterTrait
28
{
29
    /**
30
     * @var BaseQuery Base query that's about to be executed
31
     */
32
    protected $query;
33
    /**
34
     * @var Query Solarium query
35
     */
36
    protected $clientQuery;
37
38
    /**
39
     * Create filter queries
40
     */
41 9
    protected function buildFilters(): void
42
    {
43 9
        $filters = $this->query->getFilter();
44 9
        foreach ($filters as $field => $value) {
45 3
            $criteria = $this->buildCriteriaFilter($field, $value);
46 3
            $this->clientQuery->createFilterQuery('filter-' . $field)
47 3
                ->setQuery($criteria->getQuery());
48
        }
49 9
    }
50
51
    /**
52
     * Convert a field/value filter pair to a Criteria object that can build part of a Solr query.
53
     * If a Criteria object is passed as the value, it will be returned unmodified.
54
     *
55
     * @param string $field
56
     * @param mixed $value
57
     * @return Criteria
58
     */
59 4
    protected function buildCriteriaFilter(string $field, $value): Criteria
60
    {
61 4
        if ($value instanceof Criteria) {
62 2
            return $value;
63
        }
64
65 3
        $value = (array)$value;
66
67 3
        return Criteria::where($field)->in($value);
68
    }
69
70
    /**
71
     * Add filtering on canView
72
     */
73 9
    protected function buildViewFilter(): void
74
    {
75
        // Filter by what the user is allowed to see
76 9
        $viewIDs = ['null']; // null is always an option as that means publicly visible
77 9
        $member = Security::getCurrentUser();
78 9
        if ($member && $member->exists()) {
79
            // Member is logged in, thus allowed to see these
80 9
            $viewIDs[] = 'LoggedIn';
81
82
            /** @var DataList|Group[] $groups */
83 9
            $groups = Security::getCurrentUser()->Groups();
84 9
            if ($groups->count()) {
85 8
                $viewIDs = array_merge($viewIDs, $groups->column('Code'));
86
            }
87
        }
88
        /** Add canView criteria. These are based on {@link DataObjectExtension::ViewStatus()} */
89 9
        $query = Criteria::where('ViewStatus')->in($viewIDs);
90
91 9
        $this->clientQuery->createFilterQuery('ViewStatus')
92 9
            ->setQuery($query->getQuery());
93 9
    }
94
95
    /**
96
     * Add filtered queries based on class hierarchy
97
     * We only need the class itself, since the hierarchy will take care of the rest
98
     */
99 9
    protected function buildClassFilter(): void
100
    {
101 9
        if (count($this->query->getClasses())) {
102 1
            $classes = $this->query->getClasses();
103 1
            $criteria = Criteria::where('ClassHierarchy')->in($classes);
104 1
            $this->clientQuery->createFilterQuery('classes')
105 1
                ->setQuery($criteria->getQuery());
106
        }
107 9
    }
108
109
    /**
110
     * Remove items to exclude
111
     */
112 9
    protected function buildExcludes(): void
113
    {
114 9
        $filters = $this->query->getExclude();
115 9
        foreach ($filters as $field => $value) {
116 3
            $criteria = $this->buildCriteriaFilter($field, $value);
117 3
            $criteria = $criteria->not(); // Negate the filter as we're excluding
118 3
            $this->clientQuery->createFilterQuery('exclude-' . $field)
119 3
                ->setQuery($criteria->getQuery());
120
        }
121 9
    }
122
}
123