Skip to content

Commit 1f9b2a2

Browse files
committed
Ensure input data validation and consistent null checks
1 parent b0d70e5 commit 1f9b2a2

File tree

1 file changed

+58
-27
lines changed

1 file changed

+58
-27
lines changed

src/State/ScreenProcessor.php

Lines changed: 58 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,8 @@ public function __construct(
3232
EntityManagerInterface $entityManager,
3333
ProcessorInterface $persistProcessor,
3434
ProcessorInterface $removeProcessor,
35-
ScreenProvider $provider
36-
)
37-
{
35+
ScreenProvider $provider,
36+
) {
3837
parent::__construct($entityManager, $persistProcessor, $removeProcessor, $provider);
3938
}
4039

@@ -44,15 +43,15 @@ protected function fromInput(mixed $object, Operation $operation, array $uriVari
4443
$screen = $this->loadPrevious(new Screen(), $context);
4544

4645
if (!$screen instanceof Screen) {
47-
throw new InvalidArgumentException('object must by of type Screen.');
46+
throw new InvalidArgumentException('object must be of type Screen');
4847
}
4948

5049
assert($object instanceof ScreenInput);
5150
empty($object->title) ?: $screen->setTitle($object->title);
5251
empty($object->description) ?: $screen->setDescription($object->description);
5352
empty($object->createdBy) ?: $screen->setCreatedBy($object->createdBy);
5453
empty($object->modifiedBy) ?: $screen->setModifiedBy($object->modifiedBy);
55-
empty($object->size) ?: $screen->setSize((int)$object->size);
54+
empty($object->size) ?: $screen->setSize((int) $object->size);
5655
empty($object->location) ?: $screen->setLocation($object->location);
5756
empty($object->orientation) ?: $screen->setOrientation($object->orientation);
5857
empty($object->resolution) ?: $screen->setResolution($object->resolution);
@@ -61,56 +60,54 @@ protected function fromInput(mixed $object, Operation $operation, array $uriVari
6160
$screen->setEnableColorSchemeChange($object->enableColorSchemeChange);
6261
}
6362

64-
// Adding relations for playlist/screen/region
65-
if (isset($object->regions) && isset($screen)) {
66-
$psrs = $screen->getPlaylistScreenRegions();
63+
// Adding relations for playlist/screen/region if object has region property.
64+
if (isset($object->regions)) {
65+
// Ensure regions object has valid structure
66+
$this->validateRegionsAndPlaylists($object->regions);
67+
68+
$existingPlaylistScreenRegions = $screen->getPlaylistScreenRegions();
6769

6870
foreach ($object->regions as $regionAndPlaylists) {
6971
$regionId = $regionAndPlaylists['regionId'];
7072

7173
$region = $this->screenLayoutRegionsRepository->findOneBy(['id' => $regionId]);
7274

7375
if (is_null($region)) {
74-
throw new InvalidArgumentException('Unknown region resource');
76+
throw new InvalidArgumentException(sprintf('Unknown region resource (id: %s)', $regionId));
7577
}
7678

77-
$existingPlaylistScreenRegionsInRegion = $psrs->filter(
78-
function (PlaylistScreenRegion $psr) use ($regionId) {
79-
return $psr->getRegion()->getId() == $regionId;
80-
}
79+
$existingPlaylistScreenRegionsInRegion = $existingPlaylistScreenRegions->filter(
80+
fn (PlaylistScreenRegion $psr) => $psr->getRegion()?->getId() == $regionId
8181
);
8282

8383
$inputPlaylists = $regionAndPlaylists['playlists'];
84-
$inputPlaylistIds = array_map(function ($entry) {
85-
return $entry['id'];
86-
}, $inputPlaylists);
84+
$inputPlaylistIds = array_map(fn (array $entry): string => $entry['id'], $inputPlaylists);
8785

8886
// Remove playlist screen regions that should not exist in region.
8987
/** @var PlaylistScreenRegion $existingPSR */
9088
foreach ($existingPlaylistScreenRegionsInRegion as $existingPSR) {
91-
if (!in_array($existingPSR->getPlaylist()->getId(), $inputPlaylistIds)) {
89+
if (!in_array($existingPSR->getPlaylist()?->getId(), $inputPlaylistIds)) {
9290
$screen->removePlaylistScreenRegion($existingPSR);
9391
}
9492
}
9593

9694
// Add or update the input playlists.
9795
foreach ($inputPlaylists as $inputPlaylist) {
9896
$playlist = $this->playlistRepository->findOneBy(['id' => $inputPlaylist['id']]);
99-
$existing = $this->playlistScreenRegionRepository->findOneBy([
97+
98+
if (is_null($playlist)) {
99+
throw new InvalidArgumentException(sprintf('Unknown playlist resource (id: %s)', $inputPlaylist['id']));
100+
}
101+
102+
$existingPlaylistScreenRegionRelation = $this->playlistScreenRegionRepository->findOneBy([
100103
'playlist' => $playlist,
101104
'region' => $region,
102105
'screen' => $screen,
103106
]);
104107

105-
if ($existing) {
106-
$existing->setWeight($inputPlaylist['weight']);
108+
if (!is_null($existingPlaylistScreenRegionRelation)) {
109+
$existingPlaylistScreenRegionRelation->setWeight($inputPlaylist['weight'] ?? 0);
107110
} else {
108-
$playlist = $this->playlistRepository->findOneBy(['id' => $inputPlaylist['id']]);
109-
110-
if (is_null($playlist)) {
111-
throw new InvalidArgumentException('Unknown playlist resource');
112-
}
113-
114111
$newPlaylistScreenRegionRelation = new PlaylistScreenRegion();
115112
$newPlaylistScreenRegionRelation->setPlaylist($playlist);
116113
$newPlaylistScreenRegionRelation->setRegion($region);
@@ -123,7 +120,7 @@ function (PlaylistScreenRegion $psr) use ($regionId) {
123120
}
124121

125122
// Maps ids of existing groups
126-
if (isset($object->groups) && isset($screen)) {
123+
if (isset($object->groups)) {
127124
$groupCollection = new ArrayCollection();
128125
foreach ($object->groups as $group) {
129126
$groupToSave = $this->groupRepository->findOneBy(['id' => $group]);
@@ -151,4 +148,38 @@ function (PlaylistScreenRegion $psr) use ($regionId) {
151148

152149
return $screen;
153150
}
151+
152+
private function validateRegionsAndPlaylists(array $regions): void
153+
{
154+
foreach ($regions as $region) {
155+
$this->validateRegion($region);
156+
157+
foreach ($region['playlists'] as $playlist) {
158+
$this->validatePlaylist($playlist);
159+
}
160+
}
161+
}
162+
163+
private function validateRegion(array $region): void
164+
{
165+
if (!isset($region['regionId']) || !is_string($region['regionId'])) {
166+
throw new InvalidArgumentException('All regions must specify a valid Ulid');
167+
}
168+
169+
if (!isset($region['playlist']) || !is_array($region['playlist'])) {
170+
throw new InvalidArgumentException('All regions must specify a list of playlists');
171+
}
172+
}
173+
174+
private function validatePlaylist(array $playlist): void
175+
{
176+
if (!isset($playlist['id']) || !is_string($playlist['id'])) {
177+
throw new InvalidArgumentException('All playlists must specify a valid Ulid');
178+
179+
}
180+
181+
if (isset($playlist['weight']) && !is_integer($playlist['weight'])) {
182+
throw new InvalidArgumentException('Playlists weight must be an integer');
183+
}
184+
}
154185
}

0 commit comments

Comments
 (0)