Completed
Push — master ( bae495...167f56 )
by Peter
06:04
created

QueryBuilder::search()   C

Complexity

Conditions 7
Paths 6

Size

Total Lines 37
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 25.4573

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 37
ccs 5
cts 18
cp 0.2778
rs 6.7272
cc 7
eloc 19
nc 6
nop 2
crap 25.4573
1
<?php
2
3
/**
4
 * This software package is licensed under `AGPL, Commercial` license[s].
5
 *
6
 * @package maslosoft/manganel
7
 * @license AGPL, Commercial
8
 *
9
 * @copyright Copyright (c) Peter Maselkowski <[email protected]>
10
 * @link http://maslosoft.com/manganel/
11
 */
12
13
namespace Maslosoft\Manganel;
14
15
use Elasticsearch\Common\Exceptions\BadRequest400Exception;
16
use Elasticsearch\Common\Exceptions\Missing404Exception;
17
use Maslosoft\Addendum\Interfaces\AnnotatedInterface;
18
use Maslosoft\Mangan\Interfaces\CriteriaAwareInterface;
19
use Maslosoft\Mangan\Interfaces\CriteriaInterface;
20
use Maslosoft\Mangan\Traits\CriteriaAwareTrait;
21
use Maslosoft\Manganel\Helpers\QueryBuilderDecorator;
22
use Maslosoft\Manganel\Helpers\RecursiveFilter;
23
use Maslosoft\Manganel\Helpers\TypeNamer;
24
use Maslosoft\Manganel\Traits\UniqueModelsAwareTrait;
25
use UnexpectedValueException;
26
27
/**
28
 * QueryBuilder
29
 * @method SearchCriteria getCriteria()
30
 * @author Piotr Maselkowski <pmaselkowski at gmail.com>
31
 */
