Completed
Push — master ( aa2861...321c29 )
by Peter
06:19
created

QueryBuilder::count()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 4.7691

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 22
ccs 7
cts 11
cp 0.6364
rs 8.9197
c 1
b 0
f 0
cc 4
eloc 12
nc 3
nop 1
crap 4.7691
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 Maslosoft\Addendum\Interfaces\AnnotatedInterface;
17
use Maslosoft\Mangan\Interfaces\CriteriaAwareInterface;
18
use Maslosoft\Mangan\Interfaces\CriteriaInterface;
19
use Maslosoft\Mangan\Traits\CriteriaAwareTrait;
20
use Maslosoft\Manganel\Helpers\QueryBuilderDecorator;
21
use Maslosoft\Manganel\Helpers\RecursiveFilter;
22
use Maslosoft\Manganel\Helpers\TypeNamer;
23
use Maslosoft\Manganel\Traits\UniqueModelsAwareTrait;
24
use UnexpectedValueException;
25
26
/**
27
 * QueryBuilder
28
 * @method SearchCriteria getCriteria()
29
 * @author Piotr Maselkowski <pmaselkowski at gmail.com>
30
 */
31
class QueryBuilder implements CriteriaAwareInterface
32
{
33
34
	use CriteriaAwareTrait,
35
	  UniqueModelsAwareTrait;
36
37
	/**
38
	 * Manganel instance
39
	 * @var Manganel
40
	 */
41
	private $manganel = null;
42
43 36
	public function __construct($model = null)
44
	{
45 36
		if (!empty($model))
46 36
		{
47 15
			$this->addModel($model);
48 15
		}
49 36
		if (!empty($model))
50 36
		{
51 15
			$this->manganel = Manganel::create($model);
52 15
		}
53
		else
54
		{
55 32
			$this->manganel = Manganel::fly();
56
		}
57 36
	}
58
59
	/**
60
	 * Add model or array of models
61
	 * @param AnnotatedInterface|AnnotatedInterface[] $model
62
	 * @return void
63
	 */
64 32
	public function add($model)
65
	{
66 32
		if (is_array($model))
67 32
		{
68 30
			foreach ($model as $m)
69
			{
70 30
				$this->addModel($m);
71 30
			}
72 30
			return;
73
		}
74 2
		$this->addModel($model);
75 2
	}
76
77
	/**
78
	 * Set criteria
79
	 * @param CriteriaInterface|array $criteria
80
	 * @return static
81
	 */
82 30
	public function setCriteria($criteria)
83
	{
84 30
		$this->criteria = $criteria;
85 30
		assert($criteria instanceof SearchCriteria);
86 30
		$this->add($criteria->getModels());
87 30
		return $this;
88
	}
89
90
	/**
91
	 *
92
	 * @param string $q
93
	 * @return int
94
	 */
95 20
	public function count($q = null)
96
	{
97 20
		$params = $this->getParams($q);
98
		try
99
		{
100 20
			$result = $this->manganel->getClient()->count($params);
101
		}
102 20
		catch (BadRequest400Exception $e)
103
		{
104
			// Throw previous exception,
105
			// as it holds more meaningfull information
106
			$json = json_encode($params, JSON_PRETTY_PRINT);
107
			$previous = $e->getPrevious();
108
			$message = sprintf("Exception (%s) while querying `%s`: \n%s\n", $previous->getMessage(), $this->manganel->indexId, $json);
109
			throw new BadRequest400Exception($message, 400, $e);
110
		}
111 20
		if (empty($result) && empty($result['count']))
112 20
		{
113
			return 0; // @codeCoverageIgnore
114
		}
115 20
		return $result['count'];
116
	}
117
118
	/**
119
	 * Get search results
120
	 * @param string $q
121
	 * @return array
122
	 */
123 29
	public function search($q = null)
124
	{
125 29
		$params = $this->getParams($q);
126
127
		try
128
		{
129 29
			$result = $this->manganel->getClient()->search($params);
130
		}
131 29
		catch (BadRequest400Exception $e)
132
		{
133
			// Throw previous exception,
134
			// as it holds more meaningfull information
135
			$json = json_encode($params, JSON_PRETTY_PRINT);
136
			$previous = $e->getPrevious();
137
			$message = sprintf("Exception (%s) while querying `%s`: \n%s\n", $previous->getMessage(), $this->manganel->indexId, $json);
138
			throw new BadRequest400Exception($message, 400, $e);
139
		}
140
141 29
		if (empty($result) && empty($result['hits']) && empty($result['hits']['hits']))
142 29
		{
143
			return [];
144
		}
145 29
		return $result['hits']['hits'];
146
	}
147
148 36
	public function getParams($q = null)
149
	{
150 36
		$body = [];
151
		// Try to get query from criteria if empty
152 36
		$criteria = $this->getCriteria();
153 36
		if (!$criteria instanceof SearchCriteria && $criteria instanceof CriteriaInterface)
154 36
		{
155
			$criteria = new SearchCriteria($criteria);
156
		}
157 36
		if (empty($criteria))
158 36
		{
159 6
			$criteria = new SearchCriteria;
160 6
		}
161 36
		if (!empty($q))
162 36
		{
163 13
			$criteria->search($q);
164 13
		}
165
166 36
		$decorator = new QueryBuilderDecorator($this->manganel);
167 36
		$decorator->decorate($body, $criteria);
168 36
		$models = $this->getModels();
169 36
		if (empty($models))
170 36
		{
171
			$type = '_all';
172
		}
173
		else
174
		{
175 36
			$types = [];
176 36
			foreach ($models as $model)
177
			{
178 36
				assert($model instanceof AnnotatedInterface, new UnexpectedValueException(sprintf('Expected `%s` instance, got `%s`', AnnotatedInterface::class, is_object($model) ? get_class($model) : gettype($model))));
179 36
				$types[] = TypeNamer::nameType($model);
180 36
			}
181 36
			$type = implode(',', array_unique($types));
182
		}
183
184
		$params = [
185 36
			'index' => strtolower($this->manganel->index),
186 36
			'type' => $type,
187
			'body' => $body
188 36
		];
189
//		return $params;
190 36
		return RecursiveFilter::mongoIdToString($params);
191
	}
192
193
}
194