Issues (15)

src/Models/BaseElasticsearchModel.php (1 issue)

Labels
Severity
1
<?php
2
3
namespace Isswp101\Persimmon\Models;
4
5
use Elasticsearch\ClientBuilder;
6
use Isswp101\Persimmon\Concerns\Attributable;
7
use Isswp101\Persimmon\Concerns\Elasticsearchable;
8
use Isswp101\Persimmon\Concerns\Eventable;
9
use Isswp101\Persimmon\Concerns\Existable;
10
use Isswp101\Persimmon\Concerns\Timestampable;
11
use Isswp101\Persimmon\Contracts\Arrayable;
12
use Isswp101\Persimmon\Contracts\ElasticsearchModelContract;
13
use Isswp101\Persimmon\Contracts\Persistencable;
14
use Isswp101\Persimmon\Contracts\PersistenceContract;
15
use Isswp101\Persimmon\DTO\Id;
16
use Isswp101\Persimmon\DTO\Path;
17
use Isswp101\Persimmon\Exceptions\ModelNotFoundException;
18
use Isswp101\Persimmon\Persistence\Persistence;
19
use Stringable;
20
21
/**
22
 * @property int|string|null id
23
 * @property string created_at
24
 * @property string updated_at
25
 */
26
abstract class BaseElasticsearchModel implements ElasticsearchModelContract, Persistencable, Arrayable, Stringable
27
{
28
    use Elasticsearchable, Timestampable, Eventable, Existable, Attributable;
29
30
    private PersistenceContract $persistence;
31
32
    protected int $perRequest = 50;
33
34
    public function __construct(array $attributes = [])
35
    {
36
        $this->fill($attributes);
37
38
        $this->persistence = $this->createPersistence();
39
    }
40
41
    public function createPersistence(): PersistenceContract
42
    {
43
        $client = ClientBuilder::create()->build();
44
45
        return new Persistence($client);
46
    }
47
48
    public function getId(): int|string|null
49
    {
50
        return $this->id;
51
    }
52
53
    private function persist(Path $path, array $keys): Id
54
    {
55
        if ($this->exists && $keys) {
56
            $keys = $this->timestamps ? array_merge($keys, ['created_at', 'updated_at']) : $keys;
57
            return $this->persistence->update($path, $this->toArray($keys));
58
        }
59
        return $this->persistence->create($path, $this->toArray($keys));
60
    }
61
62
    public function save(array $columns = []): void
63
    {
64
        if (!$this->saving()) {
65
            return;
66
        }
67
68
        $path = new Path($this->index, $this->type, new Id($this->id));
69
70
        $this->touch($this->exists);
71
72
        $this->id = $this->persist($path, $columns)->value();
73
74
        $this->exists = true;
75
76
        $this->saved();
77
    }
78
79
    public function delete(): void
80
    {
81
        if (!$this->deleting()) {
82
            return;
83
        }
84
85
        $path = new Path($this->index, $this->type, new Id($this->id));
86
87
        $this->persistence->delete($path);
88
89
        $this->exists = false;
90
91
        $this->deleted();
92
    }
93
94
    public static function create(array $attributes): static
95
    {
96
        $model = new static($attributes);
97
98
        $model->save();
99
100
        return $model;
101
    }
102
103
    public static function find(int|string $id, array $columns = []): static|null
0 ignored issues
show
A parse error occurred: Syntax error, unexpected '|', expecting '{' or ';' on line 103 at column 76
Loading history...
104
    {
105
        $model = new static();
106
107
        $path = new Path($model->getIndex(), $model->getType(), new Id($id));
108
109
        $attributes = $model->persistence->find($path, $columns);
110
111
        if (!$attributes) {
112
            return null;
113
        }
114
115
        $model->fill($attributes);
116
117
        $model->id = $id;
118
119
        $model->exists = true;
120
121
        return $model;
122
    }
123
124
    public static function findOrFail(int|string $id, array $columns = []): static
125
    {
126
        return static::find($id, $columns) ?? throw new ModelNotFoundException();
127
    }
128
129
    public static function destroy(int|string $id): void
130
    {
131
        $model = new static();
132
133
        $model->id = $id;
134
135
        $model->delete();
136
    }
137
138
    public static function search(array $query = []): array
139
    {
140
        $model = new static();
141
142
        if (!$model->searching()) {
143
            return [];
144
        }
145
146
        $path = new Path($model->index, $model->type, Id::undefined());
147
148
        $response = $model->persistence->search($path, $query);
149
150
        $models = [];
151
        foreach ($response->getItems() as $attributes) {
152
            $models[] = new static($attributes);
153
        }
154
155
        $model->searched($response);
156
157
        return $models;
158
    }
159
160
    public static function first(array $query): static|null
161
    {
162
        $query['size'] = 1;
163
164
        $items = static::search($query);
165
166
        return $items[0] ?? null;
167
    }
168
169
    public static function firstOrFail(array $query): static
170
    {
171
        return static::first($query) ?? throw new ModelNotFoundException();
172
    }
173
174
    public static function all(array $query = []): array
175
    {
176
        $items = [];
177
178
        $model = new static();
179
180
        $query['from'] = 0;
181
        $query['size'] = $model->perRequest;
182
        $itemsPerRequest = static::search($query);
183
        $items = array_merge($items, $itemsPerRequest);
184
185
        while (count($itemsPerRequest) == $model->perRequest) {
186
            $query['from'] += $model->perRequest;
187
            $itemsPerRequest = static::search($query);
188
            $items = array_merge($items, $itemsPerRequest);
189
        }
190
191
        return $items;
192
    }
193
}
194