32
class QueryBuilder implements CriteriaAwareInterface
33
{
34
35
	use CriteriaAwareTrait,
36
	  UniqueModelsAwareTrait;
37
38
	/**
39
	 * Manganel instance
40
	 * @var Manganel
41
	 */
42
	private $manganel = null;
43
44 63
	public function __construct($model = null)
45
	{
46 63
		if (!empty($model))
47
		{
48 40
			$this->addModel($model);
49
		}
50 63
		if (!empty($model))
51
		{
52 40
			$this->manganel = Manganel::create($model);
53
		}
54
		else
55
		{
56 58
			$this->manganel = Manganel::fly();
57
		}
58 63
	}
59
60
	/**
61
	 * Add model or array of models
62
	 * @param AnnotatedInterface|AnnotatedInterface[] $model
63
	 * @return void
64
	 */
65 59
	public function add($model)
66
	{
67 59
		if (is_array($model))
68
		{
69 57
			foreach ($model as $m)
70
			{
71 57
				$this->addModel($m);
72
			}
73 57
			return;
74
		}
75 2
		$this->addModel($model);
76 2
	}
77
78
	/**
79
	 * Set criteria
80
	 * @param CriteriaInterface|array $criteria
81
	 * @return static
82
	 */
83 55
	public function setCriteria($criteria)
84
	{
85 55
		$this->criteria = $criteria;
86 55
		assert($criteria instanceof SearchCriteria);
87 55
		$this->add($criteria->getModels());
88 55
		return $this;
89
	}
90
91
	/**
92
	 *
93
	 * @param string $q
94
	 * @return int
95
	 */
96 46
	public function count($q = null)
97
	{
98 46
		$params = $this->getParams($q);
99
		try
100
		{
101 46
			$result = $this->manganel->getClient()->count($params);
102
		}
103
		catch (Missing404Exception $e)
104
		{
105
			$params = ['index' => strtolower($this->manganel->index)];
106
			$this->manganel->getClient()->indices()->create($params);
107
		}
108
		catch (BadRequest400Exception $e)
109
		{
110
			// Throw previous exception,
111
			// as it holds more meaningfull information
112
			$json = json_encode($params, JSON_PRETTY_PRINT);
113
			$prevMsg = '';
114
			$previous = $e->getPrevious();
115
			if(!empty($previous))
116
			{
117
				$prevMsg = '(' . $previous->getMessage() . ') ';
118
			}
119
			$message = sprintf("Exception %swhile querying `%s`: \n%s\n", $prevMsg, $this->manganel->indexId, $json);
120
			throw new BadRequest400Exception($message, 400, $e);
121
		}
122 46
		if (empty($result) && empty($result['count']))
123
		{
124
			return 0; // @codeCoverageIgnore
125
		}
126 46
		return $result['count'];
127
	}
128
129
	/**
130
	 * Get search results - hits from elasticsearch response.
131
	 * Optionally raw results might be obtained by reference via second param.
132
	 *
133
	 * @param string $q
134
	 * @param array $result
135
	 * @return array
136
	 */
137 54
	public function search($q = null, &$result = [])
138
	{
139 54
		$params = $this->getParams($q);
140
141
		try
142
		{
143 54
			$result = $this->manganel->getClient()->search($params);
144
		}
145
		catch (Missing404Exception $e)
146
		{
147
			$params = ['index' => strtolower($this->manganel->index)];
148
			$this->manganel->getClient()->indices()->create($params);
149
		}
150
		catch (BadRequest400Exception $e)
151
		{
152
			// Throw previous exception,
153
			// as it holds more meaningful information
154
			$json = json_encode($params, JSON_PRETTY_PRINT);
155
			$previous = $e->getPrevious();
0 ignored issues
show
Unused Code introduced by
$previous is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
156
157
			$prevMsg = '';
158
			$previous = $e->getPrevious();
159
			if(!empty($previous))
160
			{
161
				$prevMsg = '(' . $previous->getMessage() . ') ';
162
			}
163
164
			$message = sprintf("Exception %swhile querying `%s`: \n%s\n", $prevMsg, $this->manganel->indexId, $json);
165
			throw new BadRequest400Exception($message, 400, $e);
166
		}
167
168 54
		if (empty($result) && empty($result['hits']) && empty($result['hits']['hits']))
169
		{
170
			return [];
171
		}
172 54
		return $result['hits']['hits'];
173
	}
174
175 63
	public function getParams($q = null)
176
	{
177 63
		$body = [];
178
		// Try to get query from criteria if empty
179 63
		$criteria = $this->getCriteria();
180 63
		if (!$criteria instanceof SearchCriteria && $criteria instanceof CriteriaInterface)
181
		{
182
			$criteria = new SearchCriteria($criteria);
183
		}
184 63
		if (empty($criteria))
185
		{
186 8
			$criteria = new SearchCriteria;
187
		}
188 63
		if (!empty($q))
189
		{
190 37
			$criteria->search($q);
191
		}
192
193 63
		$criteria->setModels($this->getModels());
194
195 63
		$decorator = new QueryBuilderDecorator($this->manganel);
196 63
		$decorator->setModels($this->getModels());
197 63
		$decorator->decorate($body, $criteria);
198 63
		$models = $this->getModels();
199 63
		if (empty($models))
200
		{
201
			$type = '_all';
202
		}
203
		else
204
		{
205 63
			$types = [];
206 63
			foreach ($models as $model)
207
			{
208 63
				assert($model instanceof AnnotatedInterface, new UnexpectedValueException(sprintf('Expected `%s` instance, got `%s`', AnnotatedInterface::class, is_object($model) ? get_class($model) : gettype($model))));
209 63
				$types[] = TypeNamer::nameType($model);
210
			}
211 63
			$type = implode(',', array_unique($types));
212
		}
213
214
		$params = [
215 63
			'index' => strtolower($this->manganel->index),
216 63
			'type' => $type,
217 63
			'body' => $body
218
		];
219
//		return $params;
220 63
		return RecursiveFilter::mongoIdToString($params);
221
	}
222
223
}
224