Completed
Push — multimodel-dp ( 3c278b...934eb7 )
by Peter
08:07
created

IndexManager::index()   C

Complexity

Conditions 8
Paths 8

Size

Total Lines 49
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 16

Importance

Changes 0
Metric Value
dl 0
loc 49
ccs 10
cts 20
cp 0.5
rs 6.1403
c 0
b 0
f 0
cc 8
eloc 23
nc 8
nop 0
crap 16
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\Mangan;
20
use Maslosoft\Manganel\Exceptions\ManganelException;
21
use Maslosoft\Manganel\Helpers\RecursiveFilter;
22
use Maslosoft\Manganel\Helpers\TypeNamer;
23
use Maslosoft\Manganel\Meta\ManganelMeta;
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 45
	public function __construct($model)
59
	{
60 45
		$this->model = $model;
61 45
		$this->meta = ManganelMeta::create($this->model);
62 45
		if (!empty($this->meta->type()->indexId) && false !== $this->meta->type()->indexId)
63
		{
64 43
			$this->isIndexable = true;
65
		}
66 45
		if ($this->isIndexable)
67
		{
68 43
			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 43
			$this->manganel = Manganel::create($this->model);
73
		}
74 45
	}
75
76 45
	public function index()
77
	{
78 45
		if (!$this->isIndexable)
79
		{
80 3
			return;
81
		}
82
		// NOTE: Transformer must ensure that _id is string, not MongoId
83 43
		$body = SearchArray::fromModel($this->model);
84 43
		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
		// Create proper elastic search request array
98
		$params = [
99 43
			'body' => RecursiveFilter::mongoIdToString($body),
100
		];
101
		try
102
		{
103 43
			$result = $this->getClient()->index($this->getParams($params));
104 43
			if (array_key_exists('result', $result) && $result['result'] === 'updated')
105
			{
106
				// For ES 5
107
				return true;
108
			}
109 43
			elseif (is_array($result))
110
			{
111
				// For earlier ES
112 43
				return true;
113
			}
114
		}
115
		catch (BadRequest400Exception $e)
116
		{
117
			// Throw previous exception,
118
			// as it holds more meaningfull information
119
			$previous = $e->getPrevious();
120
			$message = sprintf('Exception while indexing `%s`@`%s`: %s', get_class($this->model), $this->manganel->indexId, $previous->getMessage());
121
			throw new BadRequest400Exception($message, 400, $e);
122
		}
123
		return false;
124
	}
125
126 4
	public function delete()
127
	{
128 4
		if (!$this->isIndexable)
129
		{
130
			return;
131
		}
132 4
		$this->getClient()->delete($this->getParams());
133 4
	}
134
135 5
	public function get($id = null)
136
	{
137 5
		if (!$this->isIndexable)
138
		{
139
			return;
140
		}
141 5
		$params = $id ? ['id' => (string) $id] : [];
142 5
		$data = $this->getClient()->get($this->getParams($params))['_source'];
143 5
		return SearchArray::toModel($data);
144
	}
145
146
	/**
147
	 * Get client
148
	 * @return Client
149
	 */
150 43
	public function getClient()
151
	{
152 43
		return $this->manganel->getClient();
153
	}
154
155 43
	private function getParams($params = [])
156
	{
157
		// Check refresh option
158 43
		if ($this->manganel->refresh instanceof Closure)
159
		{
160
			$func = $this->manganel->refresh;
161
			$refresh = (bool) $func($this->model);
162
		}
163
		else
164
		{
165 43
			$refresh = $this->manganel->refresh;
166
		}
167
		$result = [
168 43
			'index' => strtolower($this->manganel->index),
169 43
			'type' => TypeNamer::nameType($this->model),
170 43
			'id' => (string) $this->model->_id,
171 43
			'refresh' => $refresh
172
		];
173 43
		return array_merge($result, $params);
174
	}
175
176
}
177