Completed
Push — multimodel-dp ( bcd65b...3c278b )
by Peter
03:13
created

Manganel::getProfiler()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3.0416

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 12
ccs 5
cts 6
cp 0.8333
rs 9.4285
cc 3
eloc 6
nc 4
nop 0
crap 3.0416
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 Closure;
16
use Elasticsearch\Client;
17
use Elasticsearch\ClientBuilder;
18
use Maslosoft\Addendum\Interfaces\AnnotatedInterface;
19
use Maslosoft\EmbeDi\EmbeDi;
20
use Maslosoft\Mangan\Interfaces\ProfilerInterface;
21
use Maslosoft\Mangan\Profillers\NullProfiler;
22
use Maslosoft\Manganel\Decorators\QueryBuilder\ConditionDecorator;
23
use Maslosoft\Manganel\Decorators\QueryBuilder\ConditionsDecorator;
24
use Maslosoft\Manganel\Decorators\QueryBuilder\Operators\InDecorator;
25
use Maslosoft\Manganel\Decorators\QueryBuilder\Operators\SimpleTermDecorator;
26
use Maslosoft\Manganel\Decorators\QueryBuilder\ScrollDecorator;
27
use Maslosoft\Manganel\Decorators\QueryBuilder\SearchDecorator;
28
use Maslosoft\Manganel\Interfaces\ManganelAwareInterface;
29
use Maslosoft\Manganel\Meta\ManganelMeta;
30
31
/**
32
 * Manganel
33
 *
34
 * @author Piotr Maselkowski <pmaselkowski at gmail.com>
35
 */
36
class Manganel
37
{
38
39
	const DefaultIndexId = 'manganel';
40
41
	public $decorators = [
42
		SearchCriteria::class => [
43
			ConditionDecorator::class,
44
			ConditionsDecorator::class,
45
			ScrollDecorator::class,
46
			SearchDecorator::class,
47
			InDecorator::class,
48
			SimpleTermDecorator::class
49
		]
50
	];
51
	public $hosts = [
52
		'localhost:9200'
53
	];
54
	public $auth = null;
55
	public $username = '';
56
	public $password = '';
57
	public $params = [];
58
59
	/**
60
	 * TODO Enforce lowercase
61
	 */
62
	public $index = 'my_index';
63
	public $indexId = self::DefaultIndexId;
64
65
	/**
66
	 * Whether to use refresh option when indexing document.
67
	 * NOTE: Due to performance reasons, this should be set to `true` only when
68
	 * really necessary - so it can be also callback.
69
	 *
70
	 * Callback function signature:
71
	 * ```
72
	 * function(AnnotatedInterface $model)
73
	 * ```
74
	 * @var string|Closure
75
	 */
76
	public $refresh = false;
77
78
	/**
79
	 *
80
	 * @var Client
81
	 */
82
	private $client = null;
83
84
	/**
85
	 * Dependency injection container
86
	 * @var EmbeDi
87
	 */
88
	private $di = null;
89
90
	/**
91
	 * Instances of manganel
92
	 * @var Manganel[]
93
	 */
94
	private static $mnl = [];
95
96
	/**
97
	 * Hash map of class name to id. This is to reduce overhead of Mangan::fromModel()
98
	 * @var string[]
99
	 */
100
	private static $classToId = [];
101
102
	/**
103
	 * Profiler instance
104
	 * @var ProfilerInterface
105
	 */
106
	private $profiler = null;
107
108
	/**
109
	 * Class constructor
110
	 * @codeCoverageIgnore This is implicitly tested
111
	 * @param string $indexId
112
	 */
113
	public function __construct($indexId = self::DefaultIndexId)
114
	{
115
		if (empty($indexId))
116
		{
117
			$indexId = self::DefaultIndexId;
118
		}
119
		$this->indexId = $indexId;
120
		$this->di = new EmbeDi($this->indexId);
121
		$this->di->configure($this);
122
123
		if (empty(self::$mnl[$indexId]))
124
		{
125
			self::$mnl[$indexId] = $this;
126
		}
127
	}
128
129
	/**
130
	 * @codeCoverageIgnore This is implicitly tested
131
	 * @param AnnotatedInterface $model
132
	 * @return static
133
	 */
134
	public static function create(AnnotatedInterface $model)
135
	{
136
		$key = get_class($model);
137
		if (isset(self::$classToId[$key]))
138
		{
139
			$indexId = self::$classToId[$key];
140
		}
141
		else
142
		{
143
			$indexId = ManganelMeta::create($model)->type()->indexId;
144
			self::$classToId[$key] = $indexId;
145
		}
146
		return static::fly($indexId);
147
	}
148
149
	/**
150
	 * Get flyweight instance of Manganel component.
151
	 * Only one instance will be created for each `$indexId`.
152
	 *
153
	 * @codeCoverageIgnore This is implicitly tested
154
	 * @new
155
	 * @param string $indexId
156
	 * @return Manganel
157
	 */
158
	public static function fly($indexId = self::DefaultIndexId)
159
	{
160
		if (empty($indexId))
161
		{
162
			$indexId = self::DefaultIndexId;
163
		}
164
		if (empty(self::$mnl[$indexId]))
165
		{
166
			self::$mnl[$indexId] = new static($indexId);
167
		}
168
		return self::$mnl[$indexId];
169
	}
170
171
	/**
172
	 * @codeCoverageIgnore This is implicitly tested
173
	 */
174
	public function init()
175
	{
176
		$this->di->store($this);
177
	}
178
179
	/**
180
	 * Drop current index
181
	 * @return bool
182
	 */
183
	public function drop()
184
	{
185
		$params = [
186
			'index' => strtolower($this->index)
187
		];
188
		$result = $this->getClient()->indices()->delete($params);
189
		if (is_array($result) && array_key_exists('acknowledged', $result) && $result['acknowledged'])
190
		{
191
			return true;
192
		}
193
		return false;
194
	}
195
196
	/**
197
	 * @codeCoverageIgnore This is implicitly tested
198
	 * @return Client
199
	 */
200
	public function getClient()
201
	{
202
		if (null === $this->client)
203
		{
204
			$this->params['hosts'] = $this->hosts;
205
			$this->params['connectionParams']['auth'] = [
206
				$this->username,
207
				$this->password,
208
				$this->auth
209
			];
210
			$cb = ClientBuilder::create();
211
			$cb->setHosts($this->hosts);
212
			$this->client = $cb->build();
213
		}
214
		return $this->client;
215
	}
216
217
	/**
218
	 * Get profiler instance. This is guaranted, if not configured will return NullProfiller.
219
	 * @see NullProfiler
220
	 * @return ProfilerInterface
221
	 */
222 4
	public function getProfiler()
223
	{
224 4
		if (null === $this->profiler)
225
		{
226 1
			$this->profiler = new NullProfiler;
227
		}
228 4
		if ($this->profiler instanceof ManganelAwareInterface)
229
		{
230
			$this->profiler->setManganel($this);
231
		}
232 4
		return $this->profiler;
233
	}
234
235
	/**
236
	 * Set profiler instance
237
	 * @param ProfilerInterface $profiller
238
	 * @return static
239
	 */
240
	public function setProfiler(ProfilerInterface $profiller)
241
	{
242
		$this->profiler = $profiller;
243
		return $this;
244
	}
245
246
}
247