Query::includeFacetValues()   A
last analyzed

Complexity

Conditions 5
Paths 8

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 10
nc 8
nop 3
dl 0
loc 15
rs 9.6111
c 0
b 0
f 0
1
<?php
2
3
namespace Scriptotek\PrimoSearch;
4
5
use InvalidArgumentException;
6
7
class Query
8
{
9
    protected $data = [
10
        'q' => [],
11
        'qInclude' => [],
12
        'qExclude' => [],
13
        'multifacets' => [],
14
        'sort' => 'rank',
15
        'offset' => 0,
16
        'limit' => 10,
17
    ];
18
19
    public static function new()
20
    {
21
        return new static;
22
    }
23
24
    public function where($field, $op, $value)
25
    {
26
        $this->data['q'][] = new QueryPart($field, $op, $value);
27
        return $this;
28
    }
29
30
    public function orWhere($field, $op, $value)
31
    {
32
        if (!count($this->data['q'])) {
33
            throw new \Error('Cannot start query with OR');
34
        }
35
        $this->data['q'][count($this->data['q']) - 1]->setOperator('OR');
36
        $this->data['q'][] = new QueryPart($field, $op, $value);
37
        return $this;
38
    }
39
40
    public function not($field, $op, $value)
41
    {
42
        if (!count($this->data['q'])) {
43
            throw new \Error('Cannot start query with NOT');
44
        }
45
        $this->data['q'][count($this->data['q']) - 1]->setOperator('NOT');
46
        $this->data['q'][] = new QueryPart($field, $op, $value);
47
        return $this;
48
    }
49
50
    public function build()
51
    {
52
        if (!count($this->data['q'])) {
53
            throw new \Error('Query is empty');
54
        }
55
56
        $params = [];
57
        foreach ($this->data as $key => $val) {
58
            if (is_array($val)) {
59
                if (count($val)) {
60
                    $glue = ($key == 'q') ? ';' : '|,|';
61
                    $val = array_map(function ($part) {
62
                        return is_object($part) ? $part->build() : implode(',', $part);
63
                    }, $val);
64
                    $params[$key] = implode($glue, $val);
65
                }
66
            } else {
67
                $params[$key] = (string) $val;
68
            }
69
        }
70
71
        return $params;
72
    }
73
74
    /**
75
     * Filter results by including facet values.
76
     *
77
     * @param string $category        The facet type
78
     * @param string|array  $values   One or more facet values (string or array)
79
     * @param string $conjuction      The logical conjuction (AND or OR) to use between the facet values.
80
     */
81
    public function includeFacetValues($category, $values, $conjuction = 'OR')
82
    {
83
        if (!is_array($values)) {
84
            $values = [$values];
85
        }
86
        foreach ($values as $value) {
87
            if ($conjuction == 'OR') {
88
                $this->data['multifacets'][] = [$category, 'include', $value];
89
            } elseif ($conjuction == 'AND') {
90
                $this->data['qInclude'][] = [$category, 'exact', $value];
91
            } else {
92
                throw new InvalidArgumentException('Invalid operator: ' . $conjuction);
93
            }
94
        }
95
        return $this;
96
    }
97
98
    /**
99
     * Filter results by excluding facet values.
100
     *
101
     * @param string $category        The facet type
102
     * @param string|array  $values   One or more facet values (string or array)
103
     * @param string $conjuction      The logical conjuction (AND or OR) to use between the facet values.
104
     */
105
    public function excludeFacetValues($category, $values, $conjuction = 'OR')
106
    {
107
        if (!is_array($values)) {
108
            $values = [$values];
109
        }
110
        foreach ($values as $value) {
111
            if ($conjuction == 'OR') {
112
                $this->data['multifacets'][] = [$category, 'exclude', $value];
113
            } elseif ($conjuction == 'AND') {
114
                $this->data['qExclude'][] = [$category, 'exact', $value];
115
            } else {
116
                throw new InvalidArgumentException('Invalid operator: ' . $conjuction);
117
            }
118
        }
119
        return $this;
120
    }
121
122
    public function sort(string $value)
123
    {
124
        $this->data['sort'] = $value;
125
        return $this;
126
    }
127
128
    public function offset(int $value)
129
    {
130
        $this->data['offset'] = $value;
131
        return $this;
132
    }
133
134
    public function limit(int $value)
135
    {
136
        $this->data['limit'] = $value;
137
        return $this;
138
    }
139
}
140