Skip to content

Commit 74e7034

Browse files
feat: New modules classes
1 parent 29b38b4 commit 74e7034

File tree

2 files changed

+319
-0
lines changed

2 files changed

+319
-0
lines changed

src/Modules/Module.php

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<?php
2+
3+
namespace Kirby\Modules;
4+
5+
use Kirby\Cms\Block;
6+
use Kirby\Cms\HasSiblings;
7+
use Kirby\Cms\StructureObject;
8+
use Kirby\Content\Field;
9+
use Kirby\Uuid\Uuid;
10+
use Kirby\Toolkit\Str;
11+
12+
class Module
13+
{
14+
use HasSiblings;
15+
16+
protected array $modules = [];
17+
18+
public function __construct(
19+
protected string|int $id,
20+
protected Modules $siblings,
21+
protected string|null $uuid = null,
22+
protected array $data = [],
23+
protected Module|null $parent = null,
24+
) {
25+
$this->uuid ??= Uuid::generate();
26+
}
27+
28+
public function data(): array
29+
{
30+
return $this->data;
31+
}
32+
33+
public function find(string $id): Modules|Module|null
34+
{
35+
if (str_contains($id, '/') === true) {
36+
$ids = Str::split($id, '/');
37+
$modules = $this->modules($ids[0]);
38+
39+
return $modules->find(implode('/', array_slice($ids, 1)));
40+
}
41+
42+
return $this->modules($id);
43+
}
44+
45+
public static function from(
46+
array $data,
47+
string $id,
48+
Module|null $parent = null,
49+
Modules|null $siblings = null,
50+
string|null $uuid = null,
51+
): static {
52+
return new static(
53+
data: $data,
54+
id: $id,
55+
parent: $parent,
56+
siblings: $siblings ?? new Modules(),
57+
uuid: $uuid ?? $data['uuid'] ?? $data['id'] ?? null,
58+
);
59+
}
60+
61+
public function id(): string
62+
{
63+
return $this->id;
64+
}
65+
66+
public function modules(string $id, string $format = 'auto'): Modules
67+
{
68+
return $this->modules[$id] ??= Modules::from(
69+
data: $this->data[$id] ?? $this->data['content'][$id] ?? null,
70+
format: $format,
71+
id: $id,
72+
parent: $this,
73+
);
74+
}
75+
76+
public function parent(): Module|null
77+
{
78+
return $this->parent;
79+
}
80+
81+
public function path(): string
82+
{
83+
return $this->siblings->path() . '/' . $this->id();
84+
}
85+
86+
protected function siblingsCollection(): Modules
87+
{
88+
return $this->siblings;
89+
}
90+
91+
public function toArray(): array
92+
{
93+
$modules = [];
94+
95+
foreach ($this->modules as $id => $module) {
96+
$modules[$id] = $module->toArray();
97+
}
98+
99+
return [
100+
...$this->data,
101+
...$modules,
102+
'uuid' => $this->uuid()
103+
];
104+
}
105+
106+
public function toBlockObject(Field $field): Block
107+
{
108+
return new Block([
109+
...$this->data,
110+
'field' => $field,
111+
'id' => $this->id(),
112+
'parent' => $field->model(),
113+
]);
114+
}
115+
116+
public function toStructureObject(Field $field): StructureObject
117+
{
118+
return new StructureObject([
119+
'content' => $this->data,
120+
'field' => $field,
121+
'id' => $this->id(),
122+
'parent' => $field->model(),
123+
]);
124+
}
125+
126+
public function update(array $data): static
127+
{
128+
$this->data = [
129+
...$this->data,
130+
...$data,
131+
];
132+
133+
return $this;
134+
}
135+
136+
public function uuid(): string
137+
{
138+
return $this->uuid;
139+
}
140+
}
141+

