Ensured all input dates are changed to the default timezone before being used on any inner layer

This commit is contained in:
Alejandro Celaya 2022-04-15 19:57:27 +02:00
parent f8208b7288
commit c20c3801a8
4 changed files with 30 additions and 31 deletions

View File

@ -12,6 +12,7 @@ use Laminas\InputFilter\InputFilter;
use PUGX\Shortid\Factory as ShortIdFactory;
use Shlinkio\Shlink\Common\Util\DateRange;
use function date_default_timezone_get;
use function Functional\reduce_left;
use function is_array;
use function print_r;
@ -32,7 +33,7 @@ function generateRandomShortCode(int $length): string
function parseDateFromQuery(array $query, string $dateName): ?Chronos
{
return empty($query[$dateName] ?? null) ? null : Chronos::parse($query[$dateName]);
return normalizeDate(empty($query[$dateName] ?? null) ? null : Chronos::parse($query[$dateName]));
}
function parseDateRangeFromQuery(array $query, string $startDateName, string $endDateName): DateRange
@ -43,29 +44,15 @@ function parseDateRangeFromQuery(array $query, string $startDateName, string $en
return buildDateRange($startDate, $endDate);
}
function parseDateField(string|DateTimeInterface|Chronos|null $date): ?Chronos
function normalizeDate(string|DateTimeInterface|Chronos|null $date): ?Chronos
{
if ($date === null || $date instanceof Chronos) {
return $date;
}
$parsedDate = match (true) {
$date === null || $date instanceof Chronos => $date,
$date instanceof DateTimeInterface => Chronos::instance($date),
default => Chronos::parse($date),
};
if ($date instanceof DateTimeInterface) {
return Chronos::instance($date);
}
return Chronos::parse($date);
}
function determineTableName(string $tableName, array $emConfig = []): string
{
$schema = $emConfig['connection']['schema'] ?? null;
// $tablePrefix = $emConfig['connection']['table_prefix'] ?? null; // TODO
if ($schema === null) {
return $tableName;
}
return sprintf('%s.%s', $schema, $tableName);
return $parsedDate?->setTimezone(date_default_timezone_get());
}
function getOptionalIntFromInputFilter(InputFilter $inputFilter, string $fieldName): ?int
@ -108,6 +95,18 @@ function isCrawler(string $userAgent): bool
return $detector->isCrawler($userAgent);
}
function determineTableName(string $tableName, array $emConfig = []): string
{
$schema = $emConfig['connection']['schema'] ?? null;
// $tablePrefix = $emConfig['connection']['table_prefix'] ?? null; // TODO
if ($schema === null) {
return $tableName;
}
return sprintf('%s.%s', $schema, $tableName);
}
function fieldWithUtf8Charset(FieldBuilder $field, array $emConfig, string $collation = 'unicode_ci'): FieldBuilder
{
return match ($emConfig['connection']['driver'] ?? null) {

View File

@ -12,7 +12,7 @@ use Shlinkio\Shlink\Core\Validation\ShortUrlInputFilter;
use function array_key_exists;
use function Shlinkio\Shlink\Core\getOptionalBoolFromInputFilter;
use function Shlinkio\Shlink\Core\getOptionalIntFromInputFilter;
use function Shlinkio\Shlink\Core\parseDateField;
use function Shlinkio\Shlink\Core\normalizeDate;
final class ShortUrlEdit implements TitleResolutionModelInterface
{
@ -69,8 +69,8 @@ final class ShortUrlEdit implements TitleResolutionModelInterface
$this->forwardQueryPropWasProvided = array_key_exists(ShortUrlInputFilter::FORWARD_QUERY, $data);
$this->longUrl = $inputFilter->getValue(ShortUrlInputFilter::LONG_URL);
$this->validSince = parseDateField($inputFilter->getValue(ShortUrlInputFilter::VALID_SINCE));
$this->validUntil = parseDateField($inputFilter->getValue(ShortUrlInputFilter::VALID_UNTIL));
$this->validSince = normalizeDate($inputFilter->getValue(ShortUrlInputFilter::VALID_SINCE));
$this->validUntil = normalizeDate($inputFilter->getValue(ShortUrlInputFilter::VALID_UNTIL));
$this->maxVisits = getOptionalIntFromInputFilter($inputFilter, ShortUrlInputFilter::MAX_VISITS);
$this->validateUrl = getOptionalBoolFromInputFilter($inputFilter, ShortUrlInputFilter::VALIDATE_URL) ?? false;
$this->tags = $inputFilter->getValue(ShortUrlInputFilter::TAGS);

View File

@ -12,7 +12,7 @@ use Shlinkio\Shlink\Rest\Entity\ApiKey;
use function Shlinkio\Shlink\Core\getOptionalBoolFromInputFilter;
use function Shlinkio\Shlink\Core\getOptionalIntFromInputFilter;
use function Shlinkio\Shlink\Core\parseDateField;
use function Shlinkio\Shlink\Core\normalizeDate;
use const Shlinkio\Shlink\DEFAULT_SHORT_CODES_LENGTH;
@ -68,8 +68,8 @@ final class ShortUrlMeta implements TitleResolutionModelInterface
}
$this->longUrl = $inputFilter->getValue(ShortUrlInputFilter::LONG_URL);
$this->validSince = parseDateField($inputFilter->getValue(ShortUrlInputFilter::VALID_SINCE));
$this->validUntil = parseDateField($inputFilter->getValue(ShortUrlInputFilter::VALID_UNTIL));
$this->validSince = normalizeDate($inputFilter->getValue(ShortUrlInputFilter::VALID_SINCE));
$this->validUntil = normalizeDate($inputFilter->getValue(ShortUrlInputFilter::VALID_UNTIL));
$this->customSlug = $inputFilter->getValue(ShortUrlInputFilter::CUSTOM_SLUG);
$this->maxVisits = getOptionalIntFromInputFilter($inputFilter, ShortUrlInputFilter::MAX_VISITS);
$this->findIfExists = $inputFilter->getValue(ShortUrlInputFilter::FIND_IF_EXISTS);

View File

@ -9,7 +9,7 @@ use Shlinkio\Shlink\Core\Exception\ValidationException;
use Shlinkio\Shlink\Core\Validation\ShortUrlsParamsInputFilter;
use function Shlinkio\Shlink\Common\buildDateRange;
use function Shlinkio\Shlink\Core\parseDateField;
use function Shlinkio\Shlink\Core\normalizeDate;
final class ShortUrlsParams
{
@ -61,8 +61,8 @@ final class ShortUrlsParams
$this->searchTerm = $inputFilter->getValue(ShortUrlsParamsInputFilter::SEARCH_TERM);
$this->tags = (array) $inputFilter->getValue(ShortUrlsParamsInputFilter::TAGS);
$this->dateRange = buildDateRange(
parseDateField($inputFilter->getValue(ShortUrlsParamsInputFilter::START_DATE)),
parseDateField($inputFilter->getValue(ShortUrlsParamsInputFilter::END_DATE)),
normalizeDate($inputFilter->getValue(ShortUrlsParamsInputFilter::START_DATE)),
normalizeDate($inputFilter->getValue(ShortUrlsParamsInputFilter::END_DATE)),
);
$this->orderBy = Ordering::fromTuple($inputFilter->getValue(ShortUrlsParamsInputFilter::ORDER_BY));
$this->itemsPerPage = (int) (