Passed
Pull Request — master (#206)
by Loz
05:22
created

QueryComponentFilterTrait::buildFilters()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 7
ccs 6
cts 6
cp 1
crap 2
rs 10
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\SolrSearch\Traits
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
 * @package Firesphere\SolrSearch\Traits
24
 */
25
trait QueryComponentFilterTrait
26
{
27
    /**
28
     * @var BaseQuery Base query that's about to be executed
29
     */
30
    protected $query;
31
    /**
32
     * @var Query Solarium query
33
     */
34
    protected $clientQuery;
35
36
    /**
37
     * Convert a field/value filter pair to a Criteria object that can build part of a Solr query.
38
     * If a Criteria object is passed as the value, it will be returned unmodified.
39
     *
40
     * @param string $field
41
     * @param mixed $value
42
     * @return Criteria
43
     */
44 1
    protected function buildCriteriaFilter(string $field, $value): Criteria
45
    {
46 1
        if ($value instanceof Criteria) {
47
            return $value;
48
        }
49
50 1
        $value = (array)$value;
51 1
        return Criteria::where($field)->in($value);
52
    }
53
54
    /**
55
     * Create filter queries
56
     */
57 7
    protected function buildFilters(): void
58
    {
59 7
        $filters = $this->query->getFilter();
60 7
        foreach ($filters as $field => $value) {
61 1
            $criteria = $this->buildCriteriaFilter($field, $value);
62 1
            $this->clientQuery->createFilterQuery('filter-' . $field)
63 1
                ->setQuery($criteria->getQuery());
64
        }
65 7
    }
66
67
    /**
68
     * Add filtering on canView
69
     */
70 7
    protected function buildViewFilter(): void
71
    {
72
        // Filter by what the user is allowed to see
73 7
        $viewIDs = ['null']; // null is always an option as that means publicly visible
74 7
        $member = Security::getCurrentUser();
75 7
        if ($member && $member->exists()) {
76
            // Member is logged in, thus allowed to see these
77 7
            $viewIDs[] = 'LoggedIn';
78
79
            /** @var DataList|Group[] $groups */
80 7
            $groups = Security::getCurrentUser()->Groups();
81 7
            if ($groups->count()) {
82 6
                $viewIDs = array_merge($viewIDs, $groups->column('Code'));
83
            }
84
        }
85
        /** Add canView criteria. These are based on {@link DataObjectExtension::ViewStatus()} */
86 7
        $query = Criteria::where('ViewStatus')->in($viewIDs);
87
88 7
        $this->clientQuery->createFilterQuery('ViewStatus')
89 7
            ->setQuery($query->getQuery());
90 7
    }
91
92
    /**
93
     * Add filtered queries based on class hierarchy
94
     * We only need the class itself, since the hierarchy will take care of the rest
95
     */
96 7
    protected function buildClassFilter(): void
97
    {
98 7
        if (count($this->query->getClasses())) {
99 1
            $classes = $this->query->getClasses();
100 1
            $criteria = Criteria::where('ClassHierarchy')->in($classes);
101 1
            $this->clientQuery->createFilterQuery('classes')
102 1
                ->setQuery($criteria->getQuery());
103
        }
104 7
    }
105
106
    /**
107
     * Remove items to exclude
108
     */
109 7
    protected function buildExcludes(): void
110
    {
111 7
        $filters = $this->query->getExclude();
112 7
        foreach ($filters as $field => $value) {
113 1
            $criteria = $this->buildCriteriaFilter($field, $value);
114 1
            $criteria = $criteria->not(); // Negate the filter as we're excluding
115 1
            $this->clientQuery->createFilterQuery('exclude-' . $field)
116 1
                ->setQuery($criteria->getQuery());
117
        }
118 7
    }
119
}
120