Completed
Push — master ( 0df30f...70807f )
by Peter
03:53
created

IndexManager::index()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 48
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 7.5435

Importance

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