Completed
Push — master ( 1c7026...6247dd )
by Peter
14:53
created

IndexManager::index()   C

Complexity

Conditions 9
Paths 17

Size

Total Lines 65
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 10.2655

Importance

Changes 5
Bugs 2 Features 0
Metric Value
dl 0
loc 65
ccs 21
cts 28
cp 0.75
rs 6.4766
c 5
b 2
f 0
cc 9
eloc 33
nc 17
nop 0
crap 10.2655

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 https://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\ExceptionDecorator;
22
use Maslosoft\Manganel\Helpers\RecursiveFilter;
23
use Maslosoft\Manganel\Helpers\TypeNamer;
24
use Maslosoft\Manganel\Meta\ManganelMeta;
25
use UnexpectedValueException;
26
27
/**
28
 * IndexMangager
29
 *
30
 * @author Piotr Maselkowski <pmaselkowski at gmail.com>
31
 */
32
class IndexManager
33
{
34
35
	/**
36
	 * Manganel instance
37
	 * @var Manganel
38
	 */
39
	private $manganel = null;
40
41
	/**
42
	 * Model meta data
43
	 * @var ManganelMeta
44
	 */
45
	private $meta = null;
46
47
	/**
48
	 * Annotated model
49
	 * @var AnnotatedInterface
50
	 */
51
	private $model;
52
53
	/**
54
	 * Whether model is indexable
55
	 * @var bool
56
	 */
57
	private $isIndexable = false;
58
59 85
	public function __construct($model)
60
	{
61 85
		$this->model = $model;
62 85
		$this->meta = ManganelMeta::create($this->model);
63 85
		if (!empty($this->meta->type()->indexId) && false !== $this->meta->type()->indexId)
64
		{
65 83
			$this->isIndexable = true;
66
		}
67 85
		if ($this->isIndexable)
68
		{
69 83
			if (!isset($this->model->_id))
70
			{
71
				throw new ManganelException(sprintf('Property `_id` is not set in model `%s`, this is required by Manganel', get_class($this->model)));
72
			}
73 83
			$this->manganel = Manganel::create($this->model);
74
		}
75 85
	}
76
77 85
	public function index()
78
	{
79 85
		if (!$this->isIndexable)
80
		{
81 3
			return;
82
		}
83
		// NOTE: Transformer must ensure that _id is string, not MongoId
84 83
		$body = SearchArray::fromModel($this->model);
85 83
		if (array_key_exists('_id', $body))
86
		{
87
			$config = Mangan::fromModel($this->model)->sanitizersMap;
88
			if (!array_key_exists(SearchArray::class, $config))
89
			{
90
				throw new UnexpectedValueException(sprintf('Mangan is not properly configured for Manganel. Signals must be generated or add configuration manually from `%s::getDefault()`', ConfigManager::class));
91
			}
92
			else
93
			{
94
				throw new UnexpectedValueException(sprintf('Cannot index `%s`, as it contains _id field. Either use MongoObjectId sanitizer on it, or rename.', get_class($this->model)));
95
			}
96
		}
97
98
		// Create proper elastic search request array
99
		$params = [
100 83
			'body' => RecursiveFilter::mongoIdToString($body),
101
		];
102
		try
103
		{
104 83
			$fullParams = $this->getParams($params);
105
			// Need to check if exists, or update will fail
106
			$existsParams = [
107 83
				'index' => $fullParams['index'],
108 83
				'type' => $fullParams['type'],
109 83
				'id' => $fullParams['id']
110
			];
111 83
			$exists = $this->getClient()->exists($existsParams);
112
113 83
			if (!$exists)
114
			{
115 83
				$result = $this->getClient()->index($fullParams);
116
			}
117
			else
118
			{
119 13
				$updateParams = $fullParams;
120 13
				$updateParams['body'] = [
121 13
					'doc' => $fullParams['body']
122
				];
123 13
				$result = $this->getClient()->update($updateParams);
124
			}
125 83
			if (array_key_exists('result', $result) && $result['result'] === 'updated')
126
			{
127
				// For ES 5
128 3
				return true;
129
			}
130 83
			elseif (is_array($result))
131
			{
132
				// For earlier ES
133 83
				return true;
134
			}
135
		}
136
		catch (BadRequest400Exception $e)
137
		{
138
			throw ExceptionDecorator::getDecorated($this->manganel, $e, $params);
139
		}
140
		return false;
141
	}
142
143 5
	public function delete()
144
	{
145 5
		if (!$this->isIndexable)
146
		{
147
			return;
148
		}
149 5
		$this->getClient()->delete($this->getParams());
150 5
	}
151
152 28
	public function get($id = null)
153
	{
154 28
		if (!$this->isIndexable)
155
		{
156
			return;
157
		}
158 28
		$params = $id ? ['id' => (string) $id] : [];
159 28
		$data = $this->getClient()->get($this->getParams($params))['_source'];
160 28
		return SearchArray::toModel($data);
161
	}
162
163
	/**
164
	 * Get client
165
	 * @return Client
166
	 */
167 83
	public function getClient()
168
	{
169 83
		return $this->manganel->getClient();
170
	}
171
172 83
	private function getParams($params = [])
173
	{
174
		// Check refresh option
175 83
		if ($this->manganel->refresh instanceof Closure)
176
		{
177
			$func = $this->manganel->refresh;
178
			$refresh = (bool) $func($this->model);
179
		}
180
		else
181
		{
182 83
			$refresh = $this->manganel->refresh;
183
		}
184
		$result = [
185 83
			'index' => strtolower($this->manganel->index),
186 83
			'type' => TypeNamer::nameType($this->model),
187 83
			'id' => (string) $this->model->_id,
188 83
			'refresh' => $refresh
189
		];
190 83
		return array_merge($result, $params);
191
	}
192
193
}
194