Further removals

This commit is contained in:
Daniel Siepmann (Codappix) 2024-11-06 07:54:30 +01:00
parent ae6d7c015b
commit 8eb784cbb3
SSH key fingerprint: SHA256:nAjx3Dpp8kuAC+S7QXj8BWmqw+KI1Miu+5e40BP3LXA
61 changed files with 247 additions and 1974 deletions

View file

@ -1,195 +0,0 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2023 Daniel Siepmann <coding@daniel-siepmann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
namespace WerkraumMedia\Events\Updates;
use Generator;
use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Install\Attribute\UpgradeWizard;
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
use WerkraumMedia\Events\Domain\Model\Location;
#[UpgradeWizard(MigrateDuplicateLocations::class)]
final class MigrateDuplicateLocations implements UpgradeWizardInterface
{
public function __construct(
private readonly ConnectionPool $connectionPool
) {
}
public function getIdentifier(): string
{
return self::class;
}
public function getTitle(): string
{
return 'Remove duplicate locations of EXT:event';
}
public function getDescription(): string
{
return 'Checks for duplicates and reduces them to one entry, fixing relations to events.';
}
public function updateNecessary(): bool
{
return true;
}
public function executeUpdate(): bool
{
$duplicates = [];
foreach ($this->getLocations() as $location) {
$locationObject = $this->buildObject($location);
if ($locationObject->getGlobalId() === $location['global_id']) {
continue;
}
$uid = (int)$location['uid'];
$matchingLocation = $this->getMatchingLocation(
$locationObject->getGlobalId(),
$uid
);
// Already have entries for the new id, this one is duplicate
if ($matchingLocation > 0) {
$duplicates[$uid] = $matchingLocation;
continue;
}
// No duplicates, update this one
$this->updateLocation($locationObject, $uid);
}
$this->removeDuplicates(array_keys($duplicates));
$this->updateRelations($duplicates);
return true;
}
public function getPrerequisites(): array
{
return [];
}
/**
* @return Generator<array>
*/
private function getLocations(): Generator
{
$queryBuilder = $this->connectionPool->getQueryBuilderForTable('tx_events_domain_model_location');
$queryBuilder->select(
'name',
'street',
'zip',
'city',
'district',
'country',
'phone',
'latitude',
'longitude',
'global_id',
'uid',
'sys_language_uid'
);
$queryBuilder->from('tx_events_domain_model_location');
$queryBuilder->orderBy('uid', 'asc');
$result = $queryBuilder->executeQuery();
foreach ($result->fetchAllAssociative() as $location) {
yield $location;
}
}
private function getMatchingLocation(
string $globalId,
int $uid
): int {
$queryBuilder = $this->connectionPool->getQueryBuilderForTable('tx_events_domain_model_location');
$queryBuilder->select('uid');
$queryBuilder->from('tx_events_domain_model_location');
$queryBuilder->where($queryBuilder->expr()->eq('global_id', $queryBuilder->createNamedParameter($globalId)));
$queryBuilder->andWhere($queryBuilder->expr()->neq('uid', $queryBuilder->createNamedParameter($uid)));
$queryBuilder->setMaxResults(1);
$uid = $queryBuilder->executeQuery()->fetchOne();
if (is_numeric($uid) === false) {
return 0;
}
return (int)$uid;
}
private function buildObject(array $location): Location
{
return new Location(
$location['name'],
$location['street'],
$location['zip'],
$location['city'],
$location['district'],
$location['country'],
$location['phone'],
$location['latitude'],
$location['longitude'],
(int)$location['sys_language_uid']
);
}
private function updateLocation(Location $location, int $uid): void
{
$queryBuilder = $this->connectionPool->getQueryBuilderForTable('tx_events_domain_model_location');
$queryBuilder->update('tx_events_domain_model_location');
$queryBuilder->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($uid)));
$queryBuilder->set('global_id', $location->getGlobalId());
$queryBuilder->set('latitude', $location->getLatitude());
$queryBuilder->set('longitude', $location->getLongitude());
$queryBuilder->executeStatement();
}
/**
* @param int[] $uids
*/
private function removeDuplicates(array $uids): void
{
$queryBuilder = $this->connectionPool->getQueryBuilderForTable('tx_events_domain_model_location');
$queryBuilder->delete('tx_events_domain_model_location');
$queryBuilder->where($queryBuilder->expr()->in('uid', $queryBuilder->createNamedParameter($uids, Connection::PARAM_INT_ARRAY)));
$queryBuilder->executeStatement();
}
private function updateRelations(array $migration): void
{
$queryBuilder = $this->connectionPool->getQueryBuilderForTable('tx_events_domain_model_event');
$queryBuilder->update('tx_events_domain_model_event');
foreach ($migration as $legacyLocationUid => $newLocationUid) {
$finalBuilder = clone $queryBuilder;
$finalBuilder->where($finalBuilder->expr()->eq('location', $finalBuilder->createNamedParameter($legacyLocationUid)));
$finalBuilder->set('location', $newLocationUid);
$finalBuilder->executeStatement();
}
}
}

View file

@ -1,267 +0,0 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2023 Daniel Siepmann <coding@daniel-siepmann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
namespace WerkraumMedia\Events\Updates;
use Exception;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
use TYPO3\CMS\Core\DataHandling\DataHandler;
use TYPO3\CMS\Core\Log\Logger;
use TYPO3\CMS\Core\Log\LogManager;
use TYPO3\CMS\Install\Attribute\UpgradeWizard;
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
#[UpgradeWizard(MigrateOldLocations::class)]
class MigrateOldLocations implements UpgradeWizardInterface
{
private readonly Logger $logger;
private array $uidsForTranslation = [];
public function __construct(
private readonly ConnectionPool $connectionPool,
private readonly DataHandler $dataHandler,
LogManager $logManager
) {
$this->logger = $logManager->getLogger(self::class);
}
public function getTitle(): string
{
return 'Migrate EXT:event location data.';
}
public function getDescription(): string
{
return 'Checks for legacy location data stored within events and will create dedicated location records and relations.';
}
public function updateNecessary(): bool
{
return $this->hasOldColumns()
&& $this->getQueryBuilder()->count('*')->executeQuery()->fetchOne() > 0;
}
public function executeUpdate(): bool
{
$result = $this->getQueryBuilder()->executeQuery()->iterateAssociative();
foreach ($result as $eventRecord) {
$this->logger->info('Updating event record.', ['record' => $eventRecord]);
$eventRecord['location'] = $this->getLocationUid($eventRecord);
$this->uidsForTranslation[$eventRecord['uid'] . '-' . $eventRecord['sys_language_uid']] = $eventRecord['location'];
$this->updateEvent($eventRecord);
}
return true;
}
private function getLocationUid(array $event): int
{
$existingUid = $this->getExitingLocationUid($event);
if ($existingUid > 0) {
$this->logger->info('Location already exists', ['uid' => $existingUid, 'event' => $event]);
return $existingUid;
}
return $this->createLocation($event);
}
private function getExitingLocationUid(array $event): int
{
$columns = [
'sys_language_uid',
'name',
'street',
'district',
'city',
'zip',
'country',
'phone',
'latitude',
'longitude',
];
$qb = $this->connectionPool->getQueryBuilderForTable('tx_events_domain_model_location');
$qb->select('uid', 'l10n_parent');
$qb->from('tx_events_domain_model_location');
foreach ($columns as $column) {
$qb->andWhere($qb->expr()->eq($column, $qb->createNamedParameter($event[$column])));
}
$uids = $qb->executeQuery()->fetchAssociative();
if (is_bool($uids)) {
return 0;
}
return $uids['l10n_parent'] ?: $uids['uid'];
}
private function createLocation(array $event): int
{
$this->logger->info('Location will be created.', ['event' => $event]);
$columnsToMap = [
'pid',
'sys_language_uid',
'name',
'street',
'district',
'city',
'zip',
'country',
'phone',
'latitude',
'longitude',
];
$record = [];
foreach ($columnsToMap as $columnName) {
$record[$columnName] = $event[$columnName];
}
$recordUid = 'NEW12121';
$l10nParentUid = $this->uidsForTranslation[$event['l10n_parent'] . '-0'] ?? 0;
$dataHandler = clone $this->dataHandler;
if ($event['sys_language_uid'] > 0 && $l10nParentUid > 0) {
$this->logger->info('Foreign language, create translation.', [
'l10nParentUid' => $l10nParentUid,
'event' => $event,
]);
$dataHandler->start([], [
'tx_events_domain_model_location' => [
$l10nParentUid => [
'localize' => $event['sys_language_uid'],
],
],
]);
$dataHandler->process_cmdmap();
$recordUid = $dataHandler->copyMappingArray_merged['tx_events_domain_model_location'][$l10nParentUid] ?? 0;
}
$this->logger->info('Create or update loation.', [
'recordUid' => $recordUid,
'l10nParentUid' => $l10nParentUid,
'event' => $event,
'record' => $record,
]);
$dataHandler->start([
'tx_events_domain_model_location' => [
$recordUid => $record,
],
], []);
$dataHandler->process_datamap();
$uid = $dataHandler->substNEWwithIDs[$recordUid] ?? 0;
$this->logger->info('Created or updated location.', [
'uid' => $uid,
]);
if ($uid > 0) {
return $uid;
}
if ($l10nParentUid > 0) {
return $l10nParentUid;
}
throw new Exception('Could not create location: ' . implode(', ', $dataHandler->errorLog), 1672916613);
}
private function updateEvent(array $event): void
{
$this->connectionPool
->getConnectionForTable('tx_events_domain_model_event')
->update(
'tx_events_domain_model_event',
['location' => $event['location']],
['uid' => $event['uid']]
)
;
}
private function getQueryBuilder(): QueryBuilder
{
$columns = $this->columnsToFetch();
$qb = $this->connectionPool->getQueryBuilderForTable('tx_events_domain_model_event');
$qb->getRestrictions()->removeAll();
$qb->select(...$columns);
$qb->addSelect('uid', 'pid', 'sys_language_uid', 'l10n_parent');
$qb->from('tx_events_domain_model_event');
foreach ($columns as $columnName) {
$qb->orWhere($qb->expr()->neq($columnName, $qb->createNamedParameter('')));
}
$qb->orderBy('sys_language_uid', 'ASC');
$qb->addOrderBy('l10n_parent', 'ASC');
$qb->addOrderBy('uid', 'ASC');
return $qb;
}
public function getIdentifier(): string
{
return self::class;
}
public function getPrerequisites(): array
{
return [
DatabaseUpdatedPrerequisite::class,
];
}
private function hasOldColumns(): bool
{
$schema = $this->connectionPool
->getConnectionForTable('tx_events_domain_model_event')
->getSchemaInformation()
->introspectTable('tx_events_domain_model_event')
;
foreach ($this->columnsToFetch() as $column) {
if ($schema->hasColumn($column) === false) {
return false;
}
}
return true;
}
/**
* @return string[]
*/
private function columnsToFetch(): array
{
return [
'name',
'street',
'district',
'city',
'zip',
'country',
'phone',
'latitude',
'longitude',
];
}
}

