Import tourist attraction only in German language

Allows to import entity of type TouristAttraction.
Right now only in German, as this is most important.
Add output of tourist attraction via custom content element.
This commit is contained in:
Daniel Siepmann 2021-02-03 17:20:01 +01:00
parent a3261ab17e
commit 9176ba0cec
49 changed files with 2667 additions and 133 deletions

View file

@ -23,7 +23,7 @@ namespace WerkraumMedia\ThueCat\Domain\Import\Converter;
* 02110-1301, USA.
*/
use WerkraumMedia\ThueCat\Domain\Import\Model\Entity;
use WerkraumMedia\ThueCat\Domain\Import\Model\EntityCollection;
interface Converter
{
@ -33,5 +33,9 @@ interface Converter
*/
public function canConvert(array $type): bool;
public function convert(array $jsonIdOfEntity): Entity;
/**
* A single JSONLD entity can have multiple languages.
* That may result in multiple entities in TYPO3.
*/
public function convert(array $jsonLD): EntityCollection;
}

View file

@ -23,21 +23,38 @@ namespace WerkraumMedia\ThueCat\Domain\Import\Converter;
* 02110-1301, USA.
*/
use TYPO3\CMS\Core\Utility\GeneralUtility;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser;
use WerkraumMedia\ThueCat\Domain\Import\Model\EntityCollection;
use WerkraumMedia\ThueCat\Domain\Import\Model\GenericEntity;
class Organisation implements Converter
{
public function convert(array $jsonIdOfEntity): GenericEntity
private Parser $parser;
public function __construct(
Parser $parser
) {
$this->parser = $parser;
}
public function convert(array $jsonLD): EntityCollection
{
return new GenericEntity(
$entity = GeneralUtility::makeInstance(
GenericEntity::class,
10,
'tx_thuecat_organisation',
$jsonIdOfEntity['@id'],
0,
$this->parser->getId($jsonLD),
[
'title' => $jsonIdOfEntity['schema:name']['@value'],
'description' => $jsonIdOfEntity['schema:description']['@value'],
'title' => $this->parser->getTitle($jsonLD),
'description' => $this->parser->getDescription($jsonLD),
]
);
$entities = GeneralUtility::makeInstance(EntityCollection::class);
$entities->add($entity);
return $entities;
}
public function canConvert(array $type): bool

View file

@ -0,0 +1,86 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Domain\Import\Converter;
/*
* 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\Core\Utility\GeneralUtility;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser;
use WerkraumMedia\ThueCat\Domain\Import\Model\EntityCollection;
use WerkraumMedia\ThueCat\Domain\Import\Model\GenericEntity;
use WerkraumMedia\ThueCat\Domain\Repository\Backend\OrganisationRepository;
use WerkraumMedia\ThueCat\Domain\Repository\Backend\TownRepository;
class TouristAttraction implements Converter
{
private Parser $parser;
private OrganisationRepository $organisationRepository;
private TownRepository $townRepository;
public function __construct(
Parser $parser,
OrganisationRepository $organisationRepository,
TownRepository $townRepository
) {
$this->parser = $parser;
$this->organisationRepository = $organisationRepository;
$this->townRepository = $townRepository;
}
public function convert(array $jsonLD): EntityCollection
{
$storagePid = 10;
$manager = $this->organisationRepository->findOneByRemoteId($this->parser->getManagerId($jsonLD));
$town = $this->townRepository->findOneByRemoteIds($this->parser->getContainedInPlaceIds($jsonLD));
$entities = GeneralUtility::makeInstance(EntityCollection::class);
foreach ($this->parser->getLanguages($jsonLD) as $language) {
if ($language !== 'de') {
continue;
}
$systemLanguageUid = 0;
$entity = GeneralUtility::makeInstance(
GenericEntity::class,
$storagePid,
'tx_thuecat_tourist_attraction',
$systemLanguageUid,
$this->parser->getId($jsonLD),
[
'title' => $this->parser->getTitle($jsonLD, $language),
'description' => $this->parser->getDescription($jsonLD, $language),
'managed_by' => $manager ? $manager->getUid() : 0,
'town' => $town ? $town->getUid() : 0,
'opening_hours' => json_encode($this->parser->getOpeningHours($jsonLD)),
]
);
$entities->add($entity);
}
return $entities;
}
public function canConvert(array $type): bool
{
return array_search('schema:TouristAttraction', $type) !== false;
}
}

View file

@ -23,50 +23,59 @@ namespace WerkraumMedia\ThueCat\Domain\Import\Converter;
* 02110-1301, USA.
*/
use TYPO3\CMS\Core\Utility\GeneralUtility;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser;
use WerkraumMedia\ThueCat\Domain\Import\Model\EntityCollection;
use WerkraumMedia\ThueCat\Domain\Import\Model\GenericEntity;
use WerkraumMedia\ThueCat\Domain\Repository\Backend\OrganisationRepository;
use WerkraumMedia\ThueCat\Domain\Repository\Backend\TownRepository;
class TouristInformation implements Converter
{
private Parser $parser;
private OrganisationRepository $organisationRepository;
private TownRepository $townRepository;
public function __construct(
Parser $parser,
OrganisationRepository $organisationRepository,
TownRepository $townRepository
) {
$this->parser = $parser;
$this->organisationRepository = $organisationRepository;
$this->townRepository = $townRepository;
}
public function convert(array $jsonIdOfEntity): GenericEntity
public function convert(array $jsonLD): EntityCollection
{
$manager = $this->organisationRepository->findOneByRemoteId($jsonIdOfEntity['thuecat:managedBy']['@id']);
$town = $this->townRepository->findOneByRemoteIds($this->getContainedInPlaceIds($jsonIdOfEntity));
$manager = $this->organisationRepository->findOneByRemoteId(
$this->parser->getManagerId($jsonLD)
);
$town = $this->townRepository->findOneByRemoteIds(
$this->parser->getContainedInPlaceIds($jsonLD)
);
return new GenericEntity(
$entity = GeneralUtility::makeInstance(
GenericEntity::class,
10,
'tx_thuecat_tourist_information',
$jsonIdOfEntity['@id'],
0,
$this->parser->getId($jsonLD),
[
'title' => $jsonIdOfEntity['schema:name']['@value'],
'description' => $jsonIdOfEntity['schema:description'][0]['@value'],
'title' => $this->parser->getTitle($jsonLD),
'description' => $this->parser->getDescription($jsonLD),
'managed_by' => $manager ? $manager->getUid() : 0,
'town' => $town ? $town->getUid() : 0,
]
);
$entities = GeneralUtility::makeInstance(EntityCollection::class);
$entities->add($entity);
return $entities;
}
public function canConvert(array $type): bool
{
return array_search('thuecat:TouristInformation', $type) !== false;
}
private function getContainedInPlaceIds(array $jsonIdOfEntity): array
{
return array_map(function (array $place) {
return $place['@id'];
}, $jsonIdOfEntity['schema:containedInPlace']);
}
}

View file

@ -23,32 +23,47 @@ namespace WerkraumMedia\ThueCat\Domain\Import\Converter;
* 02110-1301, USA.
*/
use TYPO3\CMS\Core\Utility\GeneralUtility;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser;
use WerkraumMedia\ThueCat\Domain\Import\Model\EntityCollection;
use WerkraumMedia\ThueCat\Domain\Import\Model\GenericEntity;
use WerkraumMedia\ThueCat\Domain\Repository\Backend\OrganisationRepository;
class Town implements Converter
{
private Parser $parser;
private OrganisationRepository $organisationRepository;
public function __construct(
Parser $parser,
OrganisationRepository $organisationRepository
) {
$this->parser = $parser;
$this->organisationRepository = $organisationRepository;
}
public function convert(array $jsonIdOfEntity): GenericEntity
public function convert(array $jsonLD): EntityCollection
{
$manager = $this->organisationRepository->findOneByRemoteId($jsonIdOfEntity['thuecat:managedBy']['@id']);
return new GenericEntity(
$manager = $this->organisationRepository->findOneByRemoteId(
$this->parser->getManagerId($jsonLD)
);
$entity = GeneralUtility::makeInstance(
GenericEntity::class,
10,
'tx_thuecat_town',
$jsonIdOfEntity['@id'],
0,
$this->parser->getId($jsonLD),
[
'title' => $jsonIdOfEntity['schema:name']['@value'],
'description' => $jsonIdOfEntity['schema:description']['@value'] ?? '',
'title' => $this->parser->getTitle($jsonLD),
'description' => $this->parser->getDescription($jsonLD),
'managed_by' => $manager ? $manager->getUid() : 0,
]
);
$entities = GeneralUtility::makeInstance(EntityCollection::class);
$entities->add($entity);
return $entities;
}
public function canConvert(array $type): bool

View file

@ -26,6 +26,7 @@ namespace WerkraumMedia\ThueCat\Domain\Import\Importer;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\DataHandling\DataHandler;
use WerkraumMedia\ThueCat\Domain\Import\Model\Entity;
use WerkraumMedia\ThueCat\Domain\Import\Model\EntityCollection;
use WerkraumMedia\ThueCat\Domain\Model\Backend\ImportLog;
use WerkraumMedia\ThueCat\Domain\Model\Backend\ImportLogEntry;
@ -33,6 +34,7 @@ class SaveData
{
private DataHandler $dataHandler;
private ConnectionPool $connectionPool;
private array $errorLog;
public function __construct(
DataHandler $dataHandler,
@ -42,31 +44,50 @@ class SaveData
$this->connectionPool = $connectionPool;
}
public function import(Entity $entity, ImportLog $log): void
public function import(EntityCollection $entityCollection, ImportLog $log): void
{
$dataHandler = clone $this->dataHandler;
$this->errorLog = [];
$identifier = $this->getIdentifier($entity);
$dataHandler->start([
$entity->getTypo3DatabaseTableName() => [
$identifier => array_merge($entity->getData(), [
'pid' => $entity->getTypo3StoragePid(),
'remote_id' => $entity->getRemoteId(),
]),
],
], []);
$dataHandler->process_datamap();
$this->processSimpleDataHandlerDataMap($entityCollection);
// TODO: Insert update / insert of localization
if (isset($dataHandler->substNEWwithIDs[$identifier])) {
$entity->setImportedTypo3Uid($dataHandler->substNEWwithIDs[$identifier]);
} elseif (is_numeric($identifier)) {
$entity->setExistingTypo3Uid((int) $identifier);
foreach ($entityCollection->getEntities() as $entity) {
$log->addEntry(new ImportLogEntry($entity, $this->errorLog));
}
}
private function processSimpleDataHandlerDataMap(EntityCollection $collection): void
{
$dataArray = [];
$identifierMapping = [];
foreach ($collection->getEntities() as $entity) {
$identifier = $this->getIdentifier($entity);
if (strpos($identifier, 'NEW') === 0 && $entity->isTranslation()) {
continue;
}
if (is_numeric($identifier)) {
$entity->setExistingTypo3Uid((int) $identifier);
} else {
$identifierMapping[spl_object_id($entity)] = $identifier;
}
$dataArray[$entity->getTypo3DatabaseTableName()][$identifier] = $this->getEntityData($entity);
}
$log->addEntry(new ImportLogEntry(
$entity,
$dataHandler->errorLog
));
$dataHandler = clone $this->dataHandler;
$dataHandler->start($dataArray, []);
$dataHandler->process_datamap();
$this->errorLog = array_merge($this->errorLog, $dataHandler->errorLog);
foreach ($collection->getEntities() as $entity) {
if (
isset($identifierMapping[spl_object_id($entity)])
&& isset($dataHandler->substNEWwithIDs[$identifierMapping[spl_object_id($entity)]])
) {
$entity->setImportedTypo3Uid($dataHandler->substNEWwithIDs[$identifierMapping[spl_object_id($entity)]]);
}
}
}
private function getIdentifier(Entity $entity): string
@ -77,7 +98,17 @@ class SaveData
return (string) $existingUid;
}
return 'NEW_1';
$identifier = 'NEW_' . sha1($entity->getRemoteId() . $entity->getTypo3SystemLanguageUid());
// Ensure new ID is max 30, as this is max volumn of the sys_log column
return substr($identifier, 0, 30);
}
private function getEntityData(Entity $entity): array
{
return array_merge($entity->getData(), [
'pid' => $entity->getTypo3StoragePid(),
'remote_id' => $entity->getRemoteId(),
]);
}
private function getExistingUid(Entity $entity): int

View file

@ -0,0 +1,140 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Domain\Import\JsonLD;
/*
* 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 WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\OpeningHours;
class Parser
{
private OpeningHours $openingHours;
public function __construct(
OpeningHours $openingHours
) {
$this->openingHours = $openingHours;
}
public function getId(array $jsonLD): string
{
return $jsonLD['@id'];
}
public function getTitle(array $jsonLD, string $language = ''): string
{
return $this->getValueForLanguage($jsonLD['schema:name'], $language);
}
public function getDescription(array $jsonLD, string $language = ''): string
{
return $this->getValueForLanguage($jsonLD['schema:description'], $language);
}
public function getManagerId(array $jsonLD): string
{
return $jsonLD['thuecat:contentResponsible']['@id'];
}
/**
* @return string[]
*/
public function getContainedInPlaceIds(array $jsonLD): array
{
return array_map(function (array $place) {
return $place['@id'];
}, $jsonLD['schema:containedInPlace']);
}
public function getOpeningHours(array $jsonLD): array
{
return $this->openingHours->get($jsonLD);
}
/**
* @return string[]
*/
public function getLanguages(array $jsonLD): array
{
if (isset($jsonLD['schema:availableLanguage']) === false) {
return [];
}
$languages = $jsonLD['schema:availableLanguage'];
$languages = array_filter($languages, function (array $language) {
return isset($language['@type'])
&& $language['@type'] === 'thuecat:Language'
;
});
$languages = array_map(function (array $language) {
$language = $language['@value'];
if ($language === 'thuecat:German') {
return 'de';
}
if ($language === 'thuecat:English') {
return 'en';
}
if ($language === 'thuecat:French') {
return 'fr';
}
throw new \Exception('Unsupported language "' . $language . '".', 1612367481);
}, $languages);
return $languages;
}
private function getValueForLanguage(
array $property,
string $language
): string {
if (
$this->doesLanguageMatch($property, $language)
&& isset($property['@value'])
) {
return $property['@value'];
}
foreach ($property as $languageEntry) {
if (
is_array($languageEntry)
&& $this->doesLanguageMatch($languageEntry, $language)
) {
return $languageEntry['@value'];
}
}
return '';
}
private function doesLanguageMatch(array $property, string $language): bool
{
return isset($property['@language'])
&& (
$property['@language'] === $language
|| $language === ''
)
;
}
}

View file

@ -0,0 +1,102 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser;
/*
* 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.
*/
class OpeningHours
{
public function get(array $jsonLD): array
{
$openingHours = $jsonLD['schema:openingHoursSpecification'] ?? [];
if ($openingHours === []) {
return [];
}
if (isset($openingHours['@id'])) {
return [$this->parseSingleEntry($openingHours)];
}
return array_values(array_map([$this, 'parseSingleEntry'], $openingHours));
}
private function parseSingleEntry(array $openingHour): array
{
return [
'opens' => $this->getOpens($openingHour),
'closes' => $this->getCloses($openingHour),
'from' => $this->getFrom($openingHour),
'through' => $this->getThrough($openingHour),
'daysOfWeek' => $this->getDaysOfWeek($openingHour),
];
}
private function getOpens(array $openingHour): string
{
return $openingHour['schema:opens']['@value'] ?? '';
}
private function getCloses(array $openingHour): string
{
return $openingHour['schema:closes']['@value'] ?? '';
}
private function getFrom(array $openingHour): ?\DateTimeImmutable
{
if (isset($openingHour['schema:validFrom']['@value'])) {
return new \DateTimeImmutable($openingHour['schema:validFrom']['@value']);
}
return null;
}
private function getThrough(array $openingHour): ?\DateTimeImmutable
{
if (isset($openingHour['schema:validThrough']['@value'])) {
return new \DateTimeImmutable($openingHour['schema:validThrough']['@value']);
}
return null;
}
private function getDaysOfWeek(array $openingHour): array
{
if (isset($openingHour['schema:dayOfWeek']['@value'])) {
return [$this->getDayOfWeekString($openingHour['schema:dayOfWeek']['@value'])];
}
$daysOfWeek = array_map(function ($dayOfWeek) {
return $this->getDayOfWeekString($dayOfWeek['@value']);
}, $openingHour['schema:dayOfWeek'] ?? []);
sort($daysOfWeek);
return $daysOfWeek;
}
private function getDayOfWeekString(string $jsonLDValue): string
{
return str_replace(
'schema:',
'',
$jsonLDValue
);
}
}

View file

@ -29,6 +29,12 @@ interface Entity
public function getTypo3DatabaseTableName(): string;
public function getTypo3SystemLanguageUid(): int;
public function isForDefaultLanguage(): bool;
public function isTranslation(): bool;
/**
* Return full remote id as delivered by remote API.
*/

View file

@ -0,0 +1,66 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Domain\Import\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.
*/
class EntityCollection
{
/**
* @var Entity[]
*/
private array $entities = [];
public function add(Entity $entity): void
{
$this->entities[] = $entity;
}
/**
* @return Entity[]
*/
public function getEntities(): array
{
return $this->entities;
}
public function getDefaultLanguageEntity(): ?Entity
{
foreach ($this->entities as $entity) {
if ($entity->isForDefaultLanguage()) {
return $entity;
}
}
return null;
}
/**
* @return Entity[]
*/
public function getTranslatedEntities(): array
{
return array_filter($this->entities, function (Entity $entity) {
return $entity->isTranslation();
});
}
}

View file

@ -27,6 +27,7 @@ class GenericEntity implements Entity
{
private int $typo3StoragePid;
private string $typo3DatabaseTableName;
private int $typo3SystemLanguageUid;
private bool $created = false;
private int $typo3Uid = 0;
private string $remoteId;
@ -35,11 +36,13 @@ class GenericEntity implements Entity
public function __construct(
int $typo3StoragePid,
string $typo3DatabaseTableName,
int $typo3SystemLanguageUid,
string $remoteId,
array $data
) {
$this->typo3StoragePid = $typo3StoragePid;
$this->typo3DatabaseTableName = $typo3DatabaseTableName;
$this->typo3SystemLanguageUid = $typo3SystemLanguageUid;
$this->remoteId = $remoteId;
$this->data = $data;
}
@ -54,6 +57,21 @@ class GenericEntity implements Entity
return $this->typo3DatabaseTableName;
}
public function getTypo3SystemLanguageUid(): int
{
return $this->typo3SystemLanguageUid;
}
public function isForDefaultLanguage(): bool
{
return $this->getTypo3SystemLanguageUid() === 0;
}
public function isTranslation(): bool
{
return $this->getTypo3SystemLanguageUid() !== 0;
}
public function getRemoteId(): string
{
return $this->remoteId;

View file

@ -80,6 +80,7 @@ class ImportLog extends Typo3AbstractEntity
foreach ($this->getEntries() as $entry) {
if ($entry->hasErrors()) {
$errors = array_merge($errors, $entry->getErrors());
$errors = array_unique($errors);
}
}

View file

@ -85,6 +85,7 @@ class ImportLogEntry extends Typo3AbstractEntity
{
if ($this->errorsAsArray === [] && $this->errors !== '') {
$this->errorsAsArray = json_decode($this->errors, true);
$this->errorsAsArray = array_unique($this->errorsAsArray);
}
return $this->errorsAsArray;

View file

@ -0,0 +1,127 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Domain\Model\Frontend;
/*
* 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.
*/
class OpeningHour
{
private string $opens;
private string $closes;
private array $daysOfWeek;
private ?\DateTimeImmutable $from;
private ?\DateTimeImmutable $through;
private function __construct(
string $opens,
string $closes,
array $daysOfWeek,
?\DateTimeImmutable $from,
?\DateTimeImmutable $through
) {
$this->opens = $opens;
$this->closes = $closes;
$this->daysOfWeek = $daysOfWeek;
$this->from = $from;
$this->through = $through;
}
public static function createFromArray(array $rawData): self
{
$from = null;
if (isset($rawData['from'])) {
$timeZone = new \DateTimeZone($rawData['from']['timezone']);
$from = new \DateTimeImmutable($rawData['from']['date'], $timeZone);
}
$through = null;
if (isset($rawData['through'])) {
$timeZone = new \DateTimeZone($rawData['through']['timezone']);
$through = new \DateTimeImmutable($rawData['through']['date'], $timeZone);
}
return new self(
$rawData['opens'] ?? '',
$rawData['closes'] ?? '',
$rawData['daysOfWeek'] ?? '',
$from,
$through
);
}
public function getOpens(): string
{
return $this->opens;
}
public function getCloses(): string
{
return $this->closes;
}
public function getDaysOfWeek(): array
{
return $this->daysOfWeek;
}
public function getDaysOfWeekWithMondayFirstWeekDay(): array
{
return $this->sortedDaysOfWeek([
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday',
'Sunday',
]);
}
public function getFrom(): ?\DateTimeImmutable
{
return $this->from;
}
public function getThrough(): ?\DateTimeImmutable
{
return $this->through;
}
private function sortedDaysOfWeek(array $sorting): array
{
if ($this->daysOfWeek === []) {
return [];
}
$days = [];
foreach ($sorting as $weekDay) {
$position = array_search($weekDay, $this->daysOfWeek);
if ($position === false) {
continue;
}
$days[] = $this->daysOfWeek[$position];
}
return $days;
}
}

View file

@ -0,0 +1,75 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Domain\Model\Frontend;
/*
* 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\Core\Type\TypeInterface;
/**
* @implements \Iterator<int, OpeningHour>
*/
class OpeningHours implements TypeInterface, \Iterator
{
private string $serialized = '';
private array $array = [];
private int $position = 0;
public function __construct(string $serialized)
{
$this->serialized = $serialized;
$this->array = array_map(
[OpeningHour::class, 'createFromArray'],
json_decode($serialized, true)
);
}
public function __toString(): string
{
return $this->serialized;
}
public function current(): OpeningHour
{
return $this->array[$this->position];
}
public function next(): void
{
++$this->position;
}
public function key(): int
{
return $this->position;
}
public function valid(): bool
{
return isset($this->array[$this->position]);
}
public function rewind(): void
{
$this->position = 0;
}
}

View file

@ -0,0 +1,54 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Domain\Model\Frontend;
/*
* 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\DomainObject\AbstractEntity;
class TouristAttraction extends AbstractEntity
{
protected string $title = '';
protected string $description = '';
protected ?OpeningHours $openingHours = null;
protected ?Town $town = null;
public function getTitle(): string
{
return $this->title;
}
public function getDescription(): string
{
return $this->description;
}
public function getOpeningHours(): ?OpeningHours
{
return $this->openingHours;
}
public function getTown(): ?Town
{
return $this->town;
}
}

View file

@ -0,0 +1,42 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Domain\Model\Frontend;
/*
* 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\DomainObject\AbstractEntity;
class Town extends AbstractEntity
{
protected string $title = '';
protected string $description = '';
public function getTitle(): string
{
return $this->title;
}
public function getDescription(): string
{
return $this->description;
}
}

View file

@ -23,6 +23,7 @@ namespace WerkraumMedia\ThueCat;
* 02110-1301, USA.
*/
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Extbase\Utility\ExtensionUtility;
use WerkraumMedia\ThueCat\Controller\Backend\ImportController;
use WerkraumMedia\ThueCat\Controller\Backend\OverviewController;
@ -33,6 +34,8 @@ class Extension
public const EXTENSION_NAME = 'Thuecat';
public const TT_CONTENT_GROUP = 'thuecat';
public static function getLanguagePath(): string
{
return 'LLL:EXT:' . self::EXTENSION_KEY . '/Resources/Private/Language/';
@ -56,4 +59,26 @@ class Extension
]
);
}
public static function registerConfig(): void
{
$languagePath = self::getLanguagePath() . 'locallang_tca.xlf:tt_content';
// TODO: Add Icon
ExtensionManagementUtility::addPageTSConfig('
mod.wizards.newContentElement.wizardItems.thuecat {
header = ' . $languagePath . '.group
show = *
elements {
thuecat_tourist_attraction{
title = ' . $languagePath . '.thuecat_tourist_attraction
description = ' . $languagePath . '.thuecat_tourist_attraction.description
tt_content_defValues {
CType = thuecat_tourist_attraction
}
}
}
}
');
}
}

View file

@ -0,0 +1,85 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Frontend\DataProcessing;
/*
* 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\Core\Database\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface;
class ResolveEntities implements DataProcessorInterface
{
private ConnectionPool $connectionPool;
private DataMapper $dataMapper;
public function __construct(
ConnectionPool $connectionPool,
DataMapper $dataMapper
) {
$this->connectionPool = $connectionPool;
$this->dataMapper = $dataMapper;
}
public function process(
ContentObjectRenderer $cObj,
array $contentObjectConfiguration,
array $processorConfiguration,
array $processedData
) {
$as = $cObj->stdWrapValue('as', $processorConfiguration, 'entities');
$table = $cObj->stdWrapValue('table', $processorConfiguration, '');
$uids = $cObj->stdWrapValue('uids', $processorConfiguration, '');
$uids = GeneralUtility::intExplode(',', $uids);
if ($uids === [] || $table === '') {
return $processedData;
}
$processedData[$as] = $this->resolveEntities($table, $uids);
return $processedData;
}
private function resolveEntities(string $table, array $uids): array
{
$targetType = '\WerkraumMedia\ThueCat\Domain\Model\Frontend\\' . $this->convertTableToEntity($table);
$queryBuilder = $this->connectionPool->getQueryBuilderForTable($table);
$queryBuilder->select('*');
$queryBuilder->from($table);
$queryBuilder->where($queryBuilder->expr()->in(
'uid',
$queryBuilder->createNamedParameter($uids, Connection::PARAM_INT_ARRAY)
));
return $this->dataMapper->map($targetType, $queryBuilder->execute()->fetchAll());
}
private function convertTableToEntity(string $table): string
{
$entityPart = str_replace('tx_thuecat_', '', $table);
return GeneralUtility::underscoredToUpperCamelCase($entityPart);
}
}

View file

@ -19,4 +19,10 @@ return [
\WerkraumMedia\ThueCat\Domain\Model\Backend\ImportLogEntry::class => [
'tableName' => 'tx_thuecat_import_log_entry',
],
\WerkraumMedia\ThueCat\Domain\Model\Frontend\TouristAttraction::class => [
'tableName' => 'tx_thuecat_tourist_attraction',
],
\WerkraumMedia\ThueCat\Domain\Model\Frontend\Town::class => [
'tableName' => 'tx_thuecat_town',
],
];

View file

@ -10,3 +10,7 @@ services:
WerkraumMedia\ThueCat\Domain\Import\Importer\FetchData:
arguments:
$requestFactory: '@WerkraumMedia\ThueCat\Domain\Import\RequestFactory'
WerkraumMedia\ThueCat\Frontend\DataProcessing\:
resource: '../Classes/Frontend/DataProcessing/*'
public: true

View file

@ -3,7 +3,7 @@
defined('TYPO3') or die();
(static function (string $extensionKey, string $tableName) {
$languagePath = 'LLL:EXT:' . $extensionKey . '/Resources/Private/Language/locallang_be.xlf:' . $tableName . '.';
$languagePath = \WerkraumMedia\ThueCat\Extension::getLanguagePath() . 'locallang_be.xlf:' . $tableName . '.';
\TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($GLOBALS['SiteConfiguration']['site'], [
'columns' => [

View file

@ -0,0 +1,14 @@
<?php
defined('TYPO3') or die();
(static function (string $extensionKey, string $tableName) {
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile(
$extensionKey,
'Configuration/TypoScript/',
'ThüCAT'
);
})(
\WerkraumMedia\ThueCat\Extension::EXTENSION_KEY,
'sys_template'
);

View file

@ -0,0 +1,18 @@
<?php
defined('TYPO3') or die();
(static function (string $extensionKey, string $tableName) {
$languagePath = \WerkraumMedia\ThueCat\Extension::getLanguagePath()
. 'locallang_tca.xlf:' . $tableName;
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTcaSelectItemGroup(
$tableName,
'CType',
\WerkraumMedia\ThueCat\Extension::TT_CONTENT_GROUP,
$languagePath . '.group'
);
})(
\WerkraumMedia\ThueCat\Extension::EXTENSION_KEY,
'tt_content'
);

View file

@ -0,0 +1,63 @@
<?php
defined('TYPO3') or die();
(static function (string $extensionKey, string $tableName, string $cType) {
$languagePath = \WerkraumMedia\ThueCat\Extension::getLanguagePath()
. 'locallang_tca.xlf:' . $tableName . '.' . $cType;
\TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($GLOBALS['TCA'][$tableName], [
'ctrl' => [
// TODO: Add Icon
// 'typeicon_classes' => [
// $cType => '',
// ],
],
'types' => [
$cType => [
'showitem' =>
'--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general,'
. '--palette--;;general,'
. '--palette--;;headers,'
. 'records,'
. '--div--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.appearance,'
. '--palette--;;frames,'
. '--palette--;;appearanceLinks,'
. '--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:language,'
. '--palette--;;language,'
. '--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:access,'
. '--palette--;;hidden,'
. '--palette--;;access,'
. '--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:categories,'
. '--div--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_category.tabs.category,'
. 'categories,'
. '--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:notes,'
. 'rowDescription,'
. '--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:extended',
'columnsOverrides' => [
'records' => [
'config' => [
'allowed' => 'tx_thuecat_tourist_attraction',
],
],
],
],
],
]);
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTcaSelectItem(
$tableName,
'CType',
[
$languagePath,
$cType,
// TODO: Add Icon
'',
\WerkraumMedia\ThueCat\Extension::TT_CONTENT_GROUP,
]
);
})(
\WerkraumMedia\ThueCat\Extension::EXTENSION_KEY,
'tt_content',
'thuecat_tourist_attraction'
);

View file

@ -0,0 +1,89 @@
<?php
defined('TYPO3') or die();
return (static function (string $extensionKey, string $tableName) {
$languagePath = \WerkraumMedia\ThueCat\Extension::getLanguagePath() . 'locallang_tca.xlf:' . $tableName;
return [
'ctrl' => [
'label' => 'title',
'default_sortby' => 'title',
'tstamp' => 'tstamp',
'crdate' => 'crdate',
'cruser_id' => 'cruser_id',
'title' => $languagePath,
'enablecolumns' => [
'disabled' => 'disable',
],
'searchFields' => 'title, description',
],
'columns' => [
'title' => [
'label' => $languagePath . '.title',
'config' => [
'type' => 'input',
'size' => 20,
'max' => 255,
'readOnly' => true,
],
],
'description' => [
'label' => $languagePath . '.description',
'config' => [
'type' => 'text',
'readOnly' => true,
],
],
'opening_hours' => [
'label' => $languagePath . '.opening_hours',
'config' => [
'type' => 'text',
'readOnly' => true,
],
],
'remote_id' => [
'label' => $languagePath . '.remote_id',
'config' => [
'type' => 'input',
'readOnly' => true,
],
],
'town' => [
'label' => $languagePath . '.town',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'foreign_table' => 'tx_thuecat_town',
'items' => [
[
$languagePath . '.town.unkown',
0,
],
],
'readOnly' => true,
],
],
'managed_by' => [
'label' => $languagePath . '.managed_by',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'foreign_table' => 'tx_thuecat_organisation',
'items' => [
[
$languagePath . '.managed_by.unkown',
0,
],
],
'readOnly' => true,
],
],
],
'types' => [
'0' => [
'showitem' => 'title, description, opening_hours, remote_id, town, managed_by',
],
],
];
})(\WerkraumMedia\ThueCat\Extension::EXTENSION_KEY, 'tx_thuecat_tourist_attraction');

View file

@ -0,0 +1,6 @@
lib.thuecatContentElement =< lib.contentElement
lib.thuecatContentElement {
templateRootPaths {
9999 = EXT:thuecat/Resources/Private/Templates/Frontend/ContentElement/
}
}

View file

@ -0,0 +1,13 @@
tt_content {
thuecat_tourist_attraction =< lib.thuecatContentElement
thuecat_tourist_attraction {
templateName = TouristAttraction
dataProcessing {
10 = WerkraumMedia\ThueCat\Frontend\DataProcessing\ResolveEntities
10 {
table = tx_thuecat_tourist_attraction
uids.data = field:records
}
}
}
}

View file

@ -0,0 +1,6 @@
lib.thuecatContentElement =< lib.contentElement
lib.thuecatContentElement {
templateRootPaths {
9999 = EXT:thuecat/Resources/Private/Templates/Frontend/ContentElement/
}
}

View file

@ -0,0 +1 @@
@import 'EXT:thuecat/Configuration/TypoScript/Rendering/*.typoscript'

View file

@ -20,6 +20,8 @@ The extension already allows:
* Tourist information
* Tourist attraction
* Backend module:
* To inspect current existing organisations
@ -36,8 +38,6 @@ The extension already allows:
* Integrate proper icons
* Import of tourist attraction
* Content element to display tourist attraction,
town, tourist information and organisation.

View file

@ -90,6 +90,9 @@
<trans-unit id="module.imports.summary.tableName.tx_thuecat_tourist_information" xml:space="preserve">
<source>Tourist Information</source>
</trans-unit>
<trans-unit id="module.imports.summary.tableName.tx_thuecat_tourist_attraction" xml:space="preserve">
<source>Tourist Attraction</source>
</trans-unit>
<trans-unit id="controller.backend.import.import.success.title" xml:space="preserve">
<source>Import finished</source>

View file

@ -72,6 +72,31 @@
<source>Unkown</source>
</trans-unit>
<trans-unit id="tx_thuecat_tourist_attraction" xml:space="preserve">
<source>Tourist Attraction</source>
</trans-unit>
<trans-unit id="tx_thuecat_tourist_attraction.title" xml:space="preserve">
<source>Title</source>
</trans-unit>
<trans-unit id="tx_thuecat_tourist_attraction.description" xml:space="preserve">
<source>Description</source>
</trans-unit>
<trans-unit id="tx_thuecat_tourist_attraction.remote_id" xml:space="preserve">
<source>Remote ID</source>
</trans-unit>
<trans-unit id="tx_thuecat_tourist_attraction.town" xml:space="preserve">
<source>Town</source>
</trans-unit>
<trans-unit id="tx_thuecat_tourist_attraction.town.unkown" xml:space="preserve">
<source>Unkown</source>
</trans-unit>
<trans-unit id="tx_thuecat_tourist_attraction.managed_by" xml:space="preserve">
<source>Managed by</source>
</trans-unit>
<trans-unit id="tx_thuecat_tourist_attraction.managed_by.unkown" xml:space="preserve">
<source>Unkown</source>
</trans-unit>
<trans-unit id="tx_thuecat_import_configuration" xml:space="preserve">
<source>Import Configuration</source>
</trans-unit>
@ -128,6 +153,16 @@
<trans-unit id="tx_thuecat_import_log_entry.crdate" xml:space="preserve">
<source>Created</source>
</trans-unit>
<trans-unit id="tt_content.group" xml:space="preserve">
<source>ThüCAT</source>
</trans-unit>
<trans-unit id="tt_content.thuecat_tourist_attraction" xml:space="preserve">
<source>Tourist Attraction</source>
</trans-unit>
<trans-unit id="tt_content.thuecat_tourist_attraction.description" xml:space="preserve">
<source>Renders selected tourist attractions</source>
</trans-unit>
</body>
</file>
</xliff>

View file

@ -0,0 +1,21 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
data-namespace-typo3-fluid="true">
<f:for each="{entities}" as="entity">
<div class="card" style="width: 18rem;">
<div class="card-body">
<h5 class="card-title">{entity.title} ({entity.town.title})</h5>
<p class="card-text">{entity.description}</p>
<f:for each="{entity.openingHours}" as="openingHour">
<p>
<f:for each="{openingHour.daysOfWeekWithMondayFirstWeekDay}" as="weekday">
{weekday}: {openingHour.opens} - {openingHour.closes}<br>
</f:for>
{openingHour.from -> f:format.date(format: 'd.m.Y')} -
{openingHour.through -> f:format.date(format: 'd.m.Y')}
</p>
</f:for>
</div>
</div>
</f:for>
</html>

View file

@ -24,21 +24,28 @@ namespace WerkraumMedia\ThueCat\Tests\Unit\Domain\Import\Converter;
*/
use PHPUnit\Framework\TestCase;
use Prophecy\PhpUnit\ProphecyTrait;
use WerkraumMedia\ThueCat\Domain\Import\Converter\Converter;
use WerkraumMedia\ThueCat\Domain\Import\Converter\Organisation;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser;
use WerkraumMedia\ThueCat\Domain\Import\Model\EntityCollection;
/**
* @covers WerkraumMedia\ThueCat\Domain\Import\Converter\Organisation
* @uses WerkraumMedia\ThueCat\Domain\Import\Model\EntityCollection
* @uses WerkraumMedia\ThueCat\Domain\Import\Model\GenericEntity
*/
class OrganisationTest extends TestCase
{
use ProphecyTrait;
/**
* @test
*/
public function instanceCanBeCreated(): void
{
$subject = new Organisation();
$parser = $this->prophesize(Parser::class);
$subject = new Organisation($parser->reveal());
self::assertInstanceOf(Organisation::class, $subject);
}
@ -47,7 +54,8 @@ class OrganisationTest extends TestCase
*/
public function isInstanceOfConverter(): void
{
$subject = new Organisation();
$parser = $this->prophesize(Parser::class);
$subject = new Organisation($parser->reveal());
self::assertInstanceOf(Converter::class, $subject);
}
@ -56,7 +64,8 @@ class OrganisationTest extends TestCase
*/
public function canConvertTouristMarketingCompany(): void
{
$subject = new Organisation();
$parser = $this->prophesize(Parser::class);
$subject = new Organisation($parser->reveal());
self::assertTrue($subject->canConvert([
'thuecat:TouristMarketingCompany',
'schema:Thing',
@ -69,8 +78,7 @@ class OrganisationTest extends TestCase
*/
public function convertsJsonIdToGenericEntity(): void
{
$subject = new Organisation();
$entity = $subject->convert([
$jsonLD = [
'@id' => 'https://example.com/resources/018132452787-ngbe',
'schema:name' => [
'@value' => 'Title',
@ -78,8 +86,20 @@ class OrganisationTest extends TestCase
'schema:description' => [
'@value' => 'Description',
],
]);
];
$parser = $this->prophesize(Parser::class);
$parser->getId($jsonLD)->willReturn('https://example.com/resources/018132452787-ngbe');
$parser->getTitle($jsonLD)->willReturn('Title');
$parser->getDescription($jsonLD)->willReturn('Description');
$subject = new Organisation($parser->reveal());
$entities = $subject->convert($jsonLD);
self::assertInstanceOf(EntityCollection::class, $entities);
self::assertCount(1, $entities->getEntities());
$entity = $entities->getEntities()[0];
self::assertSame(10, $entity->getTypo3StoragePid());
self::assertSame('tx_thuecat_organisation', $entity->getTypo3DatabaseTableName());
self::assertSame('https://example.com/resources/018132452787-ngbe', $entity->getRemoteId());

View file

@ -0,0 +1,224 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Tests\Unit\Domain\Import\Converter;
/*
* 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 PHPUnit\Framework\TestCase;
use Prophecy\PhpUnit\ProphecyTrait;
use WerkraumMedia\ThueCat\Domain\Import\Converter\TouristAttraction;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser;
use WerkraumMedia\ThueCat\Domain\Import\Model\EntityCollection;
use WerkraumMedia\ThueCat\Domain\Model\Backend\Organisation;
use WerkraumMedia\ThueCat\Domain\Model\Backend\Town;
use WerkraumMedia\ThueCat\Domain\Repository\Backend\OrganisationRepository;
use WerkraumMedia\ThueCat\Domain\Repository\Backend\TownRepository;
/**
* @covers WerkraumMedia\ThueCat\Domain\Import\Converter\TouristAttraction
* @uses WerkraumMedia\ThueCat\Domain\Import\Model\EntityCollection
* @uses WerkraumMedia\ThueCat\Domain\Import\Model\GenericEntity
*/
class TouristAttractionTest extends TestCase
{
use ProphecyTrait;
/**
* @test
*/
public function canBeCreated(): void
{
$parser = $this->prophesize(Parser::class);
$organisationRepository = $this->prophesize(OrganisationRepository::class);
$townRepository = $this->prophesize(TownRepository::class);
$subject = new TouristAttraction(
$parser->reveal(),
$organisationRepository->reveal(),
$townRepository->reveal()
);
self::assertInstanceOf(TouristAttraction::class, $subject);
}
/**
* @test
*/
public function canConvert(): void
{
$parser = $this->prophesize(Parser::class);
$organisationRepository = $this->prophesize(OrganisationRepository::class);
$townRepository = $this->prophesize(TownRepository::class);
$subject = new TouristAttraction(
$parser->reveal(),
$organisationRepository->reveal(),
$townRepository->reveal()
);
self::assertTrue($subject->canConvert(['schema:TouristAttraction']));
}
/**
* @test
*/
public function convertsWithoutRelations(): void
{
$jsonLD = [
'@id' => 'https://example.com/resources/018132452787-ngbe',
'thuecat:managedBy' => [
'@id' => 'https://example.com/resources/018132452787-xxxx',
],
'schema:containedInPlace' => [
[
'@id' => 'https://example.com/resources/043064193523-jcyt',
],
[
'@id' => 'https://example.com/resources/573211638937-gmqb',
],
],
'schema:name' => [
'@value' => 'Title',
],
'schema:description' => [
[
'@value' => 'Description',
],
],
];
$parser = $this->prophesize(Parser::class);
$parser->getManagerId($jsonLD)->willReturn('https://example.com/resources/018132452787-xxxx');
$parser->getContainedInPlaceIds($jsonLD)->willReturn([
'https://example.com/resources/043064193523-jcyt',
'https://example.com/resources/573211638937-gmqb',
]);
$parser->getLanguages($jsonLD)->willReturn(['de']);
$parser->getId($jsonLD)->willReturn('https://example.com/resources/018132452787-ngbe');
$parser->getTitle($jsonLD, 'de')->willReturn('Title');
$parser->getDescription($jsonLD, 'de')->willReturn('Description');
$parser->getOpeningHours($jsonLD)->willReturn([]);
$organisationRepository = $this->prophesize(OrganisationRepository::class);
$townRepository = $this->prophesize(TownRepository::class);
$subject = new TouristAttraction(
$parser->reveal(),
$organisationRepository->reveal(),
$townRepository->reveal()
);
$entities = $subject->convert($jsonLD);
self::assertInstanceOf(EntityCollection::class, $entities);
self::assertCount(1, $entities->getEntities());
$entity = $entities->getEntities()[0];
self::assertSame(10, $entity->getTypo3StoragePid());
self::assertSame('tx_thuecat_tourist_attraction', $entity->getTypo3DatabaseTableName());
self::assertSame('https://example.com/resources/018132452787-ngbe', $entity->getRemoteId());
self::assertSame([
'title' => 'Title',
'description' => 'Description',
'managed_by' => 0,
'town' => 0,
'opening_hours' => '[]',
], $entity->getData());
}
/**
* @test
*/
public function convertsWithRelations(): void
{
$jsonLD = [
'@id' => 'https://example.com/resources/018132452787-ngbe',
'thuecat:managedBy' => [
'@id' => 'https://example.com/resources/018132452787-xxxx',
],
'schema:containedInPlace' => [
[
'@id' => 'https://example.com/resources/043064193523-jcyt',
],
[
'@id' => 'https://example.com/resources/573211638937-gmqb',
],
],
'schema:name' => [
'@value' => 'Title',
],
'schema:description' => [
[
'@value' => 'Description',
],
],
];
$parser = $this->prophesize(Parser::class);
$parser->getManagerId($jsonLD)->willReturn('https://example.com/resources/018132452787-xxxx');
$parser->getContainedInPlaceIds($jsonLD)->willReturn([
'https://example.com/resources/043064193523-jcyt',
'https://example.com/resources/573211638937-gmqb',
]);
$parser->getLanguages($jsonLD)->willReturn(['de']);
$parser->getId($jsonLD)->willReturn('https://example.com/resources/018132452787-ngbe');
$parser->getTitle($jsonLD, 'de')->willReturn('Title');
$parser->getDescription($jsonLD, 'de')->willReturn('Description');
$parser->getOpeningHours($jsonLD)->willReturn([]);
$organisation = $this->prophesize(Organisation::class);
$organisation->getUid()->willReturn(10);
$organisationRepository = $this->prophesize(OrganisationRepository::class);
$organisationRepository->findOneByRemoteId('https://example.com/resources/018132452787-xxxx')->willReturn($organisation->reveal());
$town = $this->prophesize(Town::class);
$town->getUid()->willReturn(20);
$townRepository = $this->prophesize(TownRepository::class);
$townRepository->findOneByRemoteIds([
'https://example.com/resources/043064193523-jcyt',
'https://example.com/resources/573211638937-gmqb',
])->willReturn($town->reveal());
$subject = new TouristAttraction(
$parser->reveal(),
$organisationRepository->reveal(),
$townRepository->reveal()
);
$entities = $subject->convert($jsonLD);
self::assertInstanceOf(EntityCollection::class, $entities);
self::assertCount(1, $entities->getEntities());
$entity = $entities->getEntities()[0];
self::assertSame(10, $entity->getTypo3StoragePid());
self::assertSame('tx_thuecat_tourist_attraction', $entity->getTypo3DatabaseTableName());
self::assertSame('https://example.com/resources/018132452787-ngbe', $entity->getRemoteId());
self::assertSame([
'title' => 'Title',
'description' => 'Description',
'managed_by' => 10,
'town' => 20,
'opening_hours' => '[]',
], $entity->getData());
}
}

View file

@ -27,6 +27,8 @@ use PHPUnit\Framework\TestCase;
use Prophecy\PhpUnit\ProphecyTrait;
use WerkraumMedia\ThueCat\Domain\Import\Converter\Converter;
use WerkraumMedia\ThueCat\Domain\Import\Converter\TouristInformation;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser;
use WerkraumMedia\ThueCat\Domain\Import\Model\EntityCollection;
use WerkraumMedia\ThueCat\Domain\Model\Backend\Organisation;
use WerkraumMedia\ThueCat\Domain\Model\Backend\Town;
use WerkraumMedia\ThueCat\Domain\Repository\Backend\OrganisationRepository;
@ -34,6 +36,7 @@ use WerkraumMedia\ThueCat\Domain\Repository\Backend\TownRepository;
/**
* @covers WerkraumMedia\ThueCat\Domain\Import\Converter\TouristInformation
* @uses WerkraumMedia\ThueCat\Domain\Import\Model\EntityCollection
* @uses WerkraumMedia\ThueCat\Domain\Import\Model\GenericEntity
*/
class TouristInformationTest extends TestCase
@ -45,10 +48,12 @@ class TouristInformationTest extends TestCase
*/
public function instanceCanBeCreated(): void
{
$parser = $this->prophesize(Parser::class);
$organisationRepository = $this->prophesize(OrganisationRepository::class);
$townRepository = $this->prophesize(TownRepository::class);
$subject = new TouristInformation(
$parser->reveal(),
$organisationRepository->reveal(),
$townRepository->reveal()
);
@ -60,10 +65,12 @@ class TouristInformationTest extends TestCase
*/
public function isInstanceOfConverter(): void
{
$parser = $this->prophesize(Parser::class);
$organisationRepository = $this->prophesize(OrganisationRepository::class);
$townRepository = $this->prophesize(TownRepository::class);
$subject = new TouristInformation(
$parser->reveal(),
$organisationRepository->reveal(),
$townRepository->reveal()
);
@ -75,10 +82,12 @@ class TouristInformationTest extends TestCase
*/
public function canConvertTouristMarketingCompany(): void
{
$parser = $this->prophesize(Parser::class);
$organisationRepository = $this->prophesize(OrganisationRepository::class);
$townRepository = $this->prophesize(TownRepository::class);
$subject = new TouristInformation(
$parser->reveal(),
$organisationRepository->reveal(),
$townRepository->reveal()
);
@ -92,21 +101,7 @@ class TouristInformationTest extends TestCase
*/
public function convertsJsonIdToGenericEntityWithoutRelations(): void
{
$organisationRepository = $this->prophesize(OrganisationRepository::class);
$organisationRepository->findOneByRemoteId('https://example.com/resources/018132452787-xxxx')
->willReturn(null);
$townRepository = $this->prophesize(TownRepository::class);
$townRepository->findOneByRemoteIds([
'https://example.com/resources/043064193523-jcyt',
'https://example.com/resources/573211638937-gmqb',
])->willReturn(null);
$subject = new TouristInformation(
$organisationRepository->reveal(),
$townRepository->reveal()
);
$entity = $subject->convert([
$jsonLD = [
'@id' => 'https://example.com/resources/018132452787-ngbe',
'thuecat:managedBy' => [
'@id' => 'https://example.com/resources/018132452787-xxxx',
@ -127,7 +122,39 @@ class TouristInformationTest extends TestCase
'@value' => 'Description',
],
],
];
$parser = $this->prophesize(Parser::class);
$parser->getManagerId($jsonLD)->willReturn('https://example.com/resources/018132452787-xxxx');
$parser->getContainedInPlaceIds($jsonLD)->willReturn([
'https://example.com/resources/043064193523-jcyt',
'https://example.com/resources/573211638937-gmqb',
]);
$parser->getId($jsonLD)->willReturn('https://example.com/resources/018132452787-ngbe');
$parser->getTitle($jsonLD)->willReturn('Title');
$parser->getDescription($jsonLD)->willReturn('Description');
$organisationRepository = $this->prophesize(OrganisationRepository::class);
$organisationRepository->findOneByRemoteId('https://example.com/resources/018132452787-xxxx')
->willReturn(null);
$townRepository = $this->prophesize(TownRepository::class);
$townRepository->findOneByRemoteIds([
'https://example.com/resources/043064193523-jcyt',
'https://example.com/resources/573211638937-gmqb',
])->willReturn(null);
$subject = new TouristInformation(
$parser->reveal(),
$organisationRepository->reveal(),
$townRepository->reveal()
);
$entities = $subject->convert($jsonLD);
self::assertInstanceOf(EntityCollection::class, $entities);
self::assertCount(1, $entities->getEntities());
$entity = $entities->getEntities()[0];
self::assertSame(10, $entity->getTypo3StoragePid());
self::assertSame('tx_thuecat_tourist_information', $entity->getTypo3DatabaseTableName());
@ -145,25 +172,7 @@ class TouristInformationTest extends TestCase
*/
public function convertsJsonIdToGenericEntityWithRelations(): void
{
$organisation = $this->prophesize(Organisation::class);
$organisation->getUid()->willReturn(10);
$organisationRepository = $this->prophesize(OrganisationRepository::class);
$organisationRepository->findOneByRemoteId('https://example.com/resources/018132452787-xxxx')
->willReturn($organisation->reveal());
$town = $this->prophesize(Town::class);
$town->getUid()->willReturn(20);
$townRepository = $this->prophesize(TownRepository::class);
$townRepository->findOneByRemoteIds([
'https://example.com/resources/043064193523-jcyt',
'https://example.com/resources/573211638937-gmqb',
])->willReturn($town->reveal());
$subject = new TouristInformation(
$organisationRepository->reveal(),
$townRepository->reveal()
);
$entity = $subject->convert([
$jsonLD = [
'@id' => 'https://example.com/resources/018132452787-ngbe',
'thuecat:managedBy' => [
'@id' => 'https://example.com/resources/018132452787-xxxx',
@ -184,7 +193,43 @@ class TouristInformationTest extends TestCase
'@value' => 'Description',
],
],
];
$parser = $this->prophesize(Parser::class);
$parser->getManagerId($jsonLD)->willReturn('https://example.com/resources/018132452787-xxxx');
$parser->getContainedInPlaceIds($jsonLD)->willReturn([
'https://example.com/resources/043064193523-jcyt',
'https://example.com/resources/573211638937-gmqb',
]);
$parser->getId($jsonLD)->willReturn('https://example.com/resources/018132452787-ngbe');
$parser->getTitle($jsonLD)->willReturn('Title');
$parser->getDescription($jsonLD)->willReturn('Description');
$organisation = $this->prophesize(Organisation::class);
$organisation->getUid()->willReturn(10);
$organisationRepository = $this->prophesize(OrganisationRepository::class);
$organisationRepository->findOneByRemoteId('https://example.com/resources/018132452787-xxxx')
->willReturn($organisation->reveal());
$town = $this->prophesize(Town::class);
$town->getUid()->willReturn(20);
$townRepository = $this->prophesize(TownRepository::class);
$townRepository->findOneByRemoteIds([
'https://example.com/resources/043064193523-jcyt',
'https://example.com/resources/573211638937-gmqb',
])->willReturn($town->reveal());
$subject = new TouristInformation(
$parser->reveal(),
$organisationRepository->reveal(),
$townRepository->reveal()
);
$entities = $subject->convert($jsonLD);
self::assertInstanceOf(EntityCollection::class, $entities);
self::assertCount(1, $entities->getEntities());
$entity = $entities->getEntities()[0];
self::assertSame(10, $entity->getTypo3StoragePid());
self::assertSame('tx_thuecat_tourist_information', $entity->getTypo3DatabaseTableName());

View file

@ -27,11 +27,14 @@ use PHPUnit\Framework\TestCase;
use Prophecy\PhpUnit\ProphecyTrait;
use WerkraumMedia\ThueCat\Domain\Import\Converter\Converter;
use WerkraumMedia\ThueCat\Domain\Import\Converter\Town;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser;
use WerkraumMedia\ThueCat\Domain\Import\Model\EntityCollection;
use WerkraumMedia\ThueCat\Domain\Model\Backend\Organisation;
use WerkraumMedia\ThueCat\Domain\Repository\Backend\OrganisationRepository;
/**
* @covers WerkraumMedia\ThueCat\Domain\Import\Converter\Town
* @uses WerkraumMedia\ThueCat\Domain\Import\Model\EntityCollection
* @uses WerkraumMedia\ThueCat\Domain\Import\Model\GenericEntity
*/
class TownTest extends TestCase
@ -43,9 +46,13 @@ class TownTest extends TestCase
*/
public function instanceCanBeCreated(): void
{
$parser = $this->prophesize(Parser::class);
$organisationRepository = $this->prophesize(OrganisationRepository::class);
$subject = new Town($organisationRepository->reveal());
$subject = new Town(
$parser->reveal(),
$organisationRepository->reveal()
);
self::assertInstanceOf(Town::class, $subject);
}
@ -54,9 +61,13 @@ class TownTest extends TestCase
*/
public function isInstanceOfConverter(): void
{
$parser = $this->prophesize(Parser::class);
$organisationRepository = $this->prophesize(OrganisationRepository::class);
$subject = new Town($organisationRepository->reveal());
$subject = new Town(
$parser->reveal(),
$organisationRepository->reveal()
);
self::assertInstanceOf(Converter::class, $subject);
}
@ -65,9 +76,13 @@ class TownTest extends TestCase
*/
public function canConvertTouristMarketingCompany(): void
{
$parser = $this->prophesize(Parser::class);
$organisationRepository = $this->prophesize(OrganisationRepository::class);
$subject = new Town($organisationRepository->reveal());
$subject = new Town(
$parser->reveal(),
$organisationRepository->reveal()
);
self::assertTrue($subject->canConvert([
'thuecat:Town',
]));
@ -78,11 +93,7 @@ class TownTest extends TestCase
*/
public function convertsJsonIdToGenericEntityWithoutOrganisation(): void
{
$organisationRepository = $this->prophesize(OrganisationRepository::class);
$organisationRepository->findOneByRemoteId('https://example.com/resources/018132452787-xxxx')->willReturn(null);
$subject = new Town($organisationRepository->reveal());
$entity = $subject->convert([
$jsonLD = [
'@id' => 'https://example.com/resources/018132452787-ngbe',
'thuecat:managedBy' => [
'@id' => 'https://example.com/resources/018132452787-xxxx',
@ -93,7 +104,27 @@ class TownTest extends TestCase
'schema:description' => [
'@value' => 'Description',
],
]);
];
$parser = $this->prophesize(Parser::class);
$parser->getManagerId($jsonLD)->willReturn('https://example.com/resources/018132452787-xxxx');
$parser->getId($jsonLD)->willReturn('https://example.com/resources/018132452787-ngbe');
$parser->getTitle($jsonLD)->willReturn('Title');
$parser->getDescription($jsonLD)->willReturn('Description');
$organisationRepository = $this->prophesize(OrganisationRepository::class);
$organisationRepository->findOneByRemoteId('https://example.com/resources/018132452787-xxxx')->willReturn(null);
$subject = new Town(
$parser->reveal(),
$organisationRepository->reveal()
);
$entities = $subject->convert($jsonLD);
self::assertInstanceOf(EntityCollection::class, $entities);
self::assertCount(1, $entities->getEntities());
$entity = $entities->getEntities()[0];
self::assertSame(10, $entity->getTypo3StoragePid());
self::assertSame('tx_thuecat_town', $entity->getTypo3DatabaseTableName());
@ -110,13 +141,7 @@ class TownTest extends TestCase
*/
public function convertsJsonIdToGenericEntityWithOrganisation(): void
{
$organisation = $this->prophesize(Organisation::class);
$organisation->getUid()->willReturn(10);
$organisationRepository = $this->prophesize(OrganisationRepository::class);
$organisationRepository->findOneByRemoteId('https://example.com/resources/018132452787-xxxx')->willReturn($organisation->reveal());
$subject = new Town($organisationRepository->reveal());
$entity = $subject->convert([
$jsonLD = [
'@id' => 'https://example.com/resources/018132452787-ngbe',
'thuecat:managedBy' => [
'@id' => 'https://example.com/resources/018132452787-xxxx',
@ -127,7 +152,29 @@ class TownTest extends TestCase
'schema:description' => [
'@value' => 'Description',
],
]);
];
$parser = $this->prophesize(Parser::class);
$parser->getManagerId($jsonLD)->willReturn('https://example.com/resources/018132452787-xxxx');
$parser->getId($jsonLD)->willReturn('https://example.com/resources/018132452787-ngbe');
$parser->getTitle($jsonLD)->willReturn('Title');
$parser->getDescription($jsonLD)->willReturn('Description');
$organisation = $this->prophesize(Organisation::class);
$organisation->getUid()->willReturn(10);
$organisationRepository = $this->prophesize(OrganisationRepository::class);
$organisationRepository->findOneByRemoteId('https://example.com/resources/018132452787-xxxx')->willReturn($organisation->reveal());
$subject = new Town(
$parser->reveal(),
$organisationRepository->reveal()
);
$entities = $subject->convert($jsonLD);
self::assertInstanceOf(EntityCollection::class, $entities);
self::assertCount(1, $entities->getEntities());
$entity = $entities->getEntities()[0];
self::assertSame(10, $entity->getTypo3StoragePid());
self::assertSame('tx_thuecat_town', $entity->getTypo3DatabaseTableName());

View file

@ -31,7 +31,7 @@ use WerkraumMedia\ThueCat\Domain\Import\Converter\Registry as ConverterRegistry;
use WerkraumMedia\ThueCat\Domain\Import\Importer;
use WerkraumMedia\ThueCat\Domain\Import\Importer\FetchData;
use WerkraumMedia\ThueCat\Domain\Import\Importer\SaveData;
use WerkraumMedia\ThueCat\Domain\Import\Model\Entity;
use WerkraumMedia\ThueCat\Domain\Import\Model\EntityCollection;
use WerkraumMedia\ThueCat\Domain\Import\UrlProvider\Registry as UrlProviderRegistry;
use WerkraumMedia\ThueCat\Domain\Import\UrlProvider\UrlProvider;
use WerkraumMedia\ThueCat\Domain\Model\Backend\ImportConfiguration;
@ -67,6 +67,35 @@ class ImporterTest extends TestCase
self::assertInstanceOf(Importer::class, $subject);
}
/**
* @test
*/
public function importsNothingIfUrlProviderCouldNotBeResolved(): void
{
$urls = $this->prophesize(UrlProviderRegistry::class);
$converter = $this->prophesize(ConverterRegistry::class);
$importLogRepository = $this->prophesize(ImportLogRepository::class);
$fetchData = $this->prophesize(FetchData::class);
$saveData = $this->prophesize(SaveData::class);
$configuration = $this->prophesize(ImportConfiguration::class);
$urls->getProviderForConfiguration($configuration->reveal())->willReturn(null);
$fetchData->jsonLDFromUrl()->shouldNotBeCalled();
$saveData->import()->shouldNotBeCalled();
$subject = new Importer(
$urls->reveal(),
$converter->reveal(),
$importLogRepository->reveal(),
$fetchData->reveal(),
$saveData->reveal()
);
$result = $subject->importConfiguration($configuration->reveal());
self::assertInstanceOf(ImportLog::class, $result);
self::assertCount(0, $result->getEntries());
}
/**
* @test
*/
@ -109,8 +138,8 @@ class ImporterTest extends TestCase
$saveData = $this->prophesize(SaveData::class);
$configuration = $this->prophesize(ImportConfiguration::class);
$entity1 = $this->prophesize(Entity::class);
$entity2 = $this->prophesize(Entity::class);
$entities1 = $this->prophesize(EntityCollection::class);
$entities2 = $this->prophesize(EntityCollection::class);
$urls->getProviderForConfiguration($configuration->reveal())->willReturn($urlProvider->reveal());
$urlProvider->getUrls()->willReturn([
@ -144,13 +173,13 @@ class ImporterTest extends TestCase
$concreteConverter->convert(Argument::that(function (array $jsonEntity) {
return $jsonEntity['@id'] === 'https://example.com/resources/34343-ex';
}))->willReturn($entity1->reveal());
}))->willReturn($entities1->reveal());
$concreteConverter->convert(Argument::that(function (array $jsonEntity) {
return $jsonEntity['@id'] === 'https://example.com/resources/34344-es';
}))->willReturn($entity2->reveal());
}))->willReturn($entities2->reveal());
$saveData->import($entity1->reveal(), Argument::type(ImportLog::class))->shouldBeCalled();
$saveData->import($entity2->reveal(), Argument::type(ImportLog::class))->shouldBeCalled();
$saveData->import($entities1->reveal(), Argument::type(ImportLog::class))->shouldBeCalled();
$saveData->import($entities2->reveal(), Argument::type(ImportLog::class))->shouldBeCalled();
$subject = new Importer(
$urls->reveal(),

View file

@ -0,0 +1,310 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Tests\Unit\Domain\Import\JsonLD\Parser;
/*
* 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 PHPUnit\Framework\TestCase;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\OpeningHours;
/**
* @covers WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\OpeningHours
*/
class OpeningHoursTest extends TestCase
{
/**
* @test
*/
public function canBeCreated(): void
{
$subject = new OpeningHours();
self::assertInstanceOf(OpeningHours::class, $subject);
}
/**
* @test
*/
public function returnsEmptyArrayIfOpeningHoursAreMissing(): void
{
$subject = new OpeningHours();
$result = $subject->get([
]);
self::assertSame([], $result);
}
/**
* @test
*/
public function returnsSingleOpeningHourWrappedInArray(): void
{
$subject = new OpeningHours();
$result = $subject->get([
'schema:openingHoursSpecification' => [
'@id' => 'genid-28b33237f71b41e3ad54a99e1da769b9-b13',
'schema:opens' => [
'@type' => 'schema:Time',
'@value' => '10:00:00',
],
'schema:closes' => [
'@type' => 'schema:Time',
'@value' => '18:00:00',
],
'schema:validFrom' => [
'@type' => 'schema:Date',
'@value' => '2021-03-01',
],
'schema:validThrough' => [
'@type' => 'schema:Date',
'@value' => '2021-12-31',
],
'schema:dayOfWeek' => [
0 => [
'@type' => 'schema:DayOfWeek',
'@value' => 'schema:Saturday',
],
1 => [
'@type' => 'schema:DayOfWeek',
'@value' => 'schema:Sunday',
],
2 => [
'@type' => 'schema:DayOfWeek',
'@value' => 'schema:Friday',
],
3 => [
'@type' => 'schema:DayOfWeek',
'@value' => 'schema:Thursday',
],
4 => [
'@type' => 'schema:DayOfWeek',
'@value' => 'schema:Tuesday',
],
5 => [
'@type' => 'schema:DayOfWeek',
'@value' => 'schema:Wednesday',
],
],
],
]);
self::assertCount(1, $result);
self::assertSame('10:00:00', $result[0]['opens']);
self::assertSame('18:00:00', $result[0]['closes']);
self::assertSame([
'Friday',
'Saturday',
'Sunday',
'Thursday',
'Tuesday',
'Wednesday',
], $result[0]['daysOfWeek']);
self::assertInstanceOf(\DateTimeImmutable::class, $result[0]['from']);
self::assertSame('2021-03-01 00:00:00', $result[0]['from']->format('Y-m-d H:i:s'));
self::assertInstanceOf(\DateTimeImmutable::class, $result[0]['through']);
self::assertSame('2021-12-31 00:00:00', $result[0]['through']->format('Y-m-d H:i:s'));
}
/**
* @test
*/
public function returnsSingleWeekDay(): void
{
$subject = new OpeningHours();
$result = $subject->get([
'schema:openingHoursSpecification' => [
'@id' => 'genid-28b33237f71b41e3ad54a99e1da769b9-b13',
'schema:dayOfWeek' => [
'@type' => 'schema:DayOfWeek',
'@value' => 'schema:Saturday',
],
],
]);
self::assertCount(1, $result);
self::assertSame([
'Saturday',
], $result[0]['daysOfWeek']);
}
/**
* @test
*/
public function returnsMultipleOpeningHours(): void
{
$subject = new OpeningHours();
$result = $subject->get([
'schema:openingHoursSpecification' => [
[
'@id' => 'genid-28b33237f71b41e3ad54a99e1da769b9-b13',
'schema:opens' => [
'@type' => 'schema:Time',
'@value' => '10:00:00',
],
'schema:closes' => [
'@type' => 'schema:Time',
'@value' => '18:00:00',
],
'schema:validFrom' => [
'@type' => 'schema:Date',
'@value' => '2021-03-01',
],
'schema:validThrough' => [
'@type' => 'schema:Date',
'@value' => '2021-12-31',
],
'schema:dayOfWeek' => [
0 => [
'@type' => 'schema:DayOfWeek',
'@value' => 'schema:Saturday',
],
1 => [
'@type' => 'schema:DayOfWeek',
'@value' => 'schema:Sunday',
],
2 => [
'@type' => 'schema:DayOfWeek',
'@value' => 'schema:Friday',
],
3 => [
'@type' => 'schema:DayOfWeek',
'@value' => 'schema:Thursday',
],
4 => [
'@type' => 'schema:DayOfWeek',
'@value' => 'schema:Tuesday',
],
5 => [
'@type' => 'schema:DayOfWeek',
'@value' => 'schema:Wednesday',
],
],
],
[
'@id' => 'genid-28b33237f71b41e3ad54a99e1da769b9-b13',
'schema:opens' => [
'@type' => 'schema:Time',
'@value' => '09:00:00',
],
'schema:closes' => [
'@type' => 'schema:Time',
'@value' => '17:00:00',
],
'schema:validFrom' => [
'@type' => 'schema:Date',
'@value' => '2022-03-01',
],
'schema:validThrough' => [
'@type' => 'schema:Date',
'@value' => '2022-12-31',
],
'schema:dayOfWeek' => [
0 => [
'@type' => 'schema:DayOfWeek',
'@value' => 'schema:Saturday',
],
1 => [
'@type' => 'schema:DayOfWeek',
'@value' => 'schema:Sunday',
],
2 => [
'@type' => 'schema:DayOfWeek',
'@value' => 'schema:Friday',
],
3 => [
'@type' => 'schema:DayOfWeek',
'@value' => 'schema:Thursday',
],
4 => [
'@type' => 'schema:DayOfWeek',
'@value' => 'schema:Tuesday',
],
5 => [
'@type' => 'schema:DayOfWeek',
'@value' => 'schema:Wednesday',
],
],
],
],
]);
self::assertCount(2, $result);
self::assertSame('10:00:00', $result[0]['opens']);
self::assertSame('18:00:00', $result[0]['closes']);
self::assertSame([
'Friday',
'Saturday',
'Sunday',
'Thursday',
'Tuesday',
'Wednesday',
], $result[0]['daysOfWeek']);
self::assertInstanceOf(\DateTimeImmutable::class, $result[0]['from']);
self::assertSame('2021-03-01 00:00:00', $result[0]['from']->format('Y-m-d H:i:s'));
self::assertInstanceOf(\DateTimeImmutable::class, $result[0]['through']);
self::assertSame('2021-12-31 00:00:00', $result[0]['through']->format('Y-m-d H:i:s'));
self::assertSame('09:00:00', $result[1]['opens']);
self::assertSame('17:00:00', $result[1]['closes']);
self::assertSame([
'Friday',
'Saturday',
'Sunday',
'Thursday',
'Tuesday',
'Wednesday',
], $result[1]['daysOfWeek']);
self::assertInstanceOf(\DateTimeImmutable::class, $result[1]['from']);
self::assertSame('2022-03-01 00:00:00', $result[1]['from']->format('Y-m-d H:i:s'));
self::assertInstanceOf(\DateTimeImmutable::class, $result[1]['through']);
self::assertSame('2022-12-31 00:00:00', $result[1]['through']->format('Y-m-d H:i:s'));
}
/**
* @test
*/
public function returnsProperDefaultsOnMissingValues(): void
{
$subject = new OpeningHours();
$result = $subject->get([
'schema:openingHoursSpecification' => [
'@id' => 'genid-28b33237f71b41e3ad54a99e1da769b9-b13',
],
]);
self::assertCount(1, $result);
self::assertSame('', $result[0]['opens']);
self::assertSame('', $result[0]['closes']);
self::assertSame([], $result[0]['daysOfWeek']);
self::assertSame(null, $result[0]['from']);
self::assertSame(null, $result[0]['through']);
}
}

View file

@ -0,0 +1,457 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Tests\Unit\Domain\Import\JsonLD;
/*
* 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 PHPUnit\Framework\TestCase;
use Prophecy\PhpUnit\ProphecyTrait;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\OpeningHours;
/**
* @covers WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser
*/
class ParserTest extends TestCase
{
use ProphecyTrait;
/**
* @test
*/
public function canBeCreated(): void
{
$openingHours = $this->prophesize(OpeningHours::class);
$subject = new Parser(
$openingHours->reveal()
);
self::assertInstanceOf(Parser::class, $subject);
}
/**
* @test
*/
public function returnsId(): void
{
$openingHours = $this->prophesize(OpeningHours::class);
$subject = new Parser(
$openingHours->reveal()
);
$result = $subject->getId([
'@id' => 'https://example.com/resources/165868194223-id',
]);
self::assertSame('https://example.com/resources/165868194223-id', $result);
}
/**
* @test
*/
public function returnsManagerId(): void
{
$openingHours = $this->prophesize(OpeningHours::class);
$subject = new Parser(
$openingHours->reveal()
);
$result = $subject->getManagerId([
'thuecat:contentResponsible' => [
'@id' => 'https://example.com/resources/165868194223-manager',
],
]);
self::assertSame('https://example.com/resources/165868194223-manager', $result);
}
/**
* @test
* @dataProvider titles
*/
public function returnsTitle(array $jsonLD, string $language, string $expected): void
{
$openingHours = $this->prophesize(OpeningHours::class);
$subject = new Parser(
$openingHours->reveal()
);
$result = $subject->getTitle($jsonLD, $language);
self::assertSame($expected, $result);
}
public function titles(): array
{
return [
'json has multiple lanugages, one matches' => [
'jsonLD' => [
'schema:name' => [
[
'@language' => 'de',
'@value' => 'DE Title',
],
[
'@language' => 'fr',
'@value' => 'FR Title',
],
],
],
'language' => 'de',
'expected' => 'DE Title',
],
'json has multiple lanugages, no language specified' => [
'jsonLD' => [
'schema:name' => [
[
'@language' => 'de',
'@value' => 'DE Title',
],
[
'@language' => 'fr',
'@value' => 'FR Title',
],
],
],
'language' => '',
'expected' => 'DE Title',
],
'json has multiple languages, none matches' => [
'jsonLD' => [
'schema:name' => [
[
'@language' => 'de',
'@value' => 'DE Title',
],
[
'@language' => 'fr',
'@value' => 'FR Title',
],
],
],
'language' => 'en',
'expected' => '',
],
'json has multiple languages, missing @language key' => [
'jsonLD' => [
'schema:name' => [
[
'@value' => 'DE Title',
],
[
'@value' => 'FR Title',
],
],
],
'language' => 'en',
'expected' => '',
],
'json has single language, that one matches' => [
'jsonLD' => [
'schema:name' => [
'@language' => 'de',
'@value' => 'DE Title',
],
],
'language' => 'de',
'expected' => 'DE Title',
],
'json contains single language, but another is requested' => [
'jsonLD' => [
'schema:name' => [
'@language' => 'de',
'@value' => 'DE Title',
],
],
'language' => 'en',
'expected' => '',
],
'json contains single language, no language specified' => [
'jsonLD' => [
'schema:name' => [
'@language' => 'de',
'@value' => 'DE Title',
],
],
'language' => '',
'expected' => 'DE Title',
],
'json contains single language, missing @language key' => [
'jsonLD' => [
'schema:name' => [
'@value' => 'DE Title',
],
],
'language' => '',
'expected' => '',
],
];
}
/**
* @test
* @dataProvider descriptions
*/
public function returnsDescription(array $jsonLD, string $language, string $expected): void
{
$openingHours = $this->prophesize(OpeningHours::class);
$subject = new Parser(
$openingHours->reveal()
);
$result = $subject->getDescription($jsonLD, $language);
self::assertSame($expected, $result);
}
public function descriptions(): array
{
return [
'json has multiple lanugages, one matches' => [
'jsonLD' => [
'schema:description' => [
[
'@language' => 'de',
'@value' => 'DE Description',
],
[
'@language' => 'fr',
'@value' => 'FR Description',
],
],
],
'language' => 'de',
'expected' => 'DE Description',
],
'json has multiple lanugages, no language specified' => [
'jsonLD' => [
'schema:description' => [
[
'@language' => 'de',
'@value' => 'DE Description',
],
[
'@language' => 'fr',
'@value' => 'FR Description',
],
],
],
'language' => '',
'expected' => 'DE Description',
],
'json has multiple languages, none matches' => [
'jsonLD' => [
'schema:description' => [
[
'@language' => 'de',
'@value' => 'DE Description',
],
[
'@language' => 'fr',
'@value' => 'FR Description',
],
],
],
'language' => 'en',
'expected' => '',
],
'json has multiple languages, missing @language key' => [
'jsonLD' => [
'schema:description' => [
[
'@value' => 'DE Description',
],
[
'@value' => 'FR Description',
],
],
],
'language' => 'en',
'expected' => '',
],
'json has single language, that one matches' => [
'jsonLD' => [
'schema:description' => [
'@language' => 'de',
'@value' => 'DE Description',
],
],
'language' => 'de',
'expected' => 'DE Description',
],
'json contains single language, but another is requested' => [
'jsonLD' => [
'schema:description' => [
'@language' => 'de',
'@value' => 'DE Description',
],
],
'language' => 'en',
'expected' => '',
],
'json contains single language, no language specified' => [
'jsonLD' => [
'schema:description' => [
'@language' => 'de',
'@value' => 'DE Description',
],
],
'language' => '',
'expected' => 'DE Description',
],
'json contains single language, missing @language key' => [
'jsonLD' => [
'schema:description' => [
'@value' => 'DE Description',
],
],
'language' => '',
'expected' => '',
],
];
}
/**
* @test
*/
public function returnsContainedInPlaceIds(): void
{
$openingHours = $this->prophesize(OpeningHours::class);
$subject = new Parser(
$openingHours->reveal()
);
$result = $subject->getContainedInPlaceIds([
'schema:containedInPlace' => [
['@id' => 'https://thuecat.org/resources/043064193523-jcyt'],
['@id' => 'https://thuecat.org/resources/349986440346-kbkf'],
['@id' => 'https://thuecat.org/resources/794900260253-wjab'],
['@id' => 'https://thuecat.org/resources/476888881990-xpwq'],
['@id' => 'https://thuecat.org/resources/573211638937-gmqb'],
],
]);
self::assertSame([
'https://thuecat.org/resources/043064193523-jcyt',
'https://thuecat.org/resources/349986440346-kbkf',
'https://thuecat.org/resources/794900260253-wjab',
'https://thuecat.org/resources/476888881990-xpwq',
'https://thuecat.org/resources/573211638937-gmqb',
], $result);
}
/**
* @test
*/
public function returnsLanguages(): void
{
$openingHours = $this->prophesize(OpeningHours::class);
$subject = new Parser(
$openingHours->reveal()
);
$result = $subject->getLanguages([
'schema:availableLanguage' => [
0 => [
'@type' => 'thuecat:Language',
'@value' => 'thuecat:German',
],
1 => [
'@type' => 'thuecat:Language',
'@value' => 'thuecat:English',
],
2 => [
'@type' => 'thuecat:Language',
'@value' => 'thuecat:French',
],
],
]);
self::assertSame([
'de',
'en',
'fr',
], $result);
}
/**
* @test
*/
public function throwsExceptionOnUnkownLanguage(): void
{
$openingHours = $this->prophesize(OpeningHours::class);
$subject = new Parser(
$openingHours->reveal()
);
$this->expectExceptionCode(1612367481);
$result = $subject->getLanguages([
'schema:availableLanguage' => [
0 => [
'@type' => 'thuecat:Language',
'@value' => 'thuecat:Unkown',
],
],
]);
}
/**
* @test
*/
public function returnsNoLanguagesIfInfoIsMissing(): void
{
$openingHours = $this->prophesize(OpeningHours::class);
$subject = new Parser(
$openingHours->reveal()
);
$result = $subject->getLanguages([]);
self::assertSame([], $result);
}
/**
* @test
*/
public function returnsOpeningHours(): void
{
$jsonLD = [
'schema:openingHoursSpecification' => [
'@id' => 'genid-28b33237f71b41e3ad54a99e1da769b9-b13',
'schema:opens' => [
'@type' => 'schema:Time',
'@value' => '10:00:00',
],
],
];
$generatedOpeningHours = [
'opens' => '10:00:00',
'closes' => '',
'from' => null,
'through' => null,
'daysOfWeek' => [],
];
$openingHours = $this->prophesize(OpeningHours::class);
$openingHours->get($jsonLD)->willReturn($generatedOpeningHours);
$subject = new Parser(
$openingHours->reveal()
);
$result = $subject->getOpeningHours($jsonLD);
self::assertSame($generatedOpeningHours, $result);
}
}

View file

@ -0,0 +1,138 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Tests\Unit\Domain\Import\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 PHPUnit\Framework\TestCase;
use Prophecy\PhpUnit\ProphecyTrait;
use WerkraumMedia\ThueCat\Domain\Import\Model\Entity;
use WerkraumMedia\ThueCat\Domain\Import\Model\EntityCollection;
/**
* @covers WerkraumMedia\ThueCat\Domain\Import\Model\EntityCollection
*/
class EntityCollectionTest extends TestCase
{
use ProphecyTrait;
/**
* @test
*/
public function canBeCreated(): void
{
$subject = new EntityCollection();
self::assertInstanceOf(EntityCollection::class, $subject);
}
/**
* @test
*/
public function returnsEmptyArrayAsDefaultEntities(): void
{
$subject = new EntityCollection();
self::assertSame([], $subject->getEntities());
}
/**
* @test
*/
public function returnsFirstEntityForDefaultLanguage(): void
{
$entityWithTranslation = $this->prophesize(Entity::class);
$entityWithTranslation->isForDefaultLanguage()->willReturn(false);
$entityWithDefaultLanguage = $this->prophesize(Entity::class);
$entityWithDefaultLanguage->isForDefaultLanguage()->willReturn(true);
$subject = new EntityCollection();
$subject->add($entityWithTranslation->reveal());
$subject->add($entityWithDefaultLanguage->reveal());
self::assertSame(
$entityWithDefaultLanguage->reveal(),
$subject->getDefaultLanguageEntity()
);
}
/**
* @test
*/
public function returnsNullIfNoEntityForDefaultLanguageExists(): void
{
$entityWithTranslation = $this->prophesize(Entity::class);
$entityWithTranslation->isForDefaultLanguage()->willReturn(false);
$subject = new EntityCollection();
$subject->add($entityWithTranslation->reveal());
self::assertSame(
null,
$subject->getDefaultLanguageEntity()
);
}
/**
* @test
*/
public function returnsAllTranslatedEntities(): void
{
$entityWithTranslation1 = $this->prophesize(Entity::class);
$entityWithTranslation1->isTranslation()->willReturn(true);
$entityWithTranslation2 = $this->prophesize(Entity::class);
$entityWithTranslation2->isTranslation()->willReturn(true);
$entitiyWithDefaultLanguage = $this->prophesize(Entity::class);
$entitiyWithDefaultLanguage->isTranslation()->willReturn(false);
$subject = new EntityCollection();
$subject->add($entityWithTranslation1->reveal());
$subject->add($entitiyWithDefaultLanguage->reveal());
$subject->add($entityWithTranslation2->reveal());
self::assertSame(
[
0 => $entityWithTranslation1->reveal(),
2 => $entityWithTranslation2->reveal(),
],
$subject->getTranslatedEntities()
);
}
/**
* @test
*/
public function returnsEmptyArrayIfNoTranslatedEntityExists(): void
{
$entitiyWithDefaultLanguage = $this->prophesize(Entity::class);
$entitiyWithDefaultLanguage->isTranslation()->willReturn(false);
$subject = new EntityCollection();
$subject->add($entitiyWithDefaultLanguage->reveal());
self::assertSame(
[],
$subject->getTranslatedEntities()
);
}
}

View file

@ -39,6 +39,7 @@ class GenericEntityTest extends TestCase
$subject = new GenericEntity(
0,
'',
0,
'',
[]
);
@ -53,6 +54,7 @@ class GenericEntityTest extends TestCase
$subject = new GenericEntity(
10,
'',
0,
'',
[]
);
@ -67,12 +69,58 @@ class GenericEntityTest extends TestCase
$subject = new GenericEntity(
0,
'tx_thuecat_entity',
0,
'',
[]
);
self::assertSame('tx_thuecat_entity', $subject->getTypo3DatabaseTableName());
}
/**
* @test
*/
public function returnsTypo3SystemLanguageUid(): void
{
$subject = new GenericEntity(
0,
'',
10,
'',
[]
);
self::assertSame(10, $subject->getTypo3SystemLanguageUid());
}
/**
* @test
*/
public function claimsIsForDefaultLanguage(): void
{
$subject = new GenericEntity(
0,
'',
0,
'',
[]
);
self::assertTrue($subject->isForDefaultLanguage());
}
/**
* @test
*/
public function claimsIsTranslation(): void
{
$subject = new GenericEntity(
0,
'',
10,
'',
[]
);
self::assertTrue($subject->isTranslation());
}
/**
* @test
*/
@ -81,6 +129,7 @@ class GenericEntityTest extends TestCase
$subject = new GenericEntity(
0,
'',
0,
'https://example.com/resources/333039283321-xxwg',
[]
);
@ -98,6 +147,7 @@ class GenericEntityTest extends TestCase
$subject = new GenericEntity(
0,
'',
0,
'',
[
'column_name_1' => 'value 1',
@ -121,6 +171,7 @@ class GenericEntityTest extends TestCase
$subject = new GenericEntity(
0,
'',
0,
'',
[]
);
@ -138,6 +189,7 @@ class GenericEntityTest extends TestCase
$subject = new GenericEntity(
0,
'',
0,
'',
[]
);
@ -155,6 +207,7 @@ class GenericEntityTest extends TestCase
$subject = new GenericEntity(
0,
'',
0,
'',
[]
);
@ -172,6 +225,7 @@ class GenericEntityTest extends TestCase
$subject = new GenericEntity(
0,
'',
0,
'',
[]
);

View file

@ -35,7 +35,8 @@
"symfony/dependency-injection": "^5.2",
"typo3/cms-backend": "^10.4",
"typo3/cms-core": "^10.4",
"typo3/cms-extbase": "^10.4"
"typo3/cms-extbase": "^10.4",
"typo3/cms-frontend": "^10.4"
},
"require-dev": {
"friendsoftypo3/phpstan-typo3": "^0.6.0",

View file

@ -5,6 +5,7 @@
"Configuration/SiteConfiguration/Overrides/*.php",
"Configuration/TCA/*.php",
"ext_emconf.php",
"ext_localconf.php",
"ext_tables.php"
]
}

5
ext_localconf.php Normal file
View file

@ -0,0 +1,5 @@
<?php
defined('TYPO3') or die();
\WerkraumMedia\ThueCat\Extension::registerConfig();

View file

@ -40,3 +40,12 @@ CREATE TABLE tx_thuecat_tourist_information (
title varchar(255) DEFAULT '' NOT NULL,
description text DEFAULT '' NOT NULL,
);
CREATE TABLE tx_thuecat_tourist_attraction (
remote_id varchar(255) DEFAULT '' NOT NULL,
managed_by int(11) unsigned DEFAULT '0' NOT NULL,
town int(11) unsigned DEFAULT '0' NOT NULL,
title varchar(255) DEFAULT '' NOT NULL,
description text DEFAULT '' NOT NULL,
opening_hours text DEFAULT '' NOT NULL,
);

27
phpstan-baseline.neon Normal file
View file

@ -0,0 +1,27 @@
parameters:
ignoreErrors:
-
message: "#^Cannot call method fetchColumn\\(\\) on Doctrine\\\\DBAL\\\\Driver\\\\Statement\\|int\\.$#"
count: 1
path: Classes/Domain/Import/Importer/SaveData.php
-
message: "#^Property WerkraumMedia\\\\ThueCat\\\\Domain\\\\Model\\\\Backend\\\\ImportLog\\:\\:\\$logEntries \\(iterable\\<WerkraumMedia\\\\ThueCat\\\\Domain\\\\Model\\\\Backend\\\\ImportLogEntry\\>&TYPO3\\\\CMS\\\\Extbase\\\\Persistence\\\\ObjectStorage\\) does not accept TYPO3\\\\CMS\\\\Extbase\\\\Persistence\\\\ObjectStorage\\.$#"
count: 1
path: Classes/Domain/Model/Backend/ImportLog.php
-
message: "#^Cannot call method getFirst\\(\\) on array\\|TYPO3\\\\CMS\\\\Extbase\\\\Persistence\\\\QueryResultInterface\\.$#"
count: 1
path: Classes/Domain/Repository/Backend/TownRepository.php
-
message: "#^Method WerkraumMedia\\\\ThueCat\\\\Domain\\\\Repository\\\\Backend\\\\TownRepository\\:\\:findOneByRemoteIds\\(\\) should return WerkraumMedia\\\\ThueCat\\\\Domain\\\\Model\\\\Backend\\\\Town\\|null but returns object\\.$#"
count: 1
path: Classes/Domain/Repository/Backend/TownRepository.php
-
message: "#^Cannot call method fetchAll\\(\\) on Doctrine\\\\DBAL\\\\Driver\\\\Statement\\|int\\.$#"
count: 1
path: Classes/Frontend/DataProcessing/ResolveEntities.php

View file

@ -1,5 +1,6 @@
includes:
- vendor/friendsoftypo3/phpstan-typo3/extension.neon
- phpstan-baseline.neon
parameters:
level: max
paths:
@ -8,20 +9,3 @@ parameters:
- Tests
checkMissingIterableValueType: false
reportUnmatchedIgnoredErrors: true
ignoreErrors:
-
message: "#^Cannot call method fetchColumn\\(\\) on Doctrine\\\\DBAL\\\\Driver\\\\Statement\\|int\\.$#"
count: 1
path: Classes/Domain/Import/Importer/SaveData.php
-
message: "#^Property WerkraumMedia\\\\ThueCat\\\\Domain\\\\Model\\\\Backend\\\\ImportLog\\:\\:\\$logEntries \\(iterable\\<WerkraumMedia\\\\ThueCat\\\\Domain\\\\Model\\\\Backend\\\\ImportLogEntry\\>&TYPO3\\\\CMS\\\\Extbase\\\\Persistence\\\\ObjectStorage\\) does not accept TYPO3\\\\CMS\\\\Extbase\\\\Persistence\\\\ObjectStorage\\.$#"
count: 1
path: Classes/Domain/Model/Backend/ImportLog.php
-
message: "#^Cannot call method getFirst\\(\\) on array\\|TYPO3\\\\CMS\\\\Extbase\\\\Persistence\\\\QueryResultInterface\\.$#"
count: 1
path: Classes/Domain/Repository/Backend/TownRepository.php
-
message: "#^Method WerkraumMedia\\\\ThueCat\\\\Domain\\\\Repository\\\\Backend\\\\TownRepository\\:\\:findOneByRemoteIds\\(\\) should return WerkraumMedia\\\\ThueCat\\\\Domain\\\\Model\\\\Backend\\\\Town\\|null but returns object\\.$#"
count: 1
path: Classes/Domain/Repository/Backend/TownRepository.php