Passed
Pull Request — master (#206)
by Loz
04:58
created

convertFilterToCriteria()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3.072

Importance

Changes 0
Metric Value
cc 3
eloc 4
c 0
b 0
f 0
nc 3
nop 2
dl 0
loc 8
ccs 4
cts 5
cp 0.8
crap 3.072
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
     *
39
     * @param string $field
40
     * @param mixed $value
41
     * @return Criteria
42
     */
43 1
    protected function convertFilterToCriteria(string $field, $value): Criteria
44
    {
45 1
        if ($value instanceof Criteria) {
46
            return $value;
47
        }
48
49 1
        $value = is_array($value) ? $value : [$value];
50 1
        return Criteria::where($field)->in($value);
51
    }
52
53
    /**
54
     * Create filter queries
55
     */
56 7
    protected function buildFilters(): void
57
    {
58 7
        $filters = $this->query->getFilter();
59 7
        foreach ($filters as $field => $value) {
60 1
            $criteria = $this->convertFilterToCriteria($field, $value);
61 1
            $this->clientQuery->createFilterQuery('filter-' . $field)
62 1
                ->setQuery($criteria->getQuery());
63
        }
64 7
    }
65
66
    /**
67
     * Add filtering on canView
68
     */
69 7
    protected function buildViewFilter(): void
70
    {
71
        // Filter by what the user is allowed to see
72 7
        $viewIDs = ['null']; // null is always an option as that means publicly visible
73 7
        $member = Security::getCurrentUser();
74 7
        if ($member && $member->exists()) {
75
            // Member is logged in, thus allowed to see these
76 7
            $viewIDs[] = 'LoggedIn';
77
78
            /** @var DataList|Group[] $groups */
79 7
            $groups = Security::getCurrentUser()->Groups();
80 7
            if ($groups->count()) {
81 6
                $viewIDs = array_merge($viewIDs, $groups->column('Code'));
82
            }
83
        }
84
        /** Add canView criteria. These are based on {@link DataObjectExtension::ViewStatus()} */
85 7
        $query = Criteria::where('ViewStatus')->in($viewIDs);
86
87 7
        $this->clientQuery->createFilterQuery('ViewStatus')
88 7
            ->setQuery($query->getQuery());
89 7
    }
90
91
    /**
92
     * Add filtered queries based on class hierarchy
93
     * We only need the class itself, since the hierarchy will take care of the rest
94
     */
95 7
    protected function buildClassFilter(): void
96
    {
97 7
        if (count($this->query->getClasses())) {
98 1
            $classes = $this->query->getClasses();
99 1
            $criteria = Criteria::where('ClassHierarchy')->in($classes);
100 1
            $this->clientQuery->createFilterQuery('classes')
101 1
                ->setQuery($criteria->getQuery());
102
        }
103 7
    }
104
105
    /**
106
     * Remove items to exclude
107
     */
108 7
    protected function buildExcludes(): void
109
    {
110 7
        $filters = $this->query->getExclude();
111 7
        foreach ($filters as $field => $value) {
112 1
            $criteria = $this->convertFilterToCriteria($field, $value);
113 1
            $criteria = $criteria->not(); // Negate the filter as we're excluding
114 1
            $this->clientQuery->createFilterQuery('exclude-' . $field)
115 1
                ->setQuery($criteria->getQuery());
116
        }
117 7
    }
118
}
119