View file

@ -1,59 +0,0 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2024 Daniel Siepmann <daniel.siepmann@codappix.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
namespace WerkraumMedia\Events\Updates;
use TYPO3\CMS\Install\Attribute\UpgradeWizard;
use TYPO3\CMS\Install\Updates\AbstractListTypeToCTypeUpdate;
// TODO: typo3/cms-core:14.0 Remove condition as this class is provided since 13.
if (class_exists(AbstractListTypeToCTypeUpdate::class) === false) {
final class MigratePluginsFromListToCtype
{
}
return;
}
#[UpgradeWizard(MigratePluginsFromListToCtype::class)]
final class MigratePluginsFromListToCtype extends AbstractListTypeToCTypeUpdate
{
protected function getListTypeToCTypeMapping(): array
{
return [
'events_datelist' => 'events_datelist',
'events_datesearch' => 'events_datesearch',
'events_dateshow ' => 'events_dateshow',
'events_selected ' => 'events_selected',
];
}
public function getTitle(): string
{
return 'Migrate EXT:events content elements.';
}
public function getDescription(): string
{
return 'Migrate CType from list to dedicated plugins.';
}
}

View file

@ -1,219 +0,0 @@
<T3DataStructure>
<sheets>
<sDEF>
<ROOT>
<sheetTitle>Options</sheetTitle>
<type>array</type>
<el>
<settings.sortByDate>
<exclude>1</exclude>
<label>Sort By</label>
<config>
<type>select</type>
<renderType>selectSingle</renderType>
<items type="array">
<numIndex index="0" type="array">
<numIndex index="label">Start</numIndex>
<numIndex index="value">start</numIndex>
</numIndex>
<numIndex index="1" type="array">
<numIndex index="label">End</numIndex>
<numIndex index="value">end</numIndex>
</numIndex>
</items>
</config>
</settings.sortByDate>
<settings.sortOrder>
<exclude>1</exclude>
<label>Sort Order</label>
<config>
<type>select</type>
<renderType>selectSingle</renderType>
<items type="array">
<numIndex index="0" type="array">
<numIndex index="label">
Ascending
</numIndex>
<numIndex index="value">ASC</numIndex>
</numIndex>
<numIndex index="1" type="array">
<numIndex index="label">
Descending
</numIndex>
<numIndex index="value">DESC</numIndex>
</numIndex>
</items>
<default>ASC</default>
</config>
</settings.sortOrder>
<settings.limit>
<exclude>1</exclude>
<label>Max Items</label>
<config>
<type>input</type>
<size>10</size>
<max>30</max>
<eval>trim</eval>
</config>
</settings.limit>
<settings.highlight>
<exclude>1</exclude>
<label>Highlights only</label>
<config>
<type>check</type>
<default>0</default>
</config>
</settings.highlight>
<settings.todayOnly>
<exclude>1</exclude>
<label>Today only</label>
<config>
<type>check</type>
<default>0</default>
</config>
</settings.todayOnly>
<settings.pagination>
<exclude>1</exclude>
<label>Show pagination</label>
<config>
<type>check</type>
<default>0</default>
</config>
</settings.pagination>
<settings.showPID>
<exclude>1</exclude>
<label>Detail page</label>
<config>
<type>group</type>
<allowed>pages</allowed>
<size>1</size>
<maxitems>1</maxitems>
<minitems>0</minitems>
<show_thumbs>1</show_thumbs>
</config>
</settings.showPID>
</el>
</ROOT>
</sDEF>
<sTemplate>
<ROOT>
<sheetTitle>Template</sheetTitle>
<type>array</type>
<el>
<settings.template>
<exclude>1</exclude>
<label>Layout option</label>
<config>
<type>select</type>
<renderType>selectSingle</renderType>
<items type="array">
<numIndex index="0" type="array">
<numIndex index="label">Default</numIndex>
<numIndex index="value">default</numIndex>
</numIndex>
<numIndex index="1" type="array">
<numIndex index="label">Custom</numIndex>
<numIndex index="value">costum</numIndex>
</numIndex>
<numIndex index="2" type="array">
<numIndex index="label">Table</numIndex>
<numIndex index="value">table</numIndex>
</numIndex>
<numIndex index="3" type="array">
<numIndex index="label">Grid</numIndex>
<numIndex index="value">grid</numIndex>
</numIndex>
</items>
<default>default</default>
</config>
</settings.template>
</el>
</ROOT>
</sTemplate>
<sConstrains>
<ROOT>
<sheetTitle>Regions &amp; Categories</sheetTitle>
<type>array</type>
<el>
<settings.region>
<label>Region</label>
<config>
<type>select</type>
<renderType>selectSingle</renderType>
<items type="array">
<numIndex index="0" type="array">
<numIndex index="label">Alle</numIndex>
<numIndex index="value"></numIndex>
</numIndex>
</items>
<foreign_table>tx_events_domain_model_region</foreign_table>
<foreign_table_where>AND tx_events_domain_model_region.deleted = 0 AND tx_events_domain_model_region.hidden = 0</foreign_table_where>
<size>1</size>
<minitems>0</minitems>
<maxitems>1</maxitems>
</config>
</settings.region>
<settings.categoryCombination>
<exclude>1</exclude>
<label>Combination</label>
<config>
<type>select</type>
<renderType>selectSingle</renderType>
<items type="array">
<numIndex index="0" type="array">
<numIndex index="label">And</numIndex>
<numIndex index="value">0</numIndex>
</numIndex>
<numIndex index="1" type="array">
<numIndex index="label">Or</numIndex>
<numIndex index="value">1</numIndex>
</numIndex>
</items>
<default>0</default>
</config>
</settings.categoryCombination>
<settings.categories>
<exclude>1</exclude>
<label>
Category
</label>
<config>
<type>select</type>
<renderType>selectTree</renderType>
<autoSizeMax>20</autoSizeMax>
<foreign_table>sys_category</foreign_table>
<foreign_table_where> AND sys_category.sys_language_uid IN (-1, 0) ORDER BY sys_category.title ASC</foreign_table_where>
<maxitems>1</maxitems>
<renderMode>tree</renderMode>
<size>8</size>
<treeConfig>
<appearance>
<expandAll>1</expandAll>
<showHeader>1</showHeader>
</appearance>
<parentField>parent</parentField>
</treeConfig>
</config>
</settings.categories>
<settings.includeSubcategories>
<exclude>1</exclude>
<label>Include Subcategories</label>
<config>
<type>check</type>
<default>0</default>
</config>
</settings.includeSubcategories>
</el>
</ROOT>
</sConstrains>
</sheets>
</T3DataStructure>

View file

@ -1,32 +0,0 @@
<T3DataStructure>
<sheets>
<sSearch>
<ROOT>
<sheetTitle>Options</sheetTitle>
<type>array</type>
<el>
<settings.pageUid>
<exclude>1</exclude>
<label>Results page</label>
<config>
<type>group</type>
<allowed>pages</allowed>
<size>1</size>
<maxitems>1</maxitems>
<minitems>0</minitems>
<show_thumbs>1</show_thumbs>
</config>
</settings.pageUid>
<settings.showRegions>
<exclude>1</exclude>
<label>Show Regions</label>
<config>
<type>check</type>
<default>0</default>
</config>
</settings.showRegions>
</el>
</ROOT>
</sSearch>
</sheets>
</T3DataStructure>

