Completed
Push — multimodel-dp ( 745c1d...bcd65b )
by Peter
03:53
created

Manganel::init()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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