Completed
Pull Request — master (#22)
by Sergey
15:20 queued 20s
created

ElasticsearchRepository   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 109
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 10

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 10
dl 0
loc 109
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A instantiate() 0 8 2
A find() 0 20 2
A all() 0 21 3
A fill() 0 6 1
A insert() 0 13 1
A update() 0 13 1
A delete() 0 12 1
1
<?php
2
3
namespace Isswp101\Persimmon\Repository;
4
5
use Elasticsearch\Client;
6
use Elasticsearch\Common\Exceptions\Missing404Exception;
7
use Isswp101\Persimmon\Collection\ElasticsearchCollection;
8
use Isswp101\Persimmon\Collection\ICollection;
9
use Isswp101\Persimmon\CollectionParser\ElasticsearchCollectionParser;
10
use Isswp101\Persimmon\Contracts\Storable;
11
use Isswp101\Persimmon\Exceptions\ClassTypeErrorException;
12
use Isswp101\Persimmon\Exceptions\ModelNotFoundException;
13
use Isswp101\Persimmon\Model\IElasticsearchModel;
14
use Isswp101\Persimmon\QueryBuilder\IQueryBuilder;
15
use Isswp101\Persimmon\Relationship\RelationshipKey;
16
use Isswp101\Persimmon\Response\ElasticsearchCollectionResponse;
17
use Isswp101\Persimmon\Response\ElasticsearchItemResponse;
18
19
class ElasticsearchRepository implements IRepository
20
{
21
    private $client;
22
23
    public function __construct(Client $client)
24
    {
25
        $this->client = $client;
26
    }
27
28
    public function instantiate(string $class): Storable
29
    {
30
        $instance = new $class;
31
        if (!$instance instanceof IElasticsearchModel) {
32
            throw new ClassTypeErrorException(IElasticsearchModel::class);
33
        }
34
        return $instance;
35
    }
36
37
    protected function fill(Storable $model, ElasticsearchItemResponse $response)
38
    {
39
        $relationshipKey = new RelationshipKey($response->id(), $response->parent());
40
        $model->setPrimaryKey($relationshipKey->build());
41
        $model->fill($response->source());
42
    }
43
44
    public function find(string $id, string $class, array $columns = []): ?Storable
45
    {
46
        $model = $this->instantiate($class);
47
        $relationshipKey = RelationshipKey::parse($id);
48
        $collection = new ElasticsearchCollectionParser($model->getCollection());
49
        $params = [
50
            'index' => $collection->getIndex(),
51
            'type' => $collection->getType(),
52
            'id' => $relationshipKey->getId(),
53
            'parent' => $relationshipKey->getParentId(),
54
            '_source' => $columns
55
        ];
56
        try {
57
            $response = new ElasticsearchItemResponse($this->client->get($params));
0 ignored issues
show
Documentation introduced by
$this->client->get($params) is of type callable, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
58
        } catch (Missing404Exception $e) {
59
            throw new ModelNotFoundException($class, $id);
60
        }
61
        $this->fill($model, $response);
62
        return $model;
63
    }
64
65
    public function all(IQueryBuilder $query, string $class, callable $callback = null): ICollection
66
    {
67
        $model = $this->instantiate($class);
68
        $collection = new ElasticsearchCollectionParser($model->getCollection());
69
        $params = [
70
            'index' => $collection->getIndex(),
71
            'type' => $collection->getType(),
72
            'body' => $query->build()
73
        ];
74
        $response = new ElasticsearchCollectionResponse($this->client->search($params));
0 ignored issues
show
Documentation introduced by
$this->client->search($params) is of type callable, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
75
        $models = new ElasticsearchCollection([], $response);
76
        foreach ($response->hits() as $hit) {
77
            $model = $this->instantiate($class);
78
            $this->fill($model, new ElasticsearchItemResponse($hit));
79
            if ($callback != null) {
80
                $callback($model);
81
            }
82
            $models->put($model->getPrimaryKey(), $model);
83
        }
84
        return $models;
85
    }
86
87
    public function insert(Storable $model): void
88
    {
89
        $relationshipKey = RelationshipKey::parse($model->getPrimaryKey());
90
        $collection = new ElasticsearchCollectionParser($model->getCollection());
91
        $params = [
92
            'index' => $collection->getIndex(),
93
            'type' => $collection->getType(),
94
            'id' => $relationshipKey->getId(),
95
            'parent' => $relationshipKey->getParentId(),
96
            'body' => $model->toArray()
97
        ];
98
        $this->client->index($params);
99
    }
100
101
    public function update(Storable $model): void
102
    {
103
        $relationshipKey = RelationshipKey::parse($model->getPrimaryKey());
104
        $collection = new ElasticsearchCollectionParser($model->getCollection());
105
        $params = [
106
            'index' => $collection->getIndex(),
107
            'type' => $collection->getType(),
108
            'id' => $relationshipKey->getId(),
109
            'parent' => $relationshipKey->getParentId(),
110
            'body' => $model->toArray()
111
        ];
112
        $this->client->index($params);
113
    }
114
115
    public function delete(Storable $model): void
116
    {
117
        $relationshipKey = RelationshipKey::parse($model->getPrimaryKey());
118
        $collection = new ElasticsearchCollectionParser($model->getCollection());
119
        $params = [
120
            'index' => $collection->getIndex(),
121
            'type' => $collection->getType(),
122
            'id' => $relationshipKey->getId(),
123
            'parent' => $relationshipKey->getParentId()
124
        ];
125
        $this->client->delete($params);
126
    }
127
}