View file

@ -1,50 +0,0 @@
<T3DataStructure>
<sheets>
<sDEF>
<ROOT>
<sheetTitle>Options</sheetTitle>
<type>array</type>
<el>
<settings.backPID>
<exclude>1</exclude>
<label>Back page</label>
<config>
<type>group</type>
<allowed>pages</allowed>
<size>1</size>
<maxitems>1</maxitems>
<minitems>0</minitems>
<show_thumbs>1</show_thumbs>
</config>
</settings.backPID>
</el>
</ROOT>
</sDEF>
<sTemplate>
<ROOT>
<sheetTitle>Template</sheetTitle>
<type>array</type>
<el>
<settings.template>
<exclude>1</exclude>
<label>Layout option</label>
<config>
<type>select</type>
<items type="array">
<numIndex index="0" type="array">
<numIndex index="label">Default</numIndex>
<numIndex index="value">default</numIndex>
</numIndex>
<numIndex index="1" type="array">
<numIndex index="label">Custom</numIndex>
<numIndex index="value">costum</numIndex>
</numIndex>
</items>
<default>default</default>
</config>
</settings.template>
</el>
</ROOT>
</sTemplate>
</sheets>
</T3DataStructure>

View file

@ -1,21 +0,0 @@
<T3DataStructure>
<sheets>
<sDEF>
<ROOT>
<type>array</type>
<el>
<settings.selectedRecords>
<exclude>1</exclude>
<label>LLL:EXT:events/Resources/Private/Language/de.locallang_db.xlf:tx_events.flexform.selected.selectedRecords</label>
<config>
<type>group</type>
<allowed>tx_events_domain_model_event</allowed>
<minitems>1</minitems>
<show_thumbs>1</show_thumbs>
</config>
</settings.selectedRecords>
</el>
</ROOT>
</sDEF>
</sheets>
</T3DataStructure>

View file

@ -1,27 +0,0 @@
# Legacy, used for Plugins
routeEnhancers:
EventsDateShow:
type: Extbase
extension: Events
plugin: DateShow
defaultController: 'Date::show'
routes:
-
routePath: '/{date}'
_controller: 'Date::show'
aspects:
date:
type: PersistedAliasMapper
tableName: tx_events_domain_model_date
routeFieldName: slug
EventsPagination:
type: Plugin
namespace: 'events_search'
routePath: '/{localizedPage}-{currentPage}'
aspects:
localizedPage:
type: LocaleModifier
default: 'page'
localeMap:
- locale: 'de*'
value: 'seite'

View file

@ -37,12 +37,6 @@ services:
identifier: 'WerkraumMediaEventsAddSpecialPropertiesToDate'
event: TYPO3\CMS\Extbase\Event\Persistence\AfterObjectThawedEvent
WerkraumMedia\Events\Updates\MigrateDuplicateLocations:
public: true
WerkraumMedia\Events\Updates\MigrateOldLocations:
public: true
WerkraumMedia\Events\Caching\PageCacheTimeout:
arguments:
'$runtimeCache': '@cache.runtime'

View file

@ -1,70 +0,0 @@
<?php
declare(strict_types=1);
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Extbase\Utility\ExtensionUtility;
(function (string $extKey, string $table) {
$GLOBALS['TCA']['tt_content']['columns']['CType']['config']['itemGroups'][$extKey] = 'Events';
/* Search Plugin */
$pluginSignature = ExtensionUtility::registerPlugin(
'Events',
'DateSearch',
'Events: Date Search',
'events-plugin',
$extKey
);
ExtensionManagementUtility::addToAllTCAtypes($table, 'pi_flexform', $pluginSignature, 'after:subheader');
ExtensionManagementUtility::addPiFlexFormValue(
'*',
'FILE:EXT:events/Configuration/FlexForms/DateSearch.xml',
$pluginSignature,
);
/* Date List Plugin */
$pluginSignature = ExtensionUtility::registerPlugin(
'Events',
'DateList',
'Events: Date List',
'events-plugin',
$extKey
);
ExtensionManagementUtility::addToAllTCAtypes($table, 'pi_flexform', $pluginSignature, 'after:subheader');
ExtensionManagementUtility::addPiFlexFormValue(
'*',
'FILE:EXT:events/Configuration/FlexForms/DateList.xml',
$pluginSignature,
);
/* Date Show Plugin */
$pluginSignature = ExtensionUtility::registerPlugin(
'Events',
'DateShow',
'Events: Date Show',
'events-plugin',
$extKey
);
ExtensionManagementUtility::addToAllTCAtypes($table, 'pi_flexform', $pluginSignature, 'after:subheader');
ExtensionManagementUtility::addPiFlexFormValue(
'*',
'FILE:EXT:events/Configuration/FlexForms/DateShow.xml',
'events_dateshow',
);
/* Event Selected Plugin */
$pluginSignature = ExtensionUtility::registerPlugin(
'Events',
'Selected',
'Events: Show selected',
'events-plugin',
$extKey
);
ExtensionManagementUtility::addToAllTCAtypes($table, 'pi_flexform', $pluginSignature, 'after:subheader');
ExtensionManagementUtility::addPiFlexFormValue(
$pluginSignature,
'FILE:EXT:events/Configuration/FlexForms/Selected.xml',
'events_selected',
);
})('events', 'tt_content');

View file

@ -1,38 +0,0 @@
mod.wizards {
newContentElement.wizardItems {
events {
header = Events
show = *
elements {
events_datesearch {
iconIdentifier = events-plugin
title = Events: Date Search
tt_content_defValues {
CType = events_datesearch
}
}
events_datelist {
iconIdentifier = events-plugin
title = Events: Date List
tt_content_defValues {
CType = events_datelist
}
}
events_dateshow {
iconIdentifier = events-plugin
title = Events: Date Show
tt_content_defValues {
CType = events_dateshow
}
}
events_selected {
iconIdentifier = events-plugin
title = Events: Show selected
tt_content_defValues {
CType = events_selected
}
}
}
}
}
}

View file

@ -1,19 +1,6 @@
plugin.tx_events {
view {
# cat=plugin.tx_events/file; type=string; label=Path to template root (FE)
templateRootPath = EXT:events/Resources/Private/Templates/
# cat=plugin.tx_events/file; type=string; label=Path to template partials (FE)
partialRootPath = EXT:events/Resources/Private/Partials/
# cat=plugin.tx_events/file; type=string; label=Path to template layouts (FE)
layoutRootPath = EXT:events/Resources/Private/Layouts/
}
persistence {
# cat=plugin.tx_events//a; type=string; label=Default storage PID
storagePid =
}
settings {
# cat=plugin.tx_events//a; type=string; label=Default Image
defaultImagePath = EXT:events/Resources/Public/Images/default.jpg
}
}

View file

@ -1,47 +1,10 @@
plugin.tx_events {
view {
templateRootPaths {
0 = EXT:events/Resources/Private/Templates/
1 = {$plugin.tx_events.view.templateRootPath}
}
partialRootPaths {
0 = EXT:events/Resources/Private/Partials/
1 = {$plugin.tx_events.view.partialRootPath}
}
layoutRootPaths {
0 = EXT:events/Resources/Private/Layouts/
1 = {$plugin.tx_events.view.layoutRootPath}
}
widget {
TYPO3\CMS\Fluid\ViewHelpers\Widget\PaginateViewHelper {
templateRootPath = {$plugin.tx_events.view.templateRootPath}
}
}
}
persistence {
storagePid = {$plugin.tx_events.persistence.storagePid}
recursive = 1
}
mvc {
callDefaultActionIfActionCantBeResolved = 1
}
settings {
defaulDetailEventsPid =
defaultDetailDatesPid =
defaultImagePath = {$plugin.tx_events.settings.defaultImagePath}
paginate {
# can be overriden by plugin
itemsPerPage = 10
insertAbove = 0
insertBelow = 1
maximumNumberOfLinks = 10
}
dataProcessing {
WerkraumMedia\Events\Domain\Model\Event {
10 = TYPO3\CMS\Frontend\DataProcessing\MenuProcessor
@ -57,17 +20,5 @@ plugin.tx_events {
}
}
}
}
}
plugin.tx_events_datelist.view.pluginNamespace = events_search
plugin.tx_events_datesearch.view.pluginNamespace = events_search
module.tx_events < plugin.tx_events
module.tx_events_import {
settings {
repeatUntil = +60 days
}
}

View file

@ -1 +0,0 @@
@import 'EXT:events/Configuration/TsConfig/Page/Mod/Wizards/NewContentElement.tsconfig'

View file

