Completed
Push — master ( 6c8c8c...21048a )
by Peter
04:47
created

IndexManager::index()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 50
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 8.4648

Importance

Changes 0
Metric Value
dl 0
loc 50
ccs 13
cts 22
cp 0.5909
rs 8.6315
c 0
b 0
f 0
cc 6
eloc 23
nc 5
nop 0
crap 8.4648
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\Common\Exceptions\BadRequest400Exception;
18
use Maslosoft\Addendum\Interfaces\AnnotatedInterface;
19
use Maslosoft\Mangan\Helpers\CollectionNamer;
20
use Maslosoft\Mangan\Mangan;
21
use Maslosoft\Manganel\Exceptions\ManganelException;
22
use Maslosoft\Manganel\Meta\ManganelMeta;
23
use MongoId;
24
use UnexpectedValueException;
25
26
/**
27
 * IndexMangager
28
 *
29
 * @author Piotr Maselkowski <pmaselkowski at gmail.com>
30
 */
31
class IndexManager
32
{
33
34
	/**
35
	 * Manganel instance
36
	 * @var Manganel
37
	 */
38
	private $manganel = null;
39
40
	/**
41
	 * Model meta data
42
	 * @var ManganelMeta
43
	 */
44
	private $meta = null;
45
46
	/**
47
	 * Annotated model
48
	 * @var AnnotatedInterface
49
	 */
50
	private $model;
51
52
	/**
53
	 * Whether model is indexable
54
	 * @var bool
55
	 */
56
	private $isIndexable = false;
57
58 21
	public function __construct($model)
59
	{
60 21
		$this->model = $model;
61 21
		$this->meta = ManganelMeta::create($this->model);
62 21
		if (!empty($this->meta->type()->indexId) && false !== $this->meta->type()->indexId)
63
		{
64 19
			$this->isIndexable = true;
65
		}
66 21
		if ($this->isIndexable)
67
		{
68 19
			if (!isset($this->model->_id))
69
			{
70
				throw new ManganelException(sprintf('Property `_id` is not set in model `%s`, this is required by Manganel', get_class($this->model)));
71
			}
72 19
			$this->manganel = Manganel::create($this->model);
73
		}
74 21
	}
75
76 21
	public function index()
77
	{
78 21
		if (!$this->isIndexable)
79
		{
80 3
			return;
81
		}
82
		// NOTE: Transformer must ensure that _id is string, not MongoId
83 19
		$body = SearchArray::fromModel($this->model);
84 19
		if (array_key_exists('_id', $body))
85
		{
86
			$config = Mangan::fromModel($this->model)->sanitizersMap;
87
			if (!array_key_exists(SearchArray::class, $config))
88
			{
89
				throw new UnexpectedValueException(sprintf('Mangan is not properly configured for Manganel. Signals must be generated or add configuration manually from `%s::getDefault()`', ConfigManager::class));
90
			}
91
			else
92
			{
93
				throw new UnexpectedValueException(sprintf('Cannot index `%s`, as it contains _id field. Either use MongoObjectId sanitizer on it, or rename.', get_class($this->model)));
94
			}
95
		}
96
97
		// In some cases $value *might* still be mongoId type,
98
		// see https://github.com/Maslosoft/Addendum/issues/43
99 19
		$func = function($value)
100
		{
101 19
			if ($value instanceof MongoId)
102
			{
103
				return (string) $value;
104
			}
105 19
			return $value;
106 19
		};
107 19
		$filtered = filter_var($body, \FILTER_CALLBACK, ['options' => $func]);
108
109
		// Create proper elastic search request array
110
		$params = [
111 19
			'body' => $filtered,
112
		];
113
		try
114
		{
115 19
			$this->getClient()->index($this->getParams($params));
116
		}
117
		catch (BadRequest400Exception $e)
118
		{
119
			// Throw previous exception,
120
			// as it holds more meaningfull information
121
			$previous = $e->getPrevious();
122
			$message = sprintf('Exception while indexing `%s`@`%s`: %s', get_class($this->model), $this->manganel->indexId, $previous->getMessage());
123
			throw new BadRequest400Exception($message);
124
		}
125 19
	}
126
127 4
	public function delete()
128
	{
129 4
		if (!$this->isIndexable)
130
		{
131
			return;
132
		}
133 4
		$this->getClient()->delete($this->getParams());
134 4
	}
135
136 4
	public function get($id = null)
137
	{
138 4
		if (!$this->isIndexable)
139
		{
140
			return;
141
		}
142 4
		$params = $id ? ['id' => (string) $id] : [];
143 4
		$data = $this->getClient()->get($this->getParams($params))['_source'];
144 4
		return SearchArray::toModel($data);
145
	}
146
147
	/**
148
	 * Get client
149
	 * @return Client
150
	 */
151 19
	public function getClient()
152
	{
153 19
		return $this->manganel->getClient();
154
	}
155
156 19
	private function getParams($params = [])
157
	{
158
		// Check refresh option
159 19
		if ($this->manganel->refresh instanceof Closure)
160
		{
161
			$func = $this->manganel->refresh;
162
			$refresh = (bool) $func($this->model);
163
		}
164
		else
165
		{
166 19
			$refresh = $this->manganel->refresh;
167
		}
168
		$result = [
169 19
			'index' => strtolower($this->manganel->index),
170 19
			'type' => CollectionNamer::nameCollection($this->model),
171 19
			'id' => (string) $this->model->_id,
172 19
			'refresh' => $refresh
173
		];
174 19
		return array_merge($result, $params);
175
	}
176
177
}
178