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

View file

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

View file

@ -2,6 +2,8 @@
namespace Wrm\Events\Domain\Repository;
use DateTimeImmutable;
use DateTimeZone;
use TYPO3\CMS\Core\Context\Context;
use TYPO3\CMS\Core\Database\ConnectionPool;
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\QueryResultInterface;
use TYPO3\CMS\Extbase\Persistence\Repository;
use UnexpectedValueException;
use Wrm\Events\Domain\Model\Dto\DateDemand;
use Wrm\Events\Service\CategoryService;
@ -87,19 +90,7 @@ class DateRepository extends Repository
}
if ($demand->shouldShowFromNow() || $demand->shouldShowFromMidnight()) {
$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()));
$now = $this->getNow();
if ($demand->shouldShowFromMidnight()) {
$now = $now->modify('midnight');
@ -109,6 +100,16 @@ class DateRepository extends Repository
$query->greaterThanOrEqual('start', $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() !== '') {
@ -283,4 +284,24 @@ class DateRepository extends Repository
$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.
* 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
-----

View file

@ -3,6 +3,28 @@
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
------

View file

@ -172,4 +172,34 @@ class DatesTest extends AbstractTestCase
self::assertStringContainsString('Event 8', $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'),
],
],
];