@ -4,15 +4,10 @@
Breaking
--------
* Only when being on 13.x or higher:
* Removed all content elements.
Content elements are no longer registered as `list` but with their own CType.
An upgrade wizard is provided that can be executed to migrate existing database
entries.
But custom TypoScript and modifications need to be adopted.
We recommend not to use the provided plugins but build your own tailored content
elements instead.
Content elements are no longer provided.
We recommend to build your own tailored content elements instead.
* Remaining TypoScript constants for import were moved.
@ -24,6 +19,10 @@ Breaking
This also affects the `repeatUntil` TypoScript setting which is now moved to the import configuration.
* Removed old update wizards.
Update to 4.x beforehand if you still need to execute them.
Features
--------
@ -32,7 +31,7 @@ Features
* Support large rest search queries.
The field no longer has a limitation.
The field is now stored as text instead of varchar.
The field is now stored as `text` instead of `varchar`.
Fixes
-----
@ -47,5 +46,4 @@ Nothing
Deprecation
-----------
* The existing content elements are deprecated.
We recommend to build your own dedicated content elements.
Nothing

View file

@ -1,5 +0,0 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="tx-events">
<f:render section="content" />
</div>
</html>

View file

@ -1,37 +0,0 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="row">
<f:for each="{dates}" as="date">
<div class="col-sm-12 col-md-6 col-lg-4 col-xl-4">
<div class="menu-tile">
<f:if condition="{date.event.images.0}">
<f:then>
<f:link.action pageUid="{settings.showPID}" action="show" controller="Date" arguments="{date: date}">
<f:image image="{date.event.images.0}" alt="{date.event.title}" title="{date.event.title}" width="480c" height="320c" class="img-fluid img-thumbnail"/>
</f:link.action>
</f:then>
<f:else>
<f:link.action pageUid="{settings.showPID}" action="show" controller="Date" arguments="{date: date}">
<f:image src="{settings.defaultImagePath}" alt="{date.event.title}" title="{date.event.title}" width="480c" height="320c" class="img-fluid img-thumbnail"/>
</f:link.action>
</f:else>
</f:if>
</div>
<div class="caption">
<div class="caption-text mt-3">
{date.event.region.title} |
<f:if condition="{f:format.date(format: 'H:i', date: '{date.start}')} == '00:00'">
<f:then>
<f:format.date format="d. m. Y">{date.start}</f:format.date>
</f:then>
<f:else>
<f:format.date format="d. m. Y - H:i">{date.start}</f:format.date>
</f:else>
</f:if>
<h4>{date.event.title}</h4>
<p>{date.event.teaser}</p>
</div>
</div>
</div>
</f:for>
</div>
</html>

View file

@ -1,60 +0,0 @@
<html
xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
data-namespace-typo3-fluid="true"
>
<f:for each="{pagination.paginator.paginatedItems}" as="date" iteration="index">
<div class="row mt-3 mb-3 pb-3">
<div class="col-12 order-2 mb-3 mb-md-0 col-md-2 order-md-1">
<f:if condition="{f:format.date(format: 'H:i', date: '{date.start}')} != '00:00'">
<b class="d-inline d-md-block"><f:format.date format="H.i">{date.start}</f:format.date></b>
</f:if>
<b class="d-inline d-md-block"><f:format.date format="%a">{date.start}</f:format.date></b>
<b class="d-inline d-md-block"><f:format.date format="d.m.">{date.start}</f:format.date></b>
{date.event.region.title}<br>
</div>
<div class="col-12 order-3 col-md-6 order-md-2">
<f:if condition="{date.canceled} == 'canceled'">
<h4 class="bg-secondary text-white p-2">
<f:translate key="LLL:EXT:events/Resources/Private/Language/locallang.xlf:tx_events.date.canceled" />
</h4>
</f:if>
<h4>
<f:link.action pageUid="{settings.showPID}" action="show" controller="Date" arguments="{date: date}">
{date.event.title}
</f:link.action>
</h4>
<p><strong>{date.event.teaser}</strong></p>
<f:format.crop maxCharacters="150">{date.event.details}</f:format.crop>
</div>
<div class="col-12 order-1 mb-3 mb-md-0 col-md-4 order-md-3 position-relative">
<f:if condition="{date.event.images.0}">
<f:then>
<f:link.action pageUid="{settings.showPID}" action="show" controller="Date" arguments="{date: date}">
<f:image image="{date.event.images.0}" alt="" width="400c" height="280c" class="img-fluid img-thumbnail"/>
</f:link.action>
</f:then>
<f:else>
<f:link.action pageUid="{settings.showPID}" action="show" controller="Date" arguments="{date: date}">
<img src="{settings.defaultImagePath}" alt="Dummy" width="480c" height="320c" class="img-fluid img-thumbnail"/>
</f:link.action>
</f:else>
</f:if>
</div>
</div>
<f:if condition="{index.isLast}">
<f:then>
</f:then>
<f:else>
<div class="mb-3 border-bottom"></div>
</f:else>
</f:if>
</f:for>
{f:render(partial: 'Pagination', arguments: {
pagination: pagination
})}
</html>

View file

@ -1,14 +0,0 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="row">
<div class="col-12">
<div class="p-3 mb-2 bg-light text-dark">
<f:form action="search" controller="Event" additionalAttributes="{role: 'form'}" method="get">
<div class="input-group mb-3">
<f:form.textfield name="search" value="{search}" class="form-control" />
<f:form.submit value="Search" class="btn btn-outline-secondary" />
</div>
</f:form>
</div>
</div>
</div>

View file

@ -1,94 +0,0 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
data-namespace-typo3-fluid="true">
<nav role="navigation" aria-label="Pagination Navigation">
<ul class="pagination">
<f:if condition="{pagination.previousPageNumber}">
<li class="page-item">
<f:if condition="{pagination.previousPageNumber} > 1">
<f:then>
<a class="page-link"
href="{f:uri.action(addQueryString: 1, arguments: {currentPage: pagination.previousPageNumber})}"
>
<span aria-hidden="true">&laquo;</span>
</a>
</f:then>
<f:else>
<a class="page-link" href="{f:uri.action(addQueryString: 1)}">
<span aria-hidden="true">&laquo;</span>
</a>
</f:else>
</f:if>
</li>
</f:if>
<f:if condition="{pagination.displayRangeStart} > 1">
<li class="page-item">
<a class="page-link"
href="{f:uri.action(addQueryString: 1)}"
aria-label="Goto Page 1"
>
1
</a>
</li>
</f:if>
<f:if condition="{pagination.hasLessPages}">
<li class="page-item">
<span class="page-link"></span>
</li>
</f:if>
<f:for each="{pagination.allPageNumbers}" as="page">
<f:if condition="{page} == {pagination.paginator.currentPageNumber}">
<f:then>
<li class="page-item active">
<span class="page-link"
aria-label="Current Page {page}"
aria-current="true"
>{page}</span>
</li>
</f:then>
<f:else>
<li class="page-item">
<a class="page-link"
href="{f:uri.action(addQueryString: 1, arguments: {currentPage: page})}"
aria-label="Goto Page {page}"
>
{page}
</a>
</li>
</f:else>
</f:if>
</f:for>
<f:if condition="{pagination.hasMorePages}">
<li class="page-item">
<span class="page-link"></span>
</li>
</f:if>
<f:if condition="{pagination.displayRangeEnd} < {pagination.lastPageNumber}">
<li class="page-item">
<a class="page-link"
href="{f:uri.action(addQueryString: 1, arguments: {currentPage: pagination.lastPageNumber})}"
aria-label="Goto Page {pagination.lastPageNumber}"
>
{pagination.lastPageNumber}
</a>
</li>
</f:if>
<f:if condition="{pagination.nextPageNumber}">
<li class="page-item">
<a class="page-link"
href="{f:uri.action(addQueryString: 1, arguments: {currentPage: pagination.nextPageNumber})}"
>
<span aria-hidden="true">&raquo;</span>
</a>
</li>
</f:if>
</ul>
</nav>
</html>

View file

@ -1,19 +0,0 @@
<html
xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
data-namespace-typo3-fluid="true"
>
<f:layout name="Default" />
<f:section name="content">
<f:if condition="{settings.template} === 'table'">
<f:then>
{f:render(partial: 'Date/ListTable', arguments: _all)}
</f:then>
<f:else>
{f:render(partial: 'Date/ListDefault', arguments: _all)}
</f:else>
</f:if>
</f:section>
</html>

View file

