Merge pull request #1595 from ArthurHoaro/feature/daily-period
This commit is contained in:
commit
b8e5a253ab
27 changed files with 1207 additions and 329 deletions
|
@ -4,6 +4,7 @@
|
||||||
use DateTime;
|
use DateTime;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Shaarli\Bookmark\Bookmark;
|
use Shaarli\Bookmark\Bookmark;
|
||||||
|
use Shaarli\Helper\FileUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class History
|
* Class History
|
||||||
|
|
|
@ -326,6 +326,23 @@ function format_date($date, $time = true, $intl = true)
|
||||||
return $formatter->format($date);
|
return $formatter->format($date);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format the date month according to the locale.
|
||||||
|
*
|
||||||
|
* @param DateTimeInterface $date to format.
|
||||||
|
*
|
||||||
|
* @return bool|string Formatted date, or false if the input is invalid.
|
||||||
|
*/
|
||||||
|
function format_month(DateTimeInterface $date)
|
||||||
|
{
|
||||||
|
if (! $date instanceof DateTimeInterface) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return strftime('%B', $date->getTimestamp());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the input is an integer, no matter its real type.
|
* Check if the input is an integer, no matter its real type.
|
||||||
*
|
*
|
||||||
|
@ -458,12 +475,16 @@ function alphabetical_sort(&$data, $reverse = false, $byKeys = false)
|
||||||
* @param string $nText The plural message ID.
|
* @param string $nText The plural message ID.
|
||||||
* @param int $nb The number of items for plural forms.
|
* @param int $nb The number of items for plural forms.
|
||||||
* @param string $domain The domain where the translation is stored (default: shaarli).
|
* @param string $domain The domain where the translation is stored (default: shaarli).
|
||||||
|
* @param array $variables Associative array of variables to replace in translated text.
|
||||||
|
* @param bool $fixCase Apply `ucfirst` on the translated string, might be useful for strings with variables.
|
||||||
*
|
*
|
||||||
* @return string Text translated.
|
* @return string Text translated.
|
||||||
*/
|
*/
|
||||||
function t($text, $nText = '', $nb = 1, $domain = 'shaarli')
|
function t($text, $nText = '', $nb = 1, $domain = 'shaarli', $variables = [], $fixCase = false)
|
||||||
{
|
{
|
||||||
return dn__($domain, $text, $nText, $nb);
|
$postFunction = $fixCase ? 'ucfirst' : function ($input) { return $input; };
|
||||||
|
|
||||||
|
return $postFunction(dn__($domain, $text, $nText, $nb, $variables));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -343,26 +343,42 @@ public function bookmarksCountPerTag(array $filteringTags = [], string $visibili
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function days(): array
|
public function findByDate(
|
||||||
{
|
\DateTimeInterface $from,
|
||||||
$bookmarkDays = [];
|
\DateTimeInterface $to,
|
||||||
foreach ($this->search() as $bookmark) {
|
?\DateTimeInterface &$previous,
|
||||||
$bookmarkDays[$bookmark->getCreated()->format('Ymd')] = 0;
|
?\DateTimeInterface &$next
|
||||||
}
|
): array {
|
||||||
$bookmarkDays = array_keys($bookmarkDays);
|
$out = [];
|
||||||
sort($bookmarkDays);
|
$previous = null;
|
||||||
|
$next = null;
|
||||||
|
|
||||||
return array_map('strval', $bookmarkDays);
|
foreach ($this->search([], null, false, false, true) as $bookmark) {
|
||||||
|
if ($to < $bookmark->getCreated()) {
|
||||||
|
$next = $bookmark->getCreated();
|
||||||
|
} else if ($from < $bookmark->getCreated() && $to > $bookmark->getCreated()) {
|
||||||
|
$out[] = $bookmark;
|
||||||
|
} else {
|
||||||
|
if ($previous !== null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$previous = $bookmark->getCreated();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function filterDay(string $request)
|
public function getLatest(): ?Bookmark
|
||||||
{
|
{
|
||||||
$visibility = $this->isLoggedIn ? BookmarkFilter::$ALL : BookmarkFilter::$PUBLIC;
|
foreach ($this->search([], null, false, false, true) as $bookmark) {
|
||||||
|
return $bookmark;
|
||||||
|
}
|
||||||
|
|
||||||
return $this->bookmarkFilter->filter(BookmarkFilter::$FILTER_DAY, $request, false, $visibility);
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -156,22 +156,29 @@ public function save(): void;
|
||||||
public function bookmarksCountPerTag(array $filteringTags = [], ?string $visibility = null): array;
|
public function bookmarksCountPerTag(array $filteringTags = [], ?string $visibility = null): array;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the list of days containing articles (oldest first)
|
* Return a list of bookmark matching provided period of time.
|
||||||
|
* It also update directly previous and next date outside of given period found in the datastore.
|
||||||
*
|
*
|
||||||
* @return array containing days (in format YYYYMMDD).
|
* @param \DateTimeInterface $from Starting date.
|
||||||
|
* @param \DateTimeInterface $to Ending date.
|
||||||
|
* @param \DateTimeInterface|null $previous (by reference) updated with first created date found before $from.
|
||||||
|
* @param \DateTimeInterface|null $next (by reference) updated with first created date found after $to.
|
||||||
|
*
|
||||||
|
* @return array List of bookmarks matching provided period of time.
|
||||||
*/
|
*/
|
||||||
public function days(): array;
|
public function findByDate(
|
||||||
|
\DateTimeInterface $from,
|
||||||
|
\DateTimeInterface $to,
|
||||||
|
?\DateTimeInterface &$previous,
|
||||||
|
?\DateTimeInterface &$next
|
||||||
|
): array;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the list of articles for a given day.
|
* Returns the latest bookmark by creation date.
|
||||||
*
|
*
|
||||||
* @param string $request day to filter. Format: YYYYMMDD.
|
* @return Bookmark|null Found Bookmark or null if the datastore is empty.
|
||||||
*
|
|
||||||
* @return Bookmark[] list of shaare found.
|
|
||||||
*
|
|
||||||
* @throws BookmarkNotFoundException
|
|
||||||
*/
|
*/
|
||||||
public function filterDay(string $request);
|
public function getLatest(): ?Bookmark;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the default database after a fresh install.
|
* Creates the default database after a fresh install.
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
|
|
||||||
namespace Shaarli\Front\Controller\Admin;
|
namespace Shaarli\Front\Controller\Admin;
|
||||||
|
|
||||||
use Shaarli\ApplicationUtils;
|
use Shaarli\Helper\ApplicationUtils;
|
||||||
use Shaarli\FileUtils;
|
use Shaarli\Helper\FileUtils;
|
||||||
use Slim\Http\Request;
|
use Slim\Http\Request;
|
||||||
use Slim\Http\Response;
|
use Slim\Http\Response;
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
namespace Shaarli\Front\Controller\Visitor;
|
namespace Shaarli\Front\Controller\Visitor;
|
||||||
|
|
||||||
use DateTime;
|
use DateTime;
|
||||||
use DateTimeImmutable;
|
|
||||||
use Shaarli\Bookmark\Bookmark;
|
use Shaarli\Bookmark\Bookmark;
|
||||||
|
use Shaarli\Helper\DailyPageHelper;
|
||||||
use Shaarli\Render\TemplatePage;
|
use Shaarli\Render\TemplatePage;
|
||||||
use Slim\Http\Request;
|
use Slim\Http\Request;
|
||||||
use Slim\Http\Response;
|
use Slim\Http\Response;
|
||||||
|
@ -26,32 +26,20 @@ class DailyController extends ShaarliVisitorController
|
||||||
*/
|
*/
|
||||||
public function index(Request $request, Response $response): Response
|
public function index(Request $request, Response $response): Response
|
||||||
{
|
{
|
||||||
$day = $request->getQueryParam('day') ?? date('Ymd');
|
$type = DailyPageHelper::extractRequestedType($request);
|
||||||
|
$format = DailyPageHelper::getFormatByType($type);
|
||||||
|
$latestBookmark = $this->container->bookmarkService->getLatest();
|
||||||
|
$dateTime = DailyPageHelper::extractRequestedDateTime($type, $request->getQueryParam($type), $latestBookmark);
|
||||||
|
$start = DailyPageHelper::getStartDateTimeByType($type, $dateTime);
|
||||||
|
$end = DailyPageHelper::getEndDateTimeByType($type, $dateTime);
|
||||||
|
$dailyDesc = DailyPageHelper::getDescriptionByType($type, $dateTime);
|
||||||
|
|
||||||
$availableDates = $this->container->bookmarkService->days();
|
$linksToDisplay = $this->container->bookmarkService->findByDate(
|
||||||
$nbAvailableDates = count($availableDates);
|
$start,
|
||||||
$index = array_search($day, $availableDates);
|
$end,
|
||||||
|
$previousDay,
|
||||||
if ($index === false) {
|
$nextDay
|
||||||
// no bookmarks for day, but at least one day with bookmarks
|
);
|
||||||
$day = $availableDates[$nbAvailableDates - 1] ?? $day;
|
|
||||||
$previousDay = $availableDates[$nbAvailableDates - 2] ?? '';
|
|
||||||
} else {
|
|
||||||
$previousDay = $availableDates[$index - 1] ?? '';
|
|
||||||
$nextDay = $availableDates[$index + 1] ?? '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($day === date('Ymd')) {
|
|
||||||
$this->assignView('dayDesc', t('Today'));
|
|
||||||
} elseif ($day === date('Ymd', strtotime('-1 days'))) {
|
|
||||||
$this->assignView('dayDesc', t('Yesterday'));
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$linksToDisplay = $this->container->bookmarkService->filterDay($day);
|
|
||||||
} catch (\Exception $exc) {
|
|
||||||
$linksToDisplay = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
$formatter = $this->container->formatterFactory->getFormatter();
|
$formatter = $this->container->formatterFactory->getFormatter();
|
||||||
$formatter->addContextData('base_path', $this->container->basePath);
|
$formatter->addContextData('base_path', $this->container->basePath);
|
||||||
|
@ -63,13 +51,15 @@ public function index(Request $request, Response $response): Response
|
||||||
$linksToDisplay[$key]['description'] = $bookmark->getDescription();
|
$linksToDisplay[$key]['description'] = $bookmark->getDescription();
|
||||||
}
|
}
|
||||||
|
|
||||||
$dayDate = DateTime::createFromFormat(Bookmark::LINK_DATE_FORMAT, $day.'_000000');
|
|
||||||
$data = [
|
$data = [
|
||||||
'linksToDisplay' => $linksToDisplay,
|
'linksToDisplay' => $linksToDisplay,
|
||||||
'day' => $dayDate->getTimestamp(),
|
'dayDate' => $start,
|
||||||
'dayDate' => $dayDate,
|
'day' => $start->getTimestamp(),
|
||||||
'previousday' => $previousDay ?? '',
|
'previousday' => $previousDay ? $previousDay->format($format) : '',
|
||||||
'nextday' => $nextDay ?? '',
|
'nextday' => $nextDay ? $nextDay->format($format) : '',
|
||||||
|
'dayDesc' => $dailyDesc,
|
||||||
|
'type' => $type,
|
||||||
|
'localizedType' => $this->translateType($type),
|
||||||
];
|
];
|
||||||
|
|
||||||
// Hooks are called before column construction so that plugins don't have to deal with columns.
|
// Hooks are called before column construction so that plugins don't have to deal with columns.
|
||||||
|
@ -82,7 +72,7 @@ public function index(Request $request, Response $response): Response
|
||||||
$mainTitle = $this->container->conf->get('general.title', 'Shaarli');
|
$mainTitle = $this->container->conf->get('general.title', 'Shaarli');
|
||||||
$this->assignView(
|
$this->assignView(
|
||||||
'pagetitle',
|
'pagetitle',
|
||||||
t('Daily') .' - '. format_date($dayDate, false) . ' - ' . $mainTitle
|
$data['localizedType'] . ' - ' . $data['dayDesc'] . ' - ' . $mainTitle
|
||||||
);
|
);
|
||||||
|
|
||||||
return $response->write($this->render(TemplatePage::DAILY));
|
return $response->write($this->render(TemplatePage::DAILY));
|
||||||
|
@ -106,11 +96,14 @@ public function rss(Request $request, Response $response): Response
|
||||||
}
|
}
|
||||||
|
|
||||||
$days = [];
|
$days = [];
|
||||||
|
$type = DailyPageHelper::extractRequestedType($request);
|
||||||
|
$format = DailyPageHelper::getFormatByType($type);
|
||||||
|
$length = DailyPageHelper::getRssLengthByType($type);
|
||||||
foreach ($this->container->bookmarkService->search() as $bookmark) {
|
foreach ($this->container->bookmarkService->search() as $bookmark) {
|
||||||
$day = $bookmark->getCreated()->format('Ymd');
|
$day = $bookmark->getCreated()->format($format);
|
||||||
|
|
||||||
// Stop iterating after DAILY_RSS_NB_DAYS entries
|
// Stop iterating after DAILY_RSS_NB_DAYS entries
|
||||||
if (count($days) === static::$DAILY_RSS_NB_DAYS && !isset($days[$day])) {
|
if (count($days) === $length && !isset($days[$day])) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,12 +120,19 @@ public function rss(Request $request, Response $response): Response
|
||||||
|
|
||||||
/** @var Bookmark[] $bookmarks */
|
/** @var Bookmark[] $bookmarks */
|
||||||
foreach ($days as $day => $bookmarks) {
|
foreach ($days as $day => $bookmarks) {
|
||||||
$dayDatetime = DateTimeImmutable::createFromFormat(Bookmark::LINK_DATE_FORMAT, $day.'_000000');
|
$dayDateTime = DailyPageHelper::extractRequestedDateTime($type, (string) $day);
|
||||||
|
$endDateTime = DailyPageHelper::getEndDateTimeByType($type, $dayDateTime);
|
||||||
|
|
||||||
|
// We only want the RSS entry to be published when the period is over.
|
||||||
|
if (new DateTime() < $endDateTime) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$dataPerDay[$day] = [
|
$dataPerDay[$day] = [
|
||||||
'date' => $dayDatetime,
|
'date' => $endDateTime,
|
||||||
'date_rss' => $dayDatetime->format(DateTime::RSS),
|
'date_rss' => $endDateTime->format(DateTime::RSS),
|
||||||
'date_human' => format_date($dayDatetime, false, true),
|
'date_human' => DailyPageHelper::getDescriptionByType($type, $dayDateTime),
|
||||||
'absolute_url' => $indexUrl . 'daily?day=' . $day,
|
'absolute_url' => $indexUrl . 'daily?'. $type .'=' . $day,
|
||||||
'links' => [],
|
'links' => [],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -141,16 +141,20 @@ public function rss(Request $request, Response $response): Response
|
||||||
|
|
||||||
// Make permalink URL absolute
|
// Make permalink URL absolute
|
||||||
if ($bookmark->isNote()) {
|
if ($bookmark->isNote()) {
|
||||||
$dataPerDay[$day]['links'][$key]['url'] = $indexUrl . $bookmark->getUrl();
|
$dataPerDay[$day]['links'][$key]['url'] = rtrim($indexUrl, '/') . $bookmark->getUrl();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->assignView('title', $this->container->conf->get('general.title', 'Shaarli'));
|
$this->assignAllView([
|
||||||
$this->assignView('index_url', $indexUrl);
|
'title' => $this->container->conf->get('general.title', 'Shaarli'),
|
||||||
$this->assignView('page_url', $pageUrl);
|
'index_url' => $indexUrl,
|
||||||
$this->assignView('hide_timestamps', $this->container->conf->get('privacy.hide_timestamps', false));
|
'page_url' => $pageUrl,
|
||||||
$this->assignView('days', $dataPerDay);
|
'hide_timestamps' => $this->container->conf->get('privacy.hide_timestamps', false),
|
||||||
|
'days' => $dataPerDay,
|
||||||
|
'type' => $type,
|
||||||
|
'localizedType' => $this->translateType($type),
|
||||||
|
]);
|
||||||
|
|
||||||
$rssContent = $this->render(TemplatePage::DAILY_RSS);
|
$rssContent = $this->render(TemplatePage::DAILY_RSS);
|
||||||
|
|
||||||
|
@ -189,4 +193,13 @@ protected function calculateColumns(array $links): array
|
||||||
|
|
||||||
return $columns;
|
return $columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function translateType($type): string
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
t('day') => t('Daily'),
|
||||||
|
t('week') => t('Weekly'),
|
||||||
|
t('month') => t('Monthly'),
|
||||||
|
][t($type)] ?? t('Daily');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
|
|
||||||
namespace Shaarli\Front\Controller\Visitor;
|
namespace Shaarli\Front\Controller\Visitor;
|
||||||
|
|
||||||
use Shaarli\ApplicationUtils;
|
|
||||||
use Shaarli\Container\ShaarliContainer;
|
use Shaarli\Container\ShaarliContainer;
|
||||||
use Shaarli\Front\Exception\AlreadyInstalledException;
|
use Shaarli\Front\Exception\AlreadyInstalledException;
|
||||||
use Shaarli\Front\Exception\ResourcePermissionException;
|
use Shaarli\Front\Exception\ResourcePermissionException;
|
||||||
|
use Shaarli\Helper\ApplicationUtils;
|
||||||
use Shaarli\Languages;
|
use Shaarli\Languages;
|
||||||
use Shaarli\Security\SessionManager;
|
use Shaarli\Security\SessionManager;
|
||||||
use Slim\Http\Request;
|
use Slim\Http\Request;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
namespace Shaarli;
|
namespace Shaarli\Helper;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use Shaarli\Config\ConfigManager;
|
use Shaarli\Config\ConfigManager;
|
208
application/helper/DailyPageHelper.php
Normal file
208
application/helper/DailyPageHelper.php
Normal file
|
@ -0,0 +1,208 @@
|
||||||
|
<?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)
|
||||||
|
*
|
||||||
|
* @return string Localized time period description
|
||||||
|
*
|
||||||
|
* @throws \Exception Type not supported.
|
||||||
|
*/
|
||||||
|
public static function getDescriptionByType(string $type, \DateTimeImmutable $requested): 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 ($requested->format('Ymd') === date('Ymd')) {
|
||||||
|
$out = t('Today') . ' - ';
|
||||||
|
} elseif ($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');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Shaarli;
|
namespace Shaarli\Helper;
|
||||||
|
|
||||||
use Shaarli\Exceptions\IOException;
|
use Shaarli\Exceptions\IOException;
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ public static function clearFolder(string $path, bool $selfDelete, array $exclud
|
||||||
*/
|
*/
|
||||||
public static function isPathInShaarliFolder(string $path): bool
|
public static function isPathInShaarliFolder(string $path): bool
|
||||||
{
|
{
|
||||||
$rootDirectory = dirname(dirname(__FILE__));
|
$rootDirectory = dirname(dirname(dirname(__FILE__)));
|
||||||
|
|
||||||
return strpos(realpath($path), $rootDirectory) !== false;
|
return strpos(realpath($path), $rootDirectory) !== false;
|
||||||
}
|
}
|
|
@ -8,7 +8,7 @@
|
||||||
use Iterator;
|
use Iterator;
|
||||||
use Shaarli\Bookmark\Exception\BookmarkNotFoundException;
|
use Shaarli\Bookmark\Exception\BookmarkNotFoundException;
|
||||||
use Shaarli\Exceptions\IOException;
|
use Shaarli\Exceptions\IOException;
|
||||||
use Shaarli\FileUtils;
|
use Shaarli\Helper\FileUtils;
|
||||||
use Shaarli\Render\PageCacheManager;
|
use Shaarli\Render\PageCacheManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
use ReflectionClass;
|
use ReflectionClass;
|
||||||
use ReflectionException;
|
use ReflectionException;
|
||||||
use ReflectionMethod;
|
use ReflectionMethod;
|
||||||
use Shaarli\ApplicationUtils;
|
|
||||||
use Shaarli\Bookmark\Bookmark;
|
use Shaarli\Bookmark\Bookmark;
|
||||||
use Shaarli\Bookmark\BookmarkArray;
|
use Shaarli\Bookmark\BookmarkArray;
|
||||||
use Shaarli\Bookmark\BookmarkFilter;
|
use Shaarli\Bookmark\BookmarkFilter;
|
||||||
|
@ -17,6 +16,7 @@
|
||||||
use Shaarli\Config\ConfigManager;
|
use Shaarli\Config\ConfigManager;
|
||||||
use Shaarli\Config\ConfigPhp;
|
use Shaarli\Config\ConfigPhp;
|
||||||
use Shaarli\Exceptions\IOException;
|
use Shaarli\Exceptions\IOException;
|
||||||
|
use Shaarli\Helper\ApplicationUtils;
|
||||||
use Shaarli\Thumbnailer;
|
use Shaarli\Thumbnailer;
|
||||||
use Shaarli\Updater\Exception\UpdaterException;
|
use Shaarli\Updater\Exception\UpdaterException;
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
use Exception;
|
use Exception;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use RainTPL;
|
use RainTPL;
|
||||||
use Shaarli\ApplicationUtils;
|
|
||||||
use Shaarli\Bookmark\BookmarkServiceInterface;
|
use Shaarli\Bookmark\BookmarkServiceInterface;
|
||||||
use Shaarli\Config\ConfigManager;
|
use Shaarli\Config\ConfigManager;
|
||||||
|
use Shaarli\Helper\ApplicationUtils;
|
||||||
use Shaarli\Security\SessionManager;
|
use Shaarli\Security\SessionManager;
|
||||||
use Shaarli\Thumbnailer;
|
use Shaarli\Thumbnailer;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
namespace Shaarli\Security;
|
namespace Shaarli\Security;
|
||||||
|
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Shaarli\FileUtils;
|
use Shaarli\Helper\FileUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class BanManager
|
* Class BanManager
|
||||||
|
|
|
@ -59,6 +59,7 @@
|
||||||
"Shaarli\\Front\\Controller\\Admin\\": "application/front/controller/admin",
|
"Shaarli\\Front\\Controller\\Admin\\": "application/front/controller/admin",
|
||||||
"Shaarli\\Front\\Controller\\Visitor\\": "application/front/controller/visitor",
|
"Shaarli\\Front\\Controller\\Visitor\\": "application/front/controller/visitor",
|
||||||
"Shaarli\\Front\\Exception\\": "application/front/exceptions",
|
"Shaarli\\Front\\Exception\\": "application/front/exceptions",
|
||||||
|
"Shaarli\\Helper\\": "application/helper",
|
||||||
"Shaarli\\Http\\": "application/http",
|
"Shaarli\\Http\\": "application/http",
|
||||||
"Shaarli\\Legacy\\": "application/legacy",
|
"Shaarli\\Legacy\\": "application/legacy",
|
||||||
"Shaarli\\Netscape\\": "application/netscape",
|
"Shaarli\\Netscape\\": "application/netscape",
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: Shaarli\n"
|
"Project-Id-Version: Shaarli\n"
|
||||||
"POT-Creation-Date: 2020-10-27 19:32+0100\n"
|
"POT-Creation-Date: 2020-10-27 19:44+0100\n"
|
||||||
"PO-Revision-Date: 2020-10-27 19:32+0100\n"
|
"PO-Revision-Date: 2020-10-27 19:44+0100\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: Shaarli\n"
|
"Language-Team: Shaarli\n"
|
||||||
"Language: fr_FR\n"
|
"Language: fr_FR\n"
|
||||||
|
@ -20,78 +20,11 @@ msgstr ""
|
||||||
"X-Poedit-SearchPath-3: init.php\n"
|
"X-Poedit-SearchPath-3: init.php\n"
|
||||||
"X-Poedit-SearchPath-4: plugins\n"
|
"X-Poedit-SearchPath-4: plugins\n"
|
||||||
|
|
||||||
#: application/ApplicationUtils.php:162
|
#: application/History.php:180
|
||||||
#, php-format
|
|
||||||
msgid ""
|
|
||||||
"Your PHP version is obsolete! Shaarli requires at least PHP %s, and thus "
|
|
||||||
"cannot run. Your PHP version has known security vulnerabilities and should "
|
|
||||||
"be updated as soon as possible."
|
|
||||||
msgstr ""
|
|
||||||
"Votre version de PHP est obsolète ! Shaarli nécessite au moins PHP %s, et ne "
|
|
||||||
"peut donc pas fonctionner. Votre version de PHP a des failles de sécurités "
|
|
||||||
"connues et devrait être mise à jour au plus tôt."
|
|
||||||
|
|
||||||
#: application/ApplicationUtils.php:195 application/ApplicationUtils.php:215
|
|
||||||
msgid "directory is not readable"
|
|
||||||
msgstr "le répertoire n'est pas accessible en lecture"
|
|
||||||
|
|
||||||
#: application/ApplicationUtils.php:218
|
|
||||||
msgid "directory is not writable"
|
|
||||||
msgstr "le répertoire n'est pas accessible en écriture"
|
|
||||||
|
|
||||||
#: application/ApplicationUtils.php:240
|
|
||||||
msgid "file is not readable"
|
|
||||||
msgstr "le fichier n'est pas accessible en lecture"
|
|
||||||
|
|
||||||
#: application/ApplicationUtils.php:243
|
|
||||||
msgid "file is not writable"
|
|
||||||
msgstr "le fichier n'est pas accessible en écriture"
|
|
||||||
|
|
||||||
#: application/ApplicationUtils.php:277
|
|
||||||
msgid "Configuration parsing"
|
|
||||||
msgstr "Chargement de la configuration"
|
|
||||||
|
|
||||||
#: application/ApplicationUtils.php:278
|
|
||||||
msgid "Slim Framework (routing, etc.)"
|
|
||||||
msgstr "Slim Framwork (routage, etc.)"
|
|
||||||
|
|
||||||
#: application/ApplicationUtils.php:279
|
|
||||||
msgid "Multibyte (Unicode) string support"
|
|
||||||
msgstr "Support des chaînes de caractère multibytes (Unicode)"
|
|
||||||
|
|
||||||
#: application/ApplicationUtils.php:280
|
|
||||||
msgid "Required to use thumbnails"
|
|
||||||
msgstr "Obligatoire pour utiliser les miniatures"
|
|
||||||
|
|
||||||
#: application/ApplicationUtils.php:281
|
|
||||||
msgid "Localized text sorting (e.g. e->è->f)"
|
|
||||||
msgstr "Tri des textes traduits (ex : e->è->f)"
|
|
||||||
|
|
||||||
#: application/ApplicationUtils.php:282
|
|
||||||
msgid "Better retrieval of bookmark metadata and thumbnail"
|
|
||||||
msgstr "Meilleure récupération des meta-données des marque-pages et minatures"
|
|
||||||
|
|
||||||
#: application/ApplicationUtils.php:283
|
|
||||||
msgid "Use the translation system in gettext mode"
|
|
||||||
msgstr "Utiliser le système de traduction en mode gettext"
|
|
||||||
|
|
||||||
#: application/ApplicationUtils.php:284
|
|
||||||
msgid "Login using LDAP server"
|
|
||||||
msgstr "Authentification via un serveur LDAP"
|
|
||||||
|
|
||||||
#: application/FileUtils.php:100
|
|
||||||
msgid "Provided path is not a directory."
|
|
||||||
msgstr "Le chemin fourni n'est pas un dossier."
|
|
||||||
|
|
||||||
#: application/FileUtils.php:104
|
|
||||||
msgid "Trying to delete a folder outside of Shaarli path."
|
|
||||||
msgstr "Tentative de supprimer un dossier en dehors du chemin de Shaarli."
|
|
||||||
|
|
||||||
#: application/History.php:179
|
|
||||||
msgid "History file isn't readable or writable"
|
msgid "History file isn't readable or writable"
|
||||||
msgstr "Le fichier d'historique n'est pas accessible en lecture ou en écriture"
|
msgstr "Le fichier d'historique n'est pas accessible en lecture ou en écriture"
|
||||||
|
|
||||||
#: application/History.php:190
|
#: application/History.php:191
|
||||||
msgid "Could not parse history file"
|
msgid "Could not parse history file"
|
||||||
msgstr "Format incorrect pour le fichier d'historique"
|
msgstr "Format incorrect pour le fichier d'historique"
|
||||||
|
|
||||||
|
@ -123,27 +56,27 @@ msgstr ""
|
||||||
"l'extension php-gd doit être chargée pour utiliser les miniatures. Les "
|
"l'extension php-gd doit être chargée pour utiliser les miniatures. Les "
|
||||||
"miniatures sont désormais désactivées. Rechargez la page."
|
"miniatures sont désormais désactivées. Rechargez la page."
|
||||||
|
|
||||||
#: application/Utils.php:385
|
#: application/Utils.php:402
|
||||||
msgid "Setting not set"
|
msgid "Setting not set"
|
||||||
msgstr "Paramètre non défini"
|
msgstr "Paramètre non défini"
|
||||||
|
|
||||||
#: application/Utils.php:392
|
#: application/Utils.php:409
|
||||||
msgid "Unlimited"
|
msgid "Unlimited"
|
||||||
msgstr "Illimité"
|
msgstr "Illimité"
|
||||||
|
|
||||||
#: application/Utils.php:395
|
#: application/Utils.php:412
|
||||||
msgid "B"
|
msgid "B"
|
||||||
msgstr "o"
|
msgstr "o"
|
||||||
|
|
||||||
#: application/Utils.php:395
|
#: application/Utils.php:412
|
||||||
msgid "kiB"
|
msgid "kiB"
|
||||||
msgstr "ko"
|
msgstr "ko"
|
||||||
|
|
||||||
#: application/Utils.php:395
|
#: application/Utils.php:412
|
||||||
msgid "MiB"
|
msgid "MiB"
|
||||||
msgstr "Mo"
|
msgstr "Mo"
|
||||||
|
|
||||||
#: application/Utils.php:395
|
#: application/Utils.php:412
|
||||||
msgid "GiB"
|
msgid "GiB"
|
||||||
msgstr "Go"
|
msgstr "Go"
|
||||||
|
|
||||||
|
@ -156,7 +89,7 @@ msgstr "Vous n'êtes pas autorisé à modifier les données"
|
||||||
|
|
||||||
#: application/bookmark/BookmarkFileService.php:208
|
#: application/bookmark/BookmarkFileService.php:208
|
||||||
msgid "This bookmarks already exists"
|
msgid "This bookmarks already exists"
|
||||||
msgstr "Ce marque-page existe déjà."
|
msgstr "Ce marque-page existe déjà"
|
||||||
|
|
||||||
#: application/bookmark/BookmarkInitializer.php:39
|
#: application/bookmark/BookmarkInitializer.php:39
|
||||||
msgid "(private bookmark with thumbnail demo)"
|
msgid "(private bookmark with thumbnail demo)"
|
||||||
|
@ -354,7 +287,8 @@ msgid "Direct link"
|
||||||
msgstr "Liens directs"
|
msgstr "Liens directs"
|
||||||
|
|
||||||
#: application/feed/FeedBuilder.php:181
|
#: application/feed/FeedBuilder.php:181
|
||||||
#: tmp/daily.b91ef64efc3688266305ea9b42e5017e.rtpl.php:96
|
#: tmp/daily.b91ef64efc3688266305ea9b42e5017e.rtpl.php:103
|
||||||
|
#: tmp/dailyrss.b91ef64efc3688266305ea9b42e5017e.rtpl.php:26
|
||||||
#: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:179
|
#: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:179
|
||||||
msgid "Permalink"
|
msgid "Permalink"
|
||||||
msgstr "Permalien"
|
msgstr "Permalien"
|
||||||
|
@ -537,20 +471,36 @@ msgstr "Outils"
|
||||||
msgid "Search: "
|
msgid "Search: "
|
||||||
msgstr "Recherche : "
|
msgstr "Recherche : "
|
||||||
|
|
||||||
#: application/front/controller/visitor/DailyController.php:45
|
#: application/front/controller/visitor/DailyController.php:200
|
||||||
msgid "Today"
|
msgid "day"
|
||||||
msgstr "Aujourd'hui"
|
msgstr "jour"
|
||||||
|
|
||||||
#: application/front/controller/visitor/DailyController.php:47
|
#: application/front/controller/visitor/DailyController.php:200
|
||||||
msgid "Yesterday"
|
#: application/front/controller/visitor/DailyController.php:203
|
||||||
msgstr "Hier"
|
#: tmp/daily.b91ef64efc3688266305ea9b42e5017e.rtpl.php:13
|
||||||
|
|
||||||
#: application/front/controller/visitor/DailyController.php:85
|
|
||||||
#: tmp/page.header.b91ef64efc3688266305ea9b42e5017e.rtpl.php:48
|
#: tmp/page.header.b91ef64efc3688266305ea9b42e5017e.rtpl.php:48
|
||||||
#: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:48
|
#: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:48
|
||||||
msgid "Daily"
|
msgid "Daily"
|
||||||
msgstr "Quotidien"
|
msgstr "Quotidien"
|
||||||
|
|
||||||
|
#: application/front/controller/visitor/DailyController.php:201
|
||||||
|
msgid "week"
|
||||||
|
msgstr "semaine"
|
||||||
|
|
||||||
|
#: application/front/controller/visitor/DailyController.php:201
|
||||||
|
#: tmp/daily.b91ef64efc3688266305ea9b42e5017e.rtpl.php:14
|
||||||
|
msgid "Weekly"
|
||||||
|
msgstr "Hebdomadaire"
|
||||||
|
|
||||||
|
#: application/front/controller/visitor/DailyController.php:202
|
||||||
|
msgid "month"
|
||||||
|
msgstr "mois"
|
||||||
|
|
||||||
|
#: application/front/controller/visitor/DailyController.php:202
|
||||||
|
#: tmp/daily.b91ef64efc3688266305ea9b42e5017e.rtpl.php:15
|
||||||
|
msgid "Monthly"
|
||||||
|
msgstr "Mensuel"
|
||||||
|
|
||||||
#: application/front/controller/visitor/ErrorController.php:33
|
#: application/front/controller/visitor/ErrorController.php:33
|
||||||
msgid "An unexpected error occurred."
|
msgid "An unexpected error occurred."
|
||||||
msgstr "Une erreur inattendue s'est produite."
|
msgstr "Une erreur inattendue s'est produite."
|
||||||
|
@ -644,6 +594,86 @@ msgstr ""
|
||||||
msgid "Wrong token."
|
msgid "Wrong token."
|
||||||
msgstr "Jeton invalide."
|
msgstr "Jeton invalide."
|
||||||
|
|
||||||
|
#: application/helper/ApplicationUtils.php:162
|
||||||
|
#, php-format
|
||||||
|
msgid ""
|
||||||
|
"Your PHP version is obsolete! Shaarli requires at least PHP %s, and thus "
|
||||||
|
"cannot run. Your PHP version has known security vulnerabilities and should "
|
||||||
|
"be updated as soon as possible."
|
||||||
|
msgstr ""
|
||||||
|
"Votre version de PHP est obsolète ! Shaarli nécessite au moins PHP %s, et ne "
|
||||||
|
"peut donc pas fonctionner. Votre version de PHP a des failles de sécurités "
|
||||||
|
"connues et devrait être mise à jour au plus tôt."
|
||||||
|
|
||||||
|
#: application/helper/ApplicationUtils.php:195
|
||||||
|
#: application/helper/ApplicationUtils.php:215
|
||||||
|
msgid "directory is not readable"
|
||||||
|
msgstr "le répertoire n'est pas accessible en lecture"
|
||||||
|
|
||||||
|
#: application/helper/ApplicationUtils.php:218
|
||||||
|
msgid "directory is not writable"
|
||||||
|
msgstr "le répertoire n'est pas accessible en écriture"
|
||||||
|
|
||||||
|
#: application/helper/ApplicationUtils.php:240
|
||||||
|
msgid "file is not readable"
|
||||||
|
msgstr "le fichier n'est pas accessible en lecture"
|
||||||
|
|
||||||
|
#: application/helper/ApplicationUtils.php:243
|
||||||
|
msgid "file is not writable"
|
||||||
|
msgstr "le fichier n'est pas accessible en écriture"
|
||||||
|
|
||||||
|
#: application/helper/ApplicationUtils.php:277
|
||||||
|
msgid "Configuration parsing"
|
||||||
|
msgstr "Chargement de la configuration"
|
||||||
|
|
||||||
|
#: application/helper/ApplicationUtils.php:278
|
||||||
|
msgid "Slim Framework (routing, etc.)"
|
||||||
|
msgstr "Slim Framwork (routage, etc.)"
|
||||||
|
|
||||||
|
#: application/helper/ApplicationUtils.php:279
|
||||||
|
msgid "Multibyte (Unicode) string support"
|
||||||
|
msgstr "Support des chaînes de caractère multibytes (Unicode)"
|
||||||
|
|
||||||
|
#: application/helper/ApplicationUtils.php:280
|
||||||
|
msgid "Required to use thumbnails"
|
||||||
|
msgstr "Obligatoire pour utiliser les miniatures"
|
||||||
|
|
||||||
|
#: application/helper/ApplicationUtils.php:281
|
||||||
|
msgid "Localized text sorting (e.g. e->è->f)"
|
||||||
|
msgstr "Tri des textes traduits (ex : e->è->f)"
|
||||||
|
|
||||||
|
#: application/helper/ApplicationUtils.php:282
|
||||||
|
msgid "Better retrieval of bookmark metadata and thumbnail"
|
||||||
|
msgstr "Meilleure récupération des meta-données des marque-pages et minatures"
|
||||||
|
|
||||||
|
#: application/helper/ApplicationUtils.php:283
|
||||||
|
msgid "Use the translation system in gettext mode"
|
||||||
|
msgstr "Utiliser le système de traduction en mode gettext"
|
||||||
|
|
||||||
|
#: application/helper/ApplicationUtils.php:284
|
||||||
|
msgid "Login using LDAP server"
|
||||||
|
msgstr "Authentification via un serveur LDAP"
|
||||||
|
|
||||||
|
#: application/helper/DailyPageHelper.php:172
|
||||||
|
msgid "Week"
|
||||||
|
msgstr "Semaine"
|
||||||
|
|
||||||
|
#: application/helper/DailyPageHelper.php:176
|
||||||
|
msgid "Today"
|
||||||
|
msgstr "Aujourd'hui"
|
||||||
|
|
||||||
|
#: application/helper/DailyPageHelper.php:178
|
||||||
|
msgid "Yesterday"
|
||||||
|
msgstr "Hier"
|
||||||
|
|
||||||
|
#: application/helper/FileUtils.php:100
|
||||||
|
msgid "Provided path is not a directory."
|
||||||
|
msgstr "Le chemin fourni n'est pas un dossier."
|
||||||
|
|
||||||
|
#: application/helper/FileUtils.php:104
|
||||||
|
msgid "Trying to delete a folder outside of Shaarli path."
|
||||||
|
msgstr "Tentative de supprimer un dossier en dehors du chemin de Shaarli."
|
||||||
|
|
||||||
#: application/legacy/LegacyLinkDB.php:131
|
#: application/legacy/LegacyLinkDB.php:131
|
||||||
msgid "You are not authorized to add a link."
|
msgid "You are not authorized to add a link."
|
||||||
msgstr "Vous n'êtes pas autorisé à ajouter un lien."
|
msgstr "Vous n'êtes pas autorisé à ajouter un lien."
|
||||||
|
@ -1103,25 +1133,30 @@ msgstr "Aucune"
|
||||||
msgid "Save"
|
msgid "Save"
|
||||||
msgstr "Enregistrer"
|
msgstr "Enregistrer"
|
||||||
|
|
||||||
#: tmp/daily.b91ef64efc3688266305ea9b42e5017e.rtpl.php:15
|
#: tmp/daily.b91ef64efc3688266305ea9b42e5017e.rtpl.php:26
|
||||||
msgid "The Daily Shaarli"
|
msgid "1 RSS entry per :type"
|
||||||
msgstr "Le Quotidien Shaarli"
|
msgid_plural ""
|
||||||
|
msgstr[0] "1 entrée RSS par :type"
|
||||||
|
msgstr[1] ""
|
||||||
|
|
||||||
#: tmp/daily.b91ef64efc3688266305ea9b42e5017e.rtpl.php:17
|
#: tmp/daily.b91ef64efc3688266305ea9b42e5017e.rtpl.php:49
|
||||||
msgid "1 RSS entry per day"
|
msgid "Previous :type"
|
||||||
msgstr "1 entrée RSS par jour"
|
msgid_plural ""
|
||||||
|
msgstr[0] ":type précédent"
|
||||||
|
msgstr[1] "Jour précédent"
|
||||||
|
|
||||||
#: tmp/daily.b91ef64efc3688266305ea9b42e5017e.rtpl.php:37
|
#: tmp/daily.b91ef64efc3688266305ea9b42e5017e.rtpl.php:56
|
||||||
msgid "Previous day"
|
#: tmp/dailyrss.b91ef64efc3688266305ea9b42e5017e.rtpl.php:7
|
||||||
msgstr "Jour précédent"
|
msgid "All links of one :type in a single page."
|
||||||
|
msgid_plural ""
|
||||||
|
msgstr[0] "Tous les liens d'un :type sur une page."
|
||||||
|
msgstr[1] "Tous les liens d'un jour sur une page."
|
||||||
|
|
||||||
#: tmp/daily.b91ef64efc3688266305ea9b42e5017e.rtpl.php:44
|
#: tmp/daily.b91ef64efc3688266305ea9b42e5017e.rtpl.php:63
|
||||||
msgid "All links of one day in a single page."
|
msgid "Next :type"
|
||||||
msgstr "Tous les liens d'un jour sur une page."
|
msgid_plural ""
|
||||||
|
msgstr[0] ":type suivant"
|
||||||
#: tmp/daily.b91ef64efc3688266305ea9b42e5017e.rtpl.php:51
|
msgstr[1] ""
|
||||||
msgid "Next day"
|
|
||||||
msgstr "Jour suivant"
|
|
||||||
|
|
||||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:21
|
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:21
|
||||||
msgid "Edit Shaare"
|
msgid "Edit Shaare"
|
||||||
|
@ -1821,8 +1856,11 @@ msgstr ""
|
||||||
"Glisser ce lien dans votre barre de favoris ou cliquer droit dessus et « "
|
"Glisser ce lien dans votre barre de favoris ou cliquer droit dessus et « "
|
||||||
"Ajouter aux favoris »"
|
"Ajouter aux favoris »"
|
||||||
|
|
||||||
#~ msgid "Rename"
|
#~ msgid "Display:"
|
||||||
#~ msgstr "Renommer"
|
#~ msgstr "Afficher :"
|
||||||
|
|
||||||
|
#~ msgid "The Daily Shaarli"
|
||||||
|
#~ msgstr "Le Quotidien Shaarli"
|
||||||
|
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
#~| msgid "Selection"
|
#~| msgid "Selection"
|
||||||
|
|
2
init.php
2
init.php
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
require_once __DIR__ . '/vendor/autoload.php';
|
require_once __DIR__ . '/vendor/autoload.php';
|
||||||
|
|
||||||
use Shaarli\ApplicationUtils;
|
use Shaarli\Helper\ApplicationUtils;
|
||||||
use Shaarli\Security\SessionManager;
|
use Shaarli\Security\SessionManager;
|
||||||
|
|
||||||
// Set 'UTC' as the default timezone if it is not defined in php.ini
|
// Set 'UTC' as the default timezone if it is not defined in php.ini
|
||||||
|
|
|
@ -685,22 +685,6 @@ public function testCountHiddenPublic()
|
||||||
$this->assertEquals(0, $linkDB->count());
|
$this->assertEquals(0, $linkDB->count());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* List the days for which bookmarks have been posted
|
|
||||||
*/
|
|
||||||
public function testDays()
|
|
||||||
{
|
|
||||||
$this->assertSame(
|
|
||||||
['20100309', '20100310', '20121206', '20121207', '20130614', '20150310'],
|
|
||||||
$this->publicLinkDB->days()
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->assertSame(
|
|
||||||
['20100309', '20100310', '20121206', '20121207', '20130614', '20141125', '20150310'],
|
|
||||||
$this->privateLinkDB->days()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The URL corresponds to an existing entry in the DB
|
* The URL corresponds to an existing entry in the DB
|
||||||
*/
|
*/
|
||||||
|
@ -1074,33 +1058,105 @@ public function testCountTagsNoMarkdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test filterDay while logged in
|
* Test find by dates in the middle of the datastore (sorted by dates) with a single bookmark as a result.
|
||||||
*/
|
*/
|
||||||
public function testFilterDayLoggedIn(): void
|
public function testFilterByDateMidTimePeriodSingleBookmark(): void
|
||||||
{
|
{
|
||||||
$bookmarks = $this->privateLinkDB->filterDay('20121206');
|
$bookmarks = $this->privateLinkDB->findByDate(
|
||||||
$expectedIds = [4, 9, 1, 0];
|
DateTime::createFromFormat('Ymd_His', '20121206_150000'),
|
||||||
|
DateTime::createFromFormat('Ymd_His', '20121206_160000'),
|
||||||
|
$before,
|
||||||
|
$after
|
||||||
|
);
|
||||||
|
|
||||||
static::assertCount(4, $bookmarks);
|
static::assertCount(1, $bookmarks);
|
||||||
foreach ($bookmarks as $bookmark) {
|
|
||||||
$i = ($i ?? -1) + 1;
|
static::assertSame(9, $bookmarks[0]->getId());
|
||||||
static::assertSame($expectedIds[$i], $bookmark->getId());
|
static::assertEquals(DateTime::createFromFormat('Ymd_His', '20121206_142300'), $before);
|
||||||
}
|
static::assertEquals(DateTime::createFromFormat('Ymd_His', '20121206_172539'), $after);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test filterDay while logged out
|
* Test find by dates in the middle of the datastore (sorted by dates) with a multiple bookmarks as a result.
|
||||||
*/
|
*/
|
||||||
public function testFilterDayLoggedOut(): void
|
public function testFilterByDateMidTimePeriodMultipleBookmarks(): void
|
||||||
{
|
{
|
||||||
$bookmarks = $this->publicLinkDB->filterDay('20121206');
|
$bookmarks = $this->privateLinkDB->findByDate(
|
||||||
$expectedIds = [4, 9, 1];
|
DateTime::createFromFormat('Ymd_His', '20121206_150000'),
|
||||||
|
DateTime::createFromFormat('Ymd_His', '20121206_180000'),
|
||||||
|
$before,
|
||||||
|
$after
|
||||||
|
);
|
||||||
|
|
||||||
static::assertCount(3, $bookmarks);
|
static::assertCount(2, $bookmarks);
|
||||||
foreach ($bookmarks as $bookmark) {
|
|
||||||
$i = ($i ?? -1) + 1;
|
static::assertSame(1, $bookmarks[0]->getId());
|
||||||
static::assertSame($expectedIds[$i], $bookmark->getId());
|
static::assertSame(9, $bookmarks[1]->getId());
|
||||||
|
static::assertEquals(DateTime::createFromFormat('Ymd_His', '20121206_142300'), $before);
|
||||||
|
static::assertEquals(DateTime::createFromFormat('Ymd_His', '20121206_182539'), $after);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test find by dates at the end of the datastore (sorted by dates).
|
||||||
|
*/
|
||||||
|
public function testFilterByDateLastTimePeriod(): void
|
||||||
|
{
|
||||||
|
$after = new DateTime();
|
||||||
|
$bookmarks = $this->privateLinkDB->findByDate(
|
||||||
|
DateTime::createFromFormat('Ymd_His', '20150310_114640'),
|
||||||
|
DateTime::createFromFormat('Ymd_His', '20450101_010101'),
|
||||||
|
$before,
|
||||||
|
$after
|
||||||
|
);
|
||||||
|
|
||||||
|
static::assertCount(1, $bookmarks);
|
||||||
|
|
||||||
|
static::assertSame(41, $bookmarks[0]->getId());
|
||||||
|
static::assertEquals(DateTime::createFromFormat('Ymd_His', '20150310_114633'), $before);
|
||||||
|
static::assertNull($after);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test find by dates at the beginning of the datastore (sorted by dates).
|
||||||
|
*/
|
||||||
|
public function testFilterByDateFirstTimePeriod(): void
|
||||||
|
{
|
||||||
|
$before = new DateTime();
|
||||||
|
$bookmarks = $this->privateLinkDB->findByDate(
|
||||||
|
DateTime::createFromFormat('Ymd_His', '20000101_101010'),
|
||||||
|
DateTime::createFromFormat('Ymd_His', '20100309_110000'),
|
||||||
|
$before,
|
||||||
|
$after
|
||||||
|
);
|
||||||
|
|
||||||
|
static::assertCount(1, $bookmarks);
|
||||||
|
|
||||||
|
static::assertSame(11, $bookmarks[0]->getId());
|
||||||
|
static::assertNull($before);
|
||||||
|
static::assertEquals(DateTime::createFromFormat('Ymd_His', '20100310_101010'), $after);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test getLatest with a sticky bookmark: it should be ignored and return the latest by creation date instead.
|
||||||
|
*/
|
||||||
|
public function testGetLatestWithSticky(): void
|
||||||
|
{
|
||||||
|
$bookmark = $this->publicLinkDB->getLatest();
|
||||||
|
|
||||||
|
static::assertSame(41, $bookmark->getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test getLatest with a sticky bookmark: it should be ignored and return the latest by creation date instead.
|
||||||
|
*/
|
||||||
|
public function testGetLatestEmptyDatastore(): void
|
||||||
|
{
|
||||||
|
unlink($this->conf->get('resource.datastore'));
|
||||||
|
$this->publicLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, false);
|
||||||
|
|
||||||
|
$bookmark = $this->publicLinkDB->getLatest();
|
||||||
|
|
||||||
|
static::assertNull($bookmark);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -28,31 +28,27 @@ public function setUp(): void
|
||||||
public function testValidIndexControllerInvokeDefault(): void
|
public function testValidIndexControllerInvokeDefault(): void
|
||||||
{
|
{
|
||||||
$currentDay = new \DateTimeImmutable('2020-05-13');
|
$currentDay = new \DateTimeImmutable('2020-05-13');
|
||||||
|
$previousDate = new \DateTime('2 days ago 00:00:00');
|
||||||
|
$nextDate = new \DateTime('today 00:00:00');
|
||||||
|
|
||||||
$request = $this->createMock(Request::class);
|
$request = $this->createMock(Request::class);
|
||||||
$request->method('getQueryParam')->willReturn($currentDay->format('Ymd'));
|
$request->method('getQueryParam')->willReturnCallback(function (string $key) use ($currentDay): ?string {
|
||||||
|
return $key === 'day' ? $currentDay->format('Ymd') : null;
|
||||||
|
});
|
||||||
$response = new Response();
|
$response = new Response();
|
||||||
|
|
||||||
// Save RainTPL assigned variables
|
// Save RainTPL assigned variables
|
||||||
$assignedVariables = [];
|
$assignedVariables = [];
|
||||||
$this->assignTemplateVars($assignedVariables);
|
$this->assignTemplateVars($assignedVariables);
|
||||||
|
|
||||||
// Links dataset: 2 links with thumbnails
|
|
||||||
$this->container->bookmarkService
|
$this->container->bookmarkService
|
||||||
->expects(static::once())
|
->expects(static::once())
|
||||||
->method('days')
|
->method('findByDate')
|
||||||
->willReturnCallback(function () use ($currentDay): array {
|
->willReturnCallback(
|
||||||
return [
|
function ($from, $to, &$previous, &$next) use ($currentDay, $previousDate, $nextDate): array {
|
||||||
'20200510',
|
$previous = $previousDate;
|
||||||
$currentDay->format('Ymd'),
|
$next = $nextDate;
|
||||||
'20200516',
|
|
||||||
];
|
|
||||||
})
|
|
||||||
;
|
|
||||||
$this->container->bookmarkService
|
|
||||||
->expects(static::once())
|
|
||||||
->method('filterDay')
|
|
||||||
->willReturnCallback(function (): array {
|
|
||||||
return [
|
return [
|
||||||
(new Bookmark())
|
(new Bookmark())
|
||||||
->setId(1)
|
->setId(1)
|
||||||
|
@ -73,7 +69,8 @@ public function testValidIndexControllerInvokeDefault(): void
|
||||||
->setDescription(static::generateString(500))
|
->setDescription(static::generateString(500))
|
||||||
,
|
,
|
||||||
];
|
];
|
||||||
})
|
}
|
||||||
|
)
|
||||||
;
|
;
|
||||||
|
|
||||||
// Make sure that PluginManager hook is triggered
|
// Make sure that PluginManager hook is triggered
|
||||||
|
@ -81,20 +78,22 @@ public function testValidIndexControllerInvokeDefault(): void
|
||||||
->expects(static::atLeastOnce())
|
->expects(static::atLeastOnce())
|
||||||
->method('executeHooks')
|
->method('executeHooks')
|
||||||
->withConsecutive(['render_daily'])
|
->withConsecutive(['render_daily'])
|
||||||
->willReturnCallback(function (string $hook, array $data, array $param) use ($currentDay): array {
|
->willReturnCallback(
|
||||||
|
function (string $hook, array $data, array $param) use ($currentDay, $previousDate, $nextDate): array {
|
||||||
if ('render_daily' === $hook) {
|
if ('render_daily' === $hook) {
|
||||||
static::assertArrayHasKey('linksToDisplay', $data);
|
static::assertArrayHasKey('linksToDisplay', $data);
|
||||||
static::assertCount(3, $data['linksToDisplay']);
|
static::assertCount(3, $data['linksToDisplay']);
|
||||||
static::assertSame(1, $data['linksToDisplay'][0]['id']);
|
static::assertSame(1, $data['linksToDisplay'][0]['id']);
|
||||||
static::assertSame($currentDay->getTimestamp(), $data['day']);
|
static::assertSame($currentDay->getTimestamp(), $data['day']);
|
||||||
static::assertSame('20200510', $data['previousday']);
|
static::assertSame($previousDate->format('Ymd'), $data['previousday']);
|
||||||
static::assertSame('20200516', $data['nextday']);
|
static::assertSame($nextDate->format('Ymd'), $data['nextday']);
|
||||||
|
|
||||||
static::assertArrayHasKey('loggedin', $param);
|
static::assertArrayHasKey('loggedin', $param);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
})
|
}
|
||||||
|
)
|
||||||
;
|
;
|
||||||
|
|
||||||
$result = $this->controller->index($request, $response);
|
$result = $this->controller->index($request, $response);
|
||||||
|
@ -107,6 +106,11 @@ public function testValidIndexControllerInvokeDefault(): void
|
||||||
);
|
);
|
||||||
static::assertEquals($currentDay, $assignedVariables['dayDate']);
|
static::assertEquals($currentDay, $assignedVariables['dayDate']);
|
||||||
static::assertEquals($currentDay->getTimestamp(), $assignedVariables['day']);
|
static::assertEquals($currentDay->getTimestamp(), $assignedVariables['day']);
|
||||||
|
static::assertSame($previousDate->format('Ymd'), $assignedVariables['previousday']);
|
||||||
|
static::assertSame($nextDate->format('Ymd'), $assignedVariables['nextday']);
|
||||||
|
static::assertSame('day', $assignedVariables['type']);
|
||||||
|
static::assertSame('May 13, 2020', $assignedVariables['dayDesc']);
|
||||||
|
static::assertSame('Daily', $assignedVariables['localizedType']);
|
||||||
static::assertCount(3, $assignedVariables['linksToDisplay']);
|
static::assertCount(3, $assignedVariables['linksToDisplay']);
|
||||||
|
|
||||||
$link = $assignedVariables['linksToDisplay'][0];
|
$link = $assignedVariables['linksToDisplay'][0];
|
||||||
|
@ -171,26 +175,19 @@ public function testValidIndexControllerInvokeNoFutureOrPast(): void
|
||||||
$currentDay = new \DateTimeImmutable('2020-05-13');
|
$currentDay = new \DateTimeImmutable('2020-05-13');
|
||||||
|
|
||||||
$request = $this->createMock(Request::class);
|
$request = $this->createMock(Request::class);
|
||||||
|
$request->method('getQueryParam')->willReturnCallback(function (string $key) use ($currentDay): ?string {
|
||||||
|
return $key === 'day' ? $currentDay->format('Ymd') : null;
|
||||||
|
});
|
||||||
$response = new Response();
|
$response = new Response();
|
||||||
|
|
||||||
// Save RainTPL assigned variables
|
// Save RainTPL assigned variables
|
||||||
$assignedVariables = [];
|
$assignedVariables = [];
|
||||||
$this->assignTemplateVars($assignedVariables);
|
$this->assignTemplateVars($assignedVariables);
|
||||||
|
|
||||||
// Links dataset: 2 links with thumbnails
|
|
||||||
$this->container->bookmarkService
|
$this->container->bookmarkService
|
||||||
->expects(static::once())
|
->expects(static::once())
|
||||||
->method('days')
|
->method('findByDate')
|
||||||
->willReturnCallback(function () use ($currentDay): array {
|
->willReturnCallback(function () use ($currentDay): array {
|
||||||
return [
|
|
||||||
$currentDay->format($currentDay->format('Ymd')),
|
|
||||||
];
|
|
||||||
})
|
|
||||||
;
|
|
||||||
$this->container->bookmarkService
|
|
||||||
->expects(static::once())
|
|
||||||
->method('filterDay')
|
|
||||||
->willReturnCallback(function (): array {
|
|
||||||
return [
|
return [
|
||||||
(new Bookmark())
|
(new Bookmark())
|
||||||
->setId(1)
|
->setId(1)
|
||||||
|
@ -250,20 +247,10 @@ public function testValidIndexControllerInvokeHeightAdjustment(): void
|
||||||
$assignedVariables = [];
|
$assignedVariables = [];
|
||||||
$this->assignTemplateVars($assignedVariables);
|
$this->assignTemplateVars($assignedVariables);
|
||||||
|
|
||||||
// Links dataset: 2 links with thumbnails
|
|
||||||
$this->container->bookmarkService
|
$this->container->bookmarkService
|
||||||
->expects(static::once())
|
->expects(static::once())
|
||||||
->method('days')
|
->method('findByDate')
|
||||||
->willReturnCallback(function () use ($currentDay): array {
|
->willReturnCallback(function () use ($currentDay): array {
|
||||||
return [
|
|
||||||
$currentDay->format($currentDay->format('Ymd')),
|
|
||||||
];
|
|
||||||
})
|
|
||||||
;
|
|
||||||
$this->container->bookmarkService
|
|
||||||
->expects(static::once())
|
|
||||||
->method('filterDay')
|
|
||||||
->willReturnCallback(function (): array {
|
|
||||||
return [
|
return [
|
||||||
(new Bookmark())->setId(1)->setUrl('http://url.tld')->setTitle('title'),
|
(new Bookmark())->setId(1)->setUrl('http://url.tld')->setTitle('title'),
|
||||||
(new Bookmark())
|
(new Bookmark())
|
||||||
|
@ -320,14 +307,7 @@ public function testValidIndexControllerInvokeNoBookmark(): void
|
||||||
// Links dataset: 2 links with thumbnails
|
// Links dataset: 2 links with thumbnails
|
||||||
$this->container->bookmarkService
|
$this->container->bookmarkService
|
||||||
->expects(static::once())
|
->expects(static::once())
|
||||||
->method('days')
|
->method('findByDate')
|
||||||
->willReturnCallback(function (): array {
|
|
||||||
return [];
|
|
||||||
})
|
|
||||||
;
|
|
||||||
$this->container->bookmarkService
|
|
||||||
->expects(static::once())
|
|
||||||
->method('filterDay')
|
|
||||||
->willReturnCallback(function (): array {
|
->willReturnCallback(function (): array {
|
||||||
return [];
|
return [];
|
||||||
})
|
})
|
||||||
|
@ -347,7 +327,7 @@ public function testValidIndexControllerInvokeNoBookmark(): void
|
||||||
static::assertSame(200, $result->getStatusCode());
|
static::assertSame(200, $result->getStatusCode());
|
||||||
static::assertSame('daily', (string) $result->getBody());
|
static::assertSame('daily', (string) $result->getBody());
|
||||||
static::assertCount(0, $assignedVariables['linksToDisplay']);
|
static::assertCount(0, $assignedVariables['linksToDisplay']);
|
||||||
static::assertSame('Today', $assignedVariables['dayDesc']);
|
static::assertSame('Today - ' . (new \DateTime())->format('F d, Y'), $assignedVariables['dayDesc']);
|
||||||
static::assertEquals((new \DateTime())->setTime(0, 0)->getTimestamp(), $assignedVariables['day']);
|
static::assertEquals((new \DateTime())->setTime(0, 0)->getTimestamp(), $assignedVariables['day']);
|
||||||
static::assertEquals((new \DateTime())->setTime(0, 0), $assignedVariables['dayDate']);
|
static::assertEquals((new \DateTime())->setTime(0, 0), $assignedVariables['dayDate']);
|
||||||
}
|
}
|
||||||
|
@ -361,6 +341,7 @@ public function testValidRssControllerInvokeDefault(): void
|
||||||
new \DateTimeImmutable('2020-05-17'),
|
new \DateTimeImmutable('2020-05-17'),
|
||||||
new \DateTimeImmutable('2020-05-15'),
|
new \DateTimeImmutable('2020-05-15'),
|
||||||
new \DateTimeImmutable('2020-05-13'),
|
new \DateTimeImmutable('2020-05-13'),
|
||||||
|
new \DateTimeImmutable('+1 month'),
|
||||||
];
|
];
|
||||||
|
|
||||||
$request = $this->createMock(Request::class);
|
$request = $this->createMock(Request::class);
|
||||||
|
@ -371,6 +352,7 @@ public function testValidRssControllerInvokeDefault(): void
|
||||||
(new Bookmark())->setId(2)->setCreated($dates[1])->setUrl('http://domain.tld/2'),
|
(new Bookmark())->setId(2)->setCreated($dates[1])->setUrl('http://domain.tld/2'),
|
||||||
(new Bookmark())->setId(3)->setCreated($dates[1])->setUrl('http://domain.tld/3'),
|
(new Bookmark())->setId(3)->setCreated($dates[1])->setUrl('http://domain.tld/3'),
|
||||||
(new Bookmark())->setId(4)->setCreated($dates[2])->setUrl('http://domain.tld/4'),
|
(new Bookmark())->setId(4)->setCreated($dates[2])->setUrl('http://domain.tld/4'),
|
||||||
|
(new Bookmark())->setId(5)->setCreated($dates[3])->setUrl('http://domain.tld/5'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->container->pageCacheManager
|
$this->container->pageCacheManager
|
||||||
|
@ -397,13 +379,14 @@ public function testValidRssControllerInvokeDefault(): void
|
||||||
static::assertSame('http://shaarli/subfolder/', $assignedVariables['index_url']);
|
static::assertSame('http://shaarli/subfolder/', $assignedVariables['index_url']);
|
||||||
static::assertSame('http://shaarli/subfolder/daily-rss', $assignedVariables['page_url']);
|
static::assertSame('http://shaarli/subfolder/daily-rss', $assignedVariables['page_url']);
|
||||||
static::assertFalse($assignedVariables['hide_timestamps']);
|
static::assertFalse($assignedVariables['hide_timestamps']);
|
||||||
static::assertCount(2, $assignedVariables['days']);
|
static::assertCount(3, $assignedVariables['days']);
|
||||||
|
|
||||||
$day = $assignedVariables['days'][$dates[0]->format('Ymd')];
|
$day = $assignedVariables['days'][$dates[0]->format('Ymd')];
|
||||||
|
$date = $dates[0]->setTime(23, 59, 59);
|
||||||
|
|
||||||
static::assertEquals($dates[0], $day['date']);
|
static::assertEquals($date, $day['date']);
|
||||||
static::assertSame($dates[0]->format(\DateTime::RSS), $day['date_rss']);
|
static::assertSame($date->format(\DateTime::RSS), $day['date_rss']);
|
||||||
static::assertSame(format_date($dates[0], false), $day['date_human']);
|
static::assertSame(format_date($date, false), $day['date_human']);
|
||||||
static::assertSame('http://shaarli/subfolder/daily?day='. $dates[0]->format('Ymd'), $day['absolute_url']);
|
static::assertSame('http://shaarli/subfolder/daily?day='. $dates[0]->format('Ymd'), $day['absolute_url']);
|
||||||
static::assertCount(1, $day['links']);
|
static::assertCount(1, $day['links']);
|
||||||
static::assertSame(1, $day['links'][0]['id']);
|
static::assertSame(1, $day['links'][0]['id']);
|
||||||
|
@ -411,10 +394,11 @@ public function testValidRssControllerInvokeDefault(): void
|
||||||
static::assertEquals($dates[0], $day['links'][0]['created']);
|
static::assertEquals($dates[0], $day['links'][0]['created']);
|
||||||
|
|
||||||
$day = $assignedVariables['days'][$dates[1]->format('Ymd')];
|
$day = $assignedVariables['days'][$dates[1]->format('Ymd')];
|
||||||
|
$date = $dates[1]->setTime(23, 59, 59);
|
||||||
|
|
||||||
static::assertEquals($dates[1], $day['date']);
|
static::assertEquals($date, $day['date']);
|
||||||
static::assertSame($dates[1]->format(\DateTime::RSS), $day['date_rss']);
|
static::assertSame($date->format(\DateTime::RSS), $day['date_rss']);
|
||||||
static::assertSame(format_date($dates[1], false), $day['date_human']);
|
static::assertSame(format_date($date, false), $day['date_human']);
|
||||||
static::assertSame('http://shaarli/subfolder/daily?day='. $dates[1]->format('Ymd'), $day['absolute_url']);
|
static::assertSame('http://shaarli/subfolder/daily?day='. $dates[1]->format('Ymd'), $day['absolute_url']);
|
||||||
static::assertCount(2, $day['links']);
|
static::assertCount(2, $day['links']);
|
||||||
|
|
||||||
|
@ -424,6 +408,18 @@ public function testValidRssControllerInvokeDefault(): void
|
||||||
static::assertSame(3, $day['links'][1]['id']);
|
static::assertSame(3, $day['links'][1]['id']);
|
||||||
static::assertSame('http://domain.tld/3', $day['links'][1]['url']);
|
static::assertSame('http://domain.tld/3', $day['links'][1]['url']);
|
||||||
static::assertEquals($dates[1], $day['links'][1]['created']);
|
static::assertEquals($dates[1], $day['links'][1]['created']);
|
||||||
|
|
||||||
|
$day = $assignedVariables['days'][$dates[2]->format('Ymd')];
|
||||||
|
$date = $dates[2]->setTime(23, 59, 59);
|
||||||
|
|
||||||
|
static::assertEquals($date, $day['date']);
|
||||||
|
static::assertSame($date->format(\DateTime::RSS), $day['date_rss']);
|
||||||
|
static::assertSame(format_date($date, false), $day['date_human']);
|
||||||
|
static::assertSame('http://shaarli/subfolder/daily?day='. $dates[2]->format('Ymd'), $day['absolute_url']);
|
||||||
|
static::assertCount(1, $day['links']);
|
||||||
|
static::assertSame(4, $day['links'][0]['id']);
|
||||||
|
static::assertSame('http://domain.tld/4', $day['links'][0]['url']);
|
||||||
|
static::assertEquals($dates[2], $day['links'][0]['created']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -475,4 +471,246 @@ public function testValidRssControllerInvokeNoBookmark(): void
|
||||||
static::assertFalse($assignedVariables['hide_timestamps']);
|
static::assertFalse($assignedVariables['hide_timestamps']);
|
||||||
static::assertCount(0, $assignedVariables['days']);
|
static::assertCount(0, $assignedVariables['days']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test simple display index with week parameter
|
||||||
|
*/
|
||||||
|
public function testSimpleIndexWeekly(): void
|
||||||
|
{
|
||||||
|
$currentDay = new \DateTimeImmutable('2020-05-13');
|
||||||
|
$expectedDay = new \DateTimeImmutable('2020-05-11');
|
||||||
|
|
||||||
|
$request = $this->createMock(Request::class);
|
||||||
|
$request->method('getQueryParam')->willReturnCallback(function (string $key) use ($currentDay): ?string {
|
||||||
|
return $key === 'week' ? $currentDay->format('YW') : null;
|
||||||
|
});
|
||||||
|
$response = new Response();
|
||||||
|
|
||||||
|
// Save RainTPL assigned variables
|
||||||
|
$assignedVariables = [];
|
||||||
|
$this->assignTemplateVars($assignedVariables);
|
||||||
|
|
||||||
|
$this->container->bookmarkService
|
||||||
|
->expects(static::once())
|
||||||
|
->method('findByDate')
|
||||||
|
->willReturnCallback(
|
||||||
|
function (): array {
|
||||||
|
return [
|
||||||
|
(new Bookmark())
|
||||||
|
->setId(1)
|
||||||
|
->setUrl('http://url.tld')
|
||||||
|
->setTitle(static::generateString(50))
|
||||||
|
->setDescription(static::generateString(500))
|
||||||
|
,
|
||||||
|
(new Bookmark())
|
||||||
|
->setId(2)
|
||||||
|
->setUrl('http://url2.tld')
|
||||||
|
->setTitle(static::generateString(50))
|
||||||
|
->setDescription(static::generateString(500))
|
||||||
|
,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
|
$result = $this->controller->index($request, $response);
|
||||||
|
|
||||||
|
static::assertSame(200, $result->getStatusCode());
|
||||||
|
static::assertSame('daily', (string) $result->getBody());
|
||||||
|
static::assertSame(
|
||||||
|
'Weekly - Week 20 (May 11, 2020) - Shaarli',
|
||||||
|
$assignedVariables['pagetitle']
|
||||||
|
);
|
||||||
|
|
||||||
|
static::assertCount(2, $assignedVariables['linksToDisplay']);
|
||||||
|
static::assertEquals($expectedDay->setTime(0, 0), $assignedVariables['dayDate']);
|
||||||
|
static::assertSame($expectedDay->setTime(0, 0)->getTimestamp(), $assignedVariables['day']);
|
||||||
|
static::assertSame('', $assignedVariables['previousday']);
|
||||||
|
static::assertSame('', $assignedVariables['nextday']);
|
||||||
|
static::assertSame('Week 20 (May 11, 2020)', $assignedVariables['dayDesc']);
|
||||||
|
static::assertSame('week', $assignedVariables['type']);
|
||||||
|
static::assertSame('Weekly', $assignedVariables['localizedType']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test simple display index with month parameter
|
||||||
|
*/
|
||||||
|
public function testSimpleIndexMonthly(): void
|
||||||
|
{
|
||||||
|
$currentDay = new \DateTimeImmutable('2020-05-13');
|
||||||
|
$expectedDay = new \DateTimeImmutable('2020-05-01');
|
||||||
|
|
||||||
|
$request = $this->createMock(Request::class);
|
||||||
|
$request->method('getQueryParam')->willReturnCallback(function (string $key) use ($currentDay): ?string {
|
||||||
|
return $key === 'month' ? $currentDay->format('Ym') : null;
|
||||||
|
});
|
||||||
|
$response = new Response();
|
||||||
|
|
||||||
|
// Save RainTPL assigned variables
|
||||||
|
$assignedVariables = [];
|
||||||
|
$this->assignTemplateVars($assignedVariables);
|
||||||
|
|
||||||
|
$this->container->bookmarkService
|
||||||
|
->expects(static::once())
|
||||||
|
->method('findByDate')
|
||||||
|
->willReturnCallback(
|
||||||
|
function (): array {
|
||||||
|
return [
|
||||||
|
(new Bookmark())
|
||||||
|
->setId(1)
|
||||||
|
->setUrl('http://url.tld')
|
||||||
|
->setTitle(static::generateString(50))
|
||||||
|
->setDescription(static::generateString(500))
|
||||||
|
,
|
||||||
|
(new Bookmark())
|
||||||
|
->setId(2)
|
||||||
|
->setUrl('http://url2.tld')
|
||||||
|
->setTitle(static::generateString(50))
|
||||||
|
->setDescription(static::generateString(500))
|
||||||
|
,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
|
$result = $this->controller->index($request, $response);
|
||||||
|
|
||||||
|
static::assertSame(200, $result->getStatusCode());
|
||||||
|
static::assertSame('daily', (string) $result->getBody());
|
||||||
|
static::assertSame(
|
||||||
|
'Monthly - May, 2020 - Shaarli',
|
||||||
|
$assignedVariables['pagetitle']
|
||||||
|
);
|
||||||
|
|
||||||
|
static::assertCount(2, $assignedVariables['linksToDisplay']);
|
||||||
|
static::assertEquals($expectedDay->setTime(0, 0), $assignedVariables['dayDate']);
|
||||||
|
static::assertSame($expectedDay->setTime(0, 0)->getTimestamp(), $assignedVariables['day']);
|
||||||
|
static::assertSame('', $assignedVariables['previousday']);
|
||||||
|
static::assertSame('', $assignedVariables['nextday']);
|
||||||
|
static::assertSame('May, 2020', $assignedVariables['dayDesc']);
|
||||||
|
static::assertSame('month', $assignedVariables['type']);
|
||||||
|
static::assertSame('Monthly', $assignedVariables['localizedType']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test simple display RSS with week parameter
|
||||||
|
*/
|
||||||
|
public function testSimpleRssWeekly(): void
|
||||||
|
{
|
||||||
|
$dates = [
|
||||||
|
new \DateTimeImmutable('2020-05-19'),
|
||||||
|
new \DateTimeImmutable('2020-05-13'),
|
||||||
|
];
|
||||||
|
$expectedDates = [
|
||||||
|
new \DateTimeImmutable('2020-05-24 23:59:59'),
|
||||||
|
new \DateTimeImmutable('2020-05-17 23:59:59'),
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->container->environment['QUERY_STRING'] = 'week';
|
||||||
|
$request = $this->createMock(Request::class);
|
||||||
|
$request->method('getQueryParam')->willReturnCallback(function (string $key): ?string {
|
||||||
|
return $key === 'week' ? '' : null;
|
||||||
|
});
|
||||||
|
$response = new Response();
|
||||||
|
|
||||||
|
$this->container->bookmarkService->expects(static::once())->method('search')->willReturn([
|
||||||
|
(new Bookmark())->setId(1)->setCreated($dates[0])->setUrl('http://domain.tld/1'),
|
||||||
|
(new Bookmark())->setId(2)->setCreated($dates[1])->setUrl('http://domain.tld/2'),
|
||||||
|
(new Bookmark())->setId(3)->setCreated($dates[1])->setUrl('http://domain.tld/3'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Save RainTPL assigned variables
|
||||||
|
$assignedVariables = [];
|
||||||
|
$this->assignTemplateVars($assignedVariables);
|
||||||
|
|
||||||
|
$result = $this->controller->rss($request, $response);
|
||||||
|
|
||||||
|
static::assertSame(200, $result->getStatusCode());
|
||||||
|
static::assertStringContainsString('application/rss', $result->getHeader('Content-Type')[0]);
|
||||||
|
static::assertSame('dailyrss', (string) $result->getBody());
|
||||||
|
static::assertSame('Shaarli', $assignedVariables['title']);
|
||||||
|
static::assertSame('http://shaarli/subfolder/', $assignedVariables['index_url']);
|
||||||
|
static::assertSame('http://shaarli/subfolder/daily-rss?week', $assignedVariables['page_url']);
|
||||||
|
static::assertFalse($assignedVariables['hide_timestamps']);
|
||||||
|
static::assertCount(2, $assignedVariables['days']);
|
||||||
|
|
||||||
|
$day = $assignedVariables['days'][$dates[0]->format('YW')];
|
||||||
|
$date = $expectedDates[0];
|
||||||
|
|
||||||
|
static::assertEquals($date, $day['date']);
|
||||||
|
static::assertSame($date->format(\DateTime::RSS), $day['date_rss']);
|
||||||
|
static::assertSame('Week 21 (May 18, 2020)', $day['date_human']);
|
||||||
|
static::assertSame('http://shaarli/subfolder/daily?week='. $dates[0]->format('YW'), $day['absolute_url']);
|
||||||
|
static::assertCount(1, $day['links']);
|
||||||
|
|
||||||
|
$day = $assignedVariables['days'][$dates[1]->format('YW')];
|
||||||
|
$date = $expectedDates[1];
|
||||||
|
|
||||||
|
static::assertEquals($date, $day['date']);
|
||||||
|
static::assertSame($date->format(\DateTime::RSS), $day['date_rss']);
|
||||||
|
static::assertSame('Week 20 (May 11, 2020)', $day['date_human']);
|
||||||
|
static::assertSame('http://shaarli/subfolder/daily?week='. $dates[1]->format('YW'), $day['absolute_url']);
|
||||||
|
static::assertCount(2, $day['links']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test simple display RSS with month parameter
|
||||||
|
*/
|
||||||
|
public function testSimpleRssMonthly(): void
|
||||||
|
{
|
||||||
|
$dates = [
|
||||||
|
new \DateTimeImmutable('2020-05-19'),
|
||||||
|
new \DateTimeImmutable('2020-04-13'),
|
||||||
|
];
|
||||||
|
$expectedDates = [
|
||||||
|
new \DateTimeImmutable('2020-05-31 23:59:59'),
|
||||||
|
new \DateTimeImmutable('2020-04-30 23:59:59'),
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->container->environment['QUERY_STRING'] = 'month';
|
||||||
|
$request = $this->createMock(Request::class);
|
||||||
|
$request->method('getQueryParam')->willReturnCallback(function (string $key): ?string {
|
||||||
|
return $key === 'month' ? '' : null;
|
||||||
|
});
|
||||||
|
$response = new Response();
|
||||||
|
|
||||||
|
$this->container->bookmarkService->expects(static::once())->method('search')->willReturn([
|
||||||
|
(new Bookmark())->setId(1)->setCreated($dates[0])->setUrl('http://domain.tld/1'),
|
||||||
|
(new Bookmark())->setId(2)->setCreated($dates[1])->setUrl('http://domain.tld/2'),
|
||||||
|
(new Bookmark())->setId(3)->setCreated($dates[1])->setUrl('http://domain.tld/3'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Save RainTPL assigned variables
|
||||||
|
$assignedVariables = [];
|
||||||
|
$this->assignTemplateVars($assignedVariables);
|
||||||
|
|
||||||
|
$result = $this->controller->rss($request, $response);
|
||||||
|
|
||||||
|
static::assertSame(200, $result->getStatusCode());
|
||||||
|
static::assertStringContainsString('application/rss', $result->getHeader('Content-Type')[0]);
|
||||||
|
static::assertSame('dailyrss', (string) $result->getBody());
|
||||||
|
static::assertSame('Shaarli', $assignedVariables['title']);
|
||||||
|
static::assertSame('http://shaarli/subfolder/', $assignedVariables['index_url']);
|
||||||
|
static::assertSame('http://shaarli/subfolder/daily-rss?month', $assignedVariables['page_url']);
|
||||||
|
static::assertFalse($assignedVariables['hide_timestamps']);
|
||||||
|
static::assertCount(2, $assignedVariables['days']);
|
||||||
|
|
||||||
|
$day = $assignedVariables['days'][$dates[0]->format('Ym')];
|
||||||
|
$date = $expectedDates[0];
|
||||||
|
|
||||||
|
static::assertEquals($date, $day['date']);
|
||||||
|
static::assertSame($date->format(\DateTime::RSS), $day['date_rss']);
|
||||||
|
static::assertSame('May, 2020', $day['date_human']);
|
||||||
|
static::assertSame('http://shaarli/subfolder/daily?month='. $dates[0]->format('Ym'), $day['absolute_url']);
|
||||||
|
static::assertCount(1, $day['links']);
|
||||||
|
|
||||||
|
$day = $assignedVariables['days'][$dates[1]->format('Ym')];
|
||||||
|
$date = $expectedDates[1];
|
||||||
|
|
||||||
|
static::assertEquals($date, $day['date']);
|
||||||
|
static::assertSame($date->format(\DateTime::RSS), $day['date_rss']);
|
||||||
|
static::assertSame('April, 2020', $day['date_human']);
|
||||||
|
static::assertSame('http://shaarli/subfolder/daily?month='. $dates[1]->format('Ym'), $day['absolute_url']);
|
||||||
|
static::assertCount(2, $day['links']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
namespace Shaarli;
|
namespace Shaarli\Helper;
|
||||||
|
|
||||||
use Shaarli\Config\ConfigManager;
|
use Shaarli\Config\ConfigManager;
|
||||||
|
use Shaarli\FakeApplicationUtils;
|
||||||
|
|
||||||
require_once 'tests/utils/FakeApplicationUtils.php';
|
require_once 'tests/utils/FakeApplicationUtils.php';
|
||||||
|
|
262
tests/helper/DailyPageHelperTest.php
Normal file
262
tests/helper/DailyPageHelperTest.php
Normal file
|
@ -0,0 +1,262 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Shaarli\Helper;
|
||||||
|
|
||||||
|
use Shaarli\Bookmark\Bookmark;
|
||||||
|
use Shaarli\TestCase;
|
||||||
|
use Slim\Http\Request;
|
||||||
|
|
||||||
|
class DailyPageHelperTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @dataProvider getRequestedTypes
|
||||||
|
*/
|
||||||
|
public function testExtractRequestedType(array $queryParams, string $expectedType): void
|
||||||
|
{
|
||||||
|
$request = $this->createMock(Request::class);
|
||||||
|
$request->method('getQueryParam')->willReturnCallback(function ($key) use ($queryParams): ?string {
|
||||||
|
return $queryParams[$key] ?? null;
|
||||||
|
});
|
||||||
|
|
||||||
|
$type = DailyPageHelper::extractRequestedType($request);
|
||||||
|
|
||||||
|
static::assertSame($type, $expectedType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getRequestedDateTimes
|
||||||
|
*/
|
||||||
|
public function testExtractRequestedDateTime(
|
||||||
|
string $type,
|
||||||
|
string $input,
|
||||||
|
?Bookmark $bookmark,
|
||||||
|
\DateTimeInterface $expectedDateTime,
|
||||||
|
string $compareFormat = 'Ymd'
|
||||||
|
): void {
|
||||||
|
$dateTime = DailyPageHelper::extractRequestedDateTime($type, $input, $bookmark);
|
||||||
|
|
||||||
|
static::assertSame($dateTime->format($compareFormat), $expectedDateTime->format($compareFormat));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testExtractRequestedDateTimeExceptionUnknownType(): void
|
||||||
|
{
|
||||||
|
$this->expectException(\Exception::class);
|
||||||
|
$this->expectExceptionMessage('Unsupported daily format type');
|
||||||
|
|
||||||
|
DailyPageHelper::extractRequestedDateTime('nope', null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getFormatsByType
|
||||||
|
*/
|
||||||
|
public function testGetFormatByType(string $type, string $expectedFormat): void
|
||||||
|
{
|
||||||
|
$format = DailyPageHelper::getFormatByType($type);
|
||||||
|
|
||||||
|
static::assertSame($expectedFormat, $format);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetFormatByTypeExceptionUnknownType(): void
|
||||||
|
{
|
||||||
|
$this->expectException(\Exception::class);
|
||||||
|
$this->expectExceptionMessage('Unsupported daily format type');
|
||||||
|
|
||||||
|
DailyPageHelper::getFormatByType('nope');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getStartDatesByType
|
||||||
|
*/
|
||||||
|
public function testGetStartDatesByType(
|
||||||
|
string $type,
|
||||||
|
\DateTimeImmutable $dateTime,
|
||||||
|
\DateTimeInterface $expectedDateTime
|
||||||
|
): void {
|
||||||
|
$startDateTime = DailyPageHelper::getStartDateTimeByType($type, $dateTime);
|
||||||
|
|
||||||
|
static::assertEquals($expectedDateTime, $startDateTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetStartDatesByTypeExceptionUnknownType(): void
|
||||||
|
{
|
||||||
|
$this->expectException(\Exception::class);
|
||||||
|
$this->expectExceptionMessage('Unsupported daily format type');
|
||||||
|
|
||||||
|
DailyPageHelper::getStartDateTimeByType('nope', new \DateTimeImmutable());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getEndDatesByType
|
||||||
|
*/
|
||||||
|
public function testGetEndDatesByType(
|
||||||
|
string $type,
|
||||||
|
\DateTimeImmutable $dateTime,
|
||||||
|
\DateTimeInterface $expectedDateTime
|
||||||
|
): void {
|
||||||
|
$endDateTime = DailyPageHelper::getEndDateTimeByType($type, $dateTime);
|
||||||
|
|
||||||
|
static::assertEquals($expectedDateTime, $endDateTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetEndDatesByTypeExceptionUnknownType(): void
|
||||||
|
{
|
||||||
|
$this->expectException(\Exception::class);
|
||||||
|
$this->expectExceptionMessage('Unsupported daily format type');
|
||||||
|
|
||||||
|
DailyPageHelper::getEndDateTimeByType('nope', new \DateTimeImmutable());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getDescriptionsByType
|
||||||
|
*/
|
||||||
|
public function testGeDescriptionsByType(
|
||||||
|
string $type,
|
||||||
|
\DateTimeImmutable $dateTime,
|
||||||
|
string $expectedDescription
|
||||||
|
): void {
|
||||||
|
$description = DailyPageHelper::getDescriptionByType($type, $dateTime);
|
||||||
|
|
||||||
|
static::assertEquals($expectedDescription, $description);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDescriptionByTypeExceptionUnknownType(): void
|
||||||
|
{
|
||||||
|
$this->expectException(\Exception::class);
|
||||||
|
$this->expectExceptionMessage('Unsupported daily format type');
|
||||||
|
|
||||||
|
DailyPageHelper::getDescriptionByType('nope', new \DateTimeImmutable());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getRssLengthsByType
|
||||||
|
*/
|
||||||
|
public function testGeRssLengthsByType(string $type): void {
|
||||||
|
$length = DailyPageHelper::getRssLengthByType($type);
|
||||||
|
|
||||||
|
static::assertIsInt($length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGeRssLengthsByTypeExceptionUnknownType(): void
|
||||||
|
{
|
||||||
|
$this->expectException(\Exception::class);
|
||||||
|
$this->expectExceptionMessage('Unsupported daily format type');
|
||||||
|
|
||||||
|
DailyPageHelper::getRssLengthByType('nope');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data provider for testExtractRequestedType() test method.
|
||||||
|
*/
|
||||||
|
public function getRequestedTypes(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[['month' => null], DailyPageHelper::DAY],
|
||||||
|
[['month' => ''], DailyPageHelper::MONTH],
|
||||||
|
[['month' => 'content'], DailyPageHelper::MONTH],
|
||||||
|
[['week' => null], DailyPageHelper::DAY],
|
||||||
|
[['week' => ''], DailyPageHelper::WEEK],
|
||||||
|
[['week' => 'content'], DailyPageHelper::WEEK],
|
||||||
|
[['day' => null], DailyPageHelper::DAY],
|
||||||
|
[['day' => ''], DailyPageHelper::DAY],
|
||||||
|
[['day' => 'content'], DailyPageHelper::DAY],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data provider for testExtractRequestedDateTime() test method.
|
||||||
|
*/
|
||||||
|
public function getRequestedDateTimes(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[DailyPageHelper::DAY, '20201013', null, new \DateTime('2020-10-13')],
|
||||||
|
[
|
||||||
|
DailyPageHelper::DAY,
|
||||||
|
'',
|
||||||
|
(new Bookmark())->setCreated($date = new \DateTime('2020-10-13 12:05:31')),
|
||||||
|
$date,
|
||||||
|
],
|
||||||
|
[DailyPageHelper::DAY, '', null, new \DateTime()],
|
||||||
|
[DailyPageHelper::WEEK, '202030', null, new \DateTime('2020-07-20')],
|
||||||
|
[
|
||||||
|
DailyPageHelper::WEEK,
|
||||||
|
'',
|
||||||
|
(new Bookmark())->setCreated($date = new \DateTime('2020-10-13 12:05:31')),
|
||||||
|
new \DateTime('2020-10-13'),
|
||||||
|
],
|
||||||
|
[DailyPageHelper::WEEK, '', null, new \DateTime(), 'Ym'],
|
||||||
|
[DailyPageHelper::MONTH, '202008', null, new \DateTime('2020-08-01'), 'Ym'],
|
||||||
|
[
|
||||||
|
DailyPageHelper::MONTH,
|
||||||
|
'',
|
||||||
|
(new Bookmark())->setCreated($date = new \DateTime('2020-10-13 12:05:31')),
|
||||||
|
new \DateTime('2020-10-13'),
|
||||||
|
'Ym'
|
||||||
|
],
|
||||||
|
[DailyPageHelper::MONTH, '', null, new \DateTime(), 'Ym'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data provider for testGetFormatByType() test method.
|
||||||
|
*/
|
||||||
|
public function getFormatsByType(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[DailyPageHelper::DAY, 'Ymd'],
|
||||||
|
[DailyPageHelper::WEEK, 'YW'],
|
||||||
|
[DailyPageHelper::MONTH, 'Ym'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data provider for testGetStartDatesByType() test method.
|
||||||
|
*/
|
||||||
|
public function getStartDatesByType(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[DailyPageHelper::DAY, new \DateTimeImmutable('2020-10-09 04:05:06'), new \DateTime('2020-10-09 00:00:00')],
|
||||||
|
[DailyPageHelper::WEEK, new \DateTimeImmutable('2020-10-09 04:05:06'), new \DateTime('2020-10-05 00:00:00')],
|
||||||
|
[DailyPageHelper::MONTH, new \DateTimeImmutable('2020-10-09 04:05:06'), new \DateTime('2020-10-01 00:00:00')],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data provider for testGetEndDatesByType() test method.
|
||||||
|
*/
|
||||||
|
public function getEndDatesByType(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[DailyPageHelper::DAY, new \DateTimeImmutable('2020-10-09 04:05:06'), new \DateTime('2020-10-09 23:59:59')],
|
||||||
|
[DailyPageHelper::WEEK, new \DateTimeImmutable('2020-10-09 04:05:06'), new \DateTime('2020-10-11 23:59:59')],
|
||||||
|
[DailyPageHelper::MONTH, new \DateTimeImmutable('2020-10-09 04:05:06'), new \DateTime('2020-10-31 23:59:59')],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data provider for testGetDescriptionsByType() test method.
|
||||||
|
*/
|
||||||
|
public function getDescriptionsByType(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[DailyPageHelper::DAY, $date = new \DateTimeImmutable(), 'Today - ' . $date->format('F d, Y')],
|
||||||
|
[DailyPageHelper::DAY, $date = new \DateTimeImmutable('-1 day'), 'Yesterday - ' . $date->format('F d, Y')],
|
||||||
|
[DailyPageHelper::DAY, new \DateTimeImmutable('2020-10-09 04:05:06'), 'October 9, 2020'],
|
||||||
|
[DailyPageHelper::WEEK, new \DateTimeImmutable('2020-10-09 04:05:06'), 'Week 41 (October 5, 2020)'],
|
||||||
|
[DailyPageHelper::MONTH, new \DateTimeImmutable('2020-10-09 04:05:06'), 'October, 2020'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data provider for testGetDescriptionsByType() test method.
|
||||||
|
*/
|
||||||
|
public function getRssLengthsByType(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[DailyPageHelper::DAY],
|
||||||
|
[DailyPageHelper::WEEK],
|
||||||
|
[DailyPageHelper::MONTH],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,10 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Shaarli;
|
namespace Shaarli\Helper;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use Shaarli\Exceptions\IOException;
|
use Shaarli\Exceptions\IOException;
|
||||||
|
use Shaarli\TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class FileUtilsTest
|
* Class FileUtilsTest
|
|
@ -4,7 +4,7 @@
|
||||||
namespace Shaarli\Security;
|
namespace Shaarli\Security;
|
||||||
|
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Shaarli\FileUtils;
|
use Shaarli\Helper\FileUtils;
|
||||||
use Shaarli\TestCase;
|
use Shaarli\TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
namespace Shaarli;
|
namespace Shaarli;
|
||||||
|
|
||||||
|
use Shaarli\Helper\ApplicationUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fake ApplicationUtils class to avoid HTTP requests
|
* Fake ApplicationUtils class to avoid HTTP requests
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Shaarli\FileUtils;
|
use Shaarli\Helper\FileUtils;
|
||||||
use Shaarli\History;
|
use Shaarli\History;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -6,12 +6,25 @@
|
||||||
<body>
|
<body>
|
||||||
{include="page.header"}
|
{include="page.header"}
|
||||||
|
|
||||||
|
<div class="pure-g">
|
||||||
|
<div class="pure-u-1 pure-alert pure-alert-success tag-sort">
|
||||||
|
<a href="{$base_path}/daily?day">{'Daily'|t}</a>
|
||||||
|
<a href="{$base_path}/daily?week">{'Weekly'|t}</a>
|
||||||
|
<a href="{$base_path}/daily?month">{'Monthly'|t}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="pure-g">
|
<div class="pure-g">
|
||||||
<div class="pure-u-lg-1-6 pure-u-1-24"></div>
|
<div class="pure-u-lg-1-6 pure-u-1-24"></div>
|
||||||
<div class="pure-u-lg-2-3 pure-u-22-24 page-form page-visitor" id="daily">
|
<div class="pure-u-lg-2-3 pure-u-22-24 page-form page-visitor" id="daily">
|
||||||
<h2 class="window-title">
|
<h2 class="window-title">
|
||||||
{'The Daily Shaarli'|t}
|
{$localizedType} Shaarli
|
||||||
<a href="{$base_path}/daily-rss" title="{'1 RSS entry per day'|t}"><i class="fa fa-rss"></i></a>
|
<a href="{$base_path}/daily-rss?{$type}"
|
||||||
|
title="{function="t('1 RSS entry per :type', '', 1, 'shaarli', [':type' => t($type)])"}"
|
||||||
|
>
|
||||||
|
<i class="fa fa-rss"></i>
|
||||||
|
</a>
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<div id="plugin_zone_start_daily" class="plugin_zone">
|
<div id="plugin_zone_start_daily" class="plugin_zone">
|
||||||
|
@ -25,19 +38,19 @@ <h2 class="window-title">
|
||||||
<div class="pure-g">
|
<div class="pure-g">
|
||||||
<div class="pure-u-lg-1-3 pure-u-1 center">
|
<div class="pure-u-lg-1-3 pure-u-1 center">
|
||||||
{if="$previousday"}
|
{if="$previousday"}
|
||||||
<a href="{$base_path}/daily?day={$previousday}">
|
<a href="{$base_path}/daily?{$type}={$previousday}">
|
||||||
<i class="fa fa-arrow-left"></i>
|
<i class="fa fa-arrow-left"></i>
|
||||||
{'Previous day'|t}
|
{function="t('Previous :type', '', 1, 'shaarli', [':type' => t($type)], true)"}
|
||||||
</a>
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class="daily-desc pure-u-lg-1-3 pure-u-1 center">
|
<div class="daily-desc pure-u-lg-1-3 pure-u-1 center">
|
||||||
{'All links of one day in a single page.'|t}
|
{function="t('All links of one :type in a single page.', '', 1, 'shaarli', [':type' => t($type)])"}
|
||||||
</div>
|
</div>
|
||||||
<div class="pure-u-lg-1-3 pure-u-1 center">
|
<div class="pure-u-lg-1-3 pure-u-1 center">
|
||||||
{if="$nextday"}
|
{if="$nextday"}
|
||||||
<a href="{$base_path}/daily?day={$nextday}">
|
<a href="{$base_path}/daily?{$type}={$nextday}">
|
||||||
{'Next day'|t}
|
{function="t('Next :type', '', 1, 'shaarli', [':type' => t($type)], true)"}
|
||||||
<i class="fa fa-arrow-right"></i>
|
<i class="fa fa-arrow-right"></i>
|
||||||
</a>
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -45,10 +58,7 @@ <h2 class="window-title">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="window-subtitle">
|
<h3 class="window-subtitle">
|
||||||
{if="!empty($dayDesc)"}
|
{$dayDesc}
|
||||||
{$dayDesc} -
|
|
||||||
{/if}
|
|
||||||
{function="format_date($dayDate, false)"}
|
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<div id="plugin_zone_about_daily" class="plugin_zone">
|
<div id="plugin_zone_about_daily" class="plugin_zone">
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<rss version="2.0">
|
<rss version="2.0">
|
||||||
<channel>
|
<channel>
|
||||||
<title>Daily - {$title}</title>
|
<title>{$localizedType} - {$title}</title>
|
||||||
<link>{$index_url}</link>
|
<link>{$index_url}</link>
|
||||||
<description>Daily shaared bookmarks</description>
|
<description>{function="t('All links of one :type in a single page.', '', 1, 'shaarli', [':type' => t($type)])"}</description>
|
||||||
<language>{$language}</language>
|
<language>{$language}</language>
|
||||||
<copyright>{$index_url}</copyright>
|
<copyright>{$index_url}</copyright>
|
||||||
<generator>Shaarli</generator>
|
<generator>Shaarli</generator>
|
||||||
|
@ -18,12 +18,15 @@
|
||||||
{loop="$value.links"}
|
{loop="$value.links"}
|
||||||
<h3><a href="{$value.url}">{$value.title}</a></h3>
|
<h3><a href="{$value.url}">{$value.title}</a></h3>
|
||||||
<small>
|
<small>
|
||||||
{if="!$hide_timestamps"}{$value.created|format_date} - {/if}{if="$value.tags"}{$value.tags}{/if}<br>
|
{if="!$hide_timestamps"}{$value.created|format_date} — {/if}
|
||||||
|
<a href="{$index_url}shaare/{$value.shorturl}">{'Permalink'|t}</a>
|
||||||
|
{if="$value.tags"} — {$value.tags}{/if}
|
||||||
|
<br>
|
||||||
{$value.url}
|
{$value.url}
|
||||||
</small><br>
|
</small><br>
|
||||||
{if="$value.thumbnail"}<img src="{$index_url}{$value.thumbnail}#" alt="thumbnail" />{/if}<br>
|
{if="$value.thumbnail"}<img src="{$index_url}{$value.thumbnail}#" alt="thumbnail" />{/if}<br>
|
||||||
{if="$value.description"}{$value.description}{/if}
|
{if="$value.description"}{$value.description}{/if}
|
||||||
<br><br><hr>
|
<br><hr>
|
||||||
{/loop}
|
{/loop}
|
||||||
]]></description>
|
]]></description>
|
||||||
</item>
|
</item>
|
||||||
|
|
Loading…
Reference in a new issue