Skip to content

Commit 11f7cba

Browse files
authored
Merge pull request #7236 from ecamp/revert-7217-feature/materialitem-nullable
Revert "MaterialItem.MaterialList is nullable"
2 parents 4233aee + 8ea5f1e commit 11f7cba

27 files changed

+52
-257
lines changed

api/migrations/schema/Version20250412165829.php

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

api/src/Entity/ContentNode.php

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
#[ORM\InheritanceType('SINGLE_TABLE')]
5454
#[ORM\DiscriminatorColumn(name: 'strategy', type: 'string')]
5555
#[ORM\UniqueConstraint(name: 'contentnode_parentid_slot_position_unique', columns: ['parentid', 'slot', 'position'])]
56-
abstract class ContentNode extends BaseEntity implements BelongsToCampInterface, BelongsToContentNodeTreeInterface, CopyFromPrototypeInterface, HasParentInterface {
56+
abstract class ContentNode extends BaseEntity implements BelongsToContentNodeTreeInterface, CopyFromPrototypeInterface, HasParentInterface {
5757
use ClassInfoTrait;
5858

5959
/**
@@ -193,17 +193,6 @@ public function setParent(?ContentNode $parent) {
193193
$this->root ??= $parent?->root;
194194
}
195195

196-
public function getCamp(): ?Camp {
197-
if (null == $this->getRoot()) {
198-
return null;
199-
}
200-
if ($this->getRoot()->campRootContentNodes->count() > 0) {
201-
return $this->getRoot()->campRootContentNodes[0]->camp;
202-
}
203-
204-
return null;
205-
}
206-
207196
/**
208197
* Holds the actual data of the content node.
209198
*/

api/src/Entity/MaterialItem.php

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
use Doctrine\Common\Collections\Collection;
2424
use Doctrine\ORM\Mapping as ORM;
2525
use Symfony\Component\Serializer\Annotation\Groups;
26-
use Symfony\Component\Serializer\Attribute\SerializedName;
2726
use Symfony\Component\Validator\Constraints as Assert;
2827

2928
/**
@@ -45,7 +44,6 @@
4544
security: 'is_authenticated()'
4645
),
4746
new Post(
48-
denormalizationContext: ['groups' => ['write', 'create']],
4947
securityPostDenormalize: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object) or object.materialList === null'
5048
),
5149
],
@@ -60,12 +58,11 @@ class MaterialItem extends BaseEntity implements BelongsToCampInterface, CopyFro
6058
* The list to which this item belongs. Lists are used to keep track of who is
6159
* responsible to prepare and bring the item to the camp.
6260
*/
63-
#[Assert\NotNull]
64-
#[AssertBelongsToSameCamp]
61+
#[AssertBelongsToSameCamp(compareToPrevious: true, groups: ['update'])]
6562
#[ApiProperty(example: '/material_lists/1a2b3c4d')]
6663
#[Groups(['read', 'write'])]
6764
#[ORM\ManyToOne(targetEntity: MaterialList::class, inversedBy: 'materialItems')]
68-
#[ORM\JoinColumn(nullable: true, onDelete: 'cascade')]
65+
#[ORM\JoinColumn(nullable: false, onDelete: 'cascade')]
6966
public ?MaterialList $materialList = null;
7067

7168
/**
@@ -134,13 +131,9 @@ public function __construct() {
134131
$this->periodMaterialItems = new ArrayCollection();
135132
}
136133

137-
#[ApiProperty]
138-
#[SerializedName('camp')]
139-
#[Groups(['read'])]
134+
#[ApiProperty(readable: false)]
140135
public function getCamp(): ?Camp {
141-
return $this->period?->getCamp()
142-
?? $this->materialNode?->getCamp()
143-
?? $this->materialList?->getCamp();
136+
return $this->materialList?->getCamp();
144137
}
145138

146139
/**
@@ -150,14 +143,9 @@ public function getCamp(): ?Camp {
150143
public function copyFromPrototype($prototype, $entityMap): void {
151144
$entityMap->add($prototype, $this);
152145

153-
if (null != $prototype->materialList) {
154-
/** @var MaterialList $materialList */
155-
$materialList = $entityMap->get($prototype->materialList);
156-
157-
if ($entityMap->belongsToTargetCamp($materialList)) {
158-
$materialList->addMaterialItem($this);
159-
}
160-
}
146+
/** @var MaterialList $materialList */
147+
$materialList = $entityMap->get($prototype->materialList);
148+
$materialList->addMaterialItem($this);
161149

162150
$this->article = $prototype->article;
163151
$this->quantity = $prototype->quantity;

api/src/Repository/MaterialItemRepository.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ public function __construct(ManagerRegistry $registry) {
2424
}
2525

2626
public function filterByUser(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, User $user): void {
27-
$periodMaterialItems = QueryBuilderHelper::findOrAddInnerRootJoinAlias($queryBuilder, $queryNameGenerator, 'periodMaterialItems');
28-
$period = QueryBuilderHelper::findOrAddInnerJoinAlias($queryBuilder, $queryNameGenerator, $periodMaterialItems, 'period');
29-
$this->filterByCampCollaboration($queryBuilder, $user, "{$period}.camp");
27+
$materialList = QueryBuilderHelper::findOrAddInnerRootJoinAlias($queryBuilder, $queryNameGenerator, 'materialList');
28+
$this->filterByCampCollaboration($queryBuilder, $user, "{$materialList}.camp");
3029
}
3130
}

