Allow to show only upcoming events (#16)

A new TypoScript option upcoming is added.
The option can be set to 0 (default) or 1.
0 behaves the same way as in the past.
1 turns off the option useMidnight, start and end.
Only dates with a start date in the future will be shown.

Relates: #10507
This commit is contained in:
Daniel Siepmann 2023-05-22 09:59:45 +02:00 committed by GitHub
parent 0fc2668d17
commit 99ef32a37b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 166 additions and 14 deletions

View file

@ -77,10 +77,19 @@ class DateDemand
protected $endObject = null; protected $endObject = null;
/** /**
* Use midnight as "start".
*
* @var bool * @var bool
*/ */
protected $useMidnight = true; protected $useMidnight = true;
/**
* Only show dates that have not started yet.
*
* @var bool
*/
protected $upcoming = false;
/** /**
* @var string * @var string
*/ */
@ -361,13 +370,25 @@ class DateDemand
public function setUseMidnight(bool $useMidnight): void public function setUseMidnight(bool $useMidnight): void
{ {
$this->useMidnight = $useMidnight; $this->useMidnight = $useMidnight;
$this->upcoming = false;
}
public function setUpcoming(bool $upcoming): void
{
$this->startObject = null;
$this->endObject = null;
$this->useMidnight = false;
$this->upcoming = $upcoming;
} }
public function shouldShowFromNow(): bool public function shouldShowFromNow(): bool
{ {
return $this->getStartObject() === null return $this->getStartObject() === null
&& $this->getEndObject() === null && $this->getEndObject() === null
&& $this->useMidnight === false; && $this->useMidnight === false
&& $this->upcoming === false
;
} }
public function shouldShowFromMidnight(): bool public function shouldShowFromMidnight(): bool
@ -377,6 +398,11 @@ class DateDemand
&& $this->useMidnight === true; && $this->useMidnight === true;
} }
public function shouldShowUpcoming(): bool
{
return $this->upcoming === true;
}
public function getConsiderDate(): bool public function getConsiderDate(): bool
{ {
return $this->considerDate; return $this->considerDate;

View file

@ -99,6 +99,9 @@ class DateDemandFactory
if (isset($settings['useMidnight'])) { if (isset($settings['useMidnight'])) {
$demand->setUseMidnight((bool)$settings['useMidnight']); $demand->setUseMidnight((bool)$settings['useMidnight']);
} }
if (isset($settings['upcoming'])) {
$demand->setUpcoming((bool)$settings['upcoming']);
}
if (!empty($settings['limit'])) { if (!empty($settings['limit'])) {
$demand->setLimit($settings['limit']); $demand->setLimit($settings['limit']);
} }

View file

@ -2,6 +2,8 @@
namespace Wrm\Events\Domain\Repository; namespace Wrm\Events\Domain\Repository;
use DateTimeImmutable;
use DateTimeZone;
use TYPO3\CMS\Core\Context\Context; use TYPO3\CMS\Core\Context\Context;
use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
@ -10,6 +12,7 @@ use TYPO3\CMS\Extbase\Persistence\Generic\QueryResult;
use TYPO3\CMS\Extbase\Persistence\QueryInterface; use TYPO3\CMS\Extbase\Persistence\QueryInterface;
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface; use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
use TYPO3\CMS\Extbase\Persistence\Repository; use TYPO3\CMS\Extbase\Persistence\Repository;
use UnexpectedValueException;
use Wrm\Events\Domain\Model\Dto\DateDemand; use Wrm\Events\Domain\Model\Dto\DateDemand;
use Wrm\Events\Service\CategoryService; use Wrm\Events\Service\CategoryService;
@ -87,19 +90,7 @@ class DateRepository extends Repository
} }
if ($demand->shouldShowFromNow() || $demand->shouldShowFromMidnight()) { if ($demand->shouldShowFromNow() || $demand->shouldShowFromMidnight()) {
$now = $this->context->getPropertyFromAspect( $now = $this->getNow();
'date',
'full',
new \DateTimeImmutable()
);
if (!$now instanceof \DateTimeImmutable) {
throw new \UnexpectedValueException(
'Could not retrieve now as DateTimeImmutable, got "' . gettype($now) . '".',
1639382648
);
}
$now = $now->setTimezone(new \DateTimeZone(date_default_timezone_get()));
if ($demand->shouldShowFromMidnight()) { if ($demand->shouldShowFromMidnight()) {
$now = $now->modify('midnight'); $now = $now->modify('midnight');
@ -109,6 +100,16 @@ class DateRepository extends Repository
$query->greaterThanOrEqual('start', $now), $query->greaterThanOrEqual('start', $now),
$query->greaterThanOrEqual('end', $now) $query->greaterThanOrEqual('end', $now)
]); ]);
} elseif ($demand->shouldShowUpcoming()) {
$now = $this->getNow();
$constraints['future'] = $query->logicalAnd([
$query->greaterThan('start', $now),
$query->logicalOr([
$query->equals('end', 0),
$query->greaterThan('end', $now)
])
]);
} }
if ($demand->getLimit() !== '') { if ($demand->getLimit() !== '') {
@ -283,4 +284,24 @@ class DateRepository extends Repository
$query->logicalNot($query->equals('event.uid', null)) $query->logicalNot($query->equals('event.uid', null))
); );
} }
private function getNow(): DateTimeImmutable
{
$now = $this->context->getPropertyFromAspect(
'date',
'full',
new DateTimeImmutable()
);
if (!$now instanceof DateTimeImmutable) {
throw new UnexpectedValueException(
'Could not retrieve now as DateTimeImmutable, got "' . gettype($now) . '".',
1639382648
);
}
$now = $now->setTimezone(new DateTimeZone(date_default_timezone_get()));
return $now;
}
} }

