Add multi language handling

Import entities in all available languages.
Provide translated records in frontend.
This commit is contained in:
Daniel Siepmann 2021-02-16 17:12:47 +01:00
parent 46144de0a7
commit 92c8bbedaa
22 changed files with 596 additions and 85 deletions

View file

@ -24,6 +24,7 @@ namespace WerkraumMedia\ThueCat\Domain\Import\Converter;
*/ */
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
use WerkraumMedia\ThueCat\Domain\Import\Importer\LanguageHandling;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser; use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser;
use WerkraumMedia\ThueCat\Domain\Import\Model\EntityCollection; use WerkraumMedia\ThueCat\Domain\Import\Model\EntityCollection;
use WerkraumMedia\ThueCat\Domain\Import\Model\GenericEntity; use WerkraumMedia\ThueCat\Domain\Import\Model\GenericEntity;
@ -33,15 +34,18 @@ use WerkraumMedia\ThueCat\Domain\Repository\Backend\TownRepository;
class TouristAttraction implements Converter class TouristAttraction implements Converter
{ {
private Parser $parser; private Parser $parser;
private LanguageHandling $language;
private OrganisationRepository $organisationRepository; private OrganisationRepository $organisationRepository;
private TownRepository $townRepository; private TownRepository $townRepository;
public function __construct( public function __construct(
Parser $parser, Parser $parser,
LanguageHandling $language,
OrganisationRepository $organisationRepository, OrganisationRepository $organisationRepository,
TownRepository $townRepository TownRepository $townRepository
) { ) {
$this->parser = $parser; $this->parser = $parser;
$this->language = $language;
$this->organisationRepository = $organisationRepository; $this->organisationRepository = $organisationRepository;
$this->townRepository = $townRepository; $this->townRepository = $townRepository;
} }
@ -54,16 +58,15 @@ class TouristAttraction implements Converter
$entities = GeneralUtility::makeInstance(EntityCollection::class); $entities = GeneralUtility::makeInstance(EntityCollection::class);
foreach ($this->parser->getLanguages($jsonLD) as $language) { foreach ($this->parser->getLanguages($jsonLD) as $language) {
if ($language !== 'de') { if ($this->language->isUnknown($language, $storagePid)) {
continue; continue;
} }
$systemLanguageUid = 0;
$entity = GeneralUtility::makeInstance( $entity = GeneralUtility::makeInstance(
GenericEntity::class, GenericEntity::class,
$storagePid, $storagePid,
'tx_thuecat_tourist_attraction', 'tx_thuecat_tourist_attraction',
$systemLanguageUid, $this->language->getSystemUid($language, $storagePid),
$this->parser->getId($jsonLD), $this->parser->getId($jsonLD),
[ [
'title' => $this->parser->getTitle($jsonLD, $language), 'title' => $this->parser->getTitle($jsonLD, $language),

View file

@ -0,0 +1,64 @@
<?php
namespace WerkraumMedia\ThueCat\Domain\Import\Importer;
/*
* 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\Site\Entity\SiteLanguage;
use TYPO3\CMS\Core\Site\SiteFinder;
class LanguageHandling
{
private SiteFinder $siteFinder;
public function __construct(
SiteFinder $siteFinder
) {
$this->siteFinder = $siteFinder;
}
public function isUnknown(string $languageIsoCode, int $pageUid): bool
{
$availableIsoCodes = array_map(function (SiteLanguage $language) {
return $language->getTwoLetterIsoCode();
}, $this->getLanguages($pageUid));
return in_array($languageIsoCode, $availableIsoCodes) === false;
}
public function getSystemUid(string $languageIsoCode, int $pageUid): int
{
foreach ($this->getLanguages($pageUid) as $language) {
if ($language->getTwoLetterIsoCode() === $languageIsoCode) {
return $language->getLanguageId();
}
}
return 0;
}
/**
* @return SiteLanguage[]
*/
private function getLanguages(int $pageUid): array
{
return $this->siteFinder->getSiteByPageId($pageUid)->getLanguages();
}
}

View file

@ -48,39 +48,54 @@ class SaveData
{ {
$this->errorLog = []; $this->errorLog = [];
$this->processSimpleDataHandlerDataMap($entityCollection); $this->updateKnownData($entityCollection);
// TODO: Insert update / insert of localization $this->createEntities($entityCollection);
$this->updateKnownData($entityCollection);
$this->updateEntities($entityCollection);
foreach ($entityCollection->getEntities() as $entity) { foreach ($entityCollection->getEntities() as $entity) {
$log->addEntry(new ImportLogEntry($entity, $this->errorLog)); $log->addEntry(new ImportLogEntry($entity, $this->errorLog));
} }
} }
private function processSimpleDataHandlerDataMap(EntityCollection $collection): void private function updateKnownData(EntityCollection $entities): void
{ {
$dataArray = []; foreach ($entities->getEntities() as $entity) {
$identifierMapping = []; if ($entity->exists()) {
foreach ($collection->getEntities() as $entity) {
$identifier = $this->getIdentifier($entity);
if (strpos($identifier, 'NEW') === 0 && $entity->isTranslation()) {
continue; continue;
} }
$identifier = $this->getIdentifier($entity);
if (is_numeric($identifier)) { if (is_numeric($identifier)) {
$entity->setExistingTypo3Uid((int) $identifier); $entity->setExistingTypo3Uid((int) $identifier);
} else { }
$identifierMapping[spl_object_id($entity)] = $identifier; }
} }
$dataArray[$entity->getTypo3DatabaseTableName()][$identifier] = $this->getEntityData($entity); private function createEntities(EntityCollection $entities): void
{
$this->createDefaultLanguageEntities($entities);
$this->createTranslationEntities($entities);
} }
private function createDefaultLanguageEntities(EntityCollection $entities): void
{
$identifierMapping = [];
$entity = $entities->getDefaultLanguageEntity();
if ($entity === null) {
return;
}
$identifier = $this->getIdentifier($entity);
$identifierMapping[spl_object_id($entity)] = $identifier;
$dataArray[$entity->getTypo3DatabaseTableName()][$identifier] = $this->getEntityData($entity);
$dataHandler = clone $this->dataHandler; $dataHandler = clone $this->dataHandler;
$dataHandler->start($dataArray, []); $dataHandler->start($dataArray, []);
$dataHandler->process_datamap(); $dataHandler->process_datamap();
$this->errorLog = array_merge($this->errorLog, $dataHandler->errorLog); $this->errorLog = array_merge($this->errorLog, $dataHandler->errorLog);
foreach ($collection->getEntities() as $entity) { foreach ($entities->getEntities() as $entity) {
if ( if (
isset($identifierMapping[spl_object_id($entity)]) isset($identifierMapping[spl_object_id($entity)])
&& isset($dataHandler->substNEWwithIDs[$identifierMapping[spl_object_id($entity)]]) && isset($dataHandler->substNEWwithIDs[$identifierMapping[spl_object_id($entity)]])
@ -90,6 +105,40 @@ class SaveData
} }
} }
private function createTranslationEntities(EntityCollection $entities): void
{
$commandMap = [];
foreach ($entities->getEntitiesToTranslate() as $entity) {
$identifier = $this->getDefaultLanguageIdentifier($entity);
if (
$entity->isForDefaultLanguage()
|| $identifier === 0
) {
continue;
}
$commandMap[$entity->getTypo3DatabaseTableName()][$identifier]['localize'] = $entity->getTypo3SystemLanguageUid();
$dataHandler = clone $this->dataHandler;
$dataHandler->start([], $commandMap);
$dataHandler->process_cmdmap();
$this->errorLog = array_merge($this->errorLog, $dataHandler->errorLog);
}
}
private function updateEntities(EntityCollection $entities): void
{
$dataArray = [];
foreach ($entities->getExistingEntities() as $entity) {
$dataArray[$entity->getTypo3DatabaseTableName()][$entity->getTypo3Uid()] = $this->getEntityData($entity);
}
$dataHandler = clone $this->dataHandler;
$dataHandler->start($dataArray, []);
$dataHandler->process_datamap();
$this->errorLog = array_merge($this->errorLog, $dataHandler->errorLog);
}
private function getIdentifier(Entity $entity): string private function getIdentifier(Entity $entity): string
{ {
$existingUid = $this->getExistingUid($entity); $existingUid = $this->getExistingUid($entity);
@ -113,6 +162,11 @@ class SaveData
private function getExistingUid(Entity $entity): int private function getExistingUid(Entity $entity): int
{ {
$tableColumns = $this->connectionPool
->getConnectionForTable($entity->getTypo3DatabaseTableName())
->getSchemaManager()
->listTableColumns($entity->getTypo3DatabaseTableName());
$queryBuilder = $this->connectionPool->getQueryBuilderForTable($entity->getTypo3DatabaseTableName()); $queryBuilder = $this->connectionPool->getQueryBuilderForTable($entity->getTypo3DatabaseTableName());
$queryBuilder->getRestrictions()->removeAll(); $queryBuilder->getRestrictions()->removeAll();
$queryBuilder->select('uid'); $queryBuilder->select('uid');
@ -121,6 +175,35 @@ class SaveData
'remote_id', 'remote_id',
$queryBuilder->createNamedParameter($entity->getRemoteId()) $queryBuilder->createNamedParameter($entity->getRemoteId())
)); ));
if (isset($tableColumns['sys_language_uid'])) {
$queryBuilder->andWhere($queryBuilder->expr()->eq(
'sys_language_uid',
$queryBuilder->createNamedParameter($entity->getTypo3SystemLanguageUid())
));
}
$result = $queryBuilder->execute()->fetchColumn();
if (is_numeric($result)) {
return (int) $result;
}
return 0;
}
private function getDefaultLanguageIdentifier(Entity $entity): int
{
$queryBuilder = $this->connectionPool->getQueryBuilderForTable($entity->getTypo3DatabaseTableName());
$queryBuilder->getRestrictions()->removeAll();
$queryBuilder->select('uid');
$queryBuilder->from($entity->getTypo3DatabaseTableName());
$queryBuilder->where($queryBuilder->expr()->eq(
'remote_id',
$queryBuilder->createNamedParameter($entity->getRemoteId())
));
$queryBuilder->andWhere($queryBuilder->expr()->eq(
'sys_language_uid',
$queryBuilder->createNamedParameter(0)
));
$result = $queryBuilder->execute()->fetchColumn(); $result = $queryBuilder->execute()->fetchColumn();
if (is_numeric($result)) { if (is_numeric($result)) {

View file

@ -64,6 +64,11 @@ interface Entity
*/ */
public function getTypo3Uid(): int; public function getTypo3Uid(): int;
/**
* Must return true in case the entitiy did exist.
*/
public function exists(): bool;
/** /**
* Must return true in case the entitiy did not exist. * Must return true in case the entitiy did not exist.
*/ */

View file

@ -57,10 +57,19 @@ class EntityCollection
/** /**
* @return Entity[] * @return Entity[]
*/ */
public function getTranslatedEntities(): array public function getEntitiesToTranslate(): array
{ {
return array_filter($this->entities, function (Entity $entity) { return array_filter($this->entities, function (Entity $entity) {
return $entity->isTranslation(); return $entity->isTranslation()
&& $entity->exists() === false
;
});
}
public function getExistingEntities(): array
{
return array_filter($this->entities, function (Entity $entity) {
return $entity->exists();
}); });
} }
} }

View file

@ -99,6 +99,11 @@ class GenericEntity implements Entity
return $this->typo3Uid; return $this->typo3Uid;
} }
public function exists(): bool
{
return $this->getTypo3Uid() !== 0;
}
public function wasCreated(): bool public function wasCreated(): bool
{ {
return $this->created; return $this->created;

View file

@ -29,11 +29,13 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper; use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface; use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
class ResolveEntities implements DataProcessorInterface class ResolveEntities implements DataProcessorInterface
{ {
private ConnectionPool $connectionPool; private ConnectionPool $connectionPool;
private DataMapper $dataMapper; private DataMapper $dataMapper;
private TypoScriptFrontendController $tsfe;
public function __construct( public function __construct(
ConnectionPool $connectionPool, ConnectionPool $connectionPool,
@ -41,6 +43,7 @@ class ResolveEntities implements DataProcessorInterface
) { ) {
$this->connectionPool = $connectionPool; $this->connectionPool = $connectionPool;
$this->dataMapper = $dataMapper; $this->dataMapper = $dataMapper;
$this->tsfe = $GLOBALS['TSFE'];
} }
public function process( public function process(
@ -50,36 +53,44 @@ class ResolveEntities implements DataProcessorInterface
array $processedData array $processedData
) { ) {
$as = $cObj->stdWrapValue('as', $processorConfiguration, 'entities'); $as = $cObj->stdWrapValue('as', $processorConfiguration, 'entities');
$table = $cObj->stdWrapValue('table', $processorConfiguration, ''); $tableName = $cObj->stdWrapValue('table', $processorConfiguration, '');
$uids = $cObj->stdWrapValue('uids', $processorConfiguration, ''); $uids = $cObj->stdWrapValue('uids', $processorConfiguration, '');
$uids = GeneralUtility::intExplode(',', $uids); $uids = GeneralUtility::intExplode(',', $uids);
if ($uids === [] || $table === '') { if ($uids === [] || $tableName === '') {
return $processedData; return $processedData;
} }
$processedData[$as] = $this->resolveEntities($table, $uids); $processedData[$as] = $this->resolveEntities($tableName, $uids);
return $processedData; return $processedData;
} }
private function resolveEntities(string $table, array $uids): array private function resolveEntities(string $tableName, array $uids): array
{ {
$targetType = '\WerkraumMedia\ThueCat\Domain\Model\Frontend\\' . $this->convertTableToEntity($table); $targetType = '\WerkraumMedia\ThueCat\Domain\Model\Frontend\\' . $this->convertTableToEntity($tableName);
$queryBuilder = $this->connectionPool->getQueryBuilderForTable($table); $queryBuilder = $this->connectionPool->getQueryBuilderForTable($tableName);
$queryBuilder->select('*'); $queryBuilder->select('*');
$queryBuilder->from($table); $queryBuilder->from($tableName);
$queryBuilder->where($queryBuilder->expr()->in( $queryBuilder->where($queryBuilder->expr()->in(
'uid', 'uid',
$queryBuilder->createNamedParameter($uids, Connection::PARAM_INT_ARRAY) $queryBuilder->createNamedParameter($uids, Connection::PARAM_INT_ARRAY)
)); ));
return $this->dataMapper->map($targetType, $queryBuilder->execute()->fetchAll()); $rows = [];
foreach ($queryBuilder->execute() as $row) {
$row = $this->tsfe->sys_page->getLanguageOverlay($tableName, $row);
if (is_array($row)) {
$rows[] = $row;
}
} }
private function convertTableToEntity(string $table): string return $this->dataMapper->map($targetType, $rows);
}
private function convertTableToEntity(string $tableName): string
{ {
$entityPart = str_replace('tx_thuecat_', '', $table); $entityPart = str_replace('tx_thuecat_', '', $tableName);
return GeneralUtility::underscoredToUpperCamelCase($entityPart); return GeneralUtility::underscoredToUpperCamelCase($entityPart);
} }
} }

View file

@ -38,6 +38,11 @@ defined('TYPO3') or die();
'records' => [ 'records' => [
'config' => [ 'config' => [
'allowed' => 'tx_thuecat_tourist_attraction', 'allowed' => 'tx_thuecat_tourist_attraction',
'suggestOptions' => [
'tx_thuecat_tourist_attraction' => [
'addWhere' => 'sys_language_uid in (0,-1)',
],
],
], ],
], ],
], ],

View file

@ -60,6 +60,15 @@ return (static function (string $extensionKey, string $tableName) {
'readOnly' => true, 'readOnly' => true,
], ],
], ],
'manages_tourist_attraction' => [
'label' => $languagePath . '.manages_tourist_attraction',
'config' => [
'type' => 'inline',
'foreign_table' => 'tx_thuecat_tourist_attraction',
'foreign_field' => 'managed_by',
'readOnly' => true,
],
],
'tstamp' => [ 'tstamp' => [
'label' => $languagePath . '.tstamp', 'label' => $languagePath . '.tstamp',
'config' => [ 'config' => [
@ -74,7 +83,7 @@ return (static function (string $extensionKey, string $tableName) {
'0' => [ '0' => [
'showitem' => 'title, description, remote_id, tstamp' 'showitem' => 'title, description, remote_id, tstamp'
. ',--div--;' . $languagePath . '.div.manages' . ',--div--;' . $languagePath . '.div.manages'
. ',manages_towns, manages_tourist_information', . ',manages_towns, manages_tourist_information, manages_tourist_attraction',
], ],
], ],
]; ];

View file

@ -17,10 +17,50 @@ return (static function (string $extensionKey, string $tableName) {
'disabled' => 'disable', 'disabled' => 'disable',
], ],
'searchFields' => 'title, description', 'searchFields' => 'title, description',
'transOrigPointerField' => 'l18n_parent',
'transOrigDiffSourceField' => 'l18n_diffsource',
'languageField' => 'sys_language_uid',
'translationSource' => 'l10n_source',
], ],
'columns' => [ 'columns' => [
'sys_language_uid' => [
'exclude' => true,
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'special' => 'languages',
'items' => [
[
'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.allLanguages',
-1,
'flags-multiple',
],
],
'default' => 0,
],
],
'l18n_parent' => [
'displayCond' => 'FIELD:sys_language_uid:>:0',
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'items' => [['', 0]],
'foreign_table' => $tableName,
'foreign_table_where' => 'AND ' . $tableName . '.pid=###CURRENT_PID### AND ' . $tableName . '.sys_language_uid IN (-1,0)',
'default' => 0,
],
],
'l10n_source' => [
'config' => [
'type' => 'passthrough',
],
],
'title' => [ 'title' => [
'label' => $languagePath . '.title', 'label' => $languagePath . '.title',
'l10n_mode' => 'prefixLangTitle',
'config' => [ 'config' => [
'type' => 'input', 'type' => 'input',
'size' => 20, 'size' => 20,
@ -30,6 +70,7 @@ return (static function (string $extensionKey, string $tableName) {
], ],
'description' => [ 'description' => [
'label' => $languagePath . '.description', 'label' => $languagePath . '.description',
'l10n_mode' => 'prefixLangTitle',
'config' => [ 'config' => [
'type' => 'text', 'type' => 'text',
'readOnly' => true, 'readOnly' => true,
@ -37,6 +78,7 @@ return (static function (string $extensionKey, string $tableName) {
], ],
'opening_hours' => [ 'opening_hours' => [
'label' => $languagePath . '.opening_hours', 'label' => $languagePath . '.opening_hours',
'l10n_mode' => 'exclude',
'config' => [ 'config' => [
'type' => 'text', 'type' => 'text',
'readOnly' => true, 'readOnly' => true,
@ -44,6 +86,7 @@ return (static function (string $extensionKey, string $tableName) {
], ],
'address' => [ 'address' => [
'label' => $languagePath . '.address', 'label' => $languagePath . '.address',
'l10n_mode' => 'exclude',
'config' => [ 'config' => [
'type' => 'text', 'type' => 'text',
'readOnly' => true, 'readOnly' => true,
@ -51,6 +94,7 @@ return (static function (string $extensionKey, string $tableName) {
], ],
'media' => [ 'media' => [
'label' => $languagePath . '.media', 'label' => $languagePath . '.media',
'l10n_mode' => 'exclude',
'config' => [ 'config' => [
'type' => 'text', 'type' => 'text',
'readOnly' => true, 'readOnly' => true,
@ -58,6 +102,7 @@ return (static function (string $extensionKey, string $tableName) {
], ],
'remote_id' => [ 'remote_id' => [
'label' => $languagePath . '.remote_id', 'label' => $languagePath . '.remote_id',
'l10n_mode' => 'exclude',
'config' => [ 'config' => [
'type' => 'input', 'type' => 'input',
'readOnly' => true, 'readOnly' => true,
@ -65,6 +110,7 @@ return (static function (string $extensionKey, string $tableName) {
], ],
'town' => [ 'town' => [
'label' => $languagePath . '.town', 'label' => $languagePath . '.town',
'l10n_mode' => 'exclude',
'config' => [ 'config' => [
'type' => 'select', 'type' => 'select',
'renderType' => 'selectSingle', 'renderType' => 'selectSingle',
@ -80,6 +126,7 @@ return (static function (string $extensionKey, string $tableName) {
], ],
'managed_by' => [ 'managed_by' => [
'label' => $languagePath . '.managed_by', 'label' => $languagePath . '.managed_by',
'l10n_mode' => 'exclude',
'config' => [ 'config' => [
'type' => 'select', 'type' => 'select',
'renderType' => 'selectSingle', 'renderType' => 'selectSingle',
@ -94,9 +141,15 @@ return (static function (string $extensionKey, string $tableName) {
], ],
], ],
], ],
'palettes' => [
'language' => [
'label' => $languagePath . '.palette.language',
'showitem' => 'sys_language_uid,l18n_parent',
],
],
'types' => [ 'types' => [
'0' => [ '0' => [
'showitem' => 'title, description, opening_hours, address, media, remote_id, town, managed_by', 'showitem' => '--palette--;;language, title, description, opening_hours, address, media, remote_id, --div--;' . $languagePath . '.tab.relations, town, managed_by',
], ],
], ],
]; ];

View file

@ -27,6 +27,9 @@
<trans-unit id="tx_thuecat_organisation.manages_tourist_information" xml:space="preserve"> <trans-unit id="tx_thuecat_organisation.manages_tourist_information" xml:space="preserve">
<source>Tourist Information</source> <source>Tourist Information</source>
</trans-unit> </trans-unit>
<trans-unit id="tx_thuecat_organisation.manages_tourist_attraction" xml:space="preserve">
<source>Tourist Attraction</source>
</trans-unit>
<trans-unit id="tx_thuecat_tourist_information" xml:space="preserve"> <trans-unit id="tx_thuecat_tourist_information" xml:space="preserve">
<source>Tourist Information</source> <source>Tourist Information</source>
@ -75,6 +78,12 @@
<trans-unit id="tx_thuecat_tourist_attraction" xml:space="preserve"> <trans-unit id="tx_thuecat_tourist_attraction" xml:space="preserve">
<source>Tourist Attraction</source> <source>Tourist Attraction</source>
</trans-unit> </trans-unit>
<trans-unit id="tx_thuecat_tourist_attraction.palette.language" xml:space="preserve">
<source>Language</source>
</trans-unit>
<trans-unit id="tx_thuecat_tourist_attraction.tab.relations" xml:space="preserve">
<source>Relations</source>
</trans-unit>
<trans-unit id="tx_thuecat_tourist_attraction.title" xml:space="preserve"> <trans-unit id="tx_thuecat_tourist_attraction.title" xml:space="preserve">
<source>Title</source> <source>Title</source>
</trans-unit> </trans-unit>
@ -90,6 +99,9 @@
<trans-unit id="tx_thuecat_tourist_attraction.address" xml:space="preserve"> <trans-unit id="tx_thuecat_tourist_attraction.address" xml:space="preserve">
<source>Address</source> <source>Address</source>
</trans-unit> </trans-unit>
<trans-unit id="tx_thuecat_tourist_attraction.media" xml:space="preserve">
<source>Media</source>
</trans-unit>
<trans-unit id="tx_thuecat_tourist_attraction.town" xml:space="preserve"> <trans-unit id="tx_thuecat_tourist_attraction.town" xml:space="preserve">
<source>Town</source> <source>Town</source>
</trans-unit> </trans-unit>

View file

@ -1,11 +1,21 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<dataset> <dataset>
<pages> <pages>
<uid>10</uid> <uid>1</uid>
<pid>0</pid> <pid>0</pid>
<tstamp>1613400587</tstamp> <tstamp>1613400587</tstamp>
<crdate>1613400558</crdate> <crdate>1613400558</crdate>
<cruser_id>1</cruser_id> <cruser_id>1</cruser_id>
<doktype>4</doktype>
<title>Rootpage</title>
<is_siteroot>1</is_siteroot>
</pages>
<pages>
<uid>10</uid>
<pid>1</pid>
<tstamp>1613400587</tstamp>
<crdate>1613400558</crdate>
<cruser_id>1</cruser_id>
<doktype>254</doktype> <doktype>254</doktype>
<title>Storage folder</title> <title>Storage folder</title>
</pages> </pages>

View file

@ -1,15 +1,41 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<dataset> <dataset>
<pages> <pages>
<uid>10</uid> <uid>1</uid>
<pid>0</pid> <pid>0</pid>
<tstamp>1613400587</tstamp> <tstamp>1613400587</tstamp>
<crdate>1613400558</crdate> <crdate>1613400558</crdate>
<cruser_id>1</cruser_id> <cruser_id>1</cruser_id>
<doktype>4</doktype>
<title>Rootpage</title>
<is_siteroot>1</is_siteroot>
</pages>
<pages>
<uid>10</uid>
<pid>1</pid>
<tstamp>1613400587</tstamp>
<crdate>1613400558</crdate>
<cruser_id>1</cruser_id>
<doktype>254</doktype> <doktype>254</doktype>
<title>Storage folder</title> <title>Storage folder</title>
</pages> </pages>
<sys_language>
<uid>1</uid>
<pid>0</pid>
<title>English</title>
<flag>en-us-gb</flag>
<language_isocode>en</language_isocode>
</sys_language>
<sys_language>
<uid>2</uid>
<pid>0</pid>
<title>French</title>
<flag>fr</flag>
<language_isocode>fr</language_isocode>
</sys_language>
<tx_thuecat_import_configuration> <tx_thuecat_import_configuration>
<uid>1</uid> <uid>1</uid>
<pid>0</pid> <pid>0</pid>

View file

@ -0,0 +1,10 @@
tx_thuecat_tourist_attraction
,"uid","pid","sys_language_uid","l18n_parent","l10n_source","l10n_state","remote_id","title","managed_by","town","address"
,1,10,0,0,0,\NULL,"https://thuecat.org/resources/835224016581-dara","Dom St. Marien",1,1,"{""street"":""Domstufen 1"",""zip"":""99084"",""city"":""Erfurt"",""email"":""dominformation@domberg-erfurt.de"",""phone"":""+49 361 6461265"",""fax"":"""",""geo"":{""latitude"":50.975955358589545,""longitude"":11.023667024961856}}"
,2,10,1,1,1,\NULL,"https://thuecat.org/resources/835224016581-dara","Cathedral of St. Mary",1,1,"{""street"":""Domstufen 1"",""zip"":""99084"",""city"":""Erfurt"",""email"":""dominformation@domberg-erfurt.de"",""phone"":""+49 361 6461265"",""fax"":"""",""geo"":{""latitude"":50.975955358589545,""longitude"":11.023667024961856}}"
,3,10,0,0,0,\NULL,"https://thuecat.org/resources/165868194223-zmqf","Alte Synagoge",1,1,"{""street"":""Waagegasse 8"",""zip"":""99084"",""city"":""Erfurt"",""email"":""altesynagoge@erfurt.de"",""phone"":""+49 361 6551520"",""fax"":""+49 361 6551669"",""geo"":{""latitude"":50.978765,""longitude"":11.029133}}"
,4,10,1,3,3,\NULL,"https://thuecat.org/resources/165868194223-zmqf","Old Synagogue",1,1,"{""street"":""Waagegasse 8"",""zip"":""99084"",""city"":""Erfurt"",""email"":""altesynagoge@erfurt.de"",""phone"":""+49 361 6551520"",""fax"":""+49 361 6551669"",""geo"":{""latitude"":50.978765,""longitude"":11.029133}}"
,5,10,2,3,3,\NULL,"https://thuecat.org/resources/165868194223-zmqf","La vieille synagogue",1,1,"{""street"":""Waagegasse 8"",""zip"":""99084"",""city"":""Erfurt"",""email"":""altesynagoge@erfurt.de"",""phone"":""+49 361 6551520"",""fax"":""+49 361 6551669"",""geo"":{""latitude"":50.978765,""longitude"":11.029133}}"
,6,10,0,0,0,\NULL,"https://thuecat.org/resources/215230952334-yyno","Krämerbrücke",1,1,"{""street"":""Benediktsplatz 1"",""zip"":""99084"",""city"":""Erfurt"",""email"":""service@erfurt-tourismus.de"",""phone"":""+49 361 66 400"",""fax"":"""",""geo"":{""latitude"":50.978772,""longitude"":11.031622}}"
,7,10,1,6,6,\NULL,"https://thuecat.org/resources/215230952334-yyno","Merchants' Bridge",1,1,"{""street"":""Benediktsplatz 1"",""zip"":""99084"",""city"":""Erfurt"",""email"":""service@erfurt-tourismus.de"",""phone"":""+49 361 66 400"",""fax"":"""",""geo"":{""latitude"":50.978772,""longitude"":11.031622}}"
,8,10,2,6,6,\NULL,"https://thuecat.org/resources/215230952334-yyno","Pont de l'épicier",1,1,"{""street"":""Benediktsplatz 1"",""zip"":""99084"",""city"":""Erfurt"",""email"":""service@erfurt-tourismus.de"",""phone"":""+49 361 66 400"",""fax"":"""",""geo"":{""latitude"":50.978772,""longitude"":11.031622}}"
Can't render this file because it has a wrong number of fields in line 2.

View file

@ -0,0 +1,47 @@
base: 'https:/example.com'
languages:
-
title: Deutsch
enabled: true
base: /
typo3Language: de
locale: de_DE.UTF-8
iso-639-1: de
navigationTitle: Deutsch
hreflang: de-DE
direction: ''
flag: de
websiteTitle: ''
languageId: 0
-
title: English
enabled: true
base: /en
typo3Language: default
locale: en_GB.UTF-8
iso-639-1: en
websiteTitle: ''
navigationTitle: English
hreflang: en-GB
direction: ''
flag: gb
languageId: 1
fallbackType: strict
fallbacks: '0'
-
title: French
enabled: true
base: /fr/
typo3Language: fr
locale: fr_FR.ytf8
iso-639-1: fr
websiteTitle: ''
navigationTitle: ''
hreflang: fr-FR
direction: ''
fallbackType: strict
fallbacks: '1,0'
flag: fr
languageId: 2
rootPageId: 1
websiteTitle: 'Example Website'

View file

@ -52,6 +52,7 @@ use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase as TestCase;
* @uses WerkraumMedia\ThueCat\Domain\Import\Converter\Town * @uses WerkraumMedia\ThueCat\Domain\Import\Converter\Town
* @uses WerkraumMedia\ThueCat\Domain\Import\Importer * @uses WerkraumMedia\ThueCat\Domain\Import\Importer
* @uses WerkraumMedia\ThueCat\Domain\Import\Importer\FetchData * @uses WerkraumMedia\ThueCat\Domain\Import\Importer\FetchData
* @uses WerkraumMedia\ThueCat\Domain\Import\Importer\LanguageHandling
* @uses WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser * @uses WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser
* @uses WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\Address * @uses WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\Address
* @uses WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\Media * @uses WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\Media
@ -83,6 +84,10 @@ class ImportTest extends TestCase
'typo3conf/ext/thuecat/', 'typo3conf/ext/thuecat/',
]; ];
protected $pathsToLinkInTestInstance = [
'typo3conf/ext/thuecat/Tests/Functional/Fixtures/Import/Sites/' => 'typo3conf/sites',
];
protected function setUp(): void protected function setUp(): void
{ {
parent::setUp(); parent::setUp();
@ -201,34 +206,9 @@ class ImportTest extends TestCase
$extbaseBootstrap->handleBackendRequest($serverRequest->reveal()); $extbaseBootstrap->handleBackendRequest($serverRequest->reveal());
$touristAttractions = $this->getAllRecords('tx_thuecat_tourist_attraction'); $touristAttractions = $this->getAllRecords('tx_thuecat_tourist_attraction');
self::assertCount(3, $touristAttractions); self::assertCount(8, $touristAttractions);
self::assertSame('https://thuecat.org/resources/835224016581-dara', $touristAttractions[0]['remote_id']); $this->assertCSVDataSet('EXT:thuecat/Tests/Functional/Fixtures/Import/ImportsTouristAttractionsWithRelationsResult.csv');
self::assertSame('Dom St. Marien', $touristAttractions[0]['title']);
self::assertSame('[{"opens":"09:30:00","closes":"18:00:00","from":{"date":"2021-05-01 00:00:00.000000","timezone_type":3,"timezone":"UTC"},"through":{"date":"2021-10-31 00:00:00.000000","timezone_type":3,"timezone":"UTC"},"daysOfWeek":["Friday","Monday","Saturday","Thursday","Tuesday","Wednesday"]},{"opens":"13:00:00","closes":"18:00:00","from":{"date":"2021-05-01 00:00:00.000000","timezone_type":3,"timezone":"UTC"},"through":{"date":"2021-10-31 00:00:00.000000","timezone_type":3,"timezone":"UTC"},"daysOfWeek":["Sunday"]},{"opens":"09:30:00","closes":"17:00:00","from":{"date":"2021-11-01 00:00:00.000000","timezone_type":3,"timezone":"UTC"},"through":{"date":"2022-04-30 00:00:00.000000","timezone_type":3,"timezone":"UTC"},"daysOfWeek":["Friday","Monday","Saturday","Thursday","Tuesday","Wednesday"]},{"opens":"13:00:00","closes":"17:00:00","from":{"date":"2021-11-01 00:00:00.000000","timezone_type":3,"timezone":"UTC"},"through":{"date":"2022-04-30 00:00:00.000000","timezone_type":3,"timezone":"UTC"},"daysOfWeek":["Sunday"]}]', $touristAttractions[0]['opening_hours']);
self::assertSame('{"street":"Domstufen 1","zip":"99084","city":"Erfurt","email":"dominformation@domberg-erfurt.de","phone":"+49 361 6461265","fax":"","geo":{"latitude":50.975955358589545,"longitude":11.023667024961856}}', $touristAttractions[0]['address']);
self::assertSame('[{"mainImage":true,"type":"image","title":"Erfurt-Dom und Severikirche-beleuchtet.jpg","description":"","url":"https:\/\/cms.thuecat.org\/o\/adaptive-media\/image\/5159216\/Preview-1280x0\/image","copyrightYear":2016,"license":{"type":"https:\/\/creativecommons.org\/licenses\/by\/4.0\/","author":""}},{"mainImage":false,"type":"image","title":"Erfurt-Dom-und-Severikirche.jpg","description":"Sicht auf Dom St. Marien, St. Severikirche sowie die davor liegenden Klostergeb\u00e4ude und einem Ausschnitt des Biergartens umgeben von einem d\u00e4mmerungsverf\u00e4rten Himmel","url":"https:\/\/cms.thuecat.org\/o\/adaptive-media\/image\/5159186\/Preview-1280x0\/image","copyrightYear":2020,"license":{"type":"https:\/\/creativecommons.org\/licenses\/by\/4.0\/","author":""}},{"mainImage":false,"type":"image","title":"Erfurt-Dom und Severikirche-beleuchtet.jpg","description":"","url":"https:\/\/cms.thuecat.org\/o\/adaptive-media\/image\/5159216\/Preview-1280x0\/image","copyrightYear":2016,"license":{"type":"https:\/\/creativecommons.org\/licenses\/by\/4.0\/","author":""}}]', $touristAttractions[0]['media']);
self::assertSame('1', $touristAttractions[0]['managed_by']);
self::assertSame('1', $touristAttractions[0]['town']);
self::assertSame('1', $touristAttractions[0]['uid']);
self::assertSame('https://thuecat.org/resources/165868194223-zmqf', $touristAttractions[1]['remote_id']);
self::assertSame('Alte Synagoge', $touristAttractions[1]['title']);
self::assertSame('[{"opens":"10:00:00","closes":"18:00:00","from":{"date":"2021-03-01 00:00:00.000000","timezone_type":3,"timezone":"UTC"},"through":{"date":"2021-12-31 00:00:00.000000","timezone_type":3,"timezone":"UTC"},"daysOfWeek":["Friday","Saturday","Sunday","Thursday","Tuesday","Wednesday"]}]', $touristAttractions[1]['opening_hours']);
self::assertSame('{"street":"Waagegasse 8","zip":"99084","city":"Erfurt","email":"altesynagoge@erfurt.de","phone":"+49 361 6551520","fax":"+49 361 6551669","geo":{"latitude":50.978765,"longitude":11.029133}}', $touristAttractions[1]['address']);
self::assertSame('[{"mainImage":true,"type":"image","title":"Erfurt-Alte Synagoge","description":"Frontaler Blick auf die Hausfront\/Hausfassade im Innenhof mit Zugang \u00fcber die Waagegasse","url":"https:\/\/cms.thuecat.org\/o\/adaptive-media\/image\/5099196\/Preview-1280x0\/image","copyrightYear":2009,"license":{"type":"https:\/\/creativecommons.org\/licenses\/by\/4.0\/","author":"F:\\\\Bilddatenbank\\\\Museen und Ausstellungen\\\\Alte Synagoge"}},{"mainImage":false,"type":"image","title":"Erfurt-Alte Synagoge","description":"Frontaler Blick auf die Hausfront\/Hausfassade im Innenhof mit Zugang \u00fcber die Waagegasse","url":"https:\/\/cms.thuecat.org\/o\/adaptive-media\/image\/5099196\/Preview-1280x0\/image","copyrightYear":2009,"license":{"type":"https:\/\/creativecommons.org\/licenses\/by\/4.0\/","author":"F:\\\\Bilddatenbank\\\\Museen und Ausstellungen\\\\Alte Synagoge"}}]', $touristAttractions[1]['media']);
self::assertSame('1', $touristAttractions[1]['managed_by']);
self::assertSame('1', $touristAttractions[1]['town']);
self::assertSame('2', $touristAttractions[1]['uid']);
self::assertSame('https://thuecat.org/resources/215230952334-yyno', $touristAttractions[2]['remote_id']);
self::assertSame('Krämerbrücke', $touristAttractions[2]['title']);
self::assertSame('[]', $touristAttractions[2]['opening_hours']);
self::assertSame('{"street":"Benediktsplatz 1","zip":"99084","city":"Erfurt","email":"service@erfurt-tourismus.de","phone":"+49 361 66 400","fax":"","geo":{"latitude":50.978772,"longitude":11.031622}}', $touristAttractions[2]['address']);
self::assertSame('[{"mainImage":true,"type":"image","title":"Erfurt-Kraemerbruecke-11.jpg","description":"Kr\u00e4merbr\u00fccke in Erfurt","url":"https:\/\/cms.thuecat.org\/o\/adaptive-media\/image\/134362\/Preview-1280x0\/image","copyrightYear":2019,"license":{"type":"https:\/\/creativecommons.org\/publicdomain\/zero\/1.0\/deed.de","author":"https:\/\/home.ttgnet.de\/ttg\/projekte\/10006\/90136\/Projektdokumente\/Vergabe%20Rahmenvertrag%20Fotoproduktion"}},{"mainImage":false,"type":"image","title":"Erfurt-Kraemerbruecke.jpg","description":"Kr\u00e4merbr\u00fccke in Erfurt","url":"https:\/\/cms.thuecat.org\/o\/adaptive-media\/image\/134288\/Preview-1280x0\/image","copyrightYear":2019,"license":{"type":"https:\/\/creativecommons.org\/publicdomain\/zero\/1.0\/deed.de","author":"https:\/\/home.ttgnet.de\/ttg\/projekte\/10006\/90136\/Projektdokumente\/Vergabe%20Rahmenvertrag%20Fotoproduktion"}},{"mainImage":false,"type":"image","title":"Erfurt-Kraemerbruecke-11.jpg","description":"Kr\u00e4merbr\u00fccke in Erfurt","url":"https:\/\/cms.thuecat.org\/o\/adaptive-media\/image\/134362\/Preview-1280x0\/image","copyrightYear":2019,"license":{"type":"https:\/\/creativecommons.org\/publicdomain\/zero\/1.0\/deed.de","author":"https:\/\/home.ttgnet.de\/ttg\/projekte\/10006\/90136\/Projektdokumente\/Vergabe%20Rahmenvertrag%20Fotoproduktion"}},{"mainImage":false,"type":"image","title":"Erfurt-Kraemerbruecke-13.jpg","description":"Ansicht der Kr\u00e4merbr\u00fccke, Erfurt","url":"https:\/\/cms.thuecat.org\/o\/adaptive-media\/image\/652340\/Preview-1280x0\/image","copyrightYear":2019,"license":{"type":"https:\/\/creativecommons.org\/publicdomain\/zero\/1.0\/deed.de","author":"https:\/\/home.ttgnet.de\/ttg\/projekte\/10006\/90136\/Projektdokumente\/Vergabe%20Rahmenvertrag%20Fotoproduktion"}}]', $touristAttractions[2]['media']);
self::assertSame('1', $touristAttractions[2]['managed_by']);
self::assertSame('1', $touristAttractions[2]['town']);
self::assertSame('3', $touristAttractions[2]['uid']);
} }
/** /**

View file

@ -26,6 +26,7 @@ namespace WerkraumMedia\ThueCat\Tests\Unit\Domain\Import\Converter;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Prophecy\PhpUnit\ProphecyTrait; use Prophecy\PhpUnit\ProphecyTrait;
use WerkraumMedia\ThueCat\Domain\Import\Converter\TouristAttraction; use WerkraumMedia\ThueCat\Domain\Import\Converter\TouristAttraction;
use WerkraumMedia\ThueCat\Domain\Import\Importer\LanguageHandling;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser; use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser;
use WerkraumMedia\ThueCat\Domain\Import\Model\EntityCollection; use WerkraumMedia\ThueCat\Domain\Import\Model\EntityCollection;
use WerkraumMedia\ThueCat\Domain\Model\Backend\Organisation; use WerkraumMedia\ThueCat\Domain\Model\Backend\Organisation;
@ -48,11 +49,13 @@ class TouristAttractionTest extends TestCase
public function canBeCreated(): void public function canBeCreated(): void
{ {
$parser = $this->prophesize(Parser::class); $parser = $this->prophesize(Parser::class);
$language = $this->prophesize(LanguageHandling::class);
$organisationRepository = $this->prophesize(OrganisationRepository::class); $organisationRepository = $this->prophesize(OrganisationRepository::class);
$townRepository = $this->prophesize(TownRepository::class); $townRepository = $this->prophesize(TownRepository::class);
$subject = new TouristAttraction( $subject = new TouristAttraction(
$parser->reveal(), $parser->reveal(),
$language->reveal(),
$organisationRepository->reveal(), $organisationRepository->reveal(),
$townRepository->reveal() $townRepository->reveal()
); );
@ -66,11 +69,13 @@ class TouristAttractionTest extends TestCase
public function canConvert(): void public function canConvert(): void
{ {
$parser = $this->prophesize(Parser::class); $parser = $this->prophesize(Parser::class);
$language = $this->prophesize(LanguageHandling::class);
$organisationRepository = $this->prophesize(OrganisationRepository::class); $organisationRepository = $this->prophesize(OrganisationRepository::class);
$townRepository = $this->prophesize(TownRepository::class); $townRepository = $this->prophesize(TownRepository::class);
$subject = new TouristAttraction( $subject = new TouristAttraction(
$parser->reveal(), $parser->reveal(),
$language->reveal(),
$organisationRepository->reveal(), $organisationRepository->reveal(),
$townRepository->reveal() $townRepository->reveal()
); );
@ -120,11 +125,16 @@ class TouristAttractionTest extends TestCase
$parser->getAddress($jsonLD)->willReturn([]); $parser->getAddress($jsonLD)->willReturn([]);
$parser->getMedia($jsonLD)->willReturn([]); $parser->getMedia($jsonLD)->willReturn([]);
$language = $this->prophesize(LanguageHandling::class);
$language->isUnknown('de', 10)->willReturn(false);
$language->getSystemUid('de', 10)->willReturn(0);
$organisationRepository = $this->prophesize(OrganisationRepository::class); $organisationRepository = $this->prophesize(OrganisationRepository::class);
$townRepository = $this->prophesize(TownRepository::class); $townRepository = $this->prophesize(TownRepository::class);
$subject = new TouristAttraction( $subject = new TouristAttraction(
$parser->reveal(), $parser->reveal(),
$language->reveal(),
$organisationRepository->reveal(), $organisationRepository->reveal(),
$townRepository->reveal() $townRepository->reveal()
); );
@ -191,6 +201,10 @@ class TouristAttractionTest extends TestCase
$parser->getAddress($jsonLD)->willReturn([]); $parser->getAddress($jsonLD)->willReturn([]);
$parser->getMedia($jsonLD)->willReturn([]); $parser->getMedia($jsonLD)->willReturn([]);
$language = $this->prophesize(LanguageHandling::class);
$language->isUnknown('de', 10)->willReturn(false);
$language->getSystemUid('de', 10)->willReturn(0);
$organisation = $this->prophesize(Organisation::class); $organisation = $this->prophesize(Organisation::class);
$organisation->getUid()->willReturn(10); $organisation->getUid()->willReturn(10);
$organisationRepository = $this->prophesize(OrganisationRepository::class); $organisationRepository = $this->prophesize(OrganisationRepository::class);
@ -206,6 +220,7 @@ class TouristAttractionTest extends TestCase
$subject = new TouristAttraction( $subject = new TouristAttraction(
$parser->reveal(), $parser->reveal(),
$language->reveal(),
$organisationRepository->reveal(), $organisationRepository->reveal(),
$townRepository->reveal() $townRepository->reveal()
); );

View file

@ -0,0 +1,144 @@
<?php
namespace WerkraumMedia\ThueCat\Tests\Unit\Domain\Import\Importer;
/*
* 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 TYPO3\CMS\Core\Site\Entity\Site;
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
use TYPO3\CMS\Core\Site\SiteFinder;
use WerkraumMedia\ThueCat\Domain\Import\Importer\LanguageHandling;
/**
* @covers WerkraumMedia\ThueCat\Domain\Import\Importer\LanguageHandling
*/
class LanguageHandlingTest extends TestCase
{
use ProphecyTrait;
/**
* @test
*/
public function canBeCreated(): void
{
$siteFinder = $this->prophesize(SiteFinder::class);
$subject = new LanguageHandling(
$siteFinder->reveal()
);
self::assertInstanceOf(LanguageHandling::class, $subject);
}
/**
* @test
*/
public function allowsToCheckForUnkownLanguage(): void
{
$language = $this->prophesize(SiteLanguage::class);
$language->getTwoLetterIsoCode()->willReturn('en');
$site = $this->prophesize(Site::class);
$site->getLanguages()->willReturn([$language->reveal()]);
$siteFinder = $this->prophesize(SiteFinder::class);
$siteFinder->getSiteByPageId(10)->willReturn($site->reveal());
$subject = new LanguageHandling(
$siteFinder->reveal()
);
$result = $subject->isUnknown('de', 10);
self::assertTrue($result);
}
/**
* @test
*/
public function allowsToCheckForKnownLanguage(): void
{
$language = $this->prophesize(SiteLanguage::class);
$language->getTwoLetterIsoCode()->willReturn('de');
$site = $this->prophesize(Site::class);
$site->getLanguages()->willReturn([$language->reveal()]);
$siteFinder = $this->prophesize(SiteFinder::class);
$siteFinder->getSiteByPageId(10)->willReturn($site->reveal());
$subject = new LanguageHandling(
$siteFinder->reveal()
);
$result = $subject->isUnknown('de', 10);
self::assertFalse($result);
}
/**
* @test
*/
public function providesSystemLanguageUidForLanguage(): void
{
$language = $this->prophesize(SiteLanguage::class);
$language->getTwoLetterIsoCode()->willReturn('de');
$language->getLanguageId()->willReturn(2);
$site = $this->prophesize(Site::class);
$site->getLanguages()->willReturn([$language->reveal()]);
$siteFinder = $this->prophesize(SiteFinder::class);
$siteFinder->getSiteByPageId(10)->willReturn($site->reveal());
$subject = new LanguageHandling(
$siteFinder->reveal()
);
$result = $subject->getSystemUid('de', 10);
self::assertSame(2, $result);
}
/**
* @test
*/
public function providesZeroAsFallbackSystemLanguageUidForUnkownLanguage(): void
{
$language = $this->prophesize(SiteLanguage::class);
$language->getTwoLetterIsoCode()->willReturn('fr');
$site = $this->prophesize(Site::class);
$site->getLanguages()->willReturn([$language->reveal()]);
$siteFinder = $this->prophesize(SiteFinder::class);
$siteFinder->getSiteByPageId(10)->willReturn($site->reveal());
$subject = new LanguageHandling(
$siteFinder->reveal()
);
$result = $subject->getSystemUid('de', 10);
self::assertSame(0, $result);
}
}

View file

@ -96,43 +96,39 @@ class EntityCollectionTest extends TestCase
/** /**
* @test * @test
*/ */
public function returnsAllTranslatedEntities(): void public function returnsEntitiesToTranslate(): void
{ {
$entityWithTranslation1 = $this->prophesize(Entity::class); $entityWithTranslation = $this->prophesize(Entity::class);
$entityWithTranslation1->isTranslation()->willReturn(true); $entityWithTranslation->isTranslation()->willReturn(true);
$entityWithTranslation2 = $this->prophesize(Entity::class); $entityWithTranslation->exists()->willReturn(false);
$entityWithTranslation2->isTranslation()->willReturn(true);
$entitiyWithDefaultLanguage = $this->prophesize(Entity::class);
$entitiyWithDefaultLanguage->isTranslation()->willReturn(false);
$subject = new EntityCollection(); $subject = new EntityCollection();
$subject->add($entityWithTranslation1->reveal()); $subject->add($entityWithTranslation->reveal());
$subject->add($entitiyWithDefaultLanguage->reveal());
$subject->add($entityWithTranslation2->reveal());
self::assertSame( self::assertSame(
[ [
0 => $entityWithTranslation1->reveal(), $entityWithTranslation->reveal(),
2 => $entityWithTranslation2->reveal(),
], ],
$subject->getTranslatedEntities() $subject->getEntitiesToTranslate()
); );
} }
/** /**
* @test * @test
*/ */
public function returnsEmptyArrayIfNoTranslatedEntityExists(): void public function returnsExistingEntities(): void
{ {
$entitiyWithDefaultLanguage = $this->prophesize(Entity::class); $entityWithTranslation = $this->prophesize(Entity::class);
$entitiyWithDefaultLanguage->isTranslation()->willReturn(false); $entityWithTranslation->exists()->willReturn(true);
$subject = new EntityCollection(); $subject = new EntityCollection();
$subject->add($entitiyWithDefaultLanguage->reveal()); $subject->add($entityWithTranslation->reveal());
self::assertSame( self::assertSame(
[], [
$subject->getTranslatedEntities() $entityWithTranslation->reveal(),
],
$subject->getExistingEntities()
); );
} }
} }

View file

@ -175,12 +175,28 @@ class GenericEntityTest extends TestCase
'', '',
[] []
); );
self::assertSame( self::assertFalse(
false,
$subject->wasCreated() $subject->wasCreated()
); );
} }
/**
* @test
*/
public function returnsNotExistingByDefault(): void
{
$subject = new GenericEntity(
0,
'',
0,
'',
[]
);
self::assertFalse(
$subject->exists()
);
}
/** /**
* @test * @test
*/ */
@ -213,7 +229,8 @@ class GenericEntityTest extends TestCase
); );
$subject->setImportedTypo3Uid(10); $subject->setImportedTypo3Uid(10);
self::assertSame(true, $subject->wasCreated()); self::assertTrue($subject->wasCreated());
self::assertTrue($subject->exists());
self::assertSame(10, $subject->getTypo3Uid()); self::assertSame(10, $subject->getTypo3Uid());
} }
@ -231,7 +248,8 @@ class GenericEntityTest extends TestCase
); );
$subject->setExistingTypo3Uid(10); $subject->setExistingTypo3Uid(10);
self::assertSame(false, $subject->wasCreated()); self::assertFalse($subject->wasCreated());
self::assertTrue($subject->exists());
self::assertSame(10, $subject->getTypo3Uid()); self::assertSame(10, $subject->getTypo3Uid());
} }
} }

View file

@ -23,6 +23,7 @@ CREATE TABLE tx_thuecat_organisation (
description text DEFAULT '' NOT NULL, description text DEFAULT '' NOT NULL,
manages_towns int(11) unsigned DEFAULT '0' NOT NULL, manages_towns int(11) unsigned DEFAULT '0' NOT NULL,
manages_tourist_information int(11) unsigned DEFAULT '0' NOT NULL, manages_tourist_information int(11) unsigned DEFAULT '0' NOT NULL,
manages_tourist_attraction int(11) unsigned DEFAULT '0' NOT NULL,
); );
CREATE TABLE tx_thuecat_town ( CREATE TABLE tx_thuecat_town (

View file

@ -2,7 +2,7 @@ parameters:
ignoreErrors: ignoreErrors:
- -
message: "#^Cannot call method fetchColumn\\(\\) on Doctrine\\\\DBAL\\\\Driver\\\\Statement\\|int\\.$#" message: "#^Cannot call method fetchColumn\\(\\) on Doctrine\\\\DBAL\\\\Driver\\\\Statement\\|int\\.$#"
count: 1 count: 2
path: Classes/Domain/Import/Importer/SaveData.php path: Classes/Domain/Import/Importer/SaveData.php
- -
@ -21,7 +21,12 @@ parameters:
path: Classes/Domain/Repository/Backend/TownRepository.php path: Classes/Domain/Repository/Backend/TownRepository.php
- -
message: "#^Cannot call method fetchAll\\(\\) on Doctrine\\\\DBAL\\\\Driver\\\\Statement\\|int\\.$#" message: "#^Argument of an invalid type Doctrine\\\\DBAL\\\\Driver\\\\Statement\\|int supplied for foreach, only iterables are supported\\.$#"
count: 1
path: Classes/Frontend/DataProcessing/ResolveEntities.php
-
message: "#^Cannot call method getLanguageOverlay\\(\\) on string\\|TYPO3\\\\CMS\\\\Core\\\\Domain\\\\Repository\\\\PageRepository\\.$#"
count: 1 count: 1
path: Classes/Frontend/DataProcessing/ResolveEntities.php path: Classes/Frontend/DataProcessing/ResolveEntities.php