Passed
Push — master ( df0bf3...ef307f )
by Hrvoje
01:32
created

DocumentManager::toDocuments()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 23
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 14
c 1
b 0
f 0
nc 4
nop 1
dl 0
loc 23
ccs 13
cts 13
cp 1
crap 4
rs 9.7998
1
<?php
2
3
namespace YucaDoo\ElasticSearcher\Managers;
4
5
use ElasticSearcher\Managers\DocumentsManager as WrappedManager;
6
use InvalidArgumentException;
7
use League\Fractal\Manager as FractalManager;
8
use League\Fractal\Resource\Item as FractalItem;
9
use League\Fractal\Resource\Collection as FractalCollection;
10
use League\Fractal\Serializer\ArraySerializer;
11
use League\Fractal\TransformerAbstract;
12
use Psr\Container\ContainerInterface;
13
14
class DocumentManager
15
{
16
    /** @var WrappedManager */
17
    protected $manager;
18
    /** @var FractalManager */
19
    protected $fractal;
20
    /** @var DocumentAdapter */
21
    protected $adapter;
22
    /** @var ContainerInterface */
23
    protected $transformerRegistry;
24
    /**
25
     * Type will be depracted in future versions.
26
     */
27
    protected const TYPE = '_doc';
28
29 33
    public function __construct(
30
        WrappedManager $manager,
31
        FractalManager $fractal,
32
        DocumentAdapter $adapter,
33
        ContainerInterface $transformerRegistry
34
    ) {
35 33
        $this->manager = $manager;
36 33
        $this->fractal = $fractal;
37 33
        $this->fractal->setSerializer(new ArraySerializer());
38 33
        $this->adapter = $adapter;
39 33
        $this->transformerRegistry = $transformerRegistry;
40 33
    }
41
42
    /**
43
     * Create Elasticsearch document for item.
44
     *
45
     * @param mixed $item
46
     * @return array Elasticsearch response.
47
     */
48 6
    public function create($item)
49
    {
50 6
        return $this->manager->index(
51 6
            $this->getIndexName($item),
52 6
            self::TYPE,
53 6
            $this->toDocument($item)
54
        );
55
    }
56
57
    /**
58
     * Create Elasticsearch documents for multiple item.
59
     *
60
     * @param \iterable $items.
61
     * @return array Empty array for empty items, Elasticsearch response otherwise.
62
     * @throws InvalidArgumentException When items belong to different indices.
63
     */
64 9
    public function bulkCreate($items)
65
    {
66
        // Get index name from first item.
67 9
        $indexName = null;
68 9
        foreach ($items as $item) {
69 6
            $indexName = $this->getIndexName($item);
70 6
            break;
71
        }
72
73 9
        if (!is_null($indexName)) {
74 6
            $documents = $this->toDocuments($items);
75
76 3
            return $this->manager->bulkIndex(
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->manager->bulkInde...self::TYPE, $documents) targeting ElasticSearcher\Managers...ntsManager::bulkIndex() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
77 3
                $indexName,
78 3
                self::TYPE,
79 1
                $documents
80
            );
81
        }
82 3
        return [];
83
    }
84
85
    /**
86
     * Delete Elasticsearch document for item.
87
     *
88
     * @param mixed $item
89
     * @return array Elasticsearch response.
90
     */
91 3
    public function delete($item)
92
    {
93 3
        return $this->manager->delete(
94 3
            $this->getIndexName($item),
95 3
            self::TYPE,
96 3
            $this->getId($item)
97
        );
98
    }
99
100
    /**
101
     * Update existing Elasticsearch document for item.
102
     *
103
     * @param mixed $item
104
     * @return array Elasticsearch response.
105
     */
106 6
    public function update($item)
107
    {
108 6
        return $this->manager->update(
109 6
            $this->getIndexName($item),
110 6
            self::TYPE,
111 6
            $this->getId($item),
112 6
            $this->toDocument($item)
113
        );
114
    }
115
116
    /**
117
     * Check if Elasticsearch document exists for item.
118
     *
119
     * @param mixed $item
120
     * @return bool True when document exists, false otherwise.
121
     */
122 12
    public function exists($item): bool
123
    {
124 12
        return $this->manager->exists(
125 12
            $this->getIndexName($item),
126 12
            self::TYPE,
127 12
            $this->getId($item)
128
        );
129
    }
130
131
    /**
132
     * Update Elasticsearch document for item. Create it if it doesn't exist.
133
     *
134
     * @param mixed $item
135
     * @return array Elasticsearch response.
136
     */
137 6
    public function updateOrCreate($item)
138
    {
139 6
        if ($this->exists($item)) {
140 3
            return $this->update($item);
141
        }
142 3
        return $this->create($item);
143
    }
144
145
    /**
146
     * Fetch Elasticsearch document.
147
     *
148
     * @param mixed $item Item for which document is fetched.
149
     * @return array Fetched Elasticsearch document.
150
     */
151 3
    public function get($item)
152
    {
153 3
        return $this->manager->get(
154 3
            $this->getIndexName($item),
155 3
            self::TYPE,
156 3
            $this->getId($item)
157
        );
158
    }
159
160
    /**
161
     * Get index name for item instance.
162
     * @param mixed $item
163
     * @return string Elasticsearch index name.
164
     */
165 30
    protected function getIndexName($item): string
166
    {
167 30
        return $this->adapter->getIndexName($item);
168
    }
169
170
    /**
171
     * Get id for item instance.
172
     * @param mixed $item
173
     * @return string|int Elasticsearch id.
174
     */
175 21
    protected function getId($item)
176
    {
177 21
        return $this->adapter->getId($item);
178
    }
179
180
    /**
181
     * Get transformer for creating documents in specified index.
182
     *
183
     * @param string $indexName Name of Elasticsearch index.
184
     * @return TransformerAbstract Fractal transformer.
185
     */
186 15
    protected function getTransformerByIndexName(string $indexName): TransformerAbstract
187
    {
188 15
        return $this->transformerRegistry->get($indexName);
189
    }
190
191
    /**
192
     * Convert item instance to document.
193
     *
194
     * @param mixed $item Item for which documents should be composed.
195
     * @return array Composed document.
196
     */
197 12
    protected function toDocument($item): array
198
    {
199 12
        $transformer = $this->getTransformerByIndexName($this->getIndexName($item));
200 12
        return $this->fractal
201 12
            ->createData(new FractalItem($item, $transformer))
202 12
            ->toArray();
203
    }
204
205
    /**
206
     * Convert multiple items to documents.
207
     * @param \iterable $items Items for which documents should be composed.
208
     * @return array Composed documents.
209
     * @throws InvalidArgumentException When items belong to different indices.
210
     */
211 6
    protected function toDocuments($items): array
212
    {
213 6
        $indexName = null;
214 6
        foreach ($items as $item) {
215 6
            if (is_null($indexName)) {
216 6
                $indexName = $this->getIndexName($item);
217
            } else {
218
                // All items should belong to the same index
219 6
                $currentIndexName = $this->getIndexName($item);
220 6
                if ($indexName != $currentIndexName) {
221 3
                    throw new InvalidArgumentException(
222
                        'All items have to belong to same index.
223 3
	                    Found ' . $indexName . ' and ' . $currentIndexName
224
                    );
225
                }
226
            }
227
        }
228
229
        // The ArraySerializer causes the documents to be wrapped.
230 3
        $wrappedDocuments = $this->fractal
231 3
            ->createData(new FractalCollection($items, $this->getTransformerByIndexName($indexName)))
232 3
            ->toArray();
233 3
        return $wrappedDocuments['data'];
234
    }
235
}
236