View file

@ -17,6 +17,13 @@ Features
That allows visitors to always see the next dates. That allows visitors to always see the next dates.
* Add ``upcoming`` setting for dates.
The option can be set to ``0`` (default) or ``1``.
``0`` behaves the same way as in the past.
``1`` turns off the option ``useMidnight``, ``start`` and ``end``.
Only dates with a start date in the future will be shown.
Fixes Fixes
----- -----

View file

@ -3,6 +3,28 @@
Settings Settings
======== ========
Frontend
--------
The frontend can be configured via TYPO3 Extbase defaults.
``stdWrap`` is applied to all options.
.. option:: settings.useMidnight
Can be set to ``1`` (default) or ``0``.
| ``0`` will show dates starting from now.
| ``1`` will use midnight of configured start date.
.. option:: settings.upcoming
Can be set to ``0`` (default) or ``1``.
| ``0`` does not alter the behaviour.
| ``1`` turns off the option ``useMidnight``, ``start`` and ``end``.
| Only dates with a start date in the future will be shown.
Import Import
------ ------

View file

@ -172,4 +172,34 @@ class DatesTest extends AbstractTestCase
self::assertStringContainsString('Event 8', $html); self::assertStringContainsString('Event 8', $html);
self::assertStringContainsString('Event 9', $html); self::assertStringContainsString('Event 9', $html);
} }
/**
* @test
*/
public function returnsUpcomingDates(): void
{
$this->importPHPDataSet(__DIR__ . '/DatesTestFixtures/ReturnsUpcomingDates.php');
$request = new InternalRequest();
$request = $request->withPageId(1);
$request = $request->withInstructions([
$this->getTypoScriptInstruction()
->withTypoScript([
'plugin.' => [
'tx_events.' => [
'settings.' => [
'upcoming' => '1',
],
],
],
])
]);
$response = $this->executeFrontendRequest($request);
self::assertSame(200, $response->getStatusCode());
$html = (string) $response->getBody();
self::assertStringNotContainsString('Event 1', $html);
self::assertStringContainsString('Event 2', $html);
}
} }

View file

@ -0,0 +1,43 @@
<?php
use DateTimeImmutable;
return [
'tt_content' => [
[
'uid' => 1,
'pid' => 1,
'CType' => 'list',
'list_type' => 'events_datelist',
'header' => 'Upcoming Dates',
],
],
'tx_events_domain_model_event' => [
[
'uid' => 1,
'pid' => 2,
'title' => 'Event 1',
],
[
'uid' => 2,
'pid' => 2,
'title' => 'Event 2',
],
],
'tx_events_domain_model_date' => [
[
'uid' => 1,
'pid' => 2,
'event' => 1,
'start' => (new DateTimeImmutable())->modify('-5 minutes')->format('U'),
'end' => (new DateTimeImmutable())->modify('+5 minutes')->format('U'),
],
[
'uid' => 2,
'pid' => 2,
'event' => 2,
'start' => (new DateTimeImmutable())->modify('+5 minutes')->format('U'),
'end' => (new DateTimeImmutable())->modify('+15 minutes')->format('U'),
],
],
];