Skip to content

Commit ccbc33a

Browse files
committed
4565: Refactored screen layout command and service
1 parent a4a1287 commit ccbc33a

10 files changed

+175
-138
lines changed

src/Command/ScreenLayout/ScreenLayoutRemoveCommand.php

Lines changed: 0 additions & 85 deletions
This file was deleted.

src/Command/ScreenLayout/ScreenLayoutsInstallCommand.php

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

55
namespace App\Command\ScreenLayout;
66

7+
use App\Exceptions\NotFoundException;
78
use App\Model\ScreenLayoutData;
89
use App\Service\ScreenLayoutService;
910
use Symfony\Component\Console\Attribute\AsCommand;
@@ -42,12 +43,8 @@ final protected function execute(InputInterface $input, OutputInterface $output)
4243
$update = $input->getOption('update');
4344
$cleanupRegions = $input->getOption('cleanupRegions');
4445

45-
$screenLayouts = $this->screenLayoutService->getScreenLayouts();
46-
4746
if ($all) {
48-
foreach ($screenLayouts as $screenLayoutToInstall) {
49-
$this->screenLayoutService->installScreenLayout($screenLayoutToInstall, $update, $cleanupRegions);
50-
}
47+
$this->screenLayoutService->installAll($update, $cleanupRegions);
5148

5249
$io->success('Installed all available screen layouts');
5350

@@ -62,16 +59,14 @@ final protected function execute(InputInterface $input, OutputInterface $output)
6259
return Command::INVALID;
6360
}
6461

65-
$screenLayoutToInstall = array_find($screenLayouts, fn (ScreenLayoutData $screenLayoutData): bool => $screenLayoutData->id === $screenLayoutUlid);
66-
67-
if (null === $screenLayoutToInstall) {
68-
$io->error('Screen layout not found.');
69-
62+
try {
63+
$this->screenLayoutService->installById($screenLayoutUlid, $update, $cleanupRegions);
64+
} catch (NotFoundException $e) {
65+
$io->error($e->getMessage());
7066
return Command::FAILURE;
7167
}
7268

73-
$this->screenLayoutService->installScreenLayout($screenLayoutToInstall, $update, $cleanupRegions);
74-
$io->success('Screen layout '.$screenLayoutToInstall->title.' installed');
69+
$io->success('Screen layout with ULID: '.$screenLayoutUlid.' installed');
7570

7671
return Command::SUCCESS;
7772
}

src/Command/ScreenLayout/ScreenLayoutsListCommand.php

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,15 @@ final protected function execute(InputInterface $input, OutputInterface $output)
3737
$status = $input->getOption('status');
3838

