diff --git a/backend/app/Element/Element.php b/backend/app/Element/Element.php index 41fec0d..37be364 100644 --- a/backend/app/Element/Element.php +++ b/backend/app/Element/Element.php @@ -29,31 +29,61 @@ class Element return $this->title; } + public function setTitle(string $title): void + { + $this->title = $title; + } + public function getDescription(): string { return $this->description; } + public function setDescription(string $description): void + { + $this->description = $description; + } + public function getIconImageUrl(): ?string { return $this->iconImageUrl; } + public function setIconImageUrl(?string $iconImageUrl): void + { + $this->iconImageUrl = $iconImageUrl; + } + public function getRichText(): string { return $this->richText; } + public function setRichText(string $richText): void + { + $this->richText = $richText; + } + public function getPdfPath(): ?string { return $this->pdfPath; } + public function setPdfPath(?string $pdfPath): void + { + $this->pdfPath = $pdfPath; + } + public function getYoutubeUrl(): ?string { return $this->youtubeUrl; } + public function setYoutubeUrl(?string $youtubeUrl): void + { + $this->youtubeUrl = $youtubeUrl; + } + public function getSet(): Set { return $this->set; diff --git a/backend/app/Element/ElementRepository.php b/backend/app/Element/ElementRepository.php index b733611..e4fa74e 100644 --- a/backend/app/Element/ElementRepository.php +++ b/backend/app/Element/ElementRepository.php @@ -8,7 +8,7 @@ interface ElementRepository { public function create(CreateElementDto $dto): Element; - public function update(Element $element, UpdateElementDto $dto): Element; + public function update(Element $element): Element; public function find(int $id): ?Element; diff --git a/backend/app/Element/EloquentElementRepository.php b/backend/app/Element/EloquentElementRepository.php index 65dc061..379abe0 100644 --- a/backend/app/Element/EloquentElementRepository.php +++ b/backend/app/Element/EloquentElementRepository.php @@ -38,7 +38,7 @@ class EloquentElementRepository implements ElementRepository ); } - public function update(Element $element, UpdateElementDto $dto): Element + public function update(Element $element): Element { $model = ElementModel::find($element->getId()); if ($model === null) { @@ -47,25 +47,17 @@ class EloquentElementRepository implements ElementRepository ); } - $model->title = $dto->title; - $model->description = $dto->description; - $model->icon_image_url = $dto->iconImageUrl; - $model->rich_text = $dto->richText; - $model->pdf_path = $dto->pdfPath; - $model->youtube_url = $dto->youtubeUrl; + $model->set_id = $element->getSet()->getId(); + $model->title = $element->getTitle(); + $model->description = $element->getDescription(); + $model->icon_image_url = $element->getIconImageUrl(); + $model->rich_text = $element->getRichText(); + $model->pdf_path = $element->getPdfPath(); + $model->youtube_url = $element->getYoutubeUrl(); + $model->parent_element_id = $element->getParentElement()?->getId(); $model->save(); - return new Element( - id: $element->getId(), - title: $dto->title, - description: $dto->description, - iconImageUrl: $dto->iconImageUrl, - richText: $dto->richText, - pdfPath: $dto->pdfPath, - youtubeUrl: $dto->youtubeUrl, - set: $element->getSet(), - parentElement: $element->getParentElement(), - ); + return $this->toDomain($model); } public function find(int $id): ?Element diff --git a/backend/app/Element/UpdateElementDto.php b/backend/app/Element/UpdateElementDto.php deleted file mode 100644 index 5c4b0b7..0000000 --- a/backend/app/Element/UpdateElementDto.php +++ /dev/null @@ -1,16 +0,0 @@ -id === null) { + throw new BadRequestException('id is required'); + } + + if ($request->description === null) { + throw new BadRequestException('description is required'); + } + + $element = $this->elementRepository->find($request->id); + if ($element === null) { + throw new NotFoundException('Element not found'); + } + + $element->setDescription($request->description); + + return $this->elementRepository->update($element); + } +} diff --git a/backend/app/Element/UseCases/UpdateElement/UpdateDescriptionRequest.php b/backend/app/Element/UseCases/UpdateElement/UpdateDescriptionRequest.php new file mode 100644 index 0000000..882d4ff --- /dev/null +++ b/backend/app/Element/UseCases/UpdateElement/UpdateDescriptionRequest.php @@ -0,0 +1,12 @@ +title === null || trim($request->title) === '') { - throw new BadRequestException('title is required'); + $hasNoFields = $request->title === null + && $request->description === null + && $request->iconImageUrl === null + && $request->richText === null + && $request->pdfPath === null + && $request->youtubeUrl === null; + if ($hasNoFields) { + throw new BadRequestException('nothing to update'); + } + + if ($request->title !== null) { + $this->updateTitle->execute(new UpdateTitleRequest( + id: $request->id, + title: $request->title, + )); + } + if ($request->description !== null) { + $this->updateDescription->execute(new UpdateDescriptionRequest( + id: $request->id, + description: $request->description, + )); + } + if ($request->iconImageUrl !== null) { + $this->updateIconImageUrl->execute( + new UpdateIconImageUrlRequest( + id: $request->id, + iconImageUrl: $request->iconImageUrl, + ) + ); + } + if ($request->richText !== null) { + $this->updateRichText->execute(new UpdateRichTextRequest( + id: $request->id, + richText: $request->richText, + )); + } + if ($request->pdfPath !== null) { + $this->updatePdfPath->execute(new UpdatePdfPathRequest( + id: $request->id, + pdfPath: $request->pdfPath, + )); + } + if ($request->youtubeUrl !== null) { + $this->updateYoutubeUrl->execute(new UpdateYoutubeUrlRequest( + id: $request->id, + youtubeUrl: $request->youtubeUrl, + )); } $element = $this->elementRepository->find($request->id); @@ -33,25 +84,6 @@ class UpdateElement throw new NotFoundException('Element not found'); } - return $this->elementRepository->update( - $element, - new UpdateElementDto( - title: $request->title, - description: $request->description ?? '', - iconImageUrl: $this->nullableString($request->iconImageUrl), - richText: $request->richText ?? '', - pdfPath: $this->nullableString($request->pdfPath), - youtubeUrl: $this->nullableString($request->youtubeUrl), - ), - ); - } - - private function nullableString(?string $value): ?string - { - if ($value === null || $value === '') { - return null; - } - - return $value; + return $element; } } diff --git a/backend/app/Element/UseCases/UpdateElement/UpdateIconImageUrl.php b/backend/app/Element/UseCases/UpdateElement/UpdateIconImageUrl.php new file mode 100644 index 0000000..cc07171 --- /dev/null +++ b/backend/app/Element/UseCases/UpdateElement/UpdateIconImageUrl.php @@ -0,0 +1,50 @@ +id === null) { + throw new BadRequestException('id is required'); + } + + if ($request->iconImageUrl === null) { + throw new BadRequestException('iconImageUrl is required'); + } + + $element = $this->elementRepository->find($request->id); + if ($element === null) { + throw new NotFoundException('Element not found'); + } + + $element->setIconImageUrl($this->nullableString( + $request->iconImageUrl, + )); + + return $this->elementRepository->update($element); + } + + private function nullableString(string $value): ?string + { + if ($value === '') { + return null; + } + + return $value; + } +} diff --git a/backend/app/Element/UseCases/UpdateElement/UpdateIconImageUrlRequest.php b/backend/app/Element/UseCases/UpdateElement/UpdateIconImageUrlRequest.php new file mode 100644 index 0000000..d328af3 --- /dev/null +++ b/backend/app/Element/UseCases/UpdateElement/UpdateIconImageUrlRequest.php @@ -0,0 +1,12 @@ +id === null) { + throw new BadRequestException('id is required'); + } + + if ($request->pdfPath === null) { + throw new BadRequestException('pdfPath is required'); + } + + $element = $this->elementRepository->find($request->id); + if ($element === null) { + throw new NotFoundException('Element not found'); + } + + $element->setPdfPath($this->nullableString($request->pdfPath)); + + return $this->elementRepository->update($element); + } + + private function nullableString(string $value): ?string + { + if ($value === '') { + return null; + } + + return $value; + } +} diff --git a/backend/app/Element/UseCases/UpdateElement/UpdatePdfPathRequest.php b/backend/app/Element/UseCases/UpdateElement/UpdatePdfPathRequest.php new file mode 100644 index 0000000..c48c47d --- /dev/null +++ b/backend/app/Element/UseCases/UpdateElement/UpdatePdfPathRequest.php @@ -0,0 +1,12 @@ +id === null) { + throw new BadRequestException('id is required'); + } + + if ($request->richText === null) { + throw new BadRequestException('richText is required'); + } + + $element = $this->elementRepository->find($request->id); + if ($element === null) { + throw new NotFoundException('Element not found'); + } + + $element->setRichText($request->richText); + + return $this->elementRepository->update($element); + } +} diff --git a/backend/app/Element/UseCases/UpdateElement/UpdateRichTextRequest.php b/backend/app/Element/UseCases/UpdateElement/UpdateRichTextRequest.php new file mode 100644 index 0000000..fe29972 --- /dev/null +++ b/backend/app/Element/UseCases/UpdateElement/UpdateRichTextRequest.php @@ -0,0 +1,12 @@ +id === null) { + throw new BadRequestException('id is required'); + } + + if ($request->title === null || trim($request->title) === '') { + throw new BadRequestException('title is required'); + } + + $element = $this->elementRepository->find($request->id); + if ($element === null) { + throw new NotFoundException('Element not found'); + } + + $element->setTitle(trim($request->title)); + + return $this->elementRepository->update($element); + } +} diff --git a/backend/app/Element/UseCases/UpdateElement/UpdateTitleRequest.php b/backend/app/Element/UseCases/UpdateElement/UpdateTitleRequest.php new file mode 100644 index 0000000..5a13ea9 --- /dev/null +++ b/backend/app/Element/UseCases/UpdateElement/UpdateTitleRequest.php @@ -0,0 +1,12 @@ +id === null) { + throw new BadRequestException('id is required'); + } + + if ($request->youtubeUrl === null) { + throw new BadRequestException('youtubeUrl is required'); + } + + $element = $this->elementRepository->find($request->id); + if ($element === null) { + throw new NotFoundException('Element not found'); + } + + $element->setYoutubeUrl($this->nullableString( + $request->youtubeUrl, + )); + + return $this->elementRepository->update($element); + } + + private function nullableString(string $value): ?string + { + if ($value === '') { + return null; + } + + return $value; + } +} diff --git a/backend/app/Element/UseCases/UpdateElement/UpdateYoutubeUrlRequest.php b/backend/app/Element/UseCases/UpdateElement/UpdateYoutubeUrlRequest.php new file mode 100644 index 0000000..3a7e06a --- /dev/null +++ b/backend/app/Element/UseCases/UpdateElement/UpdateYoutubeUrlRequest.php @@ -0,0 +1,12 @@ +getId(), - title: $dto->title, - description: $dto->description, - iconImageUrl: $dto->iconImageUrl, - richText: $dto->richText, - pdfPath: $dto->pdfPath, - youtubeUrl: $dto->youtubeUrl, - set: $element->getSet(), - parentElement: $element->getParentElement(), - ); - $this->elementsById[$element->getId()] = $updatedElement; + $updatedElement = $this->cloneElement($element); + $this->elementsById[$updatedElement->getId()] = $updatedElement; return $this->cloneElement($updatedElement); } diff --git a/backend/tests/Unit/Controllers/ElementControllerTest.php b/backend/tests/Unit/Controllers/ElementControllerTest.php index 64fcfb5..99bfa3e 100644 --- a/backend/tests/Unit/Controllers/ElementControllerTest.php +++ b/backend/tests/Unit/Controllers/ElementControllerTest.php @@ -6,7 +6,13 @@ use App\Controllers\ElementController; use App\Element\CreateElementDto; use App\Element\Element; use App\Element\UseCases\GetElement\GetElement; +use App\Element\UseCases\UpdateElement\UpdateDescription; use App\Element\UseCases\UpdateElement\UpdateElement; +use App\Element\UseCases\UpdateElement\UpdateIconImageUrl; +use App\Element\UseCases\UpdateElement\UpdatePdfPath; +use App\Element\UseCases\UpdateElement\UpdateRichText; +use App\Element\UseCases\UpdateElement\UpdateTitle; +use App\Element\UseCases\UpdateElement\UpdateYoutubeUrl; use App\Set\Set as DomainSet; use Tests\Fakes\FakeElementRepository; use Tests\TestCase; @@ -21,7 +27,15 @@ class ElementControllerTest extends TestCase { $this->elementRepo = new FakeElementRepository(); $getElement = new GetElement($this->elementRepo); - $updateElement = new UpdateElement($this->elementRepo); + $updateElement = new UpdateElement( + new UpdateTitle($this->elementRepo), + new UpdateDescription($this->elementRepo), + new UpdateIconImageUrl($this->elementRepo), + new UpdateRichText($this->elementRepo), + new UpdatePdfPath($this->elementRepo), + new UpdateYoutubeUrl($this->elementRepo), + $this->elementRepo, + ); $this->controller = new ElementController($getElement, $updateElement); }