Skip to content

Commit

Permalink
Use value objects for slides, not Row
Browse files Browse the repository at this point in the history
  • Loading branch information
spaze committed Dec 30, 2023
1 parent ab593ae commit e0081c5
Show file tree
Hide file tree
Showing 13 changed files with 615 additions and 135 deletions.
14 changes: 6 additions & 8 deletions site/app/Admin/Presenters/TalksPresenter.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,21 @@
use MichalSpacekCz\Media\Exceptions\ContentTypeException;
use MichalSpacekCz\ShouldNotHappenException;
use MichalSpacekCz\Talks\Exceptions\TalkDoesNotExistException;
use MichalSpacekCz\Talks\Slides\TalkSlideCollection;
use MichalSpacekCz\Talks\Slides\TalkSlides;
use MichalSpacekCz\Talks\Talk;
use MichalSpacekCz\Talks\TalkInputs;
use MichalSpacekCz\Talks\TalkInputsFactory;
use MichalSpacekCz\Talks\Talks;
use MichalSpacekCz\Talks\TalkSlides;
use Nette\Application\BadRequestException;
use Nette\Database\Row;
use Nette\Utils\Html;

class TalksPresenter extends BasePresenter
{

private ?Talk $talk = null;

/** @var array<int, Row> slide number => data */
private array $slides = [];
private ?TalkSlideCollection $slides = null;

private int $newCount = 0;

Expand Down Expand Up @@ -68,7 +67,7 @@ public function actionSlides(int $param): void
{
try {
$this->talk = $this->talks->getById($param);
$this->slides = $this->talkSlides->getSlides($this->talk->getId(), $this->talk->getFilenamesTalkId());
$this->slides = $this->talkSlides->getSlides($this->talk);
} catch (ContentTypeException | TalkDoesNotExistException $e) {
throw new BadRequestException($e->getMessage(), previous: $e);
}
Expand All @@ -79,8 +78,7 @@ public function actionSlides(int $param): void
$this->template->talk = $this->talk;
$this->template->maxSlideUploads = $this->talkSlidesFormFactory->getMaxSlideUploads();
$new = $this->httpInput->getPostArray('new');
$count = $new ? count($new) : 0;
$this->template->newCount = $this->newCount = ($count ?: (int)empty($this->slides));
$this->template->newCount = $this->newCount = $new ? count($new) : (int)(count($this->slides) === 0);
$this->template->dimensions = $this->talkSlides->getSlideDimensions();
}

Expand All @@ -102,7 +100,7 @@ protected function createComponentAddTalkInputs(): TalkInputs

protected function createComponentSlides(): UiForm
{
if (!$this->talk) {
if (!$this->talk || !$this->slides) {
throw new ShouldNotHappenException('actionSlides() will be called first');
}
return $this->talkSlidesFormFactory->create(
Expand Down
12 changes: 6 additions & 6 deletions site/app/Admin/Presenters/templates/Talks/slides.latte
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@
<table id="slides">
{formContainer slides}
{foreach $slides as $slide}
{formContainer $slide->slideId}
{formContainer (string)$slide->getId()}
<tbody>
<tr>
<th class="right">Číslo</th>
<th>Alias</th>
<th>Titulek</th>
<th>Soubor{ifset $slide->filenamesTalkId} z přednášky <a n:href="Talks:slides $slide->filenamesTalkId">{$slide->filenamesTalkId}</a>{/ifset}</th>
<th>Soubor{if $slide->getFilenamesTalkId()} z přednášky <a n:href="Talks:slides $slide->getFilenamesTalkId()">{$slide->getFilenamesTalkId()}</a>{/if}</th>
<th>Nahradit</th>
<th>Rozměry</th>
</tr>
Expand All @@ -46,10 +46,10 @@
<tr class="image-previews">
<td></td>
<td colspan="5">
<img n:if="$slide->image" src="{$slide->image}" alt="{$slide->title}" title="{$slide->title}" class="type-image" data-type="image">
<img n:if="!$slide->image" src="" class="hidden type-image" data-type="image">
<img n:if="$slide->imageAlternative" src="{$slide->imageAlternative}" alt="{$slide->title}" title="{$slide->title}" class="type-alternative" data-type="alternative">
<img n:if="!$slide->imageAlternative" src="" class="hidden type-alternative" data-type="alternative">
<img n:if="$slide->getImage()" src="{$slide->getImage()}" alt="{$slide->getTitle()}" title="{$slide->getTitle()}" class="type-image" data-type="image">
<img n:if="!$slide->getImage()" src="" class="hidden type-image" data-type="image">
<img n:if="$slide->getImageAlternative()" src="{$slide->getImageAlternative()}" alt="{$slide->getTitle()}" title="{$slide->getTitle()}" class="type-alternative" data-type="alternative">
<img n:if="!$slide->getImageAlternative()" src="" class="hidden type-alternative" data-type="alternative">
</td>
</tr>
<tr>
Expand Down
30 changes: 15 additions & 15 deletions site/app/Form/TalkSlidesFormFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
use MichalSpacekCz\Formatter\TexyFormatter;
use MichalSpacekCz\Media\SupportedImageFileFormats;
use MichalSpacekCz\Talks\Exceptions\DuplicatedSlideException;
use MichalSpacekCz\Talks\TalkSlides;
use MichalSpacekCz\Talks\Slides\TalkSlideCollection;
use MichalSpacekCz\Talks\Slides\TalkSlides;
use Nette\Application\Request;
use Nette\Database\Row;
use Nette\Forms\Container;
use Nette\Utils\Html;

Expand All @@ -26,27 +26,26 @@ public function __construct(

/**
* @param callable(Html, string, int): void $onSuccess
* @param Row[] $slides
*/
public function create(callable $onSuccess, int $talkId, array $slides, int $newCount, Request $request): UiForm
public function create(callable $onSuccess, int $talkId, TalkSlideCollection $slides, int $newCount, Request $request): UiForm
{
$form = $this->factory->create();
$slidesContainer = $form->addContainer('slides');
foreach ($slides as $slide) {
$slideIdContainer = $slidesContainer->addContainer($slide->slideId);
$this->addSlideFields($form, $slideIdContainer, $slide->filenamesTalkId);
$slideIdContainer = $slidesContainer->addContainer($slide->getId());
$this->addSlideFields($form, $slideIdContainer, $slide->getFilenamesTalkId());
$values = [
'alias' => $slide->alias,
'number' => $slide->number,
'title' => $slide->title,
'filename' => $slide->filename,
'filenameAlternative' => $slide->filenameAlternative,
'speakerNotes' => $slide->speakerNotesTexy,
'alias' => $slide->getAlias(),
'number' => $slide->getNumber(),
'title' => $slide->getTitle(),
'filename' => $slide->getFilename(),
'filenameAlternative' => $slide->getFilenameAlternative(),
'speakerNotes' => $slide->getSpeakerNotesTexy(),
];
$slideIdContainer->setDefaults($values);
}

if (empty($slides) && $newCount === 0) {
if (count($slides) === 0 && $newCount === 0) {
$newCount = 1;
}
$newContainer = $form->addContainer('new');
Expand All @@ -60,7 +59,8 @@ public function create(callable $onSuccess, int $talkId, array $slides, int $new

$form->onSuccess[] = function (UiForm $form) use ($slides, $onSuccess, $talkId): void {
try {
$this->talkSlides->saveSlides($talkId, $slides, $form->getFormValues());
$values = $form->getFormValues();
$this->talkSlides->saveSlides($talkId, $slides, (array)$values->slides, array_values((array)$values->new), $values->deleteReplaced);
$message = $this->texyFormatter->translate('messages.talks.admin.slideadded');
$type = 'info';
} catch (DuplicatedSlideException $e) {
Expand Down Expand Up @@ -94,7 +94,7 @@ private function addSlideFields(UiForm $form, Container $container, ?int $filena
$container->addText('alias', 'Alias:')
->setRequired('Zadejte prosím alias')
->addRule($form::Pattern, 'Alias musí být ve formátu [_.,a-z0-9-]+', '[_.,a-z0-9-]+');
$container->addText('number', 'Slajd:')
$container->addInteger('number', 'Slajd:')
->setHtmlType('number')
->setDefaultValue(1)
->setHtmlAttribute('class', 'right slide-nr')
Expand Down
16 changes: 16 additions & 0 deletions site/app/Talks/Exceptions/TalkSlideDoesNotExistException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php
declare(strict_types = 1);

namespace MichalSpacekCz\Talks\Exceptions;

use Throwable;

class TalkSlideDoesNotExistException extends TalkException
{

public function __construct(int $talkId, int $number, ?Throwable $previous = null)
{
parent::__construct("Talk id $talkId doesn't have a slide number $number", previous: $previous);
}

}
115 changes: 115 additions & 0 deletions site/app/Talks/Slides/TalkSlide.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<?php
declare(strict_types = 1);

namespace MichalSpacekCz\Talks\Slides;

use Nette\Utils\Html;

class TalkSlide
{

public function __construct(
private readonly int $id,
private readonly string $alias,
private readonly int $number,
private readonly ?string $filename,
private readonly ?string $filenameAlternative,
private readonly ?int $filenamesTalkId,
private readonly string $title,
private readonly Html $speakerNotes,
private readonly string $speakerNotesTexy,
private readonly ?string $image,
private readonly ?string $imageAlternative,
private readonly ?string $imageAlternativeType,
) {
}


public function getId(): int
{
return $this->id;
}


public function getAlias(): string
{
return $this->alias;
}


public function getNumber(): int
{
return $this->number;
}


public function getFilename(): ?string
{
return $this->filename;
}


public function getFilenameAlternative(): ?string
{
return $this->filenameAlternative;
}


public function getFilenamesTalkId(): ?int
{
return $this->filenamesTalkId;
}


public function getTitle(): string
{
return $this->title;
}


public function getSpeakerNotes(): Html
{
return $this->speakerNotes;
}


public function getSpeakerNotesTexy(): string
{
return $this->speakerNotesTexy;
}


public function getImage(): ?string
{
return $this->image;
}


public function getImageAlternative(): ?string
{
return $this->imageAlternative;
}


public function getImageAlternativeType(): ?string
{
return $this->imageAlternativeType;
}


/**
* @return list<string>
*/
public function getAllFilenames(): array
{
$filenames = [];
if ($this->filename) {
$filenames[] = $this->filename;
}
if ($this->filenameAlternative) {
$filenames[] = $this->filenameAlternative;
}
return $filenames;
}

}
59 changes: 59 additions & 0 deletions site/app/Talks/Slides/TalkSlideCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php
declare(strict_types = 1);

namespace MichalSpacekCz\Talks\Slides;

use ArrayIterator;
use Countable;
use IteratorAggregate;
use MichalSpacekCz\Talks\Exceptions\TalkSlideDoesNotExistException;

/**
* @implements IteratorAggregate<int, TalkSlide>
*/
class TalkSlideCollection implements IteratorAggregate, Countable
{

/** @var array<int, TalkSlide> slide number => slide */
private array $slides = [];


public function __construct(
private readonly int $talkId,
) {
}


public function add(TalkSlide $slide): void
{
$this->slides[$slide->getNumber()] = $slide;
}


/**
* @throws TalkSlideDoesNotExistException
*/
public function getByNumber(int $number): TalkSlide
{
if (!isset($this->slides[$number])) {
throw new TalkSlideDoesNotExistException($this->talkId, $number);
}
return $this->slides[$number];
}


/**
* @return ArrayIterator<int, TalkSlide>
*/
public function getIterator(): ArrayIterator
{
return new ArrayIterator($this->slides);
}


public function count(): int
{
return count($this->slides);
}

}
Loading

0 comments on commit e0081c5

Please sign in to comment.