3939
try {
40-
$screenLayouts = $this->screenLayoutService->getScreenLayouts();
41-
42-
if (0 === count($screenLayouts)) {
43-
$io->error('No screen layouts found.');
44-
45-
return Command::INVALID;
46-
}
47-
4840
if ($status) {
49-
$numberOfScreenLayouts = count($screenLayouts);
50-
$numberOfInstalledScreenLayouts = count(array_filter($screenLayouts, fn ($entry): bool => $entry->installed));
51-
$text = $numberOfInstalledScreenLayouts.' / '.$numberOfScreenLayouts.' templates installed.';
41+
$installStatus = $this->screenLayoutService->getInstallStatus();
42+
43+
$text = $installStatus->installed.' / '.$installStatus->available.' templates installed.';
5244

5345
$io->success($text);
5446
} else {
47+
$screenLayouts = $this->screenLayoutService->getAll();
48+
5549
$io->table(['ID', 'Title', 'Status', 'Type'], array_map(fn (ScreenLayoutData $screenLayout) => [
5650
$screenLayout->id,
5751
$screenLayout->title,
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Command\ScreenLayout;
6+
7+
use App\Exceptions\NotAcceptableException;
8+
use App\Exceptions\NotFoundException;
9+
use App\Service\ScreenLayoutService;
10+
use Symfony\Component\Console\Attribute\AsCommand;
11+
use Symfony\Component\Console\Command\Command;
12+
use Symfony\Component\Console\Input\InputArgument;
13+
use Symfony\Component\Console\Input\InputInterface;
14+
use Symfony\Component\Console\Output\OutputInterface;
15+
use Symfony\Component\Console\Style\SymfonyStyle;
16+
17+
#[AsCommand(
18+
name: 'app:screen-layouts:remove',
19+
description: 'Remove a screen layout',
20+
)]
21+
class ScreenLayoutsRemoveCommand extends Command
22+
{
23+
public function __construct(
24+
private readonly ScreenLayoutService $screenLayoutService,
25+
) {
26+
parent::__construct();
27+
}
28+
29+
protected function configure(): void
30+
{
31+
$this->addArgument('ulid', InputArgument::REQUIRED, 'The ulid of the screen layout to remove');
32+
}
33+
34+
final protected function execute(InputInterface $input, OutputInterface $output): int
35+
{
36+
$io = new SymfonyStyle($input, $output);
37+
38+
$ulid = $input->getArgument('ulid');
39+
40+
if (!$ulid) {
41+
$io->error('No ulid supplied');
42+
43+
return Command::INVALID;
44+
}
45+
46+
try {
47+
$this->screenLayoutService->remove($ulid);
48+
} catch (NotFoundException|NotAcceptableException $e) {
49+
$io->error($e->getMessage());
50+
return Command::FAILURE;
51+
}
52+
53+
$io->success('Screen layout removed.');
54+
55+
return Command::SUCCESS;
56+
}
57+
}

src/Command/ScreenLayout/ScreenLayoutsUpdateCommand.php

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

30-
$screenLayouts = $this->screenLayoutService->getScreenLayouts();
31-
32-
foreach ($screenLayouts as $screenLayoutToUpdate) {
33-
$this->screenLayoutService->updateScreenLayout($screenLayoutToUpdate);
34-
}
30+
$this->screenLayoutService->updateAll();
3531

3632
$io->success('Updated all installed screen layouts');
3733

src/Command/UpdateCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ final protected function execute(InputInterface $input, OutputInterface $output)
7777
$application->doRun($command, $output);
7878
}
7979

80-
$allScreenLayouts = $this->screenLayoutService->getScreenLayouts();
80+
$allScreenLayouts = $this->screenLayoutService->getAll();
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/Model/InstallStatus.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace App\Model;
4+
5+
class InstallStatus
6+
{
7+
public function __construct(
8+
public int $installed = 0,
9+
public int $available = 0,
10+
) {}
11+
}

src/Service/ScreenLayoutService.php

Lines changed: 83 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,13 @@
77
use App\Entity\ScreenLayout;
88
use App\Entity\ScreenLayoutRegions;
99
use App\Enum\ResourceTypeEnum;
10+
use App\Exceptions\NotAcceptableException;
11+
use App\Exceptions\NotFoundException;
12+
use App\Model\InstallStatus;
1013
use App\Model\ScreenLayoutData;
1114
use App\Repository\ScreenLayoutRegionsRepository;
15+
use App\Repository\ScreenLayoutRepository;
16+
use App\Repository\ScreenRepository;
1217
use App\Utils\ResourceLoader;
1318
use Doctrine\ORM\EntityManagerInterface;
1419
use Doctrine\ORM\Id\AssignedGenerator;
@@ -21,19 +26,41 @@ class ScreenLayoutService
2126

2227
public function __construct(
2328
private readonly EntityManagerInterface $entityManager,
29+
private readonly ScreenRepository $screenRepository,
30+
private readonly ScreenLayoutRepository $screenLayoutRepository,
2431
private readonly ScreenLayoutRegionsRepository $layoutRegionsRepository,
2532
private readonly ResourceLoader $loader,
2633
) {}
2734

28-
public function getScreenLayouts(): array
35+
public function getAll(): array
2936
{
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);
37+
$core = $this->loader->getResourceInDirectory($this::CORE_SCREEN_LAYOUTS_PATH, ScreenLayoutData::class, ResourceTypeEnum::CORE);
38+
$custom = $this->loader->getResourceInDirectory($this::CUSTOM_SCREEN_LAYOUTS_PATH, ScreenLayoutData::class, ResourceTypeEnum::CUSTOM);
3239

3340
return array_merge($core, $custom);
3441
}
3542

36-
public function installScreenLayout(ScreenLayoutData $screenLayoutData, bool $update = false, bool $cleanupRegions = false): void
43+
public function installAll(bool $update = false, bool $cleanupRegions = false): void
44+
{
45+
$screenLayouts = $this->getAll();
46+
47+
foreach ($screenLayouts as $screenLayoutToInstall) {
48+
$this->install($screenLayoutToInstall, $update, $cleanupRegions);
49+
}
50+
}
51+
52+
public function installById(string $ulidString, bool $update = false, bool $cleanupRegions = false): void
53+
{
54+
$screenLayoutToInstall = array_find($this->getAll(), fn (ScreenLayoutData $screenLayoutData): bool => $screenLayoutData->id === $ulidString);
55+
56+
if (null === $screenLayoutToInstall) {
57+
throw new NotFoundException();
58+
}
59+
60+
$this->install($screenLayoutToInstall, $update, $cleanupRegions);
61+
}
62+
63+
public function install(ScreenLayoutData $screenLayoutData, bool $update = false, bool $cleanupRegions = false): void
3764
{
3865
$screenLayout = $screenLayoutData->screenLayoutEntity;
3966

@@ -104,11 +131,61 @@ public function installScreenLayout(ScreenLayoutData $screenLayoutData, bool $up
104131
$this->entityManager->flush();
105132
}
106133

107-
public function updateScreenLayout(ScreenLayoutData $screenLayoutToUpdate): void
134+
public function updateAll(): void
135+
{
136+
$screenLayouts = $this->getAll();
137+
138+
foreach ($screenLayouts as $screenLayoutToUpdate) {
139+
$this->update($screenLayoutToUpdate);
140+
}
141+
}
142+
143+
public function update(ScreenLayoutData $screenLayoutToUpdate): void
108144
{
109145
// This only handles screen layouts that have an entity in the database.
110146
if (null !== $screenLayoutToUpdate->screenLayoutEntity) {
111-
$this->installScreenLayout($screenLayoutToUpdate, true);
147+
$this->install($screenLayoutToUpdate, true);
148+
}
149+
}
150+
151+
public function remove(string $ulidString): void
152+
{
153+
$screenLayout = $this->screenLayoutRepository->findOneBy(['id' => Ulid::fromString($ulidString)]);
154+
155+
if (!$screenLayout) {
156+
throw new NotFoundException('Screen layout not installed. Aborting.');
157+
}
158+
159+
$screens = $this->screenRepository->findBy(['screenLayout' => $screenLayout]);
160+
$numberOfScreens = count($screens);
161+
162+
if ($numberOfScreens > 0) {
163+
$message = "Aborting. Screen layout is bound to $numberOfScreens following screens:\n\n";
164+
165+
foreach ($screens as $screen) {
166+
$id = $screen->getId();
167+
$message .= "$id\n";
168+
}
169+
170+
throw new NotAcceptableException($message);
171+
}
172+
173+
foreach ($screenLayout->getRegions() as $region) {
174+
$this->entityManager->remove($region);
112175
}
176+
177+
$this->entityManager->remove($screenLayout);
178+
179+
$this->entityManager->flush();
180+
181+
}
182+
183+
public function getInstallStatus(): InstallStatus
184+
{
185+
$screenLayouts = $this->getAll();
186+
$numberOfScreenLayouts = count($screenLayouts);
187+
$numberOfInstalledScreenLayouts = count(array_filter($screenLayouts, fn ($entry): bool => $entry->installed));
188+
189+
return new InstallStatus($numberOfInstalledScreenLayouts, $numberOfScreenLayouts);
113190
}
114191
}

src/Service/TemplateService.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ public function __construct(
2424

2525
public function getTemplates(): array
2626
{
27-
$core = $this->loader->getResourceJsonInDirectory($this::CORE_TEMPLATES_PATH, TemplateData::class, ResourceTypeEnum::CORE);
28-
$custom = $this->loader->getResourceJsonInDirectory($this::CUSTOM_TEMPLATES_PATH, TemplateData::class, ResourceTypeEnum::CUSTOM);
27+
$core = $this->loader->getResourceInDirectory($this::CORE_TEMPLATES_PATH, TemplateData::class, ResourceTypeEnum::CORE);
28+
$custom = $this->loader->getResourceInDirectory($this::CUSTOM_TEMPLATES_PATH, TemplateData::class, ResourceTypeEnum::CUSTOM);
2929

3030
return array_merge($core, $custom);
3131
}

0 commit comments

Comments
 (0)