Passed
Pull Request — develop (#82)
by Csaba
02:33
created

Finder::configQuery()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 8
c 0
b 0
f 0
ccs 0
cts 7
cp 0
rs 9.4285
cc 1
eloc 6
nc 1
nop 0
crap 2
1
<?php
2
namespace Fathomminds\Rest\Database\MongoDB;
3
4
use Fathomminds\Rest\Exceptions\RestException;
5
use Fathomminds\Rest\Database\Finder as BaseFinder;
6
use MongoDB\Client;
7
8
class Finder extends BaseFinder
9
{
10
    private $filter;
11
    private $options;
12
    private $operatorMap = [
13
        'AND' => '$and',
14
        '&&' => '$and',
15
        'OR' => '$or',
16
        '||' => '$or',
17
        '==' => '$eq',
18
        '!=' => '$ne',
19
        '<' => '$lt',
20
        '>' => '$gt',
21
        '<=' => '$lte',
22
        '>=' => '$gte',
23
    ];
24
    public function __construct($client)
25
    {
26
        parent::__construct($client);
27
        $this->options = new FinderOptions;
28
    }
29
30
    protected function setLimit()
31
    {
32
        $this->options->limit = $this->queryConfiguration->limit;
33
    }
34
35
    protected function setOffset()
36
    {
37
        $this->options->skip = $this->queryConfiguration->offset;
38
    }
39
40
    protected function setOrderBy()
41
    {
42
        foreach ($this->queryConfiguration->orderBy as $orderBy) {
43
            $mongoSort = 1;
44
            switch (strtoupper(current($orderBy))) {
45
                case 'ASC':
46
                    $mongoSort = 1;
47
                    break;
48
                case 'DESC':
49
                    $mongoSort = -1;
50
                    break;
51
                default:
52
                    continue;
53
            }
54
            $this->options->sort[key($orderBy)] = $mongoSort;
55
        }
56
    }
57
58
    protected function setSelect()
59
    {
60
        if ($this->queryConfiguration->select !== '*' && is_array($this->queryConfiguration->select)) {
61
            /** @noinspection PhpWrongForeachArgumentTypeInspection */
62
            foreach ($this->queryConfiguration->select as $include) {
63
                $this->options->projection[$include] = 1;
64
            }
65
        }
66
    }
67
68
    protected function setWhere()
69
    {
70
        if (!empty($this->queryConfiguration->where)) {
71
            $this->filter = $this->parseWhere($this->queryConfiguration->where, $this->mainLogical);
72
            return;
73
        }
74
        $this->filter = [];
75
    }
76
77
    protected function parseWhere($conditions, $logical)
78
    {
79
        $subGroup = [];
80
        foreach ($conditions as $key => $condition) {
81
            switch (strtoupper($key)) {
82
                case 'AND':
83
                    $subGroup[] = $this->parseWhere($condition, 'AND');
84
                    break;
85
                case 'OR':
86
                    $subGroup[] = $this->parseWhere($condition, 'OR');
87
                    break;
88
                default:
89
                    list($fieldName, $operator, $value) = $condition;
90
                    $subGroup[] = [$fieldName => [$this->mapOperator($operator) => $value]];
91
            }
92
        }
93
        $currentGroup[$this->mapOperator($logical)] = $subGroup;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$currentGroup was never initialized. Although not strictly required by PHP, it is generally a good practice to add $currentGroup = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
94
        return $currentGroup;
95
    }
96
97
    protected function parseWhereGroup($condition, $logical) {
0 ignored issues
show
Unused Code introduced by
The parameter $condition is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $logical is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
98
99
    }
100
101
    protected function mapOperator($in)
102
    {
103
        if (!array_key_exists($in, $this->operatorMap)) {
104
            throw new RestException(
105
                'Invalid operator',
106
                [$in]
107
            );
108
        }
109
        return $this->operatorMap[$in];
110
    }
111
112
    protected function configQuery()
113
    {
114
        $this->setLimit();
115
        $this->setOffset();
116
        $this->setOrderBy();
117
        $this->setSelect();
118
        $this->setWhere();
119
    }
120
121
    public function get()
122
    {
123
        if (!($this->client instanceof Client)) {
124
            throw new RestException(
125
                'MongoDB Finder can be used with MongoDB Client only',
126
                ['type' => get_class($this->client)]
127
            );
128
        }
129
        $collection = $this->client
130
                ->selectDatabase($this->queryConfiguration->databaseName)
131
                ->selectCollection($this->queryConfiguration->from);
132
        $this->configQuery();
133
        $items = json_decode(
134
            json_encode(
135
                $collection->find(
136
                    $this->filter,
137
                    json_decode(json_encode($this->options), true)
138
                )->toArray()
139
            )
140
        );
141
        if (empty($items)) {
142
            $this->resultSet = [];
143
            return $this;
144
        }
145
        $this->resultSet = $items;
146
        return $this;
147
    }
148
149
    protected function createClient()
150
    {
151
        $this->client = new Client(Database::getUri(), Database::getUriOptions(), Database::getDriverOptions());
152
        return $this;
153
    }
154
}
155