Skip to content

Commit b2f8927

Browse files
committed
4565: Refactored screen layout and template code
1 parent 18dcfd9 commit b2f8927

12 files changed

+303
-299
lines changed

src/Command/ScreenLayout/ScreenLayoutsInstallCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ final protected function execute(InputInterface $input, OutputInterface $output)
4242
$update = $input->getOption('update');
4343
$cleanupRegions = $input->getOption('cleanupRegions');
4444

45-
$screenLayouts = $this->screenLayoutService->getAllScreenLayouts();
45+
$screenLayouts = $this->screenLayoutService->getScreenLayouts();
4646

4747
if ($all) {
4848
foreach ($screenLayouts as $screenLayoutToInstall) {

src/Command/ScreenLayout/ScreenLayoutsListCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ final protected function execute(InputInterface $input, OutputInterface $output)
3737
$status = $input->getOption('status');
3838

3939
try {
40-
$screenLayouts = $this->screenLayoutService->getAllScreenLayouts();
40+
$screenLayouts = $this->screenLayoutService->getScreenLayouts();
4141

4242
if (0 === count($screenLayouts)) {
4343
$io->error('No screen layouts found.');

src/Command/ScreenLayout/ScreenLayoutsUpdateCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ final protected function execute(InputInterface $input, OutputInterface $output)
2727
{
2828
$io = new SymfonyStyle($input, $output);
2929

30-
$screenLayouts = $this->screenLayoutService->getAllScreenLayouts();
30+
$screenLayouts = $this->screenLayoutService->getScreenLayouts();
3131

3232
foreach ($screenLayouts as $screenLayoutToUpdate) {
3333
$this->screenLayoutService->updateScreenLayout($screenLayoutToUpdate);

src/Command/Template/TemplatesInstallCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ final protected function execute(InputInterface $input, OutputInterface $output)
4040
$all = $input->getOption('all');
4141
$update = $input->getOption('update');
4242

43-
$templates = $this->templateService->getAllTemplates();
43+
$templates = $this->templateService->getTemplates();
4444

4545
if ($all) {
4646
foreach ($templates as $templateToInstall) {

src/Command/Template/TemplatesListCommand.php

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace App\Command\Template;
66

7+
use App\Enum\ResourceTypeEnum;
78
use App\Model\TemplateData;
89
use App\Service\TemplateService;
910
use Symfony\Component\Console\Attribute\AsCommand;
@@ -37,21 +38,19 @@ final protected function execute(InputInterface $input, OutputInterface $output)
3738
$status = $input->getOption('status');
3839

3940
try {
40-
$templates = $this->templateService->getCoreTemplates();
41+
$templates = $this->templateService->getTemplates();
4142

42-
if (0 === count($templates)) {
43+
$coreTemplateCount = count(array_filter($templates, fn (TemplateData $template) => $template->type === ResourceTypeEnum::CORE->value));
44+
45+
if (0 === $coreTemplateCount) {
4346
$io->error('No core templates found.');
4447

4548
return Command::INVALID;
4649
}
4750

48-
$customTemplates = $this->templateService->getCustomTemplates();
49-
50-
$allTemplates = array_merge($templates, $customTemplates);
51-
5251
if ($status) {
53-
$numberOfTemplates = count($allTemplates);
54-
$numberOfInstallledTemplates = count(array_filter($allTemplates, fn ($entry): bool => $entry->installed));
52+
$numberOfTemplates = count($templates);
53+
$numberOfInstallledTemplates = count(array_filter($templates, fn ($entry): bool => $entry->installed));
5554
$text = $numberOfInstallledTemplates.' / '.$numberOfTemplates.' templates installed.';
5655

5756
$io->success($text);
@@ -61,7 +60,7 @@ final protected function execute(InputInterface $input, OutputInterface $output)
6160
$templateData->title,
6261
$templateData->installed ? 'Installed' : 'Not Installed',
6362
$templateData->type,
64-
], $allTemplates));
63+
], $templates));
6564
}
6665

6766
return Command::SUCCESS;

src/Command/Template/TemplatesUpdateCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ final protected function execute(InputInterface $input, OutputInterface $output)
2727
{
2828
$io = new SymfonyStyle($input, $output);
2929

30-
$templates = $this->templateService->getAllTemplates();
30+
$templates = $this->templateService->getTemplates();
3131

3232
foreach ($templates as $templateToUpdate) {
3333
$this->templateService->updateTemplate($templateToUpdate);

src/Command/UpdateCommand.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class UpdateCommand extends Command
2323
public function __construct(
2424
private readonly TemplateService $templateService,
2525
private readonly ScreenLayoutService $screenLayoutService,
26-
?string $name = null
26+
?string $name = null,
2727
) {
2828
parent::__construct($name);
2929
}
@@ -53,7 +53,7 @@ final protected function execute(InputInterface $input, OutputInterface $output)
5353
return Command::FAILURE;
5454
}
5555

56-
$allTemplates = $this->templateService->getAllTemplates();
56+
$allTemplates = $this->templateService->getTemplates();
5757
$installedTemplates = array_filter($allTemplates, fn ($entry): bool => $entry->installed);
5858

5959
// If no installed templates, we assume that this is a new installation and offer to install all templates.
@@ -77,7 +77,7 @@ final protected function execute(InputInterface $input, OutputInterface $output)
7777
$application->doRun($command, $output);
7878
}
7979

80-
$allScreenLayouts = $this->screenLayoutService->getAllScreenLayouts();
80+
$allScreenLayouts = $this->screenLayoutService->getScreenLayouts();
8181
$installedScreenLayouts = array_filter($allScreenLayouts, fn ($entry): bool => $entry->installed);
8282

8383
// If no installed screen layouts, we assume that this is a new installation and offer to install all screen layouts.

src/Enum/ResourceTypeEnum.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Enum;
6+
7+
enum ResourceTypeEnum: string
8+
{
9+
case CORE = 'Core';
10+
case CUSTOM = 'Custom';
11+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Exceptions;
6+
7+
class NotImplementedException extends \Exception
8+
{
9+
}

src/Service/ScreenLayoutService.php

Lines changed: 7 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,12 @@
66

77
use App\Entity\ScreenLayout;
88
use App\Entity\ScreenLayoutRegions;
9+
use App\Enum\ResourceTypeEnum;
910
use App\Model\ScreenLayoutData;
1011
use App\Repository\ScreenLayoutRegionsRepository;
12+
use App\Utils\ResourceLoader;
1113
use Doctrine\ORM\EntityManagerInterface;
1214
use Doctrine\ORM\Id\AssignedGenerator;
13-
use JsonSchema\Constraints\Factory;
14-
use JsonSchema\SchemaStorage;
15-
use JsonSchema\Validator;
16-
use Symfony\Component\Finder\Finder;
1715
use Symfony\Component\Uid\Ulid;
1816

1917
class ScreenLayoutService
@@ -24,41 +22,15 @@ class ScreenLayoutService
2422
public function __construct(
2523
private readonly EntityManagerInterface $entityManager,
2624
private readonly ScreenLayoutRegionsRepository $layoutRegionsRepository,
25+
private readonly ResourceLoader $loader,
2726
) {}
2827

29-
public function getAllScreenLayouts(): array
28+
public function getScreenLayouts(): array
3029
{
31-
return array_merge($this->getCoreScreenLayouts(), $this->getCustomScreenLayouts());
32-
}
33-
34-
public function getCoreScreenLayouts(): array
35-
{
36-
$finder = new Finder();
37-
38-
if (is_dir($this::CORE_SCREEN_LAYOUTS_PATH)) {
39-
$finder->files()->followLinks()->ignoreUnreadableDirs()->in($this::CORE_SCREEN_LAYOUTS_PATH)->depth('== 0')->name('*.json');
40-
41-
if ($finder->hasResults()) {
42-
return $this->getScreenLayouts($finder);
43-
}
44-
}
45-
46-
return [];
47-
}
48-
49-
public function getCustomScreenLayouts(): array
50-
{
51-
$finder = new Finder();
52-
53-
if (is_dir($this::CUSTOM_SCREEN_LAYOUTS_PATH)) {
54-
$finder->files()->followLinks()->ignoreUnreadableDirs()->in($this::CUSTOM_SCREEN_LAYOUTS_PATH)->depth('== 0')->name('*.json');
55-
56-
if ($finder->hasResults()) {
57-
return $this->getScreenLayouts($finder, true);
58-
}
59-
}
30+
$core = $this->loader->getResourceJsonInDirectory($this::CORE_SCREEN_LAYOUTS_PATH, ScreenLayoutData::class, ResourceTypeEnum::CORE);
31+
$custom = $this->loader->getResourceJsonInDirectory($this::CUSTOM_SCREEN_LAYOUTS_PATH, ScreenLayoutData::class, ResourceTypeEnum::CUSTOM);
6032

61-
return [];
33+
return array_merge($core, $custom);
6234
}
6335

6436
public function installScreenLayout(ScreenLayoutData $screenLayoutData, bool $update = false, bool $cleanupRegions = false): void
@@ -138,122 +110,4 @@ public function updateScreenLayout(ScreenLayoutData $screenLayoutToUpdate): void
138110
$this->installScreenLayout($screenLayoutToUpdate, true);
139111
}
140112
}
141-
142-
public function getScreenLayouts(iterable $finder, bool $custom = false): array
143-
{
144-
$screenLayouts = [];
145-
146-
// Validate template json.
147-
$schemaStorage = new SchemaStorage();
148-
$jsonSchemaObject = $this->getSchema();
149-
$schemaStorage->addSchema('file://contentSchema', $jsonSchemaObject);
150-
$validator = new Validator(new Factory($schemaStorage));
151-
152-
foreach ($finder as $file) {
153-
$content = json_decode((string) $file->getContents());
154-
$validator->validate($content, $jsonSchemaObject);
155-
156-
if (!$validator->isValid()) {
157-
$message = 'JSON file '.$file->getFilename()." does not validate. Violations:\n";
158-
foreach ($validator->getErrors() as $error) {
159-
$message .= sprintf("\n[%s] %s", $error['property'], $error['message']);
160-
}
161-
162-
throw new \Exception($message);
163-
}
164-
165-
if (!Ulid::isValid($content->id)) {
166-
throw new \Exception('The Ulid is not valid');
167-
}
168-
169-
$repository = $this->entityManager->getRepository(ScreenLayout::class);
170-
$screenLayout = $repository->findOneBy(['id' => Ulid::fromString($content->id)]);
171-
172-
$screenLayouts[] = new ScreenLayoutData(
173-
$content->id,
174-
$content->title,
175-
$custom ? 'Custom' : 'Core',
176-
$content->grid->rows,
177-
$content->grid->columns,
178-
$screenLayout,
179-
null !== $screenLayout,
180-
$content->regions,
181-
);
182-
}
183-
184-
return $screenLayouts;
185-
}
186-
187-
/**
188-
* Supplies json schema for validation.
189-
*
190-
* @return mixed
191-
* Json schema
192-
*
193-
* @throws \JsonException
194-
*/
195-
public function getSchema(): object
196-
{
197-
$jsonSchema = <<<'JSON'
198-
{
199-
"$schema": "https://json-schema.org/draft/2020-12/schema",
200-
"$id": "https://os2display.dk/config-schema.json",
201-
"title": "Config file schema",
202-
"description": "Schema for defining config files for templates",
203-
"type": "object",
204-
"properties": {
205-
"id": {
206-
"description": "Ulid of the screen layout",
207-
"type": "string"
208-
},
209-
"title": {
210-
"description": "The title of the screen layout",
211-
"type": "string"
212-
},
213-
"grid": {
214-
"description": "Grid properties",
215-
"type": "object",
216-
"properties": {
217-
"rows": {
218-
"type": "integer",
219-
"description": "Number of rows"
220-
},
221-
"columns": {
222-
"type": "integer",
223-
"description": "Number of columns"
224-
}
225-
}
226-
},
227-
"regions": {
228-
"description": "The regions of the screen layout",
229-
"type": "array",
230-
"items": {
231-
"type": "object",
232-
"description": "Region",
233-
"properties": {
234-
"id": {
235-
"description": "Ulid of the region",
236-
"type": "string"
237-
},
238-
"title": {
239-
"description": "The title of the region",
240-
"type": "string"
241-
},
242-
"gridArea": {
243-
"description": "Grid area value",
244-
"type": "array",
245-
"items": {
246-
"type": "string"
247-
}
248-
}
249-
}
250-
}
251-
}
252-
},
253-
"required": ["id", "title", "grid", "regions"]
254-
}
255-
JSON;
256-
257-
return json_decode($jsonSchema, false, 512, JSON_THROW_ON_ERROR);
258-
}
259113
}

0 commit comments

Comments
 (0)