@ -1,75 +0,0 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<f:layout name="Default" />
<f:section name="content">
<div class="row">
<div class="col-12 mb-5">
<f:form action="list" controller="Date" pluginName="DateList" method="post" id="events_search" name="search" object="{demand}">
<div class="row">
<div class="col-12 col-md-12 col-lg-6">
<div class="row">
<div class="col">
<div class="form-group">
<label for="searchword"><f:translate key="LLL:EXT:events/Resources/Private/Language/locallang.xlf:tx_events.searchform.searchword" /></label>
<f:form.textfield type="text" class="form-control" id="searchword" property="searchword" value="{searchword}" />
</div>
</div>
</div>
<div class="row">
<div class="col col-md-6">
<div class="form-group">
<label for="start"><f:translate key="LLL:EXT:events/Resources/Private/Language/locallang.xlf:tx_events.searchform.date_from" /></label>
<f:form.textfield type="date" class="form-control" id="start" property="start" />
</div>
</div>
<div class="col col-md-6">
<div class="form-group">
<label for="end"><f:translate key="LLL:EXT:events/Resources/Private/Language/locallang.xlf:tx_events.searchform.date_to" /></label>
<f:form.textfield type="date" class="form-control" id="end" property="end" />
</div>
</div>
</div>
</div>
<div class="col-md-12 col-lg-6 d-none d-lg-block">
<f:if condition="{settings.showRegions}">
<div class="row mt-3">
<div class="col-4 col-md-4 col-lg-4">
<div class="form-check">
<f:form.radio class="form-check-input" property="region" id="radio_0" value="" />
<label class="form-check-label" for="radio_0"><f:translate key="LLL:EXT:events/Resources/Private/Language/locallang.xlf:tx_events.searchform.regions" /></label>
</div>
</div>
<f:for each="{regions}" as="region">
<div class="col-4">
<div class="form-check">
<f:form.radio class="form-check-input" property="region" value="{region.uid}" id="radio_{region.uid}"/>
<label class="form-check-label" for="radio_{region.uid}">{region.title}</label>
</div>
</div>
</f:for>
</div>
</f:if>
</div>
</div>
<f:if condition="{categories}">
<div class="row mt-lg-4 mb-lg-4">
<f:for each="{categories}" as="category">
<div class="col-3 d-none d-lg-block">
<div class="form-check">
<f:form.checkbox class="form-check-input" property="userCategories" value="{category.uid}" id="check_{category.uid}"/>
<label class="form-check-label" for="check_{category.uid}">{category.title} {category.amountOfEvents}</label>
</div>
</div>
</f:for>
</div>
</f:if>
<div class="form-group mt-3">
<f:form.submit value="{f:translate(key: 'LLL:EXT:events/Resources/Private/Language/locallang.xlf:tx_events.searchform.search')}" class="btn btn-primary" />
</div>
</f:form>
</div>
</div>
</f:section>
</html>

View file

@ -1,74 +0,0 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<f:layout name="Default" />
<f:section name="content">
<div class="row">
<div class="col-12 mb-3 mb-md-0 col-md-6">
<f:if condition="{date.event.images.0}">
<f:then>
<f:image image="{date.event.images.0}" alt="" width="480c" height="320c" class="img-fluid img-thumbnail"/>
</f:then>
<f:else>
<img src="{settings.defaultImagePath}" alt="Dummy" width="480c" height="320c" class="img-fluid img-thumbnail"/>
</f:else>
</f:if>
</div>
<div class="col-12 col-md-6">
<f:if condition="{date.canceled} == 'canceled'">
<h4 class="bg-secondary text-white p-2">
<f:translate key="LLL:EXT:events/Resources/Private/Language/locallang.xlf:tx_events.date.canceled" />
</h4>
</f:if>
<h4>
<f:format.date format="%a">{date.start}</f:format.date>
<f:format.date format="d.m.">{date.start}</f:format.date>
<f:format.date format="H.i">{date.start}</f:format.date> Uhr
</h4>
<h2>{date.event.title}</h2>
<h3>{date.event.teaser}</h3>
<f:format.html>{date.event.details}</f:format.html>
</div>
</div>
<div class="row">
<div class="col mt-3 mb-3">
</div>
</div>
<div class="row">
<div class="col-12 col-md-4">
<p><b>Preis:</b><br>
<f:if condition="{date.event.priceInfo}">
<f:then>
<f:format.nl2br>{date.event.priceInfo}</f:format.nl2br>
</f:then>
<f:else>
Keine Information
</f:else>
</f:if>
</p>
<f:if condition="{date.event.web}">
<p><b>Weitere Informationen:</b><br>
<a href="{date.event.web}" target="_blank">Website</a>
</p>
</f:if>
</div>
<div class="col-12 col-md-4">
<p><b>Veranstaltungsort:</b><br>
{date.event.location.name}<br>
{date.event.location.street}<br>
{date.event.location.zip} {date.event.location.city}<br>
{date.event.location.phone}<br>
</p>
</div>
<div class="col-12 col-md-4">
<p><b>Veranstalter:</b><br>
{date.event.organizer.name}<br>
{date.event.organizer.street}<br>
{date.event.organizer.zip} {date.event.organizer.city}<br>
{date.event.organizer.phone}<br>
<a href="{date.event.organizer.web}" target="_blank">Website</a>
</p>
</div>
</div>
</f:section>
</html>

View file

@ -1,50 +0,0 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<f:layout name="Default" />
<f:section name="content">
<div class="row">
<f:for each="{dates}" as="date">
<div class="col-sm-12 col-md-6 col-lg-4 col-xl-4">
<f:comment>
<!--
<f:link.action action="show" arguments="{date : date}"></f:link.action>
-->
</f:comment>
<div class="menu-tile">
<f:if condition="{date.event.images.0}">
<f:then>
<f:link.action pageUid="{settings.showPID}" action="show" controller="Event" arguments="{event: event}">
<f:image image="{date.event.images.0}" alt="{date.event.title}" title="{date.event.title}" width="480c" height="320c" class="img-fluid img-thumbnail"/>
</f:link.action>
</f:then>
<f:else>
<f:link.action pageUid="{settings.showPID}" action="show" controller="Event" arguments="{event: event}">
<f:image src="{settings.defaultImagePath}" alt="{date.event.title}" title="{date.event.title}" width="480c" height="320c" class="img-fluid img-thumbnail"/>
</f:link.action>
</f:else>
</f:if>
</div>
<div class="caption">
<div class="caption-text mt-3">
{date.event.region.title} |
<f:if condition="{f:format.date(format: 'H:i', date: '{date.start}')} == '00:00'">
<f:then>
<f:format.date format="d. m. Y">{date.start}</f:format.date>
</f:then>
<f:else>
<f:format.date format="d. m. Y - H:i">{date.start}</f:format.date>
</f:else>
</f:if>
<h4>{date.event.title}</h4>
<p>{date.event.teaser}</p>
<f:if condition="{date.event.highlight}">
<f:then>
<b>Highlight</b>
</f:then>
</f:if>
</div>
</div>
</div>
</f:for>
</div>
</f:section>
</html>

View file

@ -1,33 +0,0 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<f:layout name="Default" />
<f:section name="content">
<div class="row">
<f:for each="{events}" as="event">
<div class="col-sm-12 col-md-6 col-lg-4 col-xl-4">
<div class="menu-tile">
<f:if condition="{event.images.0}">
<f:then>
<f:link.action pageUid="{settings.showPID}" action="show" controller="Event" arguments="{event: event}">
<f:image image="{event.images.0}" alt="{date.event.title}" title="{date.event.title}" width="480c" height="320c" class="img-fluid img-thumbnail"/>
</f:link.action>
</f:then>
<f:else>
<f:link.action pageUid="{settings.showPID}" action="show" controller="Event" arguments="{event: event}">
<f:image src="{settings.defaultImagePath}" alt="{date.event.title}" title="{date.event.title}" width="480c" height="320c" class="img-fluid img-thumbnail"/>
</f:link.action>
</f:else>
</f:if>
</div>
<div class="caption">
<div class="caption-text mt-3">
{event.region.title}
<h4>{event.title}</h4>
<p>{event.teaser}</p>
</div>
</div>
</div>
</f:for>
</div>
</f:section>
</html>

View file

@ -1,29 +0,0 @@
<f:render partial="Event/SearchForm" arguments="{search: search}"/>
<div class="row">
<f:for each="{events}" as="event">
<div class="col-sm-12 col-md-6 col-lg-4 col-xl-4">
<div class="menu-tile">
<f:if condition="{event.images.0}">
<f:then>
<f:link.action pageUid="{settings.showPID}" action="show" controller="Event" arguments="{event: event}">
<f:image image="{event.images.0}" alt="" width="480c" height="320c" class="img-fluid img-thumbnail"/>
</f:link.action>
</f:then>
<f:else>
<f:link.action pageUid="{settings.showPID}" action="show" controller="Event" arguments="{event: event}">
<img src="{settings.defaultImagePath}" alt="Dummy" width="480c" height="320c" class="img-fluid img-thumbnail"/>
</f:link.action>
</f:else>
</f:if>
</div>
<div class="caption">
<div class="caption-text mt-3">
{event.region.title}
<h4>{event.title}</h4>
<p>{event.teaser}</p>
</div>
</div>
</div>
</f:for>
</div>

View file

@ -1,37 +0,0 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<f:layout name="Default" />
<f:section name="content">
<div class="row">
<div class="col-6">
<f:if condition="{event.images.0}">
<f:then>
<f:link.action pageUid="{settings.showPID}" action="show" controller="Event" arguments="{event: event}">
<f:image image="{event.images.0}" alt="" width="480c" height="320c" class="img-fluid img-thumbnail"/>
</f:link.action>
</f:then>
<f:else>
<f:link.action pageUid="{settings.showPID}" action="show" controller="Event" arguments="{event: event}">
<img src="{settings.defaultImagePath}" alt="Dummy" width="480c" height="320c" class="img-fluid img-thumbnail"/>
</f:link.action>
</f:else>
</f:if>
</div>
<div class="col-6">
<h2>{event.title}</h2>
<h3>{event.teaser}</h3>
<f:format.html>{event.details}</f:format.html>
<p>{event.price_info}</p>
<div class="row">
<div class="col-4">
<p>Veranstaltungsort:<br>
{event.location.street}<br>
{event.location.zip} {event.location.city}<br>
</p>
</div>
</div>
</div>
</div>
</f:section>
</html>

