77use App \Entity \ScreenLayout ;
88use App \Entity \ScreenLayoutRegions ;
99use App \Enum \ResourceTypeEnum ;
10+ use App \Exceptions \NotAcceptableException ;
11+ use App \Exceptions \NotFoundException ;
12+ use App \Model \InstallStatus ;
1013use App \Model \ScreenLayoutData ;
1114use App \Repository \ScreenLayoutRegionsRepository ;
15+ use App \Repository \ScreenLayoutRepository ;
16+ use App \Repository \ScreenRepository ;
1217use App \Utils \ResourceLoader ;
1318use Doctrine \ORM \EntityManagerInterface ;
1419use 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}
0 commit comments