Created DTOs with implicit validation to wrap short URLs lists params

This commit is contained in:
Alejandro Celaya
2020-01-28 10:49:55 +01:00
parent 240d2588f9
commit 452bfea088
15 changed files with 335 additions and 166 deletions

View File

@@ -0,0 +1,63 @@
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Model;
use Shlinkio\Shlink\Core\Exception\ValidationException;
use function is_array;
use function is_string;
use function key;
final class ShortUrlsOrdering
{
public const ORDER_BY = 'orderBy';
private const DEFAULT_ORDER_DIRECTION = 'ASC';
private ?string $orderField = null;
private string $orderDirection = self::DEFAULT_ORDER_DIRECTION;
/**
* @throws ValidationException
*/
public static function fromRawData(array $query): self
{
$instance = new self();
$instance->validateAndInit($query);
return $instance;
}
/**
* @throws ValidationException
*/
private function validateAndInit(array $data): void
{
/** @var string|array|null $orderBy */
$orderBy = $data[self::ORDER_BY] ?? null;
if ($orderBy === null) {
return;
}
$isArray = is_array($orderBy);
if (! $isArray && $orderBy !== null && ! is_string($orderBy)) {
throw ValidationException::fromArray([
'orderBy' => '"Order by" must be an array, string or null',
]);
}
$this->orderField = $isArray ? key($orderBy) : $orderBy;
$this->orderDirection = $isArray ? $orderBy[$this->orderField] : self::DEFAULT_ORDER_DIRECTION;
}
public function orderField(): ?string
{
return $this->orderField;
}
public function orderDirection(): string
{
return $this->orderDirection;
}
}

View File

@@ -0,0 +1,85 @@
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Model;
use Shlinkio\Shlink\Common\Util\DateRange;
use Shlinkio\Shlink\Core\Exception\ValidationException;
use Shlinkio\Shlink\Core\Validation\ShortUrlsParamsInputFilter;
use function Shlinkio\Shlink\Core\parseDateField;
final class ShortUrlsParams
{
private int $page;
private ?string $searchTerm;
private array $tags;
private ShortUrlsOrdering $orderBy;
private ?DateRange $dateRange;
private function __construct()
{
}
public static function emptyInstance(): self
{
return self::fromRawData([]);
}
/**
* @throws ValidationException
*/
public static function fromRawData(array $query): self
{
$instance = new self();
$instance->validateAndInit($query);
return $instance;
}
/**
* @throws ValidationException
*/
private function validateAndInit(array $query): void
{
$inputFilter = new ShortUrlsParamsInputFilter($query);
if (! $inputFilter->isValid()) {
throw ValidationException::fromInputFilter($inputFilter);
}
$this->page = (int) ($inputFilter->getValue(ShortUrlsParamsInputFilter::PAGE) ?? 1);
$this->searchTerm = $inputFilter->getValue(ShortUrlsParamsInputFilter::SEARCH_TERM);
$this->tags = (array) $inputFilter->getValue(ShortUrlsParamsInputFilter::TAGS);
$this->dateRange = new DateRange(
parseDateField($inputFilter->getValue(ShortUrlsParamsInputFilter::START_DATE)),
parseDateField($inputFilter->getValue(ShortUrlsParamsInputFilter::END_DATE)),
);
$this->orderBy = ShortUrlsOrdering::fromRawData($query);
}
public function page(): int
{
return $this->page;
}
public function searchTerm(): ?string
{
return $this->searchTerm;
}
public function tags(): array
{
return $this->tags;
}
public function orderBy(): ShortUrlsOrdering
{
return $this->orderBy;
}
public function dateRange(): ?DateRange
{
return $this->dateRange;
}
}