2883c6d0a7
It is not useful for the RSS feed, as every new entry will be 'yesterday', and it requires an update the next day.
212 lines
7.6 KiB
PHP
212 lines
7.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Shaarli\Helper;
|
|
|
|
use Shaarli\Bookmark\Bookmark;
|
|
use Slim\Http\Request;
|
|
|
|
class DailyPageHelper
|
|
{
|
|
public const MONTH = 'month';
|
|
public const WEEK = 'week';
|
|
public const DAY = 'day';
|
|
|
|
/**
|
|
* Extracts the type of the daily to display from the HTTP request parameters
|
|
*
|
|
* @param Request $request HTTP request
|
|
*
|
|
* @return string month/week/day
|
|
*/
|
|
public static function extractRequestedType(Request $request): string
|
|
{
|
|
if ($request->getQueryParam(static::MONTH) !== null) {
|
|
return static::MONTH;
|
|
} elseif ($request->getQueryParam(static::WEEK) !== null) {
|
|
return static::WEEK;
|
|
}
|
|
|
|
return static::DAY;
|
|
}
|
|
|
|
/**
|
|
* Extracts a DateTimeImmutable from provided HTTP request.
|
|
* If no parameter is provided, we rely on the creation date of the latest provided created bookmark.
|
|
* If the datastore is empty or no bookmark is provided, we use the current date.
|
|
*
|
|
* @param string $type month/week/day
|
|
* @param string|null $requestedDate Input string extracted from the request
|
|
* @param Bookmark|null $latestBookmark Latest bookmark found in the datastore (by date)
|
|
*
|
|
* @return \DateTimeImmutable from input or latest bookmark.
|
|
*
|
|
* @throws \Exception Type not supported.
|
|
*/
|
|
public static function extractRequestedDateTime(
|
|
string $type,
|
|
?string $requestedDate,
|
|
Bookmark $latestBookmark = null
|
|
): \DateTimeImmutable {
|
|
$format = static::getFormatByType($type);
|
|
if (empty($requestedDate)) {
|
|
return $latestBookmark instanceof Bookmark
|
|
? new \DateTimeImmutable($latestBookmark->getCreated()->format(\DateTime::ATOM))
|
|
: new \DateTimeImmutable()
|
|
;
|
|
}
|
|
|
|
// W is not supported by createFromFormat...
|
|
if ($type === static::WEEK) {
|
|
return (new \DateTimeImmutable())
|
|
->setISODate((int) substr($requestedDate, 0, 4), (int) substr($requestedDate, 4, 2))
|
|
;
|
|
}
|
|
|
|
return \DateTimeImmutable::createFromFormat($format, $requestedDate);
|
|
}
|
|
|
|
/**
|
|
* Get the DateTime format used by provided type
|
|
* Examples:
|
|
* - day: 20201016 (<year><month><day>)
|
|
* - week: 202041 (<year><week number>)
|
|
* - month: 202010 (<year><month>)
|
|
*
|
|
* @param string $type month/week/day
|
|
*
|
|
* @return string DateTime compatible format
|
|
*
|
|
* @see https://www.php.net/manual/en/datetime.format.php
|
|
*
|
|
* @throws \Exception Type not supported.
|
|
*/
|
|
public static function getFormatByType(string $type): string
|
|
{
|
|
switch ($type) {
|
|
case static::MONTH:
|
|
return 'Ym';
|
|
case static::WEEK:
|
|
return 'YW';
|
|
case static::DAY:
|
|
return 'Ymd';
|
|
default:
|
|
throw new \Exception('Unsupported daily format type');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the first DateTime of the time period depending on given datetime and type.
|
|
* Note: DateTimeImmutable is required because we rely heavily on DateTime->modify() syntax
|
|
* and we don't want to alter original datetime.
|
|
*
|
|
* @param string $type month/week/day
|
|
* @param \DateTimeImmutable $requested DateTime extracted from request input
|
|
* (should come from extractRequestedDateTime)
|
|
*
|
|
* @return \DateTimeInterface First DateTime of the time period
|
|
*
|
|
* @throws \Exception Type not supported.
|
|
*/
|
|
public static function getStartDateTimeByType(string $type, \DateTimeImmutable $requested): \DateTimeInterface
|
|
{
|
|
switch ($type) {
|
|
case static::MONTH:
|
|
return $requested->modify('first day of this month midnight');
|
|
case static::WEEK:
|
|
return $requested->modify('Monday this week midnight');
|
|
case static::DAY:
|
|
return $requested->modify('Today midnight');
|
|
default:
|
|
throw new \Exception('Unsupported daily format type');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the last DateTime of the time period depending on given datetime and type.
|
|
* Note: DateTimeImmutable is required because we rely heavily on DateTime->modify() syntax
|
|
* and we don't want to alter original datetime.
|
|
*
|
|
* @param string $type month/week/day
|
|
* @param \DateTimeImmutable $requested DateTime extracted from request input
|
|
* (should come from extractRequestedDateTime)
|
|
*
|
|
* @return \DateTimeInterface Last DateTime of the time period
|
|
*
|
|
* @throws \Exception Type not supported.
|
|
*/
|
|
public static function getEndDateTimeByType(string $type, \DateTimeImmutable $requested): \DateTimeInterface
|
|
{
|
|
switch ($type) {
|
|
case static::MONTH:
|
|
return $requested->modify('last day of this month 23:59:59');
|
|
case static::WEEK:
|
|
return $requested->modify('Sunday this week 23:59:59');
|
|
case static::DAY:
|
|
return $requested->modify('Today 23:59:59');
|
|
default:
|
|
throw new \Exception('Unsupported daily format type');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get localized description of the time period depending on given datetime and type.
|
|
* Example: for a month period, it returns `October, 2020`.
|
|
*
|
|
* @param string $type month/week/day
|
|
* @param \DateTimeImmutable $requested DateTime extracted from request input
|
|
* (should come from extractRequestedDateTime)
|
|
* @param bool $includeRelative Include relative date description (today, yesterday, etc.)
|
|
*
|
|
* @return string Localized time period description
|
|
*
|
|
* @throws \Exception Type not supported.
|
|
*/
|
|
public static function getDescriptionByType(
|
|
string $type,
|
|
\DateTimeImmutable $requested,
|
|
bool $includeRelative = true
|
|
): string {
|
|
switch ($type) {
|
|
case static::MONTH:
|
|
return $requested->format('F') . ', ' . $requested->format('Y');
|
|
case static::WEEK:
|
|
$requested = $requested->modify('Monday this week');
|
|
return t('Week') . ' ' . $requested->format('W') . ' (' . format_date($requested, false) . ')';
|
|
case static::DAY:
|
|
$out = '';
|
|
if ($includeRelative && $requested->format('Ymd') === date('Ymd')) {
|
|
$out = t('Today') . ' - ';
|
|
} elseif ($includeRelative && $requested->format('Ymd') === date('Ymd', strtotime('-1 days'))) {
|
|
$out = t('Yesterday') . ' - ';
|
|
}
|
|
return $out . format_date($requested, false);
|
|
default:
|
|
throw new \Exception('Unsupported daily format type');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the number of items to display in the RSS feed depending on the given type.
|
|
*
|
|
* @param string $type month/week/day
|
|
*
|
|
* @return int number of elements
|
|
*
|
|
* @throws \Exception Type not supported.
|
|
*/
|
|
public static function getRssLengthByType(string $type): int
|
|
{
|
|
switch ($type) {
|
|
case static::MONTH:
|
|
return 12; // 1 year
|
|
case static::WEEK:
|
|
return 26; // ~6 months
|
|
case static::DAY:
|
|
return 30; // ~1 month
|
|
default:
|
|
throw new \Exception('Unsupported daily format type');
|
|
}
|
|
}
|
|
}
|