View file

@ -1,33 +0,0 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<f:layout name="Default" />
<f:section name="content">
<div class="row">
<f:for each="{events}" as="event">
<div class="col-sm-12 col-md-6 col-lg-4 col-xl-4">
<div class="menu-tile">
<f:if condition="{event.images.0}">
<f:then>
<f:link.action pageUid="{settings.showPID}" action="show" controller="Event" arguments="{event: event}">
<f:image image="{event.images.0}" alt="{date.event.title}" title="{date.event.title}" width="480c" height="320c" class="img-fluid img-thumbnail"/>
</f:link.action>
</f:then>
<f:else>
<f:link.action pageUid="{settings.showPID}" action="show" controller="Event" arguments="{event: event}">
<f:image src="{settings.defaultImagePath}" alt="{date.event.title}" title="{date.event.title}" width="480c" height="320c" class="img-fluid img-thumbnail"/>
</f:link.action>
</f:else>
</f:if>
</div>
<div class="caption">
<div class="caption-text mt-3">
{event.region.title}
<h4>{event.title}</h4>
<p>{event.teaser}</p>
</div>
</div>
</div>
</f:for>
</div>
</f:section>
</html>

View file

@ -133,7 +133,7 @@ abstract class AbstractFunctionalTestCase extends FunctionalTestCase
array $argumentsAndOptions = ['configurationUid' => '1'],
string $command = ImportDestinationDataViaConfigruationCommand::class
): CommandTester {
GeneralUtility::setContainer($this->getcontainer());
GeneralUtility::setContainer($this->getContainer());
$subject = $this->get($command);
self::assertInstanceOf(Command::class, $subject);

View file

@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2024 Daniel Siepmann <daniel.siepmann@codappix.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
namespace WerkraumMedia\Events\Tests\Functional\Frontend;
use WerkraumMedia\Events\Tests\Functional\AbstractFunctionalTestCase;
abstract class AbstractFrontendTestCase extends AbstractFunctionalTestCase
{
protected function setUp(): void
{
$this->coreExtensionsToLoad = [
'seo',
];
$this->testExtensionsToLoad = [
...$this->testExtensionsToLoad,
'typo3conf/ext/events/Tests/Functional/Frontend/Fixtures/Extensions/example/',
];
parent::setUp();
$this->importPHPDataSet(__DIR__ . '/Fixtures/Database/SiteStructure.php');
$this->setUpFrontendRendering();
}
}

View file

@ -33,15 +33,11 @@ use TYPO3\CMS\Core\Cache\Backend\SimpleFileBackend;
use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\Information\Typo3Version;
use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
use WerkraumMedia\Events\Tests\Functional\AbstractFunctionalTestCase;
class CacheTest extends AbstractFunctionalTestCase
final class CacheTest extends AbstractFrontendTestCase
{
protected function setUp(): void
{
$this->testExtensionsToLoad = [
'typo3conf/ext/events/Tests/Functional/Frontend/Fixtures/Extensions/example',
];
$this->configurationToUseInTestInstance = [
'SYS' => [
// Combined with flushCaches.
@ -64,14 +60,12 @@ class CacheTest extends AbstractFunctionalTestCase
$this->get(CacheManager::class)->flushCaches();
$this->importPHPDataSet(__DIR__ . '/Fixtures/Database/SiteStructure.php');
(new PhpDataSet())->import(['tt_content' => [[
'uid' => '1',
'pid' => '1',
'CType' => 'events_datelisttest',
'header' => 'All Dates',
]]]);
$this->setUpFrontendRendering();
}
#[Test]

View file

@ -27,22 +27,9 @@ use PHPUnit\Framework\Attributes\Test;
use Psr\Http\Message\ResponseInterface;
use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
use WerkraumMedia\Events\Frontend\Dates;
use WerkraumMedia\Events\Tests\Functional\AbstractFunctionalTestCase;
class DatesTest extends AbstractFunctionalTestCase
final class DatesTest extends AbstractFrontendTestCase
{
protected function setUp(): void
{
$this->coreExtensionsToLoad = [
'seo',
];
parent::setUp();
$this->importPHPDataSet(__DIR__ . '/Fixtures/Database/SiteStructure.php');
$this->setUpFrontendRendering();
}
/**
* Covers issue https://redmine.werkraum-media.de/issues/10075.
* Editors can disable events. Dates will still be available.
@ -74,7 +61,7 @@ class DatesTest extends AbstractFunctionalTestCase
$request = new InternalRequest('https://example.com/');
$request = $request->withPageId(1);
$request = $request->withQueryParameters([
'events_search[search][start]' => '2023-02-16',
'tx_events_datelisttest[search][start]' => '2023-02-16',
]);
$response = $this->executeFrontendSubRequest($request);
@ -100,7 +87,7 @@ class DatesTest extends AbstractFunctionalTestCase
$request = new InternalRequest('https://example.com/');
$request = $request->withPageId(1);
$request = $request->withQueryParameters([
'events_search[search][end]' => '2023-02-17',
'tx_events_datelisttest[search][end]' => '2023-02-17',
]);
$response = $this->executeFrontendSubRequest($request);
@ -131,8 +118,8 @@ class DatesTest extends AbstractFunctionalTestCase
$request = new InternalRequest('https://example.com/');
$request = $request->withPageId(1);
$request = $request->withQueryParameters([
'events_search[search][start]' => '2023-02-16',
'events_search[search][end]' => '2023-02-17',
'tx_events_datelisttest[search][start]' => '2023-02-16',
'tx_events_datelisttest[search][end]' => '2023-02-17',
]);
$response = $this->executeFrontendSubRequest($request);
@ -248,7 +235,7 @@ class DatesTest extends AbstractFunctionalTestCase
{
$request = new InternalRequest('https://example.com/');
$request = $request->withPageId(1);
$request = $request->withQueryParameter('tx_events_dateshow[date]', '1');
$request = $request->withQueryParameter('tx_events_dateshowtest[date]', '1');
return $this->executeFrontendSubRequest($request);
}

View file

@ -7,7 +7,7 @@ return [
0 => [
'uid' => '1',
'pid' => '1',
'CType' => 'events_dateshow',
'CType' => 'events_dateshowtest',
'header' => 'Singleview',
],
],

View file

@ -7,7 +7,7 @@ return [
0 => [
'uid' => '1',
'pid' => '1',
'CType' => 'events_dateshow',
'CType' => 'events_dateshowtest',
'header' => 'Singleview',
],
],

View file

@ -7,7 +7,7 @@ return [
0 => [
'uid' => '1',
'pid' => '1',
'CType' => 'events_dateshow',
'CType' => 'events_dateshowtest',
'header' => 'Singleview',
],
],

View file

@ -7,7 +7,7 @@ return [
0 => [
'uid' => '1',
'pid' => '1',
'CType' => 'events_dateshow',
'CType' => 'events_dateshowtest',
'header' => 'Singleview',
],
],

View file

@ -7,7 +7,7 @@ return [
0 => [
'uid' => '1',
'pid' => '1',
'CType' => 'events_dateshow',
'CType' => 'events_dateshowtest',
'header' => 'Singleview',
],
],

View file

@ -7,7 +7,7 @@ return [
0 => [
'uid' => '1',
'pid' => '1',
'CType' => 'events_datelist',
'CType' => 'events_datelisttest',
'header' => 'All Dates',
],
],

View file

@ -7,7 +7,7 @@ return [
0 => [
'uid' => '1',
'pid' => '1',
'CType' => 'events_datelist',
'CType' => 'events_datelisttest',
'header' => 'All Dates',
],
],

View file

@ -7,7 +7,7 @@ return [
[
'uid' => 1,
'pid' => 1,
'CType' => 'events_datelist',
'CType' => 'events_datelisttest',
'header' => 'Upcoming Dates',
],
],

View file

@ -26,25 +26,9 @@ namespace WerkraumMedia\Events\Tests\Functional\Frontend;
use PHPUnit\Framework\Attributes\Test;
use Psr\Http\Message\ResponseInterface;
use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
use WerkraumMedia\Events\Tests\Functional\AbstractFunctionalTestCase;
class EventsTest extends AbstractFunctionalTestCase
final class EventsTest extends AbstractFrontendTestCase
{
protected function setUp(): void
{
$this->testExtensionsToLoad = [
'typo3conf/ext/events/Tests/Functional/Frontend/Fixtures/Extensions/example',
];
$this->coreExtensionsToLoad = [
'seo',
];
parent::setUp();
$this->importPHPDataSet(__DIR__ . '/Fixtures/Database/SiteStructure.php');
$this->setUpFrontendRendering();
}
#[Test]
public function addsMetaTags(): void
{
@ -103,7 +87,7 @@ class EventsTest extends AbstractFunctionalTestCase
{
$request = new InternalRequest('https://example.com/');
$request = $request->withPageId(1);
$request = $request->withQueryParameter('tx_events_eventshow[event]', '1');
$request = $request->withQueryParameter('tx_events_eventshowtest[event]', '1');
return $this->executeFrontendSubRequest($request);
}

View file

@ -7,7 +7,7 @@ return [
0 => [
'uid' => '1',
'pid' => '1',
'CType' => 'events_eventshow',
'CType' => 'events_eventshowtest',
'header' => 'Singleview',
],
],

View file

@ -7,7 +7,7 @@ return [
0 => [
'uid' => '1',
'pid' => '1',
'CType' => 'events_eventshow',
'CType' => 'events_eventshowtest',
'header' => 'Singleview',
],
],

View file

@ -7,7 +7,7 @@ return [
0 => [
'uid' => '1',
'pid' => '1',
'CType' => 'events_eventshow',
'CType' => 'events_eventshowtest',
'header' => 'Singleview',
],
],

View file

@ -7,7 +7,7 @@ return [
0 => [
'uid' => '1',
'pid' => '1',
'CType' => 'events_eventshow',
'CType' => 'events_eventshowtest',
'header' => 'Singleview',
],
],

View file

@ -6,18 +6,9 @@ namespace WerkraumMedia\Events\Tests\Functional\Frontend;
use PHPUnit\Framework\Attributes\Test;
use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
use WerkraumMedia\Events\Tests\Functional\AbstractFunctionalTestCase;
class FilterTest extends AbstractFunctionalTestCase
final class FilterTest extends AbstractFrontendTestCase
{
protected function setUp(): void
{
parent::setUp();
$this->importPHPDataSet(__DIR__ . '/Fixtures/Database/SiteStructure.php');
$this->setUpFrontendRendering();
}
#[Test]
public function canFilterByASingleLocationViaFlexform(): void
{

View file

@ -7,7 +7,7 @@ return [
[
'pid' => '1',
'uid' => '1',
'CType' => 'events_datelist',
'CType' => 'events_datelisttest',
'header' => 'Kino Events',
'pi_flexform' => '<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<T3FlexForms>

View file

@ -7,7 +7,7 @@ return [
[
'pid' => '1',
'uid' => '1',
'CType' => 'events_datelist',
'CType' => 'events_datelisttest',
'header' => 'Kino Events',
'pi_flexform' => '<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<T3FlexForms>

View file

@ -7,7 +7,7 @@ return [
[
'pid' => '1',
'uid' => '1',
'CType' => 'events_datelist',
'CType' => 'events_datelisttest',
'header' => 'Kino Events',
'pi_flexform' => '<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<T3FlexForms>

View file

@ -0,0 +1,35 @@
<html
xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
data-namespace-typo3-fluid="true"
>
<div class="row">
<f:for each="{dates}" as="date">
<div class="col-sm-12 col-md-6 col-lg-4 col-xl-4">
<div class="menu-tile">
<f:if condition="{date.event.images.0}">
<f:link.action pageUid="{settings.showPID}" action="show" controller="Date" arguments="{date: date}">
<f:image image="{date.event.images.0}" alt="{date.event.title}" title="{date.event.title}" width="480c" height="320c" class="img-fluid img-thumbnail"/>
</f:link.action>
</f:if>
</div>
<div class="caption">
<div class="caption-text mt-3">
{date.event.region.title} |
<f:if condition="{f:format.date(format: 'H:i', date: '{date.start}')} == '00:00'">
<f:then>
<f:format.date format="d. m. Y">{date.start}</f:format.date>
</f:then>
<f:else>
<f:format.date format="d. m. Y - H:i">{date.start}</f:format.date>
</f:else>
</f:if>
<h4>{date.event.title}</h4>
<p>{date.event.teaser}</p>
</div>
</div>
</div>
</f:for>
</div>
</html>

View file

@ -0,0 +1,73 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="row">
<div class="col-12 mb-3 mb-md-0 col-md-6">
<f:if condition="{date.event.images.0}">
<f:then>
<f:image image="{date.event.images.0}" alt="" width="480c" height="320c" class="img-fluid img-thumbnail"/>
</f:then>
<f:else>
<img src="{settings.defaultImagePath}" alt="Dummy" width="480c" height="320c" class="img-fluid img-thumbnail"/>
</f:else>
</f:if>
</div>
<div class="col-12 col-md-6">
<f:if condition="{date.canceled} == 'canceled'">
<h4 class="bg-secondary text-white p-2">
<f:translate key="LLL:EXT:events/Resources/Private/Language/locallang.xlf:tx_events.date.canceled" />
</h4>
</f:if>
<h4>
<f:format.date format="%a">{date.start}</f:format.date>
<f:format.date format="d.m.">{date.start}</f:format.date>
<f:format.date format="H.i">{date.start}</f:format.date> Uhr
</h4>
<h2>{date.event.title}</h2>
<h3>{date.event.teaser}</h3>
<f:format.html>{date.event.details}</f:format.html>
</div>
</div>
<div class="row">
<div class="col mt-3 mb-3">
</div>
</div>
<div class="row">
<div class="col-12 col-md-4">
<p><b>Preis:</b><br>
<f:if condition="{date.event.priceInfo}">
<f:then>
<f:format.nl2br>{date.event.priceInfo}</f:format.nl2br>
</f:then>
<f:else>
Keine Information
</f:else>
</f:if>
</p>
<f:if condition="{date.event.web}">
<p><b>Weitere Informationen:</b><br>
<a href="{date.event.web}" target="_blank">Website</a>
</p>
</f:if>
</div>
<div class="col-12 col-md-4">
<p><b>Veranstaltungsort:</b><br>
{date.event.location.name}<br>
{date.event.location.street}<br>
{date.event.location.zip} {date.event.location.city}<br>
{date.event.location.phone}<br>
</p>
</div>
<div class="col-12 col-md-4">
<p><b>Veranstalter:</b><br>
{date.event.organizer.name}<br>
{date.event.organizer.street}<br>
{date.event.organizer.zip} {date.event.organizer.city}<br>
{date.event.organizer.phone}<br>
<a href="{date.event.organizer.web}" target="_blank">Website</a>
</p>
</div>
</div>
</html>

View file

@ -0,0 +1,36 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="row">
<div class="col-6">
<f:if condition="{event.images.0}">
<f:then>
<f:link.action pageUid="{settings.showPID}" action="show" controller="Event" arguments="{event: event}">
<f:image image="{event.images.0}" alt="" width="480c" height="320c" class="img-fluid img-thumbnail"/>
</f:link.action>
</f:then>
<f:else>
<f:link.action pageUid="{settings.showPID}" action="show" controller="Event" arguments="{event: event}">
<img src="{settings.defaultImagePath}" alt="Dummy" width="480c" height="320c" class="img-fluid img-thumbnail"/>
</f:link.action>
</f:else>
</f:if>
</div>
<div class="col-6">
<h2>{event.title}</h2>
<h3>{event.teaser}</h3>
<f:format.html>{event.details}</f:format.html>
<p>{event.price_info}</p>
<div class="row">
<div class="col-4">
<p>Veranstaltungsort:<br>
{event.location.street}<br>
{event.location.zip} {event.location.city}<br>
</p>
</div>
</div>
</div>
</div>
</html>

View file

@ -16,7 +16,15 @@ ExtensionUtility::configurePlugin(
ExtensionUtility::configurePlugin(
'Events',
'EventShow',
'DateShowTest',
[DateController::class => 'show'],
[],
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT,
);
ExtensionUtility::configurePlugin(
'Events',
'EventShowTest',
[EventController::class => 'show'],
[],
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT,

View file

@ -32,6 +32,18 @@ plugin.tx_events {
storagePid = 2
}
view {
templateRootPaths {
0 = EXT:example/Resources/Private/Templates/
}
partialRootPaths {
0 = EXT:example/Resources/Private/Partials/
}
layoutRootPaths {
0 = EXT:example/Resources/Private/Layouts/
}
}
settings {
sortByDate = start
sortOrder = ASC

View file

@ -51,7 +51,7 @@ class ImportsAllConfigurationTest extends AbstractTestCase
self::assertSame('https://dam.destination.one/828118/f13bbf5602ffc406ebae2faa3527654dea84194666bce4925a1ca8bd3f50c5e9/tueftlerzeit-sfz-rudolstadt-jpg.jpg', (string)$requests[2]['request']->getUri());
self::assertSame('https://dam.destination.one/853436/109ac1cf87913e21b5e2b0ef0cc63d223a14374364952a855746a8e7c3fcfc36/lutherkirche-jpg.jpg', (string)$requests[3]['request']->getUri());
self::assertSame('http://meta.et4.de/rest.ashx/search/?experience=beispielstadt&licensekey=example-license&type=Event&mode=next_months%2C12&limit=3&template=ET2014A.json&q=name%3A%22Beispiel%22', (string)$requests[0]['request']->getUri());
self::assertSame('http://meta.et4.de/rest.ashx/search/?experience=anderestadt&licensekey=example-license&type=Event&mode=next_months%2C12&limit=3&template=ET2014A.json&q=name%3A%22Beispiel2%22', (string)$requests[4]['request']->getUri());
self::assertSame('https://dam.destination.one/849917/279ac45b3fc701a7197131f627164fffd9f8cc77bc75165e2fc2b864ed606920/theater-rudolstadt_johannes-gei-er_photo-by-lisa-stern_web_-jpg.jpg', (string)$requests[5]['request']->getUri());
self::assertSame('https://dam.destination.one/828118/f13bbf5602ffc406ebae2faa3527654dea84194666bce4925a1ca8bd3f50c5e9/tueftlerzeit-sfz-rudolstadt-jpg.jpg', (string)$requests[6]['request']->getUri());
self::assertSame('https://dam.destination.one/853436/109ac1cf87913e21b5e2b0ef0cc63d223a14374364952a855746a8e7c3fcfc36/lutherkirche-jpg.jpg', (string)$requests[7]['request']->getUri());

View file

@ -1,61 +0,0 @@
<?php
declare(strict_types=1);
return [
'tx_events_domain_model_location' => [
[
'uid' => 1,
'pid' => 0,
'sys_language_uid' => -1,
'global_id' => 'a91656ec76732f2b7b72987d11d81d926fa67ea3b2eb4cc6fd75bb2b748da21d',
'name' => 'Domplatz',
'street' => '',
'city' => 'Erfurt',
'zip' => '99084',
'district' => 'Altstadt',
'country' => 'Deutschland',
'phone' => '',
'latitude' => '50.977089',
'longitude' => '11.024878',
],
[
'uid' => 3,
'pid' => 0,
'sys_language_uid' => -1,
'global_id' => '95ca076b77e478cc8eb831f48aacaa608a640034e31da2e11b42da9758c84aaf',
'name' => 'Wenigemarkt',
'street' => '',
'city' => 'Erfurt',
'zip' => '99084',
'district' => 'Altstadt',
'country' => 'Deutschland',
'phone' => '',
'latitude' => '50.978500',
'longitude' => '11.031589',
],
],
'tx_events_domain_model_event' => [
[
'uid' => 1,
'pid' => 0,
'title' => 'Abendmahlsgottesdienst',
'global_id' => 'e_100171396',
'location' => 1,
],
[
'uid' => 2,
'pid' => 0,
'title' => 'Travestie-Revue "Pretty Wo(man)"',
'global_id' => 'e_100172162',
'location' => 1,
],
[
'uid' => 3,
'pid' => 0,
'title' => 'Abendgebet in englischer Sprache',
'global_id' => 'e_100172275',
'location' => 3,
],
],
];

View file

@ -1,76 +0,0 @@
<?php
declare(strict_types=1);
return [
'tx_events_domain_model_location' => [
[
'uid' => 1,
'pid' => 0,
'sys_language_uid' => -1,
'global_id' => '21e0561cb967c2b3c7977c367615b97b4176e26302dd77fadb33296cd37fb4b0',
'name' => 'Domplatz',
'street' => '',
'city' => 'Erfurt',
'zip' => '99084',
'district' => 'Altstadt',
'country' => 'Deutschland',
'phone' => '',
'latitude' => '50,977089',
'longitude' => '11,024878',
],
[
'uid' => 2,
'pid' => 0,
'sys_language_uid' => -1,
'global_id' => '1cc57820faf4a3bf6bf8326f2821068f0619f9fc8bcbebd8c6e4c496e38471c7',
'name' => 'Domplatz',
'street' => '',
'city' => 'Erfurt',
'zip' => '99084',
'district' => 'Altstadt',
'country' => 'Deutschland',
'phone' => '',
'latitude' => '50.977089',
'longitude' => '11.024878',
],
[
'uid' => 3,
'pid' => 0,
'sys_language_uid' => -1,
'global_id' => '64d0def98fe304c32c79e6926cac40c8501797158e0e43990c36f7b1fb50c17e',
'name' => 'Wenigemarkt',
'street' => '',
'city' => 'Erfurt',
'zip' => '99084',
'district' => 'Altstadt',
'country' => 'Deutschland',
'phone' => '',
'latitude' => '50.9785',
'longitude' => '11.031589',
],
],
'tx_events_domain_model_event' => [
[
'uid' => 1,
'pid' => 0,
'title' => 'Abendmahlsgottesdienst',
'global_id' => 'e_100171396',
'location' => 1,
],
[
'uid' => 2,
'pid' => 0,
'title' => 'Travestie-Revue "Pretty Wo(man)"',
'global_id' => 'e_100172162',
'location' => 2,
],
[
'uid' => 3,
'pid' => 0,
'title' => 'Abendgebet in englischer Sprache',
'global_id' => 'e_100172275',
'location' => 3,
],
],
];

View file

@ -1,38 +0,0 @@
<?php
declare(strict_types=1);
return [
'tx_events_domain_model_location' => [
[
'uid' => 1,
'pid' => 0,
'sys_language_uid' => -1,
'global_id' => '1cc57820faf4a3bf6bf8326f2821068f0619f9fc8bcbebd8c6e4c496e38471c7',
'name' => 'Domplatz',
'street' => '',
'city' => 'Erfurt',
'zip' => '99084',
'district' => 'Altstadt',
'country' => 'Deutschland',
'phone' => '',
'latitude' => '50.977089',
'longitude' => '11.024878',
],
[
'uid' => 2,
'pid' => 0,
'sys_language_uid' => -1,
'global_id' => '64d0def98fe304c32c79e6926cac40c8501797158e0e43990c36f7b1fb50c17e',
'name' => 'Wenigemarkt',
'street' => '',
'city' => 'Erfurt',
'zip' => '99084',
'district' => 'Altstadt',
'country' => 'Deutschland',
'phone' => '',
'latitude' => '50.9785',
'longitude' => '11.031589',
],
],
];

View file

@ -1,68 +0,0 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2023 Daniel Siepmann <coding@daniel-siepmann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
namespace WerkraumMedia\Events\Tests\Functional\Updates;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\Attributes\TestDox;
use WerkraumMedia\Events\Tests\Functional\AbstractFunctionalTestCase;
use WerkraumMedia\Events\Updates\MigrateDuplicateLocations;
#[TestDox('The update wizard to migrate duplicate locations')]
final class MigrateDuplicateLocationsTest extends AbstractFunctionalTestCase
{
#[Test]
public function canBeCreated(): void
{
$subject = $this->get(MigrateDuplicateLocations::class);
self::assertInstanceOf(MigrateDuplicateLocations::class, $subject);
}
#[Test]
public function keepsDataIfNothingToDo(): void
{
$this->importPHPDataSet(__DIR__ . '/Fixtures/MigrateDuplicateLocationsNoDuplicates.php');
$subject = $this->get(MigrateDuplicateLocations::class);
self::assertInstanceOf(MigrateDuplicateLocations::class, $subject);
self::assertTrue($subject->updateNecessary());
$this->assertPHPDataSet(__DIR__ . '/Fixtures/MigrateDuplicateLocationsNoDuplicates.php');
}
#[Test]
public function migratesDuplicateEntries(): void
{
$this->importPHPDataSet(__DIR__ . '/Fixtures/MigrateDuplicateLocations.php');
$subject = $this->get(MigrateDuplicateLocations::class);
self::assertInstanceOf(MigrateDuplicateLocations::class, $subject);
self::assertTrue($subject->updateNecessary());
$subject->executeUpdate();
$this->assertPHPDataSet(__DIR__ . '/Assertions/MigrateDuplicateLocations.php');
}
}

View file

@ -2,45 +2,9 @@
declare(strict_types=1);
use TYPO3\CMS\Extbase\Utility\ExtensionUtility;
use WerkraumMedia\Events\Controller\DateController;
use WerkraumMedia\Events\Controller\EventController;
defined('TYPO3') || die('Access denied.');
call_user_func(function () {
ExtensionUtility::configurePlugin(
'Events',
'DateSearch',
[DateController::class => 'search'],
[DateController::class => 'search'],
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
);
ExtensionUtility::configurePlugin(
'Events',
'DateList',
[DateController::class => 'list'],
[DateController::class => 'list'],
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
);
ExtensionUtility::configurePlugin(
'Events',
'DateShow',
[DateController::class => 'show'],
[DateController::class => 'show'],
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
);
ExtensionUtility::configurePlugin(
'Events',
'Selected',
[EventController::class => 'list'],
[],
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
);
if (
isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['events_category']) === false
|| is_array($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['events_category']) === false

View file

@ -104,8 +104,3 @@ parameters:
message: "#^Method WerkraumMedia\\\\Events\\\\Service\\\\DestinationDataImportService\\\\FilesAssignment\\:\\:getImages\\(\\) should return TYPO3\\\\CMS\\\\Extbase\\\\Persistence\\\\ObjectStorage\\<TYPO3\\\\CMS\\\\Extbase\\\\Domain\\\\Model\\\\FileReference\\> but returns TYPO3\\\\CMS\\\\Extbase\\\\Persistence\\\\ObjectStorage\\<mixed\\>\\.$#"
count: 1
path: Classes/Service/DestinationDataImportService/FilesAssignment.php
-
message: "#^Method WerkraumMedia\\\\Events\\\\Updates\\\\MigrateOldLocations\\:\\:getExitingLocationUid\\(\\) should return int but returns mixed\\.$#"
count: 1
path: Classes/Updates/MigrateOldLocations.php