mirror of
https://github.com/werkraum-media/events.git
synced 2024-11-24 16:36:11 +01:00
Integrate destination data features
Import alongside of categories. Use TYPO3 sys_category again.
This commit is contained in:
parent
3b4ecbe6ce
commit
0a56a5d482
24 changed files with 1188 additions and 64 deletions
|
@ -140,7 +140,8 @@ class DateController extends AbstractController
|
|||
'search' => $search,
|
||||
'demand' => DateDemand::createFromRequestValues($arguments, $this->settings),
|
||||
'regions' => $this->regionRepository->findAll(),
|
||||
'categories' => $this->categoryRepository->findAllCurrentlyAssigned(),
|
||||
'categories' => $this->categoryRepository->findAllCurrentlyAssigned($this->settings['uids']['categoriesParent'] ?? 0, 'categories'),
|
||||
'features' => $this->categoryRepository->findAllCurrentlyAssigned($this->settings['uids']['featuresParent'] ?? 0, 'features'),
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,29 +2,12 @@
|
|||
|
||||
namespace Wrm\Events\Domain\Model;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 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.
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Extbase\Domain\Model\Category as ExtbaseCategory;
|
||||
|
||||
/**
|
||||
* Extend original model to include furher properties.
|
||||
*
|
||||
* Used for Plugins and Import.
|
||||
*/
|
||||
class Category extends ExtbaseCategory
|
||||
{
|
||||
|
@ -33,8 +16,18 @@ class Category extends ExtbaseCategory
|
|||
*/
|
||||
protected $sorting = 0;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $hidden = false;
|
||||
|
||||
public function getSorting(): int
|
||||
{
|
||||
return $this->sorting;
|
||||
}
|
||||
|
||||
public function hide(): void
|
||||
{
|
||||
$this->hidden = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,11 @@ class DateDemand
|
|||
*/
|
||||
protected $userCategories = [];
|
||||
|
||||
/**
|
||||
* @var int[]
|
||||
*/
|
||||
protected $features = [];
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
|
@ -127,6 +132,10 @@ class DateDemand
|
|||
$instance->setUserCategories($submittedValues['userCategories']);
|
||||
}
|
||||
|
||||
if (is_array($submittedValues['features'])) {
|
||||
$instance->setFeatures($submittedValues['features']);
|
||||
}
|
||||
|
||||
$instance->setSortBy($settings['sortByDate'] ?? '');
|
||||
$instance->setSortOrder($settings['sortOrder'] ?? '');
|
||||
$instance->setQueryCallback($settings['queryCallback'] ?? '');
|
||||
|
@ -184,6 +193,22 @@ class DateDemand
|
|||
$this->categories = $categories;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int[] $categories
|
||||
*/
|
||||
public function setFeatures(array $categories): void
|
||||
{
|
||||
$this->features = array_map('intval', $categories);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int[]
|
||||
*/
|
||||
public function getFeatures(): array
|
||||
{
|
||||
return $this->features;
|
||||
}
|
||||
|
||||
public function getIncludeSubCategories(): bool
|
||||
{
|
||||
return $this->includeSubCategories;
|
||||
|
|
|
@ -155,6 +155,11 @@ class Event extends AbstractEntity
|
|||
*/
|
||||
protected $categories;
|
||||
|
||||
/**
|
||||
* @var ObjectStorage<Category>
|
||||
*/
|
||||
protected $features;
|
||||
|
||||
/**
|
||||
* @var ObjectStorage<Partner>
|
||||
*/
|
||||
|
@ -198,6 +203,7 @@ class Event extends AbstractEntity
|
|||
$this->images = new ObjectStorage();
|
||||
$this->dates = new ObjectStorage();
|
||||
$this->categories = new ObjectStorage();
|
||||
$this->features = new ObjectStorage();
|
||||
$this->partner = new ObjectStorage();
|
||||
$this->referencesEvents = new ObjectStorage();
|
||||
}
|
||||
|
@ -547,6 +553,25 @@ class Event extends AbstractEntity
|
|||
$this->categories = $categories;
|
||||
}
|
||||
|
||||
public function getFeatures(): array
|
||||
{
|
||||
$features = $this->features->toArray();
|
||||
|
||||
usort($features, function (Category $catA, Category $catB) {
|
||||
return $catA->getSorting() <=> $catB->getSorting();
|
||||
});
|
||||
|
||||
return $features;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ObjectStorage<Category> $features
|
||||
*/
|
||||
public function setFeatures(ObjectStorage $features): void
|
||||
{
|
||||
$this->features = $features;
|
||||
}
|
||||
|
||||
public function setLanguageUid(int $languageUid): void
|
||||
{
|
||||
$this->_languageUid = $languageUid;
|
||||
|
|
|
@ -31,6 +31,16 @@ class Import extends AbstractDomainObject
|
|||
*/
|
||||
protected $categoryParent;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $featuresPid;
|
||||
|
||||
/**
|
||||
* @var Category|null
|
||||
*/
|
||||
protected $featuresParent;
|
||||
|
||||
/**
|
||||
* @var Region|null
|
||||
*/
|
||||
|
@ -53,6 +63,8 @@ class Import extends AbstractDomainObject
|
|||
string $restSearchQuery = '',
|
||||
int $categoriesPid = 0,
|
||||
?Category $categoryParent = null,
|
||||
int $featuresPid = 0,
|
||||
?Category $featuresParent = null,
|
||||
?Region $region = null
|
||||
) {
|
||||
$this->filesFolder = $filesFolder;
|
||||
|
@ -61,6 +73,9 @@ class Import extends AbstractDomainObject
|
|||
$this->categoriesPid = $categoriesPid;
|
||||
$this->categoryParent = $categoryParent;
|
||||
|
||||
$this->featuresPid = $featuresPid;
|
||||
$this->featuresParent = $featuresParent;
|
||||
|
||||
$this->restExperience = $restExperience;
|
||||
$this->restSearchQuery = $restSearchQuery;
|
||||
|
||||
|
@ -87,6 +102,16 @@ class Import extends AbstractDomainObject
|
|||
return $this->categoryParent;
|
||||
}
|
||||
|
||||
public function getFeaturesPid(): int
|
||||
{
|
||||
return $this->featuresPid;
|
||||
}
|
||||
|
||||
public function getFeaturesParent(): ?Category
|
||||
{
|
||||
return $this->featuresParent;
|
||||
}
|
||||
|
||||
public function getRegion(): ?Region
|
||||
{
|
||||
return $this->region;
|
||||
|
|
|
@ -54,8 +54,10 @@ class CategoryRepository extends Repository
|
|||
/**
|
||||
* @return array<Category>
|
||||
*/
|
||||
public function findAllCurrentlyAssigned(): array
|
||||
{
|
||||
public function findAllCurrentlyAssigned(
|
||||
int $parentUid = 0,
|
||||
string $relation = 'categories'
|
||||
): array {
|
||||
$qb = $this->connectionPool->getQueryBuilderForTable('tx_events_domain_model_event');
|
||||
$qb->select('category.*');
|
||||
$qb->from('tx_events_domain_model_event', 'event');
|
||||
|
@ -66,7 +68,7 @@ class CategoryRepository extends Repository
|
|||
'mm',
|
||||
'event.uid = mm.uid_foreign'
|
||||
. ' AND mm.tablenames = ' . $qb->createNamedParameter('tx_events_domain_model_event')
|
||||
. ' AND mm.fieldname = ' . $qb->createNamedParameter('categories')
|
||||
. ' AND mm.fieldname = ' . $qb->createNamedParameter($relation)
|
||||
);
|
||||
|
||||
$qb->leftJoin(
|
||||
|
@ -75,10 +77,13 @@ class CategoryRepository extends Repository
|
|||
'category',
|
||||
'category.uid = mm.uid_local'
|
||||
. ' AND mm.tablenames = ' . $qb->createNamedParameter('tx_events_domain_model_event')
|
||||
. ' AND mm.fieldname = ' . $qb->createNamedParameter('categories')
|
||||
. ' AND mm.fieldname = ' . $qb->createNamedParameter($relation)
|
||||
);
|
||||
|
||||
$qb->where($qb->expr()->neq('category.uid', $qb->createNamedParameter(0)));
|
||||
if ($parentUid > 0) {
|
||||
$qb->andWhere($qb->expr()->eq('category.parent', $qb->createNamedParameter($parentUid)));
|
||||
}
|
||||
$qb->orderBy('category.title', 'asc');
|
||||
$qb->groupBy('category.uid');
|
||||
|
||||
|
@ -87,4 +92,27 @@ class CategoryRepository extends Repository
|
|||
$qb->execute()->fetchAll()
|
||||
);
|
||||
}
|
||||
|
||||
public function findOneForImport(
|
||||
Category $parentCategory,
|
||||
int $pid,
|
||||
string $title
|
||||
): ?Category {
|
||||
$query = $this->createQuery();
|
||||
|
||||
$query->getQuerySettings()->setStoragePageIds([$pid]);
|
||||
// Necessary as enableFieldsToBeIgnored would not be respected.
|
||||
// Both combined lead to only ignoring defined enable fields.
|
||||
$query->getQuerySettings()->setIgnoreEnableFields(true);
|
||||
$query->getQuerySettings()->setEnableFieldsToBeIgnored(['disabled']);
|
||||
|
||||
$query->matching($query->logicalAnd([
|
||||
$query->equals('parent', $parentCategory),
|
||||
$query->equals('title', $title)
|
||||
]));
|
||||
|
||||
$query->setLimit(1);
|
||||
|
||||
return $query->execute()->getFirst();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,6 +60,10 @@ class DateRepository extends Repository
|
|||
}
|
||||
}
|
||||
|
||||
if ($demand->getFeatures() !== []) {
|
||||
$constraints['features'] = $this->createFeaturesConstraint($query, $demand);
|
||||
}
|
||||
|
||||
if ($demand->getRegion() !== '') {
|
||||
$constraints['region'] = $query->equals('event.region', $demand->getRegion());
|
||||
}
|
||||
|
@ -183,6 +187,19 @@ class DateRepository extends Repository
|
|||
return $constraints;
|
||||
}
|
||||
|
||||
private function createFeaturesConstraint(
|
||||
QueryInterface $query,
|
||||
DateDemand $demand
|
||||
): ConstraintInterface {
|
||||
$constraints = [];
|
||||
|
||||
foreach ($demand->getFeatures() as $feature) {
|
||||
$constraints[] = $query->contains('event.features', $feature);
|
||||
}
|
||||
|
||||
return $query->logicalAnd($constraints);
|
||||
}
|
||||
|
||||
public function findSearchWord(string $search): array
|
||||
{
|
||||
$connection = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
|
|
|
@ -27,6 +27,8 @@ use Wrm\Events\Domain\Repository\CategoryRepository;
|
|||
use Wrm\Events\Domain\Repository\DateRepository;
|
||||
use Wrm\Events\Domain\Repository\EventRepository;
|
||||
use Wrm\Events\Domain\Repository\OrganizerRepository;
|
||||
use Wrm\Events\Service\DestinationDataImportService\CategoriesAssignment;
|
||||
use Wrm\Events\Service\DestinationDataImportService\CategoriesAssignment\Import as CategoryImport;
|
||||
use Wrm\Events\Service\DestinationDataImportService\DataFetcher;
|
||||
use Wrm\Events\Service\DestinationDataImportService\DatesFactory;
|
||||
|
||||
|
@ -62,11 +64,6 @@ class DestinationDataImportService
|
|||
*/
|
||||
private $dateRepository;
|
||||
|
||||
/**
|
||||
* @var CategoryRepository
|
||||
*/
|
||||
private $sysCategoriesRepository;
|
||||
|
||||
/**
|
||||
* @var MetaDataRepository
|
||||
*/
|
||||
|
@ -97,40 +94,45 @@ class DestinationDataImportService
|
|||
*/
|
||||
private $datesFactory;
|
||||
|
||||
/**
|
||||
* @var CategoriesAssignment
|
||||
*/
|
||||
private $categoriesAssignment;
|
||||
|
||||
/**
|
||||
* ImportService constructor.
|
||||
* @param EventRepository $eventRepository
|
||||
* @param OrganizerRepository $organizerRepository
|
||||
* @param DateRepository $dateRepository
|
||||
* @param CategoryRepository $sysCategoriesRepository
|
||||
* @param MetaDataRepository $metaDataRepository
|
||||
* @param ConfigurationManager $configurationManager
|
||||
* @param PersistenceManager $persistenceManager
|
||||
* @param ObjectManager $objectManager
|
||||
* @param DataFetcher $dataFetcher
|
||||
* @param CategoriesAssignment $categoriesAssignment
|
||||
*/
|
||||
public function __construct(
|
||||
EventRepository $eventRepository,
|
||||
OrganizerRepository $organizerRepository,
|
||||
DateRepository $dateRepository,
|
||||
CategoryRepository $sysCategoriesRepository,
|
||||
MetaDataRepository $metaDataRepository,
|
||||
ConfigurationManager $configurationManager,
|
||||
PersistenceManager $persistenceManager,
|
||||
ObjectManager $objectManager,
|
||||
DataFetcher $dataFetcher,
|
||||
DatesFactory $datesFactory
|
||||
DatesFactory $datesFactory,
|
||||
CategoriesAssignment $categoriesAssignment
|
||||
) {
|
||||
$this->eventRepository = $eventRepository;
|
||||
$this->organizerRepository = $organizerRepository;
|
||||
$this->dateRepository = $dateRepository;
|
||||
$this->sysCategoriesRepository = $sysCategoriesRepository;
|
||||
$this->metaDataRepository = $metaDataRepository;
|
||||
$this->configurationManager = $configurationManager;
|
||||
$this->persistenceManager = $persistenceManager;
|
||||
$this->objectManager = $objectManager;
|
||||
$this->dataFetcher = $dataFetcher;
|
||||
$this->datesFactory = $datesFactory;
|
||||
$this->categoriesAssignment = $categoriesAssignment;
|
||||
}
|
||||
|
||||
public function import(
|
||||
|
@ -224,6 +226,11 @@ class DestinationDataImportService
|
|||
$this->setCategories($event['categories']);
|
||||
}
|
||||
|
||||
// Set Features
|
||||
if ($event['features']) {
|
||||
$this->setFeatures($event['features']);
|
||||
}
|
||||
|
||||
// Set Organizer
|
||||
if ($event['addresses'] ?? false) {
|
||||
$this->setOrganizer($event['addresses']);
|
||||
|
@ -262,31 +269,27 @@ class DestinationDataImportService
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $categories
|
||||
*/
|
||||
private function setCategories(array $categories): void
|
||||
{
|
||||
$sysParentCategory = $this->import->getCategoryParent();
|
||||
if (!$sysParentCategory instanceof Category) {
|
||||
return;
|
||||
$categories = $this->categoriesAssignment->getCategories(new CategoryImport(
|
||||
$this->import->getCategoryParent(),
|
||||
$this->import->getCategoriesPid(),
|
||||
$categories
|
||||
));
|
||||
|
||||
$this->tmpCurrentEvent->setCategories($categories);
|
||||
}
|
||||
|
||||
foreach ($categories as $categoryTitle) {
|
||||
$tmpSysCategory = $this->sysCategoriesRepository->findOneByTitle($categoryTitle);
|
||||
if (!$tmpSysCategory) {
|
||||
$this->logger->info('Creating new category: ' . $categoryTitle);
|
||||
$tmpSysCategory = $this->objectManager->get(Category::class);
|
||||
$tmpSysCategory->setTitle($categoryTitle);
|
||||
$tmpSysCategory->setParent($sysParentCategory);
|
||||
$tmpSysCategory->setPid($this->import->getCategoriesPid());
|
||||
$this->sysCategoriesRepository->add($tmpSysCategory);
|
||||
$this->tmpCurrentEvent->addCategory($tmpSysCategory);
|
||||
} else {
|
||||
$this->tmpCurrentEvent->addCategory($tmpSysCategory);
|
||||
}
|
||||
}
|
||||
private function setFeatures(array $features): void
|
||||
{
|
||||
$features = $this->categoriesAssignment->getCategories(new CategoryImport(
|
||||
$this->import->getFeaturesParent(),
|
||||
$this->import->getFeaturesPid(),
|
||||
$features,
|
||||
true
|
||||
));
|
||||
|
||||
$this->tmpCurrentEvent->setFeatures($features);
|
||||
}
|
||||
|
||||
private function setDates(
|
||||
|
@ -456,7 +459,6 @@ class DestinationDataImportService
|
|||
$event = $this->objectManager->get(Event::class);
|
||||
// Create event and persist
|
||||
$event->setGlobalId($globalId);
|
||||
$event->setCategories(new ObjectStorage());
|
||||
$this->eventRepository->add($event);
|
||||
$this->persistenceManager->persistAll();
|
||||
$this->logger->info(
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Wrm\Events\Service\DestinationDataImportService;
|
||||
|
||||
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
|
||||
use Wrm\Events\Domain\Model\Category;
|
||||
use Wrm\Events\Domain\Repository\CategoryRepository;
|
||||
use Wrm\Events\Service\DestinationDataImportService\CategoriesAssignment\Import;
|
||||
|
||||
/**
|
||||
* Provides APIs to work with categories that will be assigned to events during import.
|
||||
*
|
||||
* Categories mean TYPO3 sys_category records.
|
||||
* Those are used for multiple records within destination data. E.g. categories or features.
|
||||
*/
|
||||
class CategoriesAssignment
|
||||
{
|
||||
/**
|
||||
* @var CategoryRepository
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
public function __construct(
|
||||
CategoryRepository $repository
|
||||
) {
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ObjectStorage<Category>
|
||||
*/
|
||||
public function getCategories(
|
||||
Import $import
|
||||
): ObjectStorage {
|
||||
$categories = new ObjectStorage();
|
||||
|
||||
if ($import->getParentCategory() === null) {
|
||||
return $categories;
|
||||
}
|
||||
|
||||
foreach ($import->getCategoryTitles() as $categoryTitle) {
|
||||
$category = $this->repository->findOneForImport(
|
||||
$import->getParentCategory(),
|
||||
$import->getPid(),
|
||||
$categoryTitle
|
||||
);
|
||||
|
||||
if (!$category instanceof Category) {
|
||||
$category = new Category();
|
||||
$category->setParent($import->getParentCategory());
|
||||
$category->setPid($import->getPid());
|
||||
$category->setTitle($categoryTitle);
|
||||
if ($import->getHideByDefault()) {
|
||||
$category->hide();
|
||||
}
|
||||
$this->repository->add($category);
|
||||
}
|
||||
|
||||
$categories->attach($category);
|
||||
}
|
||||
|
||||
return $categories;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
|
||||
namespace Wrm\Events\Service\DestinationDataImportService\CategoriesAssignment;
|
||||
|
||||
use Wrm\Events\Domain\Model\Category;
|
||||
|
||||
class Import
|
||||
{
|
||||
/**
|
||||
* @var null|Category
|
||||
*/
|
||||
private $parentCategory;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $pid;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $categoryTitles;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $hideByDefault;
|
||||
|
||||
public function __construct(
|
||||
?Category $parentCategory,
|
||||
int $pid,
|
||||
array $categoryTitles,
|
||||
bool $hideByDefault = false
|
||||
) {
|
||||
$this->parentCategory = $parentCategory;
|
||||
$this->pid = $pid;
|
||||
$this->categoryTitles = $categoryTitles;
|
||||
$this->hideByDefault = $hideByDefault;
|
||||
}
|
||||
|
||||
public function getParentCategory(): ?Category
|
||||
{
|
||||
return $this->parentCategory;
|
||||
}
|
||||
|
||||
public function getPid(): int
|
||||
{
|
||||
return $this->pid;
|
||||
}
|
||||
|
||||
public function getCategoryTitles(): array
|
||||
{
|
||||
return $this->categoryTitles;
|
||||
}
|
||||
|
||||
public function getHideByDefault(): bool
|
||||
{
|
||||
return $this->hideByDefault;
|
||||
}
|
||||
}
|
|
@ -13,4 +13,17 @@
|
|||
]
|
||||
]
|
||||
);
|
||||
|
||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::makeCategorizable(
|
||||
$extKey,
|
||||
$table,
|
||||
'features',
|
||||
[
|
||||
'label' => 'Features',
|
||||
'fieldConfiguration' => [
|
||||
'minitems' => 0,
|
||||
'multiple' => true,
|
||||
]
|
||||
]
|
||||
);
|
||||
})('events', 'tx_events_domain_model_event');
|
||||
|
|
|
@ -60,6 +60,7 @@ return [
|
|||
region,
|
||||
partner,
|
||||
categories,
|
||||
features,
|
||||
references_events,
|
||||
pages,
|
||||
--div--;' . $l10nPath . ':tx_events_domain_model_event.tabs.media,
|
||||
|
@ -457,12 +458,9 @@ return [
|
|||
|
||||
'categories' => [
|
||||
'exclude' => true,
|
||||
'label' => $l10nPath . ':tx_events_domain_model_event.categories',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => 4,
|
||||
'eval' => 'int'
|
||||
]
|
||||
],
|
||||
'features' => [
|
||||
'exclude' => true,
|
||||
],
|
||||
|
||||
'dates' => [
|
||||
|
|
|
@ -18,7 +18,7 @@ return [
|
|||
],
|
||||
'types' => [
|
||||
'1' => [
|
||||
'showitem' => 'title, hidden, --div--;LLL:EXT:events/Resources/Private/Language/locallang_csh_import.xlf:tx_events_domain_model_import.div.typo3, --palette--;;typo3_storage, --palette--;;categories, --palette--;;relations, --div--;LLL:EXT:events/Resources/Private/Language/locallang_csh_import.xlf:tx_events_domain_model_import.div.rest, rest_experience, rest_search_query'
|
||||
'showitem' => 'title, hidden, --div--;LLL:EXT:events/Resources/Private/Language/locallang_csh_import.xlf:tx_events_domain_model_import.div.typo3, --palette--;;typo3_storage, --palette--;;categories, --palette--;;features,--palette--;;relations, --div--;LLL:EXT:events/Resources/Private/Language/locallang_csh_import.xlf:tx_events_domain_model_import.div.rest, rest_experience, rest_search_query'
|
||||
],
|
||||
],
|
||||
'palettes' => [
|
||||
|
@ -30,6 +30,10 @@ return [
|
|||
'label' => 'LLL:EXT:events/Resources/Private/Language/locallang_csh_import.xlf:tx_events_domain_model_import.palette.categories',
|
||||
'showitem' => 'category_parent, categories_pid'
|
||||
],
|
||||
'features' => [
|
||||
'label' => 'LLL:EXT:events/Resources/Private/Language/locallang_csh_import.xlf:tx_events_domain_model_import.palette.features',
|
||||
'showitem' => 'features_parent, features_pid, '
|
||||
],
|
||||
'relations' => [
|
||||
'label' => 'LLL:EXT:events/Resources/Private/Language/locallang_csh_import.xlf:tx_events_domain_model_import.palette.relations',
|
||||
'showitem' => 'region'
|
||||
|
@ -113,6 +117,32 @@ return [
|
|||
'minitems' => 0,
|
||||
],
|
||||
],
|
||||
'features_pid' => [
|
||||
'exclude' => true,
|
||||
'label' => 'LLL:EXT:events/Resources/Private/Language/locallang_csh_import.xlf:tx_events_domain_model_import.features_pid',
|
||||
'description' => 'LLL:EXT:events/Resources/Private/Language/locallang_csh_import.xlf:tx_events_domain_model_import.features_pid.description',
|
||||
'config' => [
|
||||
'type' => 'group',
|
||||
'internal_type' => 'db',
|
||||
'allowed' => 'pages',
|
||||
'size' => 1,
|
||||
'maxitems' => 1,
|
||||
'minitems' => 0,
|
||||
],
|
||||
],
|
||||
'features_parent' => [
|
||||
'exclude' => true,
|
||||
'label' => 'LLL:EXT:events/Resources/Private/Language/locallang_csh_import.xlf:tx_events_domain_model_import.features_parent',
|
||||
'description' => 'LLL:EXT:events/Resources/Private/Language/locallang_csh_import.xlf:tx_events_domain_model_import.features_parent.description',
|
||||
'config' => [
|
||||
'type' => 'group',
|
||||
'internal_type' => 'db',
|
||||
'allowed' => 'sys_category',
|
||||
'size' => 1,
|
||||
'maxitems' => 1,
|
||||
'minitems' => 0,
|
||||
],
|
||||
],
|
||||
'files_folder' => [
|
||||
'exclude' => true,
|
||||
'label' => 'LLL:EXT:events/Resources/Private/Language/locallang_csh_import.xlf:tx_events_domain_model_import.files_folder',
|
||||
|
|
|
@ -31,6 +31,14 @@ Features
|
|||
|
||||
* ``getEndsOnSameDay()``
|
||||
|
||||
* Add destination data "Features" to events.
|
||||
Features are again TYPO3 categories with different parent as existing categories.
|
||||
New features are hidden by default but can be activated within TYPO3.
|
||||
That allows to fetch all within controller and provide them as filter.
|
||||
But editors actively need to enable them for filtering.
|
||||
|
||||
It is possible to add them to user submitted filter.
|
||||
|
||||
Fixes
|
||||
-----
|
||||
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
<trans-unit id="tx_events_domain_model_import.palette.categories">
|
||||
<source>Categories</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_events_domain_model_import.palette.features">
|
||||
<source>Features</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_events_domain_model_import.title">
|
||||
<source>Title</source>
|
||||
</trans-unit>
|
||||
|
@ -48,6 +51,18 @@
|
|||
<trans-unit id="tx_events_domain_model_import.category_parent.description">
|
||||
<source>Existing TYPO3 category used as parent for all categories created during import.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_events_domain_model_import.features_pid">
|
||||
<source>Features Storage Folder</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_events_domain_model_import.features_pid.description">
|
||||
<source>TYPO3 page to use for storing imported features.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_events_domain_model_import.features_parent">
|
||||
<source>Parent Features Category</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_events_domain_model_import.features_parent.description">
|
||||
<source>Existing TYPO3 category used as parent for all features created during import.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_events_domain_model_import.files_folder">
|
||||
<source>Folder</source>
|
||||
</trans-unit>
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
"tx_events_domain_model_event",,,,,,
|
||||
,"uid","pid","features",,,
|
||||
,1,2,1,,,
|
||||
,2,2,1,,,
|
||||
,3,2,0,,,
|
||||
"sys_category",,,,,,
|
||||
,"uid","pid","title","parent","hidden",
|
||||
,1,2,"Top Category",0,0,
|
||||
,2,2,"Event Category Parent",1,0,
|
||||
,4,2,"Event Feature Parent",1,0,
|
||||
,5,3,"vorhandenes Feature",4,0,
|
||||
,6,3,"Barrierefrei",4,1,
|
||||
,7,3,"Zielgruppe Jugendliche",4,1,
|
||||
,8,3,"Karten an der Abendkasse",4,1,
|
||||
,9,3,"Ausreichende Lüftung",4,1,
|
||||
,10,3,"Beachtung der Hygienehinweise",4,1,
|
||||
,11,3,"neues Feature",4,1,
|
||||
"sys_category_record_mm",,,,,,
|
||||
,"uid_local","uid_foreign","tablenames","fieldname","sorting","sorting_foreign"
|
||||
,5,1,"tx_events_domain_model_event","features",0,1
|
||||
,6,1,"tx_events_domain_model_event","features",0,2
|
||||
,7,1,"tx_events_domain_model_event","features",0,3
|
||||
,8,1,"tx_events_domain_model_event","features",0,4
|
||||
,9,1,"tx_events_domain_model_event","features",0,5
|
||||
,10,1,"tx_events_domain_model_event","features",0,6
|
||||
,5,2,"tx_events_domain_model_event","features",0,1
|
||||
,6,2,"tx_events_domain_model_event","features",0,2
|
||||
,7,2,"tx_events_domain_model_event","features",0,3
|
||||
,11,2,"tx_events_domain_model_event","features",0,4
|
|
|
@ -0,0 +1,43 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<dataset>
|
||||
<tx_events_domain_model_import>
|
||||
<uid>1</uid>
|
||||
<pid>2</pid>
|
||||
<title>Example for test</title>
|
||||
<storage_pid>2</storage_pid>
|
||||
<features_pid>3</features_pid>
|
||||
<features_parent>4</features_parent>
|
||||
</tx_events_domain_model_import>
|
||||
|
||||
<pages>
|
||||
<pid>2</pid>
|
||||
<uid>3</uid>
|
||||
<title>Features Storage</title>
|
||||
<doktype>254</doktype>
|
||||
</pages>
|
||||
|
||||
<sys_category>
|
||||
<uid>1</uid>
|
||||
<pid>2</pid>
|
||||
<title>Top Category</title>
|
||||
</sys_category>
|
||||
<sys_category>
|
||||
<uid>2</uid>
|
||||
<pid>2</pid>
|
||||
<title>Event Category Parent</title>
|
||||
<parent>1</parent>
|
||||
</sys_category>
|
||||
<sys_category>
|
||||
<uid>4</uid>
|
||||
<pid>2</pid>
|
||||
<title>Event Feature Parent</title>
|
||||
<parent>1</parent>
|
||||
</sys_category>
|
||||
<sys_category>
|
||||
<uid>5</uid>
|
||||
<pid>3</pid>
|
||||
<title>vorhandenes Feature</title>
|
||||
<parent>4</parent>
|
||||
<hidden>0</hidden>
|
||||
</sys_category>
|
||||
</dataset>
|
|
@ -0,0 +1,517 @@
|
|||
{
|
||||
"status": "OK",
|
||||
"count": 3,
|
||||
"overallcount": 50,
|
||||
"channels": [],
|
||||
"facetGroups": [],
|
||||
"items": [
|
||||
{
|
||||
"global_id": "e_100347853",
|
||||
"id": "100347853",
|
||||
"title": "Allerlei Weihnachtliches (Heute mit Johannes Geißer)",
|
||||
"type": "Event",
|
||||
"categories": [
|
||||
"Weihnachten"
|
||||
],
|
||||
"texts": [
|
||||
{
|
||||
"rel": "details",
|
||||
"type": "text/html",
|
||||
"value": "Die Lichter sind entzündet, die Plätzchen duften, man rückt endlich wieder näher zusammen und lauscht den Geschichten. Vier Schauspieler*innen unseres Theaters überraschen mit ihren weihnachtlichen Texten, die sie für uns ausgewählt haben. Dazu plaudern sie über persönliche Anekdoten und erinnern sich an ihre schönsten und verrücktesten Weihnachtsfeste. Und da der Genuss in der Vorweihnachtszeit nicht fehlen darf, wird an jedem Adventssonntag eine andere weihnachtliche Spezialität serviert.<br>Eintritt: 10 € (inkl. Gedeck mit weihnachtlicher Schillerlocke)<br>Um Voranmeldung unter 03672-486470 oder <a data-cke-saved-href=\"mailto:schillerhaus@rudolstadt.de\" href=\"mailto:schillerhaus@rudolstadt.de\">schillerhaus@rudolstadt.de</a> wird gebeten. <br><strong>Es gilt die 2G-PLUS-Regel.</strong> <br>"
|
||||
},
|
||||
{
|
||||
"rel": "details",
|
||||
"type": "text/plain",
|
||||
"value": "Die Lichter sind entzündet, die Plätzchen duften, man rückt endlich wieder näher zusammen und lauscht den Geschichten. Vier Schauspieler*innen unseres Theaters überraschen mit ihren weihnachtlichen Texten, die sie für uns ausgewählt haben. Dazu plaudern sie über persönliche Anekdoten und erinnern sich an ihre schönsten und verrücktesten Weihnachtsfeste. Und da der Genuss in der Vorweihnachtszeit nicht fehlen darf, wird an jedem Adventssonntag eine andere weihnachtliche Spezialität serviert.\nEintritt: 10 € (inkl. Gedeck mit weihnachtlicher Schillerlocke)\nUm Voranmeldung unter 03672-486470 oder schillerhaus@rudolstadt.de wird gebeten.\nEs gilt die 2G-PLUS-Regel."
|
||||
},
|
||||
{
|
||||
"rel": "teaser",
|
||||
"type": "text/html"
|
||||
},
|
||||
{
|
||||
"rel": "teaser",
|
||||
"type": "text/plain"
|
||||
}
|
||||
],
|
||||
"country": "Deutschland",
|
||||
"areas": [
|
||||
"Rudolstadt und Umgebung"
|
||||
],
|
||||
"city": "Rudolstadt",
|
||||
"zip": "07407",
|
||||
"street": "Schillerstraße 25",
|
||||
"phone": "+ 49 3672 / 486470",
|
||||
"fax": "+ 49 3672 / 486475",
|
||||
"web": "http://www.schillerhaus.rudolstadt.de/",
|
||||
"email": "schillerhaus@rudolstadt.de",
|
||||
"author": "support@hubermedia.de",
|
||||
"geo": {
|
||||
"main": {
|
||||
"latitude": 50.720971023258805,
|
||||
"longitude": 11.335229873657227
|
||||
},
|
||||
"entry": [],
|
||||
"attributes": []
|
||||
},
|
||||
"ratings": [
|
||||
{
|
||||
"type": "eT4",
|
||||
"value": 40.0
|
||||
},
|
||||
{
|
||||
"type": "order",
|
||||
"value": 99.0001
|
||||
}
|
||||
],
|
||||
"cuisine_types": [],
|
||||
"payment": [],
|
||||
"media_objects": [
|
||||
],
|
||||
"keywords": [],
|
||||
"timeIntervals": [
|
||||
{
|
||||
"weekdays": [],
|
||||
"start": "2099-12-19T15:00:00+01:00",
|
||||
"end": "2099-12-19T16:30:00+01:00",
|
||||
"tz": "Europe/Berlin",
|
||||
"interval": 1
|
||||
}
|
||||
],
|
||||
"kitchenTimeIntervals": [],
|
||||
"deliveryTimeIntervals": [],
|
||||
"numbers": [],
|
||||
"name": "Schillerhaus Rudolstadt",
|
||||
"attributes": [
|
||||
{
|
||||
"key": "VO_Id",
|
||||
"value": "100050775"
|
||||
},
|
||||
{
|
||||
"key": "VO_CategoryName",
|
||||
"value": "POI"
|
||||
},
|
||||
{
|
||||
"key": "VA_Id",
|
||||
"value": "100050775"
|
||||
},
|
||||
{
|
||||
"key": "VA_CategoryName",
|
||||
"value": "POI"
|
||||
},
|
||||
{
|
||||
"key": "interval_first_match_start",
|
||||
"value": "2099-12-19T15:00:00+01"
|
||||
},
|
||||
{
|
||||
"key": "interval_first_match_end",
|
||||
"value": "2099-12-19T16:30:00+01"
|
||||
},
|
||||
{
|
||||
"key": "interval_match_count",
|
||||
"value": "1"
|
||||
}
|
||||
],
|
||||
"features": [
|
||||
"vorhandenes Feature",
|
||||
"Barrierefrei",
|
||||
"Zielgruppe Jugendliche",
|
||||
"Karten an der Abendkasse",
|
||||
"Ausreichende Lüftung",
|
||||
"Beachtung der Hygienehinweise"
|
||||
],
|
||||
"addresses": [
|
||||
{
|
||||
"name": "Städtetourismus in Thüringen e.V.",
|
||||
"city": "Weimar",
|
||||
"zip": "99423",
|
||||
"street": "UNESCO-Platz 1",
|
||||
"phone": "+49 (3643) 745 314",
|
||||
"web": "http://www.thueringer-staedte.de",
|
||||
"email": "verein@thueringer-staedte.de",
|
||||
"rel": "author"
|
||||
},
|
||||
{
|
||||
"name": "Städtetourismus in Thüringen\" e.V.",
|
||||
"web": "http://www.thueringer-staedte.de",
|
||||
"email": "verein@thueringer-staedte.de",
|
||||
"rel": "organisation"
|
||||
},
|
||||
{
|
||||
"name": "Schillerhaus Rudolstadt",
|
||||
"city": "Rudolstadt",
|
||||
"zip": "07407",
|
||||
"street": "Schillerstraße 25",
|
||||
"phone": "+ 49 3672 / 486470",
|
||||
"fax": "+ 49 3672 / 486475",
|
||||
"web": "http://schillerhaus.rudolstadt.de",
|
||||
"email": "schillerhaus@rudolstadt.de",
|
||||
"rel": "organizer"
|
||||
}
|
||||
],
|
||||
"created": "2099-10-31T12:29:00+00:00",
|
||||
"changed": "2099-12-14T08:29:00+00:00",
|
||||
"source": {
|
||||
"url": "http://destination.one/",
|
||||
"value": "destination.one"
|
||||
},
|
||||
"company": "",
|
||||
"district": "",
|
||||
"postoffice": "",
|
||||
"phone2": "",
|
||||
"seasons": [],
|
||||
"subitems": [],
|
||||
"hyperObjects": []
|
||||
},
|
||||
{
|
||||
"global_id": "e_100354481",
|
||||
"id": "100354481",
|
||||
"title": "Tüftlerzeit",
|
||||
"type": "Event",
|
||||
"categories": [
|
||||
"Kinder"
|
||||
],
|
||||
"texts": [
|
||||
{
|
||||
"rel": "details",
|
||||
"type": "text/html",
|
||||
"value": "Die Tüftlerzeit wird dieses Mal ein weihnachtliches Angebot bereithalten. Alle kleinen Tüftler dürfen gespannt sein.<br>Voranmeldung über: kinderbibliothek@rudolstadt.de oder 03672-486420<br><br>Bitte beachten Sie die derzeit geltenden Zugangsregeln."
|
||||
},
|
||||
{
|
||||
"rel": "details",
|
||||
"type": "text/plain",
|
||||
"value": "Die Tüftlerzeit wird dieses Mal ein weihnachtliches Angebot bereithalten. Alle kleinen Tüftler dürfen gespannt sein.\nVoranmeldung über: kinderbibliothek@rudolstadt.de oder 03672-486420\n\nBitte beachten Sie die derzeit geltenden Zugangsregeln."
|
||||
},
|
||||
{
|
||||
"rel": "teaser",
|
||||
"type": "text/html"
|
||||
},
|
||||
{
|
||||
"rel": "teaser",
|
||||
"type": "text/plain"
|
||||
}
|
||||
],
|
||||
"country": "Deutschland",
|
||||
"areas": [
|
||||
"Rudolstadt und Umgebung"
|
||||
],
|
||||
"city": "Rudolstadt",
|
||||
"zip": "07407",
|
||||
"street": "Schulplatz 13",
|
||||
"phone": "0 36 72 - 48 64 20",
|
||||
"fax": "0 36 72 - 48 64 30",
|
||||
"web": "http://www.stadtbibliothek-rudolstadt.de/",
|
||||
"email": "stadtbibliothek@rudolstadt.de",
|
||||
"author": "support@hubermedia.de",
|
||||
"geo": {
|
||||
"main": {
|
||||
"latitude": 50.720835175055917,
|
||||
"longitude": 11.342568397521973
|
||||
},
|
||||
"entry": [],
|
||||
"attributes": []
|
||||
},
|
||||
"ratings": [
|
||||
{
|
||||
"type": "eT4",
|
||||
"value": 40.0
|
||||
},
|
||||
{
|
||||
"type": "order",
|
||||
"value": 99.0001
|
||||
}
|
||||
],
|
||||
"cuisine_types": [],
|
||||
"payment": [],
|
||||
"media_objects": [
|
||||
],
|
||||
"keywords": [],
|
||||
"timeIntervals": [
|
||||
{
|
||||
"weekdays": [],
|
||||
"start": "2099-12-16T15:00:00+01:00",
|
||||
"end": "2099-12-16T16:30:00+01:00",
|
||||
"tz": "Europe/Berlin",
|
||||
"interval": 1
|
||||
},
|
||||
{
|
||||
"weekdays": [],
|
||||
"start": "2099-04-01T11:00:00+02:00",
|
||||
"end": "2099-04-01T13:00:00+02:00",
|
||||
"repeatUntil": "2099-04-03T00:00+02:00",
|
||||
"tz": "Europe/Berlin",
|
||||
"freq": "Daily",
|
||||
"interval": 1
|
||||
},
|
||||
{
|
||||
"weekdays": [],
|
||||
"start": "2099-02-17T15:00:00+01:00",
|
||||
"end": "2099-02-17T17:00:00+01:00",
|
||||
"tz": "Europe/Berlin",
|
||||
"interval": 1
|
||||
}
|
||||
],
|
||||
"kitchenTimeIntervals": [],
|
||||
"deliveryTimeIntervals": [],
|
||||
"numbers": [],
|
||||
"name": "Stadtbibliothek Rudolstadt",
|
||||
"attributes": [
|
||||
{
|
||||
"key": "VO_Id",
|
||||
"value": "100042570"
|
||||
},
|
||||
{
|
||||
"key": "VO_CategoryName",
|
||||
"value": "POI"
|
||||
},
|
||||
{
|
||||
"key": "VA_Id",
|
||||
"value": "100042570"
|
||||
},
|
||||
{
|
||||
"key": "VA_CategoryName",
|
||||
"value": "POI"
|
||||
},
|
||||
{
|
||||
"key": "interval_first_match_start",
|
||||
"value": "2099-12-16T15:00:00+01"
|
||||
},
|
||||
{
|
||||
"key": "interval_first_match_end",
|
||||
"value": "2099-12-16T16:30:00+01"
|
||||
},
|
||||
{
|
||||
"key": "interval_match_count",
|
||||
"value": "3"
|
||||
},
|
||||
{
|
||||
"key": "interval_last_match_start",
|
||||
"value": "2022-02-17T15:00:00+01"
|
||||
},
|
||||
{
|
||||
"key": "interval_last_match_end",
|
||||
"value": "2022-02-17T17:00:00+01"
|
||||
}
|
||||
],
|
||||
"features": [
|
||||
"vorhandenes Feature",
|
||||
"Barrierefrei",
|
||||
"Zielgruppe Jugendliche",
|
||||
"neues Feature"
|
||||
],
|
||||
"addresses": [
|
||||
{
|
||||
"name": "Städtetourismus in Thüringen e.V.",
|
||||
"city": "Weimar",
|
||||
"zip": "99423",
|
||||
"street": "UNESCO-Platz 1",
|
||||
"phone": "+49 (3643) 745 314",
|
||||
"web": "http://www.thueringer-staedte.de",
|
||||
"email": "verein@thueringer-staedte.de",
|
||||
"rel": "author"
|
||||
},
|
||||
{
|
||||
"name": "Städtetourismus in Thüringen\" e.V.",
|
||||
"web": "http://www.thueringer-staedte.de",
|
||||
"email": "verein@thueringer-staedte.de",
|
||||
"rel": "organisation"
|
||||
},
|
||||
{
|
||||
"name": "Stadtbibliothek Rudolstadt",
|
||||
"city": "Rudolstadt",
|
||||
"zip": "07407",
|
||||
"street": "Schulplatz 13",
|
||||
"phone": "0 36 72 - 48 64 20",
|
||||
"fax": "0 36 72 - 48 64 30",
|
||||
"web": "http://www.stadtbibliothek-rudolstadt.de ",
|
||||
"email": "stadtbibliothek@rudolstadt.de",
|
||||
"rel": "organizer"
|
||||
}
|
||||
],
|
||||
"created": "2099-11-10T23:02:00+00:00",
|
||||
"changed": "2099-12-14T08:28:00+00:00",
|
||||
"source": {
|
||||
"url": "http://destination.one/",
|
||||
"value": "destination.one"
|
||||
},
|
||||
"company": "",
|
||||
"district": "",
|
||||
"postoffice": "",
|
||||
"phone2": "",
|
||||
"seasons": [],
|
||||
"subitems": [],
|
||||
"hyperObjects": []
|
||||
},
|
||||
{
|
||||
"global_id": "e_100350503",
|
||||
"id": "100350503",
|
||||
"title": "Adventliche Orgelmusik (Orgel: KMD Frank Bettenhausen)",
|
||||
"type": "Event",
|
||||
"categories": [
|
||||
"Konzerte, Festivals, Show & Tanz",
|
||||
"Weihnachten"
|
||||
],
|
||||
"texts": [
|
||||
{
|
||||
"rel": "details",
|
||||
"type": "text/html",
|
||||
"value": "Immer mittwochs in der Adventszeit spielt Frank Bettenhausen solo und zusammen mit anderen Musikern auf der Steinmeyerorgel aus dem Jahr 1906. Bekannte Adventslieder, barocke und romantische Kompositionen stehen neben besinnlichen Texten von Pfarrer Johannes-Martin Weiss.<br><br><strong>Es gilt die 2G-PLUS-Regel.</strong><br>"
|
||||
},
|
||||
{
|
||||
"rel": "details",
|
||||
"type": "text/plain",
|
||||
"value": "Immer mittwochs in der Adventszeit spielt Frank Bettenhausen solo und zusammen mit anderen Musikern auf der Steinmeyerorgel aus dem Jahr 1906. Bekannte Adventslieder, barocke und romantische Kompositionen stehen neben besinnlichen Texten von Pfarrer Johannes-Martin Weiss.\n\nEs gilt die 2G-PLUS-Regel."
|
||||
},
|
||||
{
|
||||
"rel": "teaser",
|
||||
"type": "text/html"
|
||||
},
|
||||
{
|
||||
"rel": "teaser",
|
||||
"type": "text/plain"
|
||||
}
|
||||
],
|
||||
"country": "Deutschland",
|
||||
"areas": [
|
||||
"Rudolstadt und Umgebung"
|
||||
],
|
||||
"city": "Rudolstadt",
|
||||
"zip": "07407",
|
||||
"street": "Caspar-Schulte-Straße",
|
||||
"phone": "03672 - 48 96 13",
|
||||
"author": "support@hubermedia.de",
|
||||
"geo": {
|
||||
"main": {
|
||||
"latitude": 50.718688721182531,
|
||||
"longitude": 11.327333450317383
|
||||
},
|
||||
"entry": [],
|
||||
"attributes": []
|
||||
},
|
||||
"ratings": [
|
||||
{
|
||||
"type": "eT4",
|
||||
"value": 40.0
|
||||
},
|
||||
{
|
||||
"type": "order",
|
||||
"value": 99.0001
|
||||
}
|
||||
],
|
||||
"cuisine_types": [],
|
||||
"payment": [],
|
||||
"media_objects": [
|
||||
],
|
||||
"keywords": [],
|
||||
"timeIntervals": [
|
||||
{
|
||||
"weekdays": [],
|
||||
"start": "2099-12-01T19:00:00+01:00",
|
||||
"end": "2099-12-01T20:00:00+01:00",
|
||||
"tz": "Europe/Berlin",
|
||||
"interval": 1
|
||||
},
|
||||
{
|
||||
"weekdays": [
|
||||
"Saturday",
|
||||
"Sunday"
|
||||
],
|
||||
"start": "2099-11-02T11:00:00+01:00",
|
||||
"end": "2099-11-02T13:00:00+01:00",
|
||||
"repeatUntil": "2099-11-25T13:00:00+01:00",
|
||||
"tz": "Europe/Berlin",
|
||||
"freq": "Weekly",
|
||||
"interval": 1
|
||||
},
|
||||
{
|
||||
"weekdays": [],
|
||||
"start": "2099-12-22T19:00:00+01:00",
|
||||
"end": "2099-12-22T20:00:00+01:00",
|
||||
"tz": "Europe/Berlin",
|
||||
"interval": 1
|
||||
}
|
||||
],
|
||||
"kitchenTimeIntervals": [],
|
||||
"deliveryTimeIntervals": [],
|
||||
"numbers": [],
|
||||
"name": "Lutherkirche",
|
||||
"attributes": [
|
||||
{
|
||||
"key": "VO_Id",
|
||||
"value": "100118350"
|
||||
},
|
||||
{
|
||||
"key": "VO_CategoryName",
|
||||
"value": "POI"
|
||||
},
|
||||
{
|
||||
"key": "VA_Id",
|
||||
"value": "100118350"
|
||||
},
|
||||
{
|
||||
"key": "VA_CategoryName",
|
||||
"value": "POI"
|
||||
},
|
||||
{
|
||||
"key": "interval_first_match_start",
|
||||
"value": "2099-12-15T19:00:00+01"
|
||||
},
|
||||
{
|
||||
"key": "interval_first_match_end",
|
||||
"value": "2099-12-15T20:00:00+01"
|
||||
},
|
||||
{
|
||||
"key": "interval_match_count",
|
||||
"value": "2"
|
||||
},
|
||||
{
|
||||
"key": "interval_last_match_start",
|
||||
"value": "2099-12-22T19:00:00+01"
|
||||
},
|
||||
{
|
||||
"key": "interval_last_match_end",
|
||||
"value": "2099-12-22T20:00:00+01"
|
||||
}
|
||||
],
|
||||
"features": [],
|
||||
"addresses": [
|
||||
{
|
||||
"name": "Städtetourismus in Thüringen e.V.",
|
||||
"city": "Weimar",
|
||||
"zip": "99423",
|
||||
"street": "UNESCO-Platz 1",
|
||||
"phone": "+49 (3643) 745 314",
|
||||
"web": "http://www.thueringer-staedte.de",
|
||||
"email": "verein@thueringer-staedte.de",
|
||||
"rel": "author"
|
||||
},
|
||||
{
|
||||
"name": "Städtetourismus in Thüringen\" e.V.",
|
||||
"web": "http://www.thueringer-staedte.de",
|
||||
"email": "verein@thueringer-staedte.de",
|
||||
"rel": "organisation"
|
||||
},
|
||||
{
|
||||
"name": "Lutherkirche",
|
||||
"city": "Rudolstadt",
|
||||
"zip": "07407",
|
||||
"street": "Caspar-Schulte-Straße",
|
||||
"phone": "03672 - 48 96 13",
|
||||
"rel": "organizer"
|
||||
}
|
||||
],
|
||||
"created": "2099-11-08T22:15:00+00:00",
|
||||
"changed": "2099-12-14T08:38:00+00:00",
|
||||
"source": {
|
||||
"url": "http://destination.one/",
|
||||
"value": "destination.one"
|
||||
},
|
||||
"company": "",
|
||||
"district": "",
|
||||
"postoffice": "",
|
||||
"phone2": "",
|
||||
"seasons": [],
|
||||
"subitems": [],
|
||||
"hyperObjects": []
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace Wrm\Events\Tests\Functional\Import\DestinationDataTest;
|
||||
|
||||
use GuzzleHttp\Psr7\Response;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use Wrm\Events\Command\ImportDestinationDataViaConfigruationCommand;
|
||||
|
||||
/**
|
||||
* @testdox DestinationData import
|
||||
*/
|
||||
class ImportsFeaturesTest extends AbstractTest
|
||||
{
|
||||
/**
|
||||
* @test
|
||||
* Only 1 associated feature count as other features are new and hidden and not counted.
|
||||
*/
|
||||
public function addsNewFeatures(): void
|
||||
{
|
||||
$this->setUpConfiguration([
|
||||
'restUrl = https://example.com/some-path/',
|
||||
]);
|
||||
$this->importDataSet('EXT:events/Tests/Functional/Import/DestinationDataTest/Fixtures/FeaturesImportConfiguration.xml');
|
||||
$this->setUpResponses([
|
||||
new Response(200, [], file_get_contents(__DIR__ . '/Fixtures/ResponseWithFeatures.json') ?: ''),
|
||||
]);
|
||||
$tester = $this->executeCommand([
|
||||
'configurationUid' => '1',
|
||||
], ImportDestinationDataViaConfigruationCommand::class);
|
||||
|
||||
|
||||
$this->assertCSVDataSet('EXT:events/Tests/Functional/Import/DestinationDataTest/Assertions/ImportsFeaturesAddsNewFeatures.csv');
|
||||
self::assertFileEquals(
|
||||
__DIR__ . '/Assertions/EmptyLogFile.txt',
|
||||
$this->getInstancePath() . '/typo3temp/var/log/typo3_0493d91d8e.log',
|
||||
'Logfile was not empty.'
|
||||
);
|
||||
}
|
||||
}
|
51
Tests/Unit/Domain/Model/CategoryTest.php
Normal file
51
Tests/Unit/Domain/Model/CategoryTest.php
Normal file
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Wrm\Events\Tests\Unit\Domain\Model;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Wrm\Events\Domain\Model\Category;
|
||||
|
||||
/**
|
||||
* @covers \Wrm\Events\Domain\Model\Category
|
||||
*/
|
||||
class CategoryTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function canBeCreated(): void
|
||||
{
|
||||
$subject = new Category();
|
||||
|
||||
self::assertInstanceOf(
|
||||
Category::class,
|
||||
$subject
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function returnsSorting(): void
|
||||
{
|
||||
$subject = new Category();
|
||||
$subject->_setProperty('sorting', 10);
|
||||
|
||||
self::assertSame(10, $subject->getSorting());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function canHide(): void
|
||||
{
|
||||
$subject = new Category();
|
||||
|
||||
self::assertFalse($subject->_getProperty('hidden'));
|
||||
|
||||
$subject->hide();
|
||||
self::assertTrue($subject->_getProperty('hidden'));
|
||||
}
|
||||
}
|
|
@ -102,6 +102,30 @@ class DateDemandTest extends TestCase
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function featuresAreSetByRequest(): void
|
||||
{
|
||||
$result = DateDemand::createFromRequestValues(
|
||||
[
|
||||
'features' => [
|
||||
'10', '20',
|
||||
],
|
||||
],
|
||||
[
|
||||
]
|
||||
);
|
||||
|
||||
self::assertSame(
|
||||
[
|
||||
10,
|
||||
20,
|
||||
],
|
||||
$result->getFeatures()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
|
|
63
Tests/Unit/Domain/Model/EventTest.php
Normal file
63
Tests/Unit/Domain/Model/EventTest.php
Normal file
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Wrm\Events\Tests\Unit\Domain\Model;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
|
||||
use Wrm\Events\Domain\Model\Category;
|
||||
use Wrm\Events\Domain\Model\Event;
|
||||
|
||||
/**
|
||||
* @covers \Wrm\Events\Domain\Model\Event
|
||||
*/
|
||||
class EventTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function canBeCreated(): void
|
||||
{
|
||||
$subject = new Event();
|
||||
|
||||
self::assertInstanceOf(
|
||||
Event::class,
|
||||
$subject
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function returnsSortedFeatures(): void
|
||||
{
|
||||
$feature1 = new Category();
|
||||
$feature1->_setProperty('sorting', 10);
|
||||
$feature2 = new Category();
|
||||
$feature2->_setProperty('sorting', 5);
|
||||
|
||||
$storage = new ObjectStorage();
|
||||
$storage->attach($feature1);
|
||||
$storage->attach($feature2);
|
||||
|
||||
$subject = new Event();
|
||||
$subject->setFeatures($storage);
|
||||
|
||||
self::assertSame([
|
||||
$feature2,
|
||||
$feature1,
|
||||
], $subject->getFeatures());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function returnsEmptyFeaturesStorage(): void
|
||||
{
|
||||
$subject = new Event();
|
||||
$subject->setFeatures(new ObjectStorage());
|
||||
|
||||
self::assertSame([], $subject->getFeatures());
|
||||
}
|
||||
}
|
|
@ -9,7 +9,6 @@ use PHPUnit\Framework\TestCase;
|
|||
use Wrm\Events\Domain\Model\Region;
|
||||
use Wrm\Events\Tests\ProphecyTrait;
|
||||
|
||||
|
||||
/**
|
||||
* @covers \Wrm\Events\Domain\Model\Import
|
||||
*/
|
||||
|
@ -89,6 +88,8 @@ class ImportTest extends TestCase
|
|||
'',
|
||||
0,
|
||||
null,
|
||||
0,
|
||||
null,
|
||||
$region->reveal()
|
||||
);
|
||||
|
||||
|
@ -161,6 +162,54 @@ class ImportTest extends TestCase
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function returnsFeaturesPid(): void
|
||||
{
|
||||
$folder = $this->prophesize(Folder::class);
|
||||
|
||||
$subject = new Import(
|
||||
$folder->reveal(),
|
||||
0,
|
||||
'',
|
||||
'',
|
||||
0,
|
||||
null,
|
||||
10
|
||||
);
|
||||
|
||||
self::assertSame(
|
||||
10,
|
||||
$subject->getFeaturesPid()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function returnsFeaturesParent(): void
|
||||
{
|
||||
$feature = $this->prophesize(Category::class);
|
||||
$folder = $this->prophesize(Folder::class);
|
||||
|
||||
$subject = new Import(
|
||||
$folder->reveal(),
|
||||
0,
|
||||
'',
|
||||
'',
|
||||
0,
|
||||
null,
|
||||
0,
|
||||
$feature->reveal()
|
||||
);
|
||||
|
||||
self::assertSame(
|
||||
$feature->reveal(),
|
||||
$subject->getFeaturesParent()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
|
|
|
@ -27,6 +27,7 @@ CREATE TABLE tx_events_domain_model_event (
|
|||
longitude varchar(255) DEFAULT '' NOT NULL,
|
||||
images int(11) unsigned NOT NULL default '0',
|
||||
categories int(11) DEFAULT '0' NOT NULL,
|
||||
features int(11) DEFAULT '0' NOT NULL,
|
||||
pages text,
|
||||
dates int(11) unsigned DEFAULT '0' NOT NULL,
|
||||
organizer int(11) unsigned DEFAULT '0',
|
||||
|
@ -106,6 +107,9 @@ CREATE TABLE tx_events_domain_model_import (
|
|||
categories_pid int(11) unsigned DEFAULT '0' NOT NULL,
|
||||
category_parent int(11) unsigned DEFAULT '0' NOT NULL,
|
||||
|
||||
features_pid int(11) unsigned DEFAULT '0' NOT NULL,
|
||||
features_parent int(11) unsigned DEFAULT '0' NOT NULL,
|
||||
|
||||
region int(11) unsigned DEFAULT '0' NOT NULL,
|
||||
|
||||
rest_experience varchar(1024) DEFAULT '' NOT NULL,
|
||||
|
|
Loading…
Reference in a new issue