-
-
Notifications
You must be signed in to change notification settings - Fork 625
Expand file tree
/
Copy pathAggregateStore.php
More file actions
119 lines (92 loc) · 2.79 KB
/
AggregateStore.php
File metadata and controls
119 lines (92 loc) · 2.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
<?php
namespace Statamic\Stache\Stores;
use Closure;
abstract class AggregateStore extends Store
{
protected $stores;
protected $childStoreCreator;
public function __construct()
{
$this->stores = collect();
}
public function store($key)
{
if (! $this->stores->has($key)) {
$this->stores->put($key, $this->createChildStore($key));
}
return $this->stores->get($key);
}
protected function createChildStore($key)
{
$store = $this->childStoreCreator
? call_user_func($this->childStoreCreator)
: app($this->childStore);
return $store
->setChildKey($key)
->setParent($this);
}
public function setChildStoreCreator(Closure $callback)
{
$this->childStoreCreator = $callback;
return $this;
}
public function stores()
{
return $this->stores;
}
public function childDirectory($child)
{
return $this->directory.$child->childKey();
}
public function getItems($keys)
{
$keys = collect($keys);
if ($keys->isEmpty()) {
return collect();
}
// Group keys by child store for batch fetching
$grouped = $keys->mapWithKeys(function ($key) {
[$store, $id] = explode('::', $key, 2);
return [$key => compact('store', 'id')];
})->groupBy('store');
// Batch fetch from each child store
$fetched = $grouped->flatMap(function ($items, $store) {
$ids = $items->pluck('id');
$storeItems = $this->store($store)->getItems($ids);
// Re-key with full keys (store::id)
return $ids->mapWithKeys(fn ($id, $i) => ["{$store}::{$id}" => $storeItems[$i]]);
});
// Return in original order
return $keys->map(fn ($key) => $fetched[$key]);
}
public function getItem($key)
{
[$store, $id] = explode('::', $key, 2);
return $this->store($store)->getItem($id);
}
public function getItemValues($keys, $valueIndex, $keyIndex)
{
return $keys
->map(function ($key) {
[$store, $key] = explode('::', $key, 2);
return compact('store', 'key');
})
->groupBy('store')
->flatMap(fn ($items, $store) => $this->store($store)->getItemValues($items->map->key, $valueIndex, $keyIndex));
}
public function clear()
{
$this->discoverStores()->each->clear();
}
public function warm()
{
$this->discoverStores()->each->warm();
}
public function paths()
{
return $this->discoverStores()->flatMap(function ($store) {
return $store->paths();
});
}
abstract public function discoverStores();
}