api/src/State/ActivityCreateProcessor.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ public function onBefore($data, Operation $operation, array $uriVariables = [],
3434
throw new \UnexpectedValueException('Property rootContentNode of provided category is of wrong type. Object of type '.ColumnLayout::class.' expected.');
3535
}
3636

37-
$targetCamp = $data->category->camp;
3837
$data->camp = $data->category->camp;
3938
$rootContentNodePrototype = $data->category->rootContentNode;
4039

@@ -51,7 +50,7 @@ public function onBefore($data, Operation $operation, array $uriVariables = [],
5150
$data->setRootContentNode($rootContentNode);
5251

5352
// deep copy from category root node
54-
$entityMap = new EntityMap($targetCamp);
53+
$entityMap = new EntityMap();
5554
$rootContentNode->copyFromPrototype($rootContentNodePrototype, $entityMap);
5655

5756
return $data;

api/src/State/CampCreateProcessor.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public function onBefore($data, Operation $operation, array $uriVariables = [],
3737

3838
// copy from prototype, if given
3939
if (isset($data->campPrototype)) {
40-
$entityMap = new EntityMap($data);
40+
$entityMap = new EntityMap();
4141
$data->copyFromPrototype($data->campPrototype, $entityMap);
4242
}
4343

api/src/State/CategoryCreateProcessor.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public function onBefore($data, Operation $operation, array $uriVariables = [],
3838

3939
if (isset($data->copyCategorySource)) {
4040
// CopyActivity Source is set -> copy it's content (rootContentNode)
41-
$entityMap = new EntityMap($data->camp);
41+
$entityMap = new EntityMap();
4242
$rootContentNode->copyFromPrototype($data->copyCategorySource->getRootContentNode(), $entityMap);
4343
}
4444

api/src/State/ChecklistCreateProcessor.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public function __construct(ProcessorInterface $decorated) {
2222
public function onBefore($data, Operation $operation, array $uriVariables = [], array $context = []): Checklist {
2323
if (isset($data->copyChecklistSource)) {
2424
// CopyChecklist Source is set -> copy it's content
25-
$entityMap = new EntityMap($data->camp);
25+
$entityMap = new EntityMap();
2626
$data->copyFromPrototype($data->copyChecklistSource, $entityMap);
2727
}
2828

api/src/Util/EntityMap.php

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,12 @@
33
namespace App\Util;
44

55
use App\Entity\BaseEntity;
6-
use App\Entity\BelongsToCampInterface;
7-
use App\Entity\Camp;
86

97
class EntityMap {
108
use ClassInfoTrait;
119

1210
private $map = [];
1311

14-
public function __construct(private Camp $targetCamp) {}
15-
1612
public function add(BaseEntity $prototype, BaseEntity $entity) {
1713
$key = $this->getObjectClass($prototype).'#'.$prototype->getId();
1814
$this->map[$key] = $entity;
@@ -24,8 +20,4 @@ public function get(BaseEntity $prototype): BaseEntity {
2420

2521
return $keyExists ? $this->map[$key] : $prototype;
2622
}
27-
28-
public function belongsToTargetCamp(BelongsToCampInterface $entity) {
29-
return $entity->getCamp() == $this->targetCamp;
30-
}
3123
}

api/tests/Api/Activities/CreateActivityTest.php

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,7 @@ public function testCreateActivityFromCopySourceWithinSameCamp() {
519519
}
520520

521521
public function testCreateActivityFromCopySourceAcrossCamp() {
522-
$response = static::createClientWithCredentials()->request(
522+
static::createClientWithCredentials()->request(
523523
'POST',
524524
'/activities',
525525
['json' => $this->getExampleWritePayload(
@@ -540,21 +540,6 @@ public function testCreateActivityFromCopySourceAcrossCamp() {
540540

541541
// Activity created
542542
$this->assertResponseStatusCodeSame(201);
543-
544-
// Embedded MaterialNode -> MaterialItems
545-
// Test MaterialList is nulled
546-
$responseArray = $response->toArray();
547-
$contentNodes = $responseArray['_embedded']['contentNodes'];
548-
549-
$materialNodes = array_filter($contentNodes, fn ($cn) => 'Material' == $cn['contentTypeName']);
550-
$this->assertCount(1, $materialNodes);
551-
552-
$materialNode = reset($materialNodes);
553-
$materialItems = $materialNode['_embedded']['materialItems'];
554-
$this->assertCount(1, $materialItems);
555-
556-
$materailItem = reset($materialItems);
557-
$this->assertNull($materailItem['_links']['materialList']);
558543
}
559544

560545
/**

0 commit comments

Comments
 (0)