| 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
Bug
introduced
by
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 |