src/Modules/Modules.php

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
<?php
2+
3+
namespace Kirby\Modules;
4+
5+
use Closure;
6+
use Kirby\Cms\Blocks;
7+
use Kirby\Cms\Collection;
8+
use Kirby\Cms\Structure;
9+
use Kirby\Content\Field;
10+
use Kirby\Data\Data;
11+
use Kirby\Data\Json;
12+
use Kirby\Toolkit\Str;
13+
14+
class Modules extends Collection
15+
{
16+
public function __construct(
17+
protected string $id = '/',
18+
array $modules = [],
19+
protected object|null $parent = null,
20+
) {
21+
foreach ($modules as $name => $module) {
22+
$this->__set($name, $module);
23+
}
24+
}
25+
26+
public function changeSort(array $ids): static
27+
{
28+
$modules = [];
29+
30+
if (count($ids) === 0) {
31+
return $this;
32+
}
33+
34+
foreach ($ids as $id) {
35+
if ($module = $this->findByKey($id)) {
36+
$modules[] = $module;
37+
}
38+
}
39+
40+
if (count($modules) === 0) {
41+
return $this;
42+
}
43+
44+
foreach ($this as $module) {
45+
if (in_array($module, $modules) === false) {
46+
$modules[] = $module;
47+
}
48+
}
49+
50+
$this->data = $modules;
51+
52+
return $this;
53+
}
54+
55+
public function findByKey(string $key): Modules|Module|null
56+
{
57+
if (str_contains($key, '/')) {
58+
return $this->findByKeyRecursive($key);
59+
}
60+
61+
if ($module = parent::findByKey($key)) {
62+
return $module;
63+
}
64+
65+
return $this->findBy('uuid', $key);
66+
}
67+
68+
public function findByKeyRecursive(string $key): Modules|Module|null
69+
{
70+
$ids = Str::split($key, '/');
71+
72+
// search for the module by id
73+
$module = $this->findByKey($ids[0]);
74+
75+
// no module found
76+
if ($module === null) {
77+
return null;
78+
}
79+
80+
return $module->find(implode('/', array_slice($ids, 1)));
81+
}
82+
83+
public static function from(
84+
array|string|null $data,
85+
string $id = '/',
86+
string $format = 'auto',
87+
Module|null $parent = null,
88+
): static {
89+
if (is_string($data) === true) {
90+
if ($format === 'auto') {
91+
$format = 'yaml';
92+
93+
if (json_validate($data) === true) {
94+
$format = 'json';
95+
}
96+
}
97+
98+
$data = Data::decode($data, $format);
99+
}
100+
101+
$modules = new static(
102+
id: $id,
103+
parent: $parent,
104+
);
105+
106+
if ($data === null) {
107+
return $modules;
108+
}
109+
110+
foreach ($data as $id => $module) {
111+
$modules->add(Module::from(
112+
data: $module,
113+
id: $id,
114+
parent: $parent,
115+
siblings: $modules,
116+
));
117+
}
118+
119+
return $modules;
120+
}
121+
122+
public function id(): string
123+
{
124+
return $this->id;
125+
}
126+
127+
public function parent(): Module|null
128+
{
129+
return $this->parent;
130+
}
131+
132+
public function path(): string
133+
{
134+
return trim($this->parent?->path() . '/' . $this->id(), '/');
135+
}
136+
137+
public function toArray(Closure|null $callback = null): array
138+
{
139+
if ($callback !== null) {
140+
return parent::toArray($callback);
141+
}
142+
143+
$array = [];
144+
145+
foreach ($this as $module) {
146+
$array[$module->id()] = $module->toArray();
147+
}
148+
149+
return $array;
150+
}
151+
152+
public function toBlocks(Field $field): Blocks
153+
{
154+
return new Blocks(
155+
$this->map(fn (Module $module) => $module->toBlockObject($field)),
156+
[
157+
'field' => $field,
158+
'parent' => $field->model(),
159+
]
160+
);
161+
}
162+
163+
public function toJson(bool $pretty = true): string
164+
{
165+
return Json::encode($this->toArray(), pretty: $pretty);
166+
}
167+
168+
public function toStructure(Field $field): Structure
169+
{
170+
return new Structure(
171+
$this->map(fn (Module $module) => $module->toStructureObject($field)),
172+
[
173+
'field' => $field,
174+
'parent' => $field->model(),
175+
]
176+
);
177+
}
178+
}

0 commit comments

Comments
 (0)