* If no URL is provided, it will generate a local note URL.
* If no title is provided, it will use the URL as title.
*
- * @param array|null $input Request Link.
- * @param bool $defaultPrivate Setting defined if a bookmark is private by default.
+ * @param array|null $input Request Link.
+ * @param bool $defaultPrivate Setting defined if a bookmark is private by default.
+ * @param string $tagsSeparator Tags separator loaded from the config file.
*
* @return Bookmark instance.
*/
- public static function buildBookmarkFromRequest(?array $input, bool $defaultPrivate): Bookmark
- {
+ public static function buildBookmarkFromRequest(
+ ?array $input,
+ bool $defaultPrivate,
+ string $tagsSeparator
+ ): Bookmark {
$bookmark = new Bookmark();
$url = ! empty($input['url']) ? cleanup_url($input['url']) : '';
if (isset($input['private'])) {
$bookmark->setTitle(! empty($input['title']) ? $input['title'] : '');
$bookmark->setUrl($url);
$bookmark->setDescription(! empty($input['description']) ? $input['description'] : '');
+
+ // Be permissive with provided tags format
+ if (is_string($input['tags'] ?? null)) {
+ $input['tags'] = tags_str2array($input['tags'], $tagsSeparator);
+ }
+ if (is_array($input['tags'] ?? null) && count($input['tags']) === 1 && is_string($input['tags'][0])) {
+ $input['tags'] = tags_str2array($input['tags'][0], $tagsSeparator);
+ }
+
$bookmark->setTags(! empty($input['tags']) ? $input['tags'] : []);
$bookmark->setPrivate($private);
public function postLink($request, $response)
{
$data = (array) ($request->getParsedBody() ?? []);
- $bookmark = ApiUtils::buildBookmarkFromRequest($data, $this->conf->get('privacy.default_private_links'));
+ $bookmark = ApiUtils::buildBookmarkFromRequest(
+ $data,
+ $this->conf->get('privacy.default_private_links'),
+ $this->conf->get('general.tags_separator', ' ')
+ );
// duplicate by URL, return 409 Conflict
if (
! empty($bookmark->getUrl())
$index = index_url($this->ci['environment']);
$data = $request->getParsedBody();
- $requestBookmark = ApiUtils::buildBookmarkFromRequest($data, $this->conf->get('privacy.default_private_links'));
+ $requestBookmark = ApiUtils::buildBookmarkFromRequest(
+ $data,
+ $this->conf->get('privacy.default_private_links'),
+ $this->conf->get('general.tags_separator', ' ')
+ );
// duplicate URL on a different link, return 409 Conflict
if (
! empty($requestBookmark->getUrl())
$properties = implode('|', $propertiesKey);
// We need a OR here to accept either 'property=og:noquote' or 'property="og:unrelated og:my-tag"'
$orCondition = '["\']?(?:og:)?' . $tag . '["\']?|["\'][^\'"]*?(?:og:)?' . $tag . '[^\'"]*?[\'"]';
+ // Support quotes in double quoted content, and the other way around
+ $content = 'content=(["\'])((?:(?!\1).)*)\1';
// Try to retrieve OpenGraph tag.
- $ogRegex = '#<meta[^>]+(?:' . $properties . ')=(?:' . $orCondition . ')[^>]*content=(["\'])([^\1]*?)\1.*?>#';
+ $ogRegex = '#<meta[^>]+(?:' . $properties . ')=(?:' . $orCondition . ')[^>]*' . $content . '.*?>#';
// If the attributes are not in the order property => content (e.g. Github)
// New regex to keep this readable... more or less.
- $ogRegexReverse = '#<meta[^>]+content=(["\'])([^\1]*?)\1[^>]+(?:' . $properties . ')=(?:' . $orCondition . ').*?>#';
+ $ogRegexReverse = '#<meta[^>]+' . $content . '[^>]+(?:' . $properties . ')=(?:' . $orCondition . ').*?>#';
if (
preg_match($ogRegex, $html, $matches) > 0
<?php
+declare(strict_types=1);
+
namespace Shaarli\Feed;
+use DatePeriod;
+
/**
* Simple cache system, mainly for the RSS/ATOM feeds
*/
class CachedPage
{
- // Directory containing page caches
- private $cacheDir;
+ /** Directory containing page caches */
+ protected $cacheDir;
+
+ /** Should this URL be cached (boolean)? */
+ protected $shouldBeCached;
- // Should this URL be cached (boolean)?
- private $shouldBeCached;
+ /** Name of the cache file for this URL */
+ protected $filename;
- // Name of the cache file for this URL
- private $filename;
+ /** @var DatePeriod|null Optionally specify a period of time for cache validity */
+ protected $validityPeriod;
/**
* Creates a new CachedPage
*
- * @param string $cacheDir page cache directory
- * @param string $url page URL
- * @param bool $shouldBeCached whether this page needs to be cached
+ * @param string $cacheDir page cache directory
+ * @param string $url page URL
+ * @param bool $shouldBeCached whether this page needs to be cached
+ * @param ?DatePeriod $validityPeriod Optionally specify a time limit on requested cache
*/
- public function __construct($cacheDir, $url, $shouldBeCached)
+ public function __construct($cacheDir, $url, $shouldBeCached, ?DatePeriod $validityPeriod)
{
// TODO: check write access to the cache directory
$this->cacheDir = $cacheDir;
$this->filename = $this->cacheDir . '/' . sha1($url) . '.cache';
$this->shouldBeCached = $shouldBeCached;
+ $this->validityPeriod = $validityPeriod;
}
/**
if (!$this->shouldBeCached) {
return null;
}
- if (is_file($this->filename)) {
- return file_get_contents($this->filename);
+ if (!is_file($this->filename)) {
+ return null;
+ }
+ if ($this->validityPeriod !== null) {
+ $cacheDate = \DateTime::createFromFormat('U', (string) filemtime($this->filename));
+ if (
+ $cacheDate < $this->validityPeriod->getStartDate()
+ || $cacheDate > $this->validityPeriod->getEndDate()
+ ) {
+ return null;
+ }
}
- return null;
+
+ return file_get_contents($this->filename);
}
/**
protected function buildFormData(array $link, bool $isNew, Request $request): array
{
- $link['tags'] = strlen($link['tags']) > 0
+ $link['tags'] = $link['tags'] !== null && strlen($link['tags']) > 0
? $link['tags'] . $this->container->conf->get('general.tags_separator', ' ')
: $link['tags']
;
public function rss(Request $request, Response $response): Response
{
$response = $response->withHeader('Content-Type', 'application/rss+xml; charset=utf-8');
+ $type = DailyPageHelper::extractRequestedType($request);
+ $cacheDuration = DailyPageHelper::getCacheDatePeriodByType($type);
$pageUrl = page_url($this->container->environment);
- $cache = $this->container->pageCacheManager->getCachePage($pageUrl);
+ $cache = $this->container->pageCacheManager->getCachePage($pageUrl, $cacheDuration);
$cached = $cache->cachedVersion();
if (!empty($cached)) {
}
$days = [];
- $type = DailyPageHelper::extractRequestedType($request);
$format = DailyPageHelper::getFormatByType($type);
$length = DailyPageHelper::getRssLengthByType($type);
foreach ($this->container->bookmarkService->search() as $bookmark) {
namespace Shaarli\Helper;
+use DatePeriod;
+use DateTimeImmutable;
+use Exception;
use Shaarli\Bookmark\Bookmark;
use Slim\Http\Request;
* @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.
+ * @return DateTimeImmutable from input or latest bookmark.
*
- * @throws \Exception Type not supported.
+ * @throws Exception Type not supported.
*/
public static function extractRequestedDateTime(
string $type,
?string $requestedDate,
Bookmark $latestBookmark = null
- ): \DateTimeImmutable {
+ ): DateTimeImmutable {
$format = static::getFormatByType($type);
if (empty($requestedDate)) {
return $latestBookmark instanceof Bookmark
- ? new \DateTimeImmutable($latestBookmark->getCreated()->format(\DateTime::ATOM))
- : new \DateTimeImmutable()
+ ? new DateTimeImmutable($latestBookmark->getCreated()->format(\DateTime::ATOM))
+ : new DateTimeImmutable()
;
}
// W is not supported by createFromFormat...
if ($type === static::WEEK) {
- return (new \DateTimeImmutable())
+ return (new DateTimeImmutable())
->setISODate((int) substr($requestedDate, 0, 4), (int) substr($requestedDate, 4, 2))
;
}
- return \DateTimeImmutable::createFromFormat($format, $requestedDate);
+ return DateTimeImmutable::createFromFormat($format, $requestedDate);
}
/**
*
* @see https://www.php.net/manual/en/datetime.format.php
*
- * @throws \Exception Type not supported.
+ * @throws Exception Type not supported.
*/
public static function getFormatByType(string $type): string
{
case static::DAY:
return 'Ymd';
default:
- throw new \Exception('Unsupported daily format type');
+ throw new Exception('Unsupported daily format type');
}
}
* and we don't want to alter original datetime.
*
* @param string $type month/week/day
- * @param \DateTimeImmutable $requested DateTime extracted from request input
+ * @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.
+ * @throws Exception Type not supported.
*/
- public static function getStartDateTimeByType(string $type, \DateTimeImmutable $requested): \DateTimeInterface
+ public static function getStartDateTimeByType(string $type, DateTimeImmutable $requested): \DateTimeInterface
{
switch ($type) {
case static::MONTH:
case static::DAY:
return $requested->modify('Today midnight');
default:
- throw new \Exception('Unsupported daily format type');
+ throw new Exception('Unsupported daily format type');
}
}
* and we don't want to alter original datetime.
*
* @param string $type month/week/day
- * @param \DateTimeImmutable $requested DateTime extracted from request input
+ * @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.
+ * @throws Exception Type not supported.
*/
- public static function getEndDateTimeByType(string $type, \DateTimeImmutable $requested): \DateTimeInterface
+ public static function getEndDateTimeByType(string $type, DateTimeImmutable $requested): \DateTimeInterface
{
switch ($type) {
case static::MONTH:
case static::DAY:
return $requested->modify('Today 23:59:59');
default:
- throw new \Exception('Unsupported daily format type');
+ throw new Exception('Unsupported daily format type');
}
}
*
* @return string Localized time period description
*
- * @throws \Exception Type not supported.
+ * @throws Exception Type not supported.
*/
public static function getDescriptionByType(
string $type,
}
return $out . format_date($requested, false);
default:
- throw new \Exception('Unsupported daily format type');
+ throw new Exception('Unsupported daily format type');
}
}
*
* @return int number of elements
*
- * @throws \Exception Type not supported.
+ * @throws Exception Type not supported.
*/
public static function getRssLengthByType(string $type): int
{
case static::DAY:
return 30; // ~1 month
default:
- throw new \Exception('Unsupported daily format type');
+ 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
+ * @param ?DateTimeImmutable $requested Currently only used for UT
+ *
+ * @return DatePeriod number of elements
+ *
+ * @throws Exception Type not supported.
+ */
+ public static function getCacheDatePeriodByType(string $type, DateTimeImmutable $requested = null): DatePeriod
+ {
+ $requested = $requested ?? new DateTimeImmutable();
+
+ return new DatePeriod(
+ static::getStartDateTimeByType($type, $requested),
+ new \DateInterval('P1D'),
+ static::getEndDateTimeByType($type, $requested)
+ );
+ }
}
$title = mb_convert_encoding($title, 'utf-8', $charset);
}
- return [
+ return array_map([$this, 'cleanMetadata'], [
'title' => $title,
'description' => $description,
'tags' => $tags,
- ];
+ ]);
+ }
+
+ protected function cleanMetadata($data): ?string
+ {
+ return !is_string($data) || empty(trim($data)) ? null : trim($data);
}
}
namespace Shaarli\Render;
+use DatePeriod;
use Shaarli\Feed\CachedPage;
/**
$this->purgeCachedPages();
}
- public function getCachePage(string $pageUrl): CachedPage
+ /**
+ * Get CachedPage instance for provided URL.
+ *
+ * @param string $pageUrl
+ * @param ?DatePeriod $validityPeriod Optionally specify a time limit on requested cache
+ *
+ * @return CachedPage
+ */
+ public function getCachePage(string $pageUrl, DatePeriod $validityPeriod = null): CachedPage
{
return new CachedPage(
$this->pageCacheDir,
$pageUrl,
- false === $this->isLoggedIn
+ false === $this->isLoggedIn,
+ $validityPeriod
);
}
}
\DateTime::createFromFormat(\DateTime::ATOM, $data['updated'])
);
}
+
+ /**
+ * Test link creation with a tag string provided
+ */
+ public function testPostLinkWithTagString(): void
+ {
+ $link = [
+ 'tags' => 'one two',
+ ];
+ $env = Environment::mock([
+ 'REQUEST_METHOD' => 'POST',
+ 'CONTENT_TYPE' => 'application/json'
+ ]);
+
+ $request = Request::createFromEnvironment($env);
+ $request = $request->withParsedBody($link);
+ $response = $this->controller->postLink($request, new Response());
+
+ $this->assertEquals(201, $response->getStatusCode());
+ $this->assertEquals('/api/v1/bookmarks/1', $response->getHeader('Location')[0]);
+ $data = json_decode((string) $response->getBody(), true);
+ $this->assertEquals(self::NB_FIELDS_LINK, count($data));
+ $this->assertEquals(['one', 'two'], $data['tags']);
+ }
+
+ /**
+ * Test link creation with a tag string provided
+ */
+ public function testPostLinkWithTagString2(): void
+ {
+ $link = [
+ 'tags' => ['one two'],
+ ];
+ $env = Environment::mock([
+ 'REQUEST_METHOD' => 'POST',
+ 'CONTENT_TYPE' => 'application/json'
+ ]);
+
+ $request = Request::createFromEnvironment($env);
+ $request = $request->withParsedBody($link);
+ $response = $this->controller->postLink($request, new Response());
+
+ $this->assertEquals(201, $response->getStatusCode());
+ $this->assertEquals('/api/v1/bookmarks/1', $response->getHeader('Location')[0]);
+ $data = json_decode((string) $response->getBody(), true);
+ $this->assertEquals(self::NB_FIELDS_LINK, count($data));
+ $this->assertEquals(['one', 'two'], $data['tags']);
+ }
}
$this->controller->putLink($request, new Response(), ['id' => -1]);
}
+
+ /**
+ * Test link creation with a tag string provided
+ */
+ public function testPutLinkWithTagString(): void
+ {
+ $link = [
+ 'tags' => 'one two',
+ ];
+ $id = '41';
+ $env = Environment::mock([
+ 'REQUEST_METHOD' => 'PUT',
+ 'CONTENT_TYPE' => 'application/json'
+ ]);
+
+ $request = Request::createFromEnvironment($env);
+ $request = $request->withParsedBody($link);
+ $response = $this->controller->putLink($request, new Response(), ['id' => $id]);
+
+ $this->assertEquals(200, $response->getStatusCode());
+ $data = json_decode((string) $response->getBody(), true);
+ $this->assertEquals(self::NB_FIELDS_LINK, count($data));
+ $this->assertEquals(['one', 'two'], $data['tags']);
+ }
+
+ /**
+ * Test link creation with a tag string provided
+ */
+ public function testPutLinkWithTagString2(): void
+ {
+ $link = [
+ 'tags' => ['one two'],
+ ];
+ $id = '41';
+ $env = Environment::mock([
+ 'REQUEST_METHOD' => 'PUT',
+ 'CONTENT_TYPE' => 'application/json'
+ ]);
+
+ $request = Request::createFromEnvironment($env);
+ $request = $request->withParsedBody($link);
+ $response = $this->controller->putLink($request, new Response(), ['id' => $id]);
+
+ $this->assertEquals(200, $response->getStatusCode());
+ $data = json_decode((string) $response->getBody(), true);
+ $this->assertEquals(self::NB_FIELDS_LINK, count($data));
+ $this->assertEquals(['one', 'two'], $data['tags']);
+ }
}
$this->assertFalse(html_extract_tag('description', $html));
}
+ public function testHtmlExtractDescriptionFromGoogleRealCase(): void
+ {
+ $html = 'id="gsr"><meta content="Fêtes de fin d\'année" property="twitter:title"><meta '.
+ 'content="Bonnes fêtes de fin d\'année ! #GoogleDoodle" property="twitter:description">'.
+ '<meta content="Bonnes fêtes de fin d\'année ! #GoogleDoodle" property="og:description">'.
+ '<meta content="summary_large_image" property="twitter:card"><meta co'
+ ;
+ $this->assertSame('Bonnes fêtes de fin d\'année ! #GoogleDoodle', html_extract_tag('description', $html));
+ }
+
/**
* Test the header callback with valid value
*/
*/
public function testConstruct()
{
- new CachedPage(self::$testCacheDir, '', true);
- new CachedPage(self::$testCacheDir, '', false);
- new CachedPage(self::$testCacheDir, 'http://shaar.li/feed/rss', true);
- new CachedPage(self::$testCacheDir, 'http://shaar.li/feed/atom', false);
+ new CachedPage(self::$testCacheDir, '', true, null);
+ new CachedPage(self::$testCacheDir, '', false, null);
+ new CachedPage(self::$testCacheDir, 'http://shaar.li/feed/rss', true, null);
+ new CachedPage(self::$testCacheDir, 'http://shaar.li/feed/atom', false, null);
$this->addToAssertionCount(1);
}
*/
public function testCache()
{
- $page = new CachedPage(self::$testCacheDir, self::$url, true);
+ $page = new CachedPage(self::$testCacheDir, self::$url, true, null);
$this->assertFileNotExists(self::$filename);
$page->cache('<p>Some content</p>');
*/
public function testShouldNotCache()
{
- $page = new CachedPage(self::$testCacheDir, self::$url, false);
+ $page = new CachedPage(self::$testCacheDir, self::$url, false, null);
$this->assertFileNotExists(self::$filename);
$page->cache('<p>Some content</p>');
*/
public function testCachedVersion()
{
- $page = new CachedPage(self::$testCacheDir, self::$url, true);
+ $page = new CachedPage(self::$testCacheDir, self::$url, true, null);
$this->assertFileNotExists(self::$filename);
$page->cache('<p>Some content</p>');
*/
public function testCachedVersionNoFile()
{
- $page = new CachedPage(self::$testCacheDir, self::$url, true);
+ $page = new CachedPage(self::$testCacheDir, self::$url, true, null);
$this->assertFileNotExists(self::$filename);
$this->assertEquals(
*/
public function testNoCachedVersion()
{
- $page = new CachedPage(self::$testCacheDir, self::$url, false);
+ $page = new CachedPage(self::$testCacheDir, self::$url, false, null);
$this->assertFileNotExists(self::$filename);
$this->assertEquals(
$page->cachedVersion()
);
}
+
+ /**
+ * Return a page's cached content within date period
+ */
+ public function testCachedVersionInDatePeriod()
+ {
+ $period = new \DatePeriod(
+ new \DateTime('yesterday'),
+ new \DateInterval('P1D'),
+ new \DateTime('tomorrow')
+ );
+ $page = new CachedPage(self::$testCacheDir, self::$url, true, $period);
+
+ $this->assertFileNotExists(self::$filename);
+ $page->cache('<p>Some content</p>');
+ $this->assertFileExists(self::$filename);
+ $this->assertEquals(
+ '<p>Some content</p>',
+ $page->cachedVersion()
+ );
+ }
+
+ /**
+ * Return a page's cached content outside of date period
+ */
+ public function testCachedVersionNotInDatePeriod()
+ {
+ $period = new \DatePeriod(
+ new \DateTime('yesterday noon'),
+ new \DateInterval('P1D'),
+ new \DateTime('yesterday midnight')
+ );
+ $page = new CachedPage(self::$testCacheDir, self::$url, true, $period);
+
+ $this->assertFileNotExists(self::$filename);
+ $page->cache('<p>Some content</p>');
+ $this->assertFileExists(self::$filename);
+ $this->assertNull($page->cachedVersion());
+ }
}
namespace Shaarli\Helper;
+use DateTimeImmutable;
+use DateTimeInterface;
use Shaarli\Bookmark\Bookmark;
use Shaarli\TestCase;
use Slim\Http\Request;
string $type,
string $input,
?Bookmark $bookmark,
- \DateTimeInterface $expectedDateTime,
+ DateTimeInterface $expectedDateTime,
string $compareFormat = 'Ymd'
): void {
$dateTime = DailyPageHelper::extractRequestedDateTime($type, $input, $bookmark);
*/
public function testGetStartDatesByType(
string $type,
- \DateTimeImmutable $dateTime,
- \DateTimeInterface $expectedDateTime
+ DateTimeImmutable $dateTime,
+ DateTimeInterface $expectedDateTime
): void {
$startDateTime = DailyPageHelper::getStartDateTimeByType($type, $dateTime);
$this->expectException(\Exception::class);
$this->expectExceptionMessage('Unsupported daily format type');
- DailyPageHelper::getStartDateTimeByType('nope', new \DateTimeImmutable());
+ DailyPageHelper::getStartDateTimeByType('nope', new DateTimeImmutable());
}
/**
*/
public function testGetEndDatesByType(
string $type,
- \DateTimeImmutable $dateTime,
- \DateTimeInterface $expectedDateTime
+ DateTimeImmutable $dateTime,
+ DateTimeInterface $expectedDateTime
): void {
$endDateTime = DailyPageHelper::getEndDateTimeByType($type, $dateTime);
$this->expectException(\Exception::class);
$this->expectExceptionMessage('Unsupported daily format type');
- DailyPageHelper::getEndDateTimeByType('nope', new \DateTimeImmutable());
+ DailyPageHelper::getEndDateTimeByType('nope', new DateTimeImmutable());
}
/**
*/
public function testGeDescriptionsByType(
string $type,
- \DateTimeImmutable $dateTime,
+ DateTimeImmutable $dateTime,
string $expectedDescription
): void {
$description = DailyPageHelper::getDescriptionByType($type, $dateTime);
$this->expectException(\Exception::class);
$this->expectExceptionMessage('Unsupported daily format type');
- DailyPageHelper::getDescriptionByType('nope', new \DateTimeImmutable());
+ DailyPageHelper::getDescriptionByType('nope', new DateTimeImmutable());
}
/**
DailyPageHelper::getRssLengthByType('nope');
}
+ /**
+ * @dataProvider getCacheDatePeriodByType
+ */
+ public function testGetCacheDatePeriodByType(
+ string $type,
+ DateTimeImmutable $requested,
+ DateTimeInterface $start,
+ DateTimeInterface $end
+ ): void {
+ $period = DailyPageHelper::getCacheDatePeriodByType($type, $requested);
+
+ static::assertEquals($start, $period->getStartDate());
+ static::assertEquals($end, $period->getEndDate());
+ }
+
+ public function testGetCacheDatePeriodByTypeExceptionUnknownType(): void
+ {
+ $this->expectException(\Exception::class);
+ $this->expectExceptionMessage('Unsupported daily format type');
+
+ DailyPageHelper::getCacheDatePeriodByType('nope');
+ }
+
/**
* Data provider for testExtractRequestedType() 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')],
+ [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')],
];
}
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')],
+ [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')],
];
}
public function getDescriptionsByType(): array
{
return [
- [DailyPageHelper::DAY, $date = new \DateTimeImmutable(), 'Today - ' . $date->format('F j, Y')],
- [DailyPageHelper::DAY, $date = new \DateTimeImmutable('-1 day'), 'Yesterday - ' . $date->format('F j, 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'],
+ [DailyPageHelper::DAY, $date = new DateTimeImmutable(), 'Today - ' . $date->format('F j, Y')],
+ [DailyPageHelper::DAY, $date = new DateTimeImmutable('-1 day'), 'Yesterday - ' . $date->format('F j, 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.
+ * Data provider for testGetRssLengthsByType() test method.
*/
public function getRssLengthsByType(): array
{
[DailyPageHelper::MONTH],
];
}
+
+ /**
+ * Data provider for testGetCacheDatePeriodByType() test method.
+ */
+ public function getCacheDatePeriodByType(): array
+ {
+ return [
+ [
+ DailyPageHelper::DAY,
+ new DateTimeImmutable('2020-10-09 04:05:06'),
+ new \DateTime('2020-10-09 00:00:00'),
+ new \DateTime('2020-10-09 23:59:59'),
+ ],
+ [
+ DailyPageHelper::WEEK,
+ new DateTimeImmutable('2020-10-09 04:05:06'),
+ new \DateTime('2020-10-05 00:00:00'),
+ new \DateTime('2020-10-11 23:59:59'),
+ ],
+ [
+ DailyPageHelper::MONTH,
+ new DateTimeImmutable('2020-10-09 04:05:06'),
+ new \DateTime('2020-10-01 00:00:00'),
+ new \DateTime('2020-10-31 23:59:59'),
+ ],
+ ];
+ }
}
$remoteCharset = 'utf-8';
$expectedResult = [
- 'title' => $remoteTitle,
+ 'title' => trim($remoteTitle),
'description' => $remoteDesc,
'tags' => $remoteTags,
];