Initial import mechanism

Provide first basic import mechanism.
It already allows to import entities into TYPO3 database.
Three entities are supported.

Entities are configured through import configuration.
This can be created, viewed, and edited through backend module.

Imports are tracked and accessible from backend module.

Still this is basic.
Importing lists of entities is not supported.
Multiple languages is not supported, etc.

Relates: #8214
This commit is contained in:
Daniel Siepmann 2021-02-01 14:14:05 +01:00
parent 7386a0601a
commit dc1c45f1c1
69 changed files with 4546 additions and 11 deletions

View file

@ -0,0 +1,59 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Controller\Backend;
/*
* 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\Backend\View\BackendTemplateView;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
use WerkraumMedia\ThueCat\View\Backend\Menu;
abstract class AbstractController extends ActionController
{
/**
* BackendTemplateContainer
*
* @var BackendTemplateView
*/
protected $view;
/**
* Backend Template Container
*
* @var string
*/
protected $defaultViewObjectName = BackendTemplateView::class;
protected function initializeView(ViewInterface $view)
{
if ($view instanceof BackendTemplateView) {
$this->getMenu()->addMenu(
$view->getModuleTemplate()->getDocHeaderComponent()->getMenuRegistry(),
$this->uriBuilder,
get_class($this)
);
}
}
abstract protected function getMenu(): Menu;
}

View file

@ -0,0 +1,80 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Controller\Backend;
/*
* 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\Importer;
use WerkraumMedia\ThueCat\Domain\Model\Backend\ImportConfiguration;
use WerkraumMedia\ThueCat\Domain\Repository\Backend\ImportLogRepository;
use WerkraumMedia\ThueCat\Extension;
use WerkraumMedia\ThueCat\Typo3Wrapper\TranslationService;
use WerkraumMedia\ThueCat\View\Backend\Menu;
class ImportController extends AbstractController
{
private Importer $importer;
private ImportLogRepository $repository;
private TranslationService $translation;
private Menu $menu;
public function __construct(
Importer $importer,
ImportLogRepository $repository,
TranslationService $translation,
Menu $menu
) {
$this->importer = $importer;
$this->repository = $repository;
$this->translation = $translation;
$this->menu = $menu;
}
public function indexAction(): void
{
$this->view->assignMultiple([
'imports' => $this->repository->findAll(),
]);
}
public function importAction(ImportConfiguration $importConfiguration): void
{
$this->importer->importConfiguration($importConfiguration);
$this->addFlashMessage(
$this->translation->translate(
'controller.backend.import.import.success.text',
Extension::EXTENSION_NAME,
[$importConfiguration->getTitle()]
),
$this->translation->translate(
'controller.backend.import.import.success.title',
Extension::EXTENSION_NAME
)
);
$this->redirect('index', 'Backend\Overview');
}
protected function getMenu(): Menu
{
return $this->menu;
}
}

View file

@ -0,0 +1,58 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Controller\Backend;
/*
* 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\Repository\Backend\ImportConfigurationRepository;
use WerkraumMedia\ThueCat\Domain\Repository\Backend\OrganisationRepository;
use WerkraumMedia\ThueCat\View\Backend\Menu;
class OverviewController extends AbstractController
{
private OrganisationRepository $organisationRepository;
private ImportConfigurationRepository $importConfigurationRepository;
private Menu $menu;
public function __construct(
OrganisationRepository $organisationRepository,
ImportConfigurationRepository $importConfigurationRepository,
Menu $menu
) {
$this->organisationRepository = $organisationRepository;
$this->importConfigurationRepository = $importConfigurationRepository;
$this->menu = $menu;
}
public function indexAction(): void
{
$this->view->assignMultiple([
'importConfigurations' => $this->importConfigurationRepository->findAll(),
'organisations' => $this->organisationRepository->findAll(),
]);
}
protected function getMenu(): Menu
{
return $this->menu;
}
}

View file

@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\DependencyInjection;
/*
* 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 Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use WerkraumMedia\ThueCat\Domain\Import\Converter\Registry;
class ConverterPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$registry = $container->findDefinition(Registry::class);
foreach ($container->findTaggedServiceIds('thuecat.converter') as $id => $tags) {
$definition = $container->findDefinition($id);
if (!$definition->isAutoconfigured() || $definition->isAbstract()) {
continue;
}
// Services that implement MyCustomInterface need to be public,
// to be lazy loadable by the registry via $container->get()
// $container->findDefinition($id)->setPublic(true);
$registry->addMethodCall('registerConverter', [$definition]);
}
}
}

View file

@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\DependencyInjection;
/*
* 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 Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use WerkraumMedia\ThueCat\Domain\Import\UrlProvider\Registry;
class UrlProvidersPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$registry = $container->findDefinition(Registry::class);
foreach ($container->findTaggedServiceIds('thuecat.urlprovider') as $id => $tags) {
$definition = $container->findDefinition($id);
if (!$definition->isAutoconfigured() || $definition->isAbstract()) {
continue;
}
// Services that implement MyCustomInterface need to be public,
// to be lazy loadable by the registry via $container->get()
// $container->findDefinition($id)->setPublic(true);
$registry->addMethodCall('registerProvider', [$definition]);
}
}
}

View file

@ -0,0 +1,37 @@
<?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 WerkraumMedia\ThueCat\Domain\Import\Model\Entity;
interface Converter
{
/**
* A single type is an array of different types.
* All types together identify a specific entity and possible converter.
*/
public function canConvert(array $type): bool;
public function convert(array $jsonIdOfEntity): Entity;
}

View file

@ -0,0 +1,47 @@
<?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 WerkraumMedia\ThueCat\Domain\Import\Model\GenericEntity;
class Organisation implements Converter
{
public function convert(array $jsonIdOfEntity): GenericEntity
{
return new GenericEntity(
95,
'tx_thuecat_organisation',
$jsonIdOfEntity['@id'],
[
'title' => $jsonIdOfEntity['schema:name']['@value'],
'description' => $jsonIdOfEntity['schema:description']['@value'],
]
);
}
public function canConvert(array $type): bool
{
return array_search('thuecat:TouristMarketingCompany', $type) !== false;
}
}

View file

@ -0,0 +1,48 @@
<?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.
*/
/**
* Central registry of all available converters.
*/
class Registry
{
private array $converters = [];
public function registerConverter(Converter $converter): void
{
$this->converters[] = $converter;
}
public function getConverterBasedOnType(array $type): ?Converter
{
foreach ($this->converters as $converter) {
if ($converter->canConvert($type)) {
return $converter;
}
}
return null;
}
}

View file

@ -0,0 +1,72 @@
<?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 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 OrganisationRepository $organisationRepository;
private TownRepository $townRepository;
public function __construct(
OrganisationRepository $organisationRepository,
TownRepository $townRepository
) {
$this->organisationRepository = $organisationRepository;
$this->townRepository = $townRepository;
}
public function convert(array $jsonIdOfEntity): GenericEntity
{
$manager = $this->organisationRepository->findOneByRemoteId($jsonIdOfEntity['thuecat:managedBy']['@id']);
$town = $this->townRepository->findOneByRemoteIds($this->getContainedInPlaceIds($jsonIdOfEntity));
return new GenericEntity(
95,
'tx_thuecat_tourist_information',
$jsonIdOfEntity['@id'],
[
'title' => $jsonIdOfEntity['schema:name']['@value'],
'description' => $jsonIdOfEntity['schema:description'][0]['@value'],
'managed_by' => $manager ? $manager->getUid() : 0,
'town' => $town ? $town->getUid() : 0,
]
);
}
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

@ -0,0 +1,58 @@
<?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 WerkraumMedia\ThueCat\Domain\Import\Model\GenericEntity;
use WerkraumMedia\ThueCat\Domain\Repository\Backend\OrganisationRepository;
class Town implements Converter
{
private OrganisationRepository $organisationRepository;
public function __construct(
OrganisationRepository $organisationRepository
) {
$this->organisationRepository = $organisationRepository;
}
public function convert(array $jsonIdOfEntity): GenericEntity
{
$manager = $this->organisationRepository->findOneByRemoteId($jsonIdOfEntity['thuecat:managedBy']['@id']);
return new GenericEntity(
95,
'tx_thuecat_town',
$jsonIdOfEntity['@id'],
[
'title' => $jsonIdOfEntity['schema:name']['@value'],
'description' => $jsonIdOfEntity['schema:description']['@value'] ?? '',
'managed_by' => $manager ? $manager->getUid() : 0,
]
);
}
public function canConvert(array $type): bool
{
return array_search('thuecat:Town', $type) !== false;
}
}

View file

@ -0,0 +1,93 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Domain\Import;
/*
* 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\Converter\Converter;
use WerkraumMedia\ThueCat\Domain\Import\Converter\Registry as ConverterRegistry;
use WerkraumMedia\ThueCat\Domain\Import\Importer\FetchData;
use WerkraumMedia\ThueCat\Domain\Import\Importer\SaveData;
use WerkraumMedia\ThueCat\Domain\Import\UrlProvider\Registry as UrlProviderRegistry;
use WerkraumMedia\ThueCat\Domain\Model\Backend\ImportConfiguration;
use WerkraumMedia\ThueCat\Domain\Model\Backend\ImportLog;
use WerkraumMedia\ThueCat\Domain\Repository\Backend\ImportLogRepository;
class Importer
{
private UrlProviderRegistry $urls;
private ConverterRegistry $converter;
private FetchData $fetchData;
private SaveData $saveData;
private ImportLog $importLog;
private ImportLogRepository $importLogRepository;
public function __construct(
UrlProviderRegistry $urls,
ConverterRegistry $converter,
ImportLogRepository $importLogRepository,
FetchData $fetchData,
SaveData $saveData
) {
$this->urls = $urls;
$this->converter = $converter;
$this->importLogRepository = $importLogRepository;
$this->fetchData = $fetchData;
$this->saveData = $saveData;
}
public function importConfiguration(ImportConfiguration $configuration): ImportLog
{
$this->importLog = GeneralUtility::makeInstance(ImportLog::class, $configuration);
$urlProvider = $this->urls->getProviderForConfiguration($configuration);
foreach ($urlProvider->getUrls() as $url) {
$this->importResourceByUrl($url);
}
$this->importLogRepository->addLog($this->importLog);
return clone $this->importLog;
}
private function importResourceByUrl(string $url): void
{
$content = $this->fetchData->jsonLDFromUrl($url);
if ($content === []) {
return;
}
foreach ($content['@graph'] as $jsonEntity) {
$this->importJsonEntity($jsonEntity);
}
}
private function importJsonEntity(array $jsonEntity): void
{
$converter = $this->converter->getConverterBasedOnType($jsonEntity['@type']);
if ($converter instanceof Converter) {
$this->saveData->import($converter->convert($jsonEntity), $this->importLog);
return;
}
}
}

View file

@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
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 Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestFactoryInterface;
class FetchData
{
public function __construct(
RequestFactoryInterface $requestFactory,
ClientInterface $httpClient
) {
$this->requestFactory = $requestFactory;
$this->httpClient = $httpClient;
}
public function jsonLDFromUrl(string $url): array
{
$request = $this->requestFactory->createRequest('GET', $url);
$response = $this->httpClient->sendRequest($request);
$json = json_decode((string) $response->getBody(), true);
if (is_array($json)) {
return $json;
}
return [];
}
}

View file

@ -0,0 +1,102 @@
<?php
declare(strict_types=1);
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\Database\ConnectionPool;
use TYPO3\CMS\Core\DataHandling\DataHandler;
use WerkraumMedia\ThueCat\Domain\Import\Model\Entity;
use WerkraumMedia\ThueCat\Domain\Model\Backend\ImportLog;
use WerkraumMedia\ThueCat\Domain\Model\Backend\ImportLogEntry;
class SaveData
{
private DataHandler $dataHandler;
private ConnectionPool $connectionPool;
public function __construct(
DataHandler $dataHandler,
ConnectionPool $connectionPool
) {
$this->dataHandler = $dataHandler;
$this->dataHandler->stripslashes_values = 0;
$this->connectionPool = $connectionPool;
}
public function import(Entity $entity, ImportLog $log): void
{
$dataHandler = clone $this->dataHandler;
$identifier = $this->getIdentifier($entity);
$dataHandler->start([
$entity->getTypo3DatabaseTableName() => [
$identifier => array_merge($entity->getData(), [
'pid' => $entity->getTypo3StoragePid(),
'remote_id' => $entity->getRemoteId(),
]),
],
], []);
$dataHandler->process_datamap();
if (isset($dataHandler->substNEWwithIDs[$identifier])) {
$entity->setImportedTypo3Uid($dataHandler->substNEWwithIDs[$identifier]);
} elseif (is_numeric($identifier)) {
$entity->setExistingTypo3Uid((int) $identifier);
}
$log->addEntry(new ImportLogEntry(
$entity,
$dataHandler->errorLog
));
}
private function getIdentifier(Entity $entity): string
{
$existingUid = $this->getExistingUid($entity);
if ($existingUid > 0) {
return (string) $existingUid;
}
return 'NEW_1';
}
private function getExistingUid(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())
));
$result = $queryBuilder->execute()->fetchColumn();
if (is_numeric($result)) {
return (int) $result;
}
return 0;
}
}

View file

@ -0,0 +1,65 @@
<?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.
*/
interface Entity
{
public function getTypo3StoragePid(): int;
public function getTypo3DatabaseTableName(): string;
/**
* Return full remote id as delivered by remote API.
*/
public function getRemoteId(): string;
/**
* Return db_column_name => db_value.
*/
public function getData(): array;
/**
* Might be called during import.
* Only in case entitiy already existed.
* Is then called with existing UID from system.
*/
public function setExistingTypo3Uid(int $uid): void;
/**
* Might be called during import.
* Only in case entitiy didn't exist within system.
* Is then called with new UID from system.
*/
public function setImportedTypo3Uid(int $uid): void;
/**
* Should be 0 if no uid is known.
*/
public function getTypo3Uid(): int;
/**
* Must return true in case the entitiy did not exist.
*/
public function wasCreated(): bool;
}

View file

@ -0,0 +1,88 @@
<?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 GenericEntity implements Entity
{
private int $typo3StoragePid;
private string $typo3DatabaseTableName;
private bool $created = false;
private int $typo3Uid = 0;
private string $remoteId;
private array $data;
public function __construct(
int $typo3StoragePid,
string $typo3DatabaseTableName,
string $remoteId,
array $data
) {
$this->typo3StoragePid = $typo3StoragePid;
$this->typo3DatabaseTableName = $typo3DatabaseTableName;
$this->remoteId = $remoteId;
$this->data = $data;
}
public function getTypo3StoragePid(): int
{
return $this->typo3StoragePid;
}
public function getTypo3DatabaseTableName(): string
{
return $this->typo3DatabaseTableName;
}
public function getRemoteId(): string
{
return $this->remoteId;
}
public function getData(): array
{
return $this->data;
}
public function setImportedTypo3Uid(int $uid): void
{
$this->typo3Uid = $uid;
$this->created = true;
}
public function setExistingTypo3Uid(int $uid): void
{
$this->typo3Uid = $uid;
$this->created = false;
}
public function getTypo3Uid(): int
{
return $this->typo3Uid;
}
public function wasCreated(): bool
{
return $this->created;
}
}

View file

@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Domain\Import;
/*
* 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 Psr\Http\Message\RequestInterface;
use TYPO3\CMS\Core\Http\RequestFactory as Typo3RequestFactory;
use TYPO3\CMS\Core\Http\Uri;
class RequestFactory extends Typo3RequestFactory
{
public function createRequest(string $method, $uri): RequestInterface
{
$uri = new Uri($uri);
$uri = $uri->withQuery('?format=jsonId');
// TODO: Add api key from site
return parent::createRequest($method, $uri);
}
}

View file

@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Domain\Import\UrlProvider;
/*
* 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\Model\Backend\ImportConfiguration;
/**
* Central registry of all available url provider.
*/
class Registry
{
private array $provider = [];
public function registerProvider(UrlProvider $provider): void
{
$this->provider[] = $provider;
}
/**
* @return UrlProvider[]
*/
public function getProviderForConfiguration(ImportConfiguration $configuration): ?UrlProvider
{
foreach ($this->provider as $provider) {
if ($provider->canProvideForConfiguration($configuration)) {
return $provider->createWithConfiguration($configuration);
}
}
return null;
}
}

View file

@ -0,0 +1,57 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Domain\Import\UrlProvider;
/*
* 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\Model\Backend\ImportConfiguration;
class StaticUrlProvider implements UrlProvider
{
private array $urls = [];
public function __construct(
ImportConfiguration $configuration
) {
if ($configuration instanceof ImportConfiguration) {
$this->urls = $configuration->getUrls();
}
}
public function canProvideForConfiguration(
ImportConfiguration $configuration
): bool {
return $configuration->getType() === 'static';
}
public function createWithConfiguration(
ImportConfiguration $configuration
): UrlProvider {
return GeneralUtility::makeInstance(self::class, $configuration);
}
public function getUrls(): array
{
return $this->urls;
}
}

View file

@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Domain\Import\UrlProvider;
/*
* 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\Model\Backend\ImportConfiguration;
interface UrlProvider
{
/**
* @var string[]
*/
public function getUrls(): array;
public function canProvideForConfiguration(ImportConfiguration $configuration): bool;
public function createWithConfiguration(ImportConfiguration $configuration): UrlProvider;
}

View file

@ -0,0 +1,54 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Domain\Model\Backend;
/*
* 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 as Typo3AbstractEntity;
class AbstractEntity extends Typo3AbstractEntity
{
protected string $remoteId = '';
protected string $title = '';
protected string $description = '';
protected ?\DateTimeImmutable $tstamp = null;
public function getRemoteId(): string
{
return $this->remoteId;
}
public function getTitle(): string
{
return $this->title;
}
public function getDescription(): string
{
return $this->description;
}
public function getLastImported(): ?\DateTimeImmutable
{
return $this->tstamp;
}
}

View file

@ -0,0 +1,77 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Domain\Model\Backend;
/*
* 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\ArrayUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
class ImportConfiguration extends AbstractEntity
{
protected string $title = '';
protected string $type = '';
protected string $configuration = '';
protected ?\DateTimeImmutable $tstamp = null;
public function getTitle(): string
{
return $this->title;
}
public function getType(): string
{
return $this->type;
}
public function getTableName(): string
{
return 'tx_thuecat_import_configuration';
}
public function getLastChanged(): ?\DateTimeImmutable
{
return $this->tstamp;
}
public function getUrls(): array
{
if ($this->configuration === '') {
return [];
}
$entries = array_map(function (array $urlEntry) {
return ArrayUtility::getValueByPath($urlEntry, 'url/el/url/vDEF');
}, $this->getEntries());
return array_values($entries);
}
private function getEntries(): array
{
return ArrayUtility::getValueByPath(
GeneralUtility::xml2array($this->configuration),
'data/sDEF/lDEF/urls/el'
);
}
}

View file

@ -0,0 +1,114 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Domain\Model\Backend;
/*
* 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 as Typo3AbstractEntity;
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
class ImportLog extends Typo3AbstractEntity
{
/**
* @var ObjectStorage<ImportLogEntry>
*/
protected $logEntries = [];
/**
* @var ImportConfiguration
*/
protected $configuration;
/**
* @var \DateTimeImmutable|null
*/
protected $crdate;
public function __construct(
ImportConfiguration $configuration
) {
$this->logEntries = new ObjectStorage();
$this->configuration = $configuration;
}
public function addEntry(ImportLogEntry $entry): void
{
$this->logEntries->attach($entry);
}
public function getConfiguration(): ImportConfiguration
{
return $this->configuration;
}
/**
* @return ObjectStorage<ImportLogEntry>
*/
public function getEntries(): ObjectStorage
{
return $this->logEntries;
}
public function getCreated(): ?\DateTimeImmutable
{
return $this->crdate;
}
public function getListOfErrors(): array
{
$errors = [];
foreach ($this->getEntries() as $entry) {
if ($entry->hasErrors()) {
$errors = array_merge($errors, $entry->getErrors());
}
}
return $errors;
}
public function hasErrors(): bool
{
foreach ($this->getEntries() as $entry) {
if ($entry->hasErrors()) {
return true;
}
}
return false;
}
public function getSummaryOfEntries(): array
{
$summary = [];
foreach ($this->getEntries() as $entry) {
if (isset($summary[$entry->getRecordDatabaseTableName()])) {
++$summary[$entry->getRecordDatabaseTableName()];
continue;
}
$summary[$entry->getRecordDatabaseTableName()] = 1;
}
return $summary;
}
}

View file

@ -0,0 +1,97 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Domain\Model\Backend;
/*
* 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 as Typo3AbstractEntity;
use WerkraumMedia\ThueCat\Domain\Import\Model\Entity;
class ImportLogEntry extends Typo3AbstractEntity
{
/**
* @var bool
*/
protected $insertion = false;
/**
* @var int
*/
protected $recordUid = 0;
/**
* @var int
*/
protected $recordPid = 0;
/**
* @var string
*/
protected $tableName = '';
/**
* @var string
*/
protected $errors = '';
protected array $errorsAsArray = [];
public function __construct(
Entity $entity,
array $dataHandlerErrorLog
) {
$this->insertion = $entity->wasCreated();
$this->recordUid = $entity->getTypo3Uid();
$this->recordPid = $entity->getTypo3StoragePid();
$this->tableName = $entity->getTypo3DatabaseTableName();
$this->errorsAsArray = $dataHandlerErrorLog;
}
public function wasInsertion(): bool
{
return $this->insertion;
}
public function getRecordUid(): int
{
return $this->recordUid;
}
public function getRecordDatabaseTableName(): string
{
return $this->tableName;
}
public function getErrors(): array
{
if ($this->errorsAsArray === [] && $this->errors !== '') {
$this->errorsAsArray = json_decode($this->errors, true);
}
return $this->errorsAsArray;
}
public function hasErrors(): bool
{
return $this->getErrors() !== [];
}
}

View file

@ -0,0 +1,54 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Domain\Model\Backend;
/*
* 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\Persistence\ObjectStorage;
class Organisation extends AbstractEntity
{
/**
* @var ObjectStorage<Town>
*/
protected $managesTowns;
/**
* @var ObjectStorage<TouristInformation>
*/
protected $managesTouristInformation;
public function getManagesTowns(): ObjectStorage
{
return $this->managesTowns;
}
public function getManagesTouristInformation(): ObjectStorage
{
return $this->managesTouristInformation;
}
public function getTableName(): string
{
return 'tx_thuecat_organisation';
}
}

View file

@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Domain\Model\Backend;
/*
* 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 TouristInformation extends AbstractEntity
{
}

View file

@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Domain\Model\Backend;
/*
* 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\Persistence\ObjectStorage;
class Town extends AbstractEntity
{
/**
* @var ObjectStorage<TouristInformation>
*/
protected $touristInformation;
public function getTouristInformation(): ObjectStorage
{
return $this->touristInformation;
}
}

View file

@ -0,0 +1,42 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Domain\Repository\Backend;
/*
* 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\Object\ObjectManagerInterface;
use TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings;
use TYPO3\CMS\Extbase\Persistence\Repository;
class ImportConfigurationRepository extends Repository
{
public function __construct(
ObjectManagerInterface $objectManager,
Typo3QuerySettings $querySettings
) {
parent::__construct($objectManager);
$querySettings->setRespectStoragePage(false);
$this->setDefaultQuerySettings($querySettings);
}
}

View file

@ -0,0 +1,90 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Domain\Repository\Backend;
/*
* 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\DataHandling\DataHandler;
use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
use TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings;
use TYPO3\CMS\Extbase\Persistence\QueryInterface;
use TYPO3\CMS\Extbase\Persistence\Repository;
use WerkraumMedia\ThueCat\Domain\Model\Backend\ImportLog;
class ImportLogRepository extends Repository
{
private DataHandler $dataHandler;
public function __construct(
ObjectManagerInterface $objectManager,
DataHandler $dataHandler,
Typo3QuerySettings $querySettings
) {
parent::__construct($objectManager);
$this->dataHandler = $dataHandler;
$this->dataHandler->stripslashes_values = 0;
$querySettings->setRespectStoragePage(false);
$this->setDefaultQuerySettings($querySettings);
$this->setDefaultOrderings([
'crdate' => QueryInterface::ORDER_DESCENDING,
]);
}
public function addLog(ImportLog $log): void
{
$dataHandler = clone $this->dataHandler;
$dataHandler->start([
'tx_thuecat_import_log' => [
'NEW0' => [
'pid' => 0,
'configuration' => $log->getConfiguration()->getUid(),
],
],
'tx_thuecat_import_log_entry' => $this->getLogEntries($log),
], []);
$dataHandler->process_datamap();
}
private function getLogEntries(ImportLog $log): array
{
$number = 1;
$entries = [];
foreach ($log->getEntries() as $entry) {
$number++;
$entries['NEW' . $number] = [
'pid' => 0,
'import_log' => 'NEW0',
'insertion' => $entry->wasInsertion(),
'record_uid' => $entry->getRecordUid(),
'table_name' => $entry->getRecordDatabaseTableName(),
'errors' => json_encode($entry->getErrors()),
];
}
return $entries;
}
}

View file

@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Domain\Repository\Backend;
/*
* 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\Object\ObjectManagerInterface;
use TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings;
use TYPO3\CMS\Extbase\Persistence\Repository;
/**
* @method Organisation|null findOneByRemoteId(string $remoteId)
*/
class OrganisationRepository extends Repository
{
public function __construct(
ObjectManagerInterface $objectManager,
Typo3QuerySettings $querySettings
) {
parent::__construct($objectManager);
$querySettings->setRespectStoragePage(false);
$this->setDefaultQuerySettings($querySettings);
}
}

View file

@ -0,0 +1,56 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Domain\Repository\Backend;
/*
* 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\Object\ObjectManagerInterface;
use TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings;
use TYPO3\CMS\Extbase\Persistence\Repository;
use WerkraumMedia\ThueCat\Domain\Model\Backend\Town;
/**
* @method Town|null findOneByRemoteIds(string[] $remoteIds)
*/
class TownRepository extends Repository
{
public function __construct(
ObjectManagerInterface $objectManager,
Typo3QuerySettings $querySettings
) {
parent::__construct($objectManager);
$querySettings->setRespectStoragePage(false);
$this->setDefaultQuerySettings($querySettings);
}
public function findOneByRemoteIds(array $remoteIds): ?Town
{
$query = $this->createQuery();
$query->in('remoteId', $remoteIds);
$query->setLimit(1);
return $query->execute()->getFirst();
}
}

59
Classes/Extension.php Normal file
View file

@ -0,0 +1,59 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat;
/*
* 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\Utility\ExtensionUtility;
use WerkraumMedia\ThueCat\Controller\Backend\ImportController;
use WerkraumMedia\ThueCat\Controller\Backend\OverviewController;
class Extension
{
public const EXTENSION_KEY = 'thuecat';
public const EXTENSION_NAME = 'Thuecat';
public static function getLanguagePath(): string
{
return 'LLL:EXT:' . self::EXTENSION_KEY . '/Resources/Private/Language/';
}
public static function registerBackendModules(): void
{
ExtensionUtility::registerModule(
self::EXTENSION_NAME,
'site',
'thuecat',
'',
[
OverviewController::class => 'index',
ImportController::class => 'import, index',
],
[
'access' => 'user,group',
'icon' => 'EXT:' . self::EXTENSION_KEY . '/Resources/Public/Icons/module.svg',
'labels' => self::getLanguagePath() . 'locallang_mod.xlf',
]
);
}
}

View file

@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Typo3Wrapper;
/*
* 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\Utility\LocalizationUtility;
class TranslationService
{
public function translate(
string $id,
string $extensionName,
array $arguments = null
): string {
return LocalizationUtility::translate($id, $extensionName, $arguments) ?? '';
}
}

View file

@ -0,0 +1,65 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\View\Backend;
/*
* 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\Backend\Template\Components\MenuRegistry;
use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder;
use WerkraumMedia\ThueCat\Controller\Backend\ImportController;
use WerkraumMedia\ThueCat\Controller\Backend\OverviewController;
use WerkraumMedia\ThueCat\Extension;
use WerkraumMedia\ThueCat\Typo3Wrapper\TranslationService;
class Menu
{
private TranslationService $translation;
public function __construct(
TranslationService $translation
) {
$this->translation = $translation;
}
public function addMenu(
MenuRegistry $registry,
UriBuilder $uriBuilder,
string $controllerClassName
): void {
$menu = $registry->makeMenu();
$menu->setIdentifier('action');
$menuItem = $menu->makeMenuItem();
$menuItem->setTitle($this->translation->translate('module.overview.headline', Extension::EXTENSION_NAME));
$menuItem->setHref($uriBuilder->reset()->uriFor('index', [], 'Backend\Overview'));
$menuItem->setActive($controllerClassName === OverviewController::class);
$menu->addMenuItem($menuItem);
$menuItem = $menu->makeMenuItem();
$menuItem->setTitle($this->translation->translate('module.imports.headline', Extension::EXTENSION_NAME));
$menuItem->setHref($uriBuilder->reset()->uriFor('index', [], 'Backend\Import'));
$menuItem->setActive($controllerClassName === ImportController::class);
$menu->addMenuItem($menuItem);
$registry->addMenu($menu);
}
}

View file

@ -0,0 +1,22 @@
<?php
return [
\WerkraumMedia\ThueCat\Domain\Model\Backend\Organisation::class => [
'tableName' => 'tx_thuecat_organisation',
],
\WerkraumMedia\ThueCat\Domain\Model\Backend\Town::class => [
'tableName' => 'tx_thuecat_town',
],
\WerkraumMedia\ThueCat\Domain\Model\Backend\TouristInformation::class => [
'tableName' => 'tx_thuecat_tourist_information',
],
\WerkraumMedia\ThueCat\Domain\Model\Backend\ImportConfiguration::class => [
'tableName' => 'tx_thuecat_import_configuration',
],
\WerkraumMedia\ThueCat\Domain\Model\Backend\ImportLog::class => [
'tableName' => 'tx_thuecat_import_log',
],
\WerkraumMedia\ThueCat\Domain\Model\Backend\ImportLogEntry::class => [
'tableName' => 'tx_thuecat_import_log_entry',
],
];

View file

@ -0,0 +1,39 @@
<T3DataStructure>
<meta>
<langDisable>1</langDisable>
</meta>
<sheets>
<sDEF>
<ROOT>
<TCEforms>
<sheetTitle>LLL:EXT:thuecat/Resources/Private/Language/locallang_flexform.xlf:importConfiguration.static.sheetTitle</sheetTitle>
</TCEforms>
<type>array</type>
<el>
<urls>
<title>LLL:EXT:thuecat/Resources/Private/Language/locallang_flexform.xlf:importConfiguration.static.urls</title>
<section>1</section>
<type>array</type>
<el>
<url>
<title>LLL:EXT:thuecat/Resources/Private/Language/locallang_flexform.xlf:importConfiguration.static.url</title>
<type>array</type>
<el>
<url>
<TCEforms>
<label>LLL:EXT:thuecat/Resources/Private/Language/locallang_flexform.xlf:importConfiguration.static.url</label>
<config>
<type>input</type>
<eval>required,trim</eval>
</config>
</TCEforms>
</url>
</el>
</url>
</el>
</urls>
</el>
</ROOT>
</sDEF>
</sheets>
</T3DataStructure>

View file

@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use WerkraumMedia\ThueCat\Domain\Import\Converter\Converter;
use WerkraumMedia\ThueCat\Domain\Import\UrlProvider\UrlProvider;
return function (ContainerConfigurator $container, ContainerBuilder $containerBuilder) {
$containerBuilder->registerForAutoconfiguration(UrlProvider::class)->addTag('thuecat.urlprovider');
$containerBuilder->addCompilerPass(new DependencyInjection\UrlProvidersPass('thuecat.urlprovider'));
$containerBuilder->registerForAutoconfiguration(Converter::class)->addTag('thuecat.converter');
$containerBuilder->addCompilerPass(new DependencyInjection\ConverterPass('thuecat.converter'));
};

View file

@ -0,0 +1,12 @@
services:
_defaults:
autowire: true
autoconfigure: true
public: false
WerkraumMedia\ThueCat\:
resource: '../Classes/*'
WerkraumMedia\ThueCat\Domain\Import\Importer\FetchData:
arguments:
$requestFactory: '@WerkraumMedia\ThueCat\Domain\Import\RequestFactory'

View file

@ -1,5 +1,7 @@
<?php <?php
defined('TYPO3') or die();
(static function (string $extensionKey, string $tableName) { (static function (string $extensionKey, string $tableName) {
$languagePath = 'LLL:EXT:' . $extensionKey . '/Resources/Private/Language/locallang_be.xlf:' . $tableName . '.'; $languagePath = 'LLL:EXT:' . $extensionKey . '/Resources/Private/Language/locallang_be.xlf:' . $tableName . '.';
@ -22,4 +24,4 @@
], ],
], ],
]); ]);
})('thuecat', 'site'); })(\WerkraumMedia\ThueCat\Extension::EXTENSION_KEY, 'site');

View file

@ -0,0 +1,71 @@
<?php
defined('TYPO3') or die();
return (static function (string $extensionKey, string $tableName) {
$languagePath = \WerkraumMedia\ThueCat\Extension::getLanguagePath() . 'locallang_tca.xlf:' . $tableName;
$flexFormConfigurationPath = 'FILE:EXT:' . \WerkraumMedia\ThueCat\Extension::EXTENSION_KEY . '/Configuration/FlexForm/';
return [
'ctrl' => [
'label' => 'title',
'default_sortby' => 'title',
'tstamp' => 'tstamp',
'crdate' => 'crdate',
'cruser_id' => 'cruser_id',
'title' => $languagePath,
'enablecolumns' => [
'disabled' => 'disable',
],
'searchFields' => 'title',
'rootLevel' => 1,
],
'columns' => [
'title' => [
'label' => $languagePath . '.title',
'config' => [
'type' => 'input',
'max' => 255,
'eval' => 'required,trim,unique',
],
],
'type' => [
'label' => $languagePath . '.type',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'items' => [
[
$languagePath . '.type.static',
'static',
],
],
],
],
'configuration' => [
'label' => $languagePath . '.configuration',
'config' => [
'type' => 'flex',
'ds_pointerField' => 'type',
'ds' => [
'default' => $flexFormConfigurationPath . 'ImportConfiguration/Static.xml',
'static' => $flexFormConfigurationPath . 'ImportConfiguration/Static.xml',
],
],
],
'tstamp' => [
'config' => [
'type' => 'input',
'renderType' => 'inputDateTime',
'eval' => 'datetime',
'readOnly' => true,
],
],
],
'types' => [
'0' => [
'showitem' => 'title, type, configuration',
],
],
];
})(\WerkraumMedia\ThueCat\Extension::EXTENSION_KEY, 'tx_thuecat_import_configuration');

View file

@ -0,0 +1,57 @@
<?php
defined('TYPO3') or die();
return (static function (string $extensionKey, string $tableName) {
$languagePath = \WerkraumMedia\ThueCat\Extension::getLanguagePath() . 'locallang_tca.xlf:' . $tableName;
$flexFormConfigurationPath = 'FILE:EXT:' . \WerkraumMedia\ThueCat\Extension::EXTENSION_KEY . '/Configuration/FlexForm/';
return [
'ctrl' => [
'label' => 'crdate',
'default_sortby' => 'crdate',
'tstamp' => 'tstamp',
'crdate' => 'crdate',
'cruser_id' => 'cruser_id',
'title' => $languagePath,
'enablecolumns' => [
'disabled' => 'disable',
],
'rootLevel' => 1,
],
'columns' => [
'configuration' => [
'label' => $languagePath . '.configuration',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'foreign_table' => 'tx_thuecat_import_configuration',
'readOnly' => true,
],
],
'log_entries' => [
'label' => $languagePath . '.log_entries',
'config' => [
'type' => 'inline',
'foreign_table' => 'tx_thuecat_import_log_entry',
'foreign_field' => 'import_log',
'readOnly' => true,
],
],
'crdate' => [
'label' => $languagePath . '.crdate',
'config' => [
'type' => 'input',
'renderType' => 'inputDateTime',
'eval' => 'datetime',
'readOnly' => true,
],
],
],
'types' => [
'0' => [
'showitem' => 'crdate, log_entries, configuration',
],
],
];
})(\WerkraumMedia\ThueCat\Extension::EXTENSION_KEY, 'tx_thuecat_import_log');

View file

@ -0,0 +1,88 @@
<?php
defined('TYPO3') or die();
return (static function (string $extensionKey, string $tableName) {
$languagePath = \WerkraumMedia\ThueCat\Extension::getLanguagePath() . 'locallang_tca.xlf:' . $tableName;
$flexFormConfigurationPath = 'FILE:EXT:' . \WerkraumMedia\ThueCat\Extension::EXTENSION_KEY . '/Configuration/FlexForm/';
return [
'ctrl' => [
'label' => 'table_name',
'label_alt' => 'record_uid',
'label_alt_force' => true,
'default_sortby' => 'title',
'tstamp' => 'tstamp',
'crdate' => 'crdate',
'cruser_id' => 'cruser_id',
'title' => $languagePath,
'enablecolumns' => [
'disabled' => 'disable',
],
'rootLevel' => 1,
'hideTable' => true,
],
'columns' => [
'insertion' => [
'label' => $languagePath . '.insertion',
'config' => [
'type' => 'check',
'renderType' => 'checkboxLabeledToggle',
'items' => [
[
0 => '',
1 => '',
'labelChecked' => $languagePath . '.insertion.yes',
'labelUnchecked' => $languagePath . '.insertion.no',
],
],
'readOnly' => true,
],
],
'table_name' => [
'label' => $languagePath . '.table_name',
'config' => [
'type' => 'input',
'readOnly' => true,
],
],
'record_uid' => [
'label' => $languagePath . '.record_uid',
'config' => [
'type' => 'input',
'readOnly' => true,
],
],
'errors' => [
'label' => $languagePath . '.errors',
'config' => [
'type' => 'text',
'readOnly' => true,
],
],
'import_log' => [
'label' => $languagePath . '.import_log',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'foreign_table' => 'tx_thuecat_import_log',
'readOnly' => true,
],
],
'crdate' => [
'label' => $languagePath . '.crdate',
'config' => [
'type' => 'input',
'renderType' => 'inputDateTime',
'eval' => 'datetime',
'readOnly' => true,
],
],
],
'types' => [
'0' => [
'showitem' => 'table_name, record_uid, insertion, errors, import_log, crdate',
],
],
];
})(\WerkraumMedia\ThueCat\Extension::EXTENSION_KEY, 'tx_thuecat_import_log_entry');

View file

@ -0,0 +1,81 @@
<?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',
],
'columns' => [
'title' => [
'label' => $languagePath . '.title',
'config' => [
'type' => 'input',
'size' => 20,
'max' => 255,
'readOnly' => true,
],
],
'description' => [
'label' => $languagePath . '.description',
'config' => [
'type' => 'text',
'readOnly' => true,
],
],
'remote_id' => [
'label' => $languagePath . '.remote_id',
'config' => [
'type' => 'input',
'readOnly' => true,
],
],
'manages_towns' => [
'label' => $languagePath . '.manages_towns',
'config' => [
'type' => 'inline',
'foreign_table' => 'tx_thuecat_town',
'foreign_field' => 'managed_by',
'readOnly' => true,
],
],
'manages_tourist_information' => [
'label' => $languagePath . '.manages_tourist_information',
'config' => [
'type' => 'inline',
'foreign_table' => 'tx_thuecat_tourist_information',
'foreign_field' => 'managed_by',
'readOnly' => true,
],
],
'tstamp' => [
'label' => $languagePath . '.tstamp',
'config' => [
'type' => 'input',
'renderType' => 'inputDateTime',
'eval' => 'datetime',
'readOnly' => true,
],
],
],
'types' => [
'0' => [
'showitem' => 'title, description, remote_id, tstamp'
. ',--div--;' . $languagePath . '.div.manages'
. ',manages_towns, manages_tourist_information',
],
],
];
})(\WerkraumMedia\ThueCat\Extension::EXTENSION_KEY, 'tx_thuecat_organisation');

View file

@ -0,0 +1,82 @@
<?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',
],
'columns' => [
'title' => [
'label' => $languagePath . '.title',
'config' => [
'type' => 'input',
'size' => 20,
'max' => 255,
'readOnly' => true,
],
],
'description' => [
'label' => $languagePath . '.description',
'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, remote_id, town, managed_by',
],
],
];
})(\WerkraumMedia\ThueCat\Extension::EXTENSION_KEY, 'tx_thuecat_tourist_information');

View file

@ -0,0 +1,76 @@
<?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',
],
'columns' => [
'title' => [
'label' => $languagePath . '.title',
'config' => [
'type' => 'input',
'size' => 20,
'max' => 255,
'readOnly' => true,
],
],
'description' => [
'label' => $languagePath . '.description',
'config' => [
'type' => 'text',
'readOnly' => true,
],
],
'remote_id' => [
'label' => $languagePath . '.remote_id',
'config' => [
'type' => 'input',
'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,
],
],
'tourist_information' => [
'label' => $languagePath . '.tourist_information',
'config' => [
'type' => 'inline',
'foreign_table' => 'tx_thuecat_tourist_information',
'foreign_field' => 'town',
'readOnly' => true,
],
],
],
'types' => [
'0' => [
'showitem' => 'title, description, remote_id, tourist_information, managed_by',
],
],
];
})(\WerkraumMedia\ThueCat\Extension::EXTENSION_KEY, 'tx_thuecat_town');

View file

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" datatype="plaintext" original="messages" date="2021-02-01T09:24:10Z" product-name="ThueCat Plugins and Modules">
<header/>
<body>
<trans-unit id="module.actions" xml:space="preserve">
<source>Actions</source>
</trans-unit>
<trans-unit id="module.overview.headline" xml:space="preserve">
<source>ThüCAT - Overview</source>
</trans-unit>
<trans-unit id="module.importConfigurations.headline" xml:space="preserve">
<source>Import Configurations</source>
</trans-unit>
<trans-unit id="module.importConfigurations.missing.title" xml:space="preserve">
<source>None configured</source>
</trans-unit>
<trans-unit id="module.importConfigurations.title" xml:space="preserve">
<source>Title</source>
</trans-unit>
<trans-unit id="module.importConfigurations.lastChanged" xml:space="preserve">
<source>Last changed</source>
</trans-unit>
<trans-unit id="module.importConfigurations.missing.text" xml:space="preserve">
<source><![CDATA[No import configuration is available yet. Please <a href="%1$s">create the first</a> to get started.]]></source>
</trans-unit>
<trans-unit id="module.importConfigurations.actions.edit" xml:space="preserve">
<source>Edit import configuration</source>
</trans-unit>
<trans-unit id="module.importConfigurations.actions.new" xml:space="preserve">
<source>Create new import configuration</source>
</trans-unit>
<trans-unit id="module.importConfigurations.actions.import" xml:space="preserve">
<source>Import based on import configuration</source>
</trans-unit>
<trans-unit id="module.organisations.headline" xml:space="preserve">
<source>Organisations</source>
</trans-unit>
<trans-unit id="module.organisations.missing.title" xml:space="preserve">
<source>None imported</source>
</trans-unit>
<trans-unit id="module.organisations.missing.text" xml:space="preserve">
<source>Please provide an import configuration and trigger import to create an organisation.</source>
</trans-unit>
<trans-unit id="module.organisation.title" xml:space="preserve">
<source>Organisation</source>
</trans-unit>
<trans-unit id="module.organisation.towns" xml:space="preserve">
<source>Towns</source>
</trans-unit>
<trans-unit id="module.organisation.towns.none" xml:space="preserve">
<source>-</source>
</trans-unit>
<trans-unit id="module.organisation.lastImported" xml:space="preserve">
<source>Last imported</source>
</trans-unit>
<trans-unit id="module.imports.headline" xml:space="preserve">
<source>ThüCAT - Imports</source>
</trans-unit>
<trans-unit id="module.imports.missing.title" xml:space="preserve">
<source>No imports</source>
</trans-unit>
<trans-unit id="module.imports.missing.text" xml:space="preserve">
<source>No import was executed yet.</source>
</trans-unit>
<trans-unit id="module.imports.th.created" xml:space="preserve">
<source>Created</source>
</trans-unit>
<trans-unit id="module.imports.th.amountOfRecords" xml:space="preserve">
<source>Number of records</source>
</trans-unit>
<trans-unit id="module.imports.th.configuration" xml:space="preserve">
<source>Configuration</source>
</trans-unit>
<trans-unit id="module.imports.th.errors" xml:space="preserve">
<source>Errors</source>
</trans-unit>
<trans-unit id="module.imports.th.summary" xml:space="preserve">
<source>Summary</source>
</trans-unit>
<trans-unit id="module.imports.summary.tableName.tx_thuecat_organisation" xml:space="preserve">
<source>Organisation</source>
</trans-unit>
<trans-unit id="module.imports.summary.tableName.tx_thuecat_town" xml:space="preserve">
<source>Town</source>
</trans-unit>
<trans-unit id="module.imports.summary.tableName.tx_thuecat_tourist_information" xml:space="preserve">
<source>Tourist Information</source>
</trans-unit>
<trans-unit id="controller.backend.import.import.success.title" xml:space="preserve">
<source>Import finished</source>
</trans-unit>
<trans-unit id="controller.backend.import.import.success.text" xml:space="preserve">
<source>Imported configuration "%1$s".</source>
</trans-unit>
</body>
</file>
</xliff>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"> <xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" datatype="plaintext" original="messages" date="2021-02-01T09:24:10Z" product-name="Resources"> <file source-language="en" datatype="plaintext" original="messages" date="2021-02-01T09:24:10Z" product-name="ThueCat Backend Labels (SiteConfiguration)">
<header/> <header/>
<body> <body>
<trans-unit id="site.div.thuecat" xml:space="preserve"> <trans-unit id="site.div.thuecat" xml:space="preserve">

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" datatype="plaintext" original="messages" date="2021-02-01T09:24:10Z" product-name="ThueCat FlexForms Labels">
<header/>
<body>
<trans-unit id="importConfiguration.static.sheetTitle" xml:space="preserve">
<source>Static import configuration</source>
</trans-unit>
<trans-unit id="importConfiguration.static.urls" xml:space="preserve">
<source>URLs</source>
</trans-unit>
<trans-unit id="importConfiguration.static.url" xml:space="preserve">
<source>URL</source>
</trans-unit>
</body>
</file>
</xliff>

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" datatype="plaintext" original="messages" date="2021-02-01T09:56:02Z" product-name="ThueCat Backend Module Labels (Title, Description, …)">
<header/>
<body>
<trans-unit id="mlang_labels_tablabel" resname="mlang_labels_tablabel">
<source>ThüCat</source>
</trans-unit>
<trans-unit id="mlang_labels_tabdescr" resname="mlang_labels_tabdescr">
<source>Provides access to current connection, imported data and configuration.</source>
</trans-unit>
<trans-unit id="mlang_tabs_tab" resname="mlang_tabs_tab">
<source>ThüCat</source>
</trans-unit>
</body>
</file>
</xliff>

View file

@ -0,0 +1,133 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" datatype="plaintext" original="messages" date="2021-02-01T09:24:10Z" product-name="ThueCat TCA Labels">
<header/>
<body>
<trans-unit id="tx_thuecat_organisation" xml:space="preserve">
<source>Organisation</source>
</trans-unit>
<trans-unit id="tx_thuecat_organisation.title" xml:space="preserve">
<source>Title</source>
</trans-unit>
<trans-unit id="tx_thuecat_organisation.description" xml:space="preserve">
<source>Description</source>
</trans-unit>
<trans-unit id="tx_thuecat_organisation.remote_id" xml:space="preserve">
<source>Remote ID</source>
</trans-unit>
<trans-unit id="tx_thuecat_organisation.tstamp" xml:space="preserve">
<source>Last imported</source>
</trans-unit>
<trans-unit id="tx_thuecat_organisation.div.manages" xml:space="preserve">
<source>Manages</source>
</trans-unit>
<trans-unit id="tx_thuecat_organisation.manages_towns" xml:space="preserve">
<source>Towns</source>
</trans-unit>
<trans-unit id="tx_thuecat_organisation.manages_tourist_information" xml:space="preserve">
<source>Tourist Information</source>
</trans-unit>
<trans-unit id="tx_thuecat_tourist_information" xml:space="preserve">
<source>Tourist Information</source>
</trans-unit>
<trans-unit id="tx_thuecat_tourist_information.title" xml:space="preserve">
<source>Title</source>
</trans-unit>
<trans-unit id="tx_thuecat_tourist_information.description" xml:space="preserve">
<source>Description</source>
</trans-unit>
<trans-unit id="tx_thuecat_tourist_information.remote_id" xml:space="preserve">
<source>Remote ID</source>
</trans-unit>
<trans-unit id="tx_thuecat_tourist_information.town" xml:space="preserve">
<source>Town</source>
</trans-unit>
<trans-unit id="tx_thuecat_tourist_information.managed_by" xml:space="preserve">
<source>Managed by</source>
</trans-unit>
<trans-unit id="tx_thuecat_tourist_information.managed_by.unkown" xml:space="preserve">
<source>Unkown</source>
</trans-unit>
<trans-unit id="tx_thuecat_town" xml:space="preserve">
<source>Town</source>
</trans-unit>
<trans-unit id="tx_thuecat_town.title" xml:space="preserve">
<source>Title</source>
</trans-unit>
<trans-unit id="tx_thuecat_town.description" xml:space="preserve">
<source>Description</source>
</trans-unit>
<trans-unit id="tx_thuecat_town.remote_id" xml:space="preserve">
<source>Remote ID</source>
</trans-unit>
<trans-unit id="tx_thuecat_town.tourist_information" xml:space="preserve">
<source>Tourist Information</source>
</trans-unit>
<trans-unit id="tx_thuecat_town.managed_by" xml:space="preserve">
<source>Managed by</source>
</trans-unit>
<trans-unit id="tx_thuecat_town.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>
<trans-unit id="tx_thuecat_import_configuration.title" xml:space="preserve">
<source>Title</source>
</trans-unit>
<trans-unit id="tx_thuecat_import_configuration.type" xml:space="preserve">
<source>Type</source>
</trans-unit>
<trans-unit id="tx_thuecat_import_configuration.type.static" xml:space="preserve">
<source>Static list of URLs</source>
</trans-unit>
<trans-unit id="tx_thuecat_import_configuration.configuration" xml:space="preserve">
<source>Configuration</source>
</trans-unit>
<trans-unit id="tx_thuecat_import_log" xml:space="preserve">
<source>Import Log</source>
</trans-unit>
<trans-unit id="tx_thuecat_import_log.configuration" xml:space="preserve">
<source>Used configuration</source>
</trans-unit>
<trans-unit id="tx_thuecat_import_log.log_entries" xml:space="preserve">
<source>Imported entries</source>
</trans-unit>
<trans-unit id="tx_thuecat_import_log.crdate" xml:space="preserve">
<source>Created</source>
</trans-unit>
<trans-unit id="tx_thuecat_import_log_entry" xml:space="preserve">
<source>Import Log Entry</source>
</trans-unit>
<trans-unit id="tx_thuecat_import_log_entry.insertion" xml:space="preserve">
<source>Was inserted or updated</source>
</trans-unit>
<trans-unit id="tx_thuecat_import_log_entry.insertion.yes" xml:space="preserve">
<source>Inserted</source>
</trans-unit>
<trans-unit id="tx_thuecat_import_log_entry.insertion.no" xml:space="preserve">
<source>Updated</source>
</trans-unit>
<trans-unit id="tx_thuecat_import_log_entry.table_name" xml:space="preserve">
<source>Table name (record type)</source>
</trans-unit>
<trans-unit id="tx_thuecat_import_log_entry.record_uid" xml:space="preserve">
<source>Record UID</source>
</trans-unit>
<trans-unit id="tx_thuecat_import_log_entry.errors" xml:space="preserve">
<source>Errors (JSON Format)</source>
</trans-unit>
<trans-unit id="tx_thuecat_import_log_entry.import_log" xml:space="preserve">
<source>Part of this import log</source>
</trans-unit>
<trans-unit id="tx_thuecat_import_log_entry.crdate" xml:space="preserve">
<source>Created</source>
</trans-unit>
</body>
</file>
</xliff>

View file

@ -0,0 +1,54 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
data-namespace-typo3-fluid="true">
<h1>{f:translate(id: 'module.imports.headline')}</h1>
<f:flashMessages />
<f:if condition="{imports}">
<f:then>
{f:render(section: 'Imports', arguments: {imports: imports})}
</f:then>
<f:else>
<f:be.infobox
title="{f:translate(id: 'module.imports.missing.title')}"
state="1"
>
{f:translate(id: 'module.imports.missing.text')}
</f:be.infobox>
</f:else>
</f:if>
<f:section name="Imports">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>{f:translate(id: 'module.imports.th.created')}</th>
<th>{f:translate(id: 'module.imports.th.configuration')}</th>
<th>{f:translate(id: 'module.imports.th.amountOfRecords')}</th>
<th>{f:translate(id: 'module.imports.th.summary')}</th>
<th>{f:translate(id: 'module.imports.th.errors')}</th>
</tr>
</thead>
<tbody>
<f:for each="{imports}" as="import">
{f:render(section: 'Import', arguments: {import: import})}
</f:for>
</tbody>
</table>
</f:section>
<f:section name="Import">
<tr class="{f:if(condition: import.errors, then: 'danger')}">
<td>{import.created -> f:format.date(format: 'd.m.Y H:i:s')}</td>
<td>{import.configuration.title}</td>
<td>{import.entries -> f:count()}</td>
<td><f:for each="{import.summaryOfEntries}" key="tableName" as="amount">
{f:translate(id: 'module.imports.summary.tableName.{tableName}')} {amount}<br>
</f:for></td>
<td><f:for each="{import.listOfErrors}" as="error">
{error}<br>
</f:for></td>
</tr>
</f:section>
</html>

View file

@ -0,0 +1,138 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
xmlns:f="http://typo3.org/ns/TYPO3/CMS/Core/ViewHelpers"
xmlns:f="http://typo3.org/ns/TYPO3/CMS/Backend/ViewHelpers"
data-namespace-typo3-fluid="true">
<h1>{f:translate(id: 'module.overview.headline')}</h1>
<f:flashMessages />
<h2>
{f:translate(id: 'module.importConfigurations.headline')}
<f:link.newRecord
table="tx_thuecat_import_configuration"
title="{f:translate(id: 'module.importConfigurations.actions.new')}"
>
{f:icon(identifier: 'actions-document-add')}
</f:link.newRecord>
</h2>
<f:if condition="{importConfigurations}">
<f:then>
{f:render(section: 'ImportConfigurations', arguments: {importConfigurations: importConfigurations})}
</f:then>
<f:else>
<f:be.infobox
title="{f:translate(id: 'module.importConfigurations.missing.title')}"
state="1"
>
{f:translate(
id: 'module.importConfigurations.missing.text',
arguments: {
0: "{f:uri.newRecord(table: 'tx_thuecat_import_configuration')}"
}
) -> f:format.raw()}
</f:be.infobox>
</f:else>
</f:if>
<h2>{f:translate(id: 'module.organisations.headline')}</h2>
<f:if condition="{organisations}">
<f:then>
{f:render(section: 'Organisations', arguments: {organisations: organisations})}
</f:then>
<f:else>
<f:be.infobox
title="{f:translate(id: 'module.organisations.missing.title')}"
state="1"
>{f:translate(id: 'module.organisations.missing.text')}</f:be.infobox>
</f:else>
</f:if>
<f:section name="ImportConfigurations">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>{f:translate(id: 'module.importConfigurations.title')}</th>
<th>{f:translate(id: 'module.importConfigurations.lastChanged')}</th>
<th>{f:translate(id: 'module.actions')}</th>
</tr>
</thead>
<tbody>
<f:for each="{importConfigurations}" as="importConfiguration">
<tr>
<td>{importConfiguration.title}</td>
<td>{importConfiguration.lastChanged -> f:format.date(format: 'd.m.Y H:i')}</td>
<td>
<f:link.editRecord
uid="{importConfiguration.uid}"
table="{importConfiguration.tableName}"
title="{f:translate(id: 'module.importConfigurations.actions.edit')}"
>
{f:icon(identifier: 'actions-document-edit')}
</f:link.editRecord>
<f:link.action
action="import"
controller="Backend\Import"
arguments="{importConfiguration: importConfiguration}"
title="{f:translate(id: 'module.importConfigurations.actions.import')}"
>
{f:icon(identifier: 'actions-download')}
</f:link.action>
</td>
</tr>
</f:for>
</tbody>
</table>
</f:section>
<f:section name="Organisations">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>{f:translate(id: 'module.organisation.title')}</th>
<th>{f:translate(id: 'module.organisation.towns')}</th>
<th>{f:translate(id: 'module.organisation.lastImported')}</th>
<th>{f:translate(id: 'module.actions')}</th>
</tr>
</thead>
<tbody>
<f:for each="{organisations}" as="organisation">
<tr>
<td>{organisation.title}</td>
<td>
{f:render(section: 'Towns', arguments: {towns: organisation.managesTowns})}
</td>
<td>{organisation.lastImported -> f:format.date(format: 'd.m.Y H:i')}</td>
<td>
<f:link.editRecord
uid="{organisation.uid}"
table="{organisation.tableName}"
>
{f:icon(identifier: 'actions-document-edit')}
</f:link.editRecord>
</td>
</tr>
</f:for>
</tbody>
</table>
</f:section>
<f:section name="Towns">
<f:if condition="{towns}">
<f:else>
{f:translate(id: 'module.organisation.towns.none')}
</f:else>
</f:if>
<f:for each="{towns}" as="town">
{town.title} {f:render(section: 'TouristInformation', arguments: {touristInformation: town.touristInformation})}
</f:for>
</f:section>
<f:section name="TouristInformation">
<f:if condition="{touristInformation}">(</f:if>
<f:for each="{touristInformation}" as="info">
{info.title}
</f:for>
<f:if condition="{touristInformation}">)</f:if>
</f:section>
</html>

View file

@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Tests\Functional\Domain\Import;
/*
* 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\TestingFramework\Core\Functional\FunctionalTestCase as TestCase;
/**
* @covers WerkraumMedia\ThueCat\Domain\Import\Importer
*/
class ImporterTest extends TestCase
{
/**
* @test
*/
public function importsNewEntity(): void
{
$command = new CommandTester();
$command->execute();
}
/**
* @test
*/
public function updatesExistingEntity(): void
{
}
}

View file

@ -0,0 +1,91 @@
<?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 WerkraumMedia\ThueCat\Domain\Import\Converter\Converter;
use WerkraumMedia\ThueCat\Domain\Import\Converter\Organisation;
/**
* @covers WerkraumMedia\ThueCat\Domain\Import\Converter\Organisation
* @uses WerkraumMedia\ThueCat\Domain\Import\Model\GenericEntity
*/
class OrganisationTest extends TestCase
{
/**
* @test
*/
public function instanceCanBeCreated(): void
{
$subject = new Organisation();
self::assertInstanceOf(Organisation::class, $subject);
}
/**
* @test
*/
public function isInstanceOfConverter(): void
{
$subject = new Organisation();
self::assertInstanceOf(Converter::class, $subject);
}
/**
* @test
*/
public function canConvertTouristMarketingCompany(): void
{
$subject = new Organisation();
self::assertTrue($subject->canConvert([
'thuecat:TouristMarketingCompany',
'schema:Thing',
'ttgds:Organization',
]));
}
/**
* @test
*/
public function convertsJsonIdToGenericEntity(): void
{
$subject = new Organisation();
$entity = $subject->convert([
'@id' => 'https://example.com/resources/018132452787-ngbe',
'schema:name' => [
'@value' => 'Title',
],
'schema:description' => [
'@value' => 'Description',
],
]);
self::assertSame(95, $entity->getTypo3StoragePid());
self::assertSame('tx_thuecat_organisation', $entity->getTypo3DatabaseTableName());
self::assertSame('https://example.com/resources/018132452787-ngbe', $entity->getRemoteId());
self::assertSame([
'title' => 'Title',
'description' => 'Description',
], $entity->getData());
}
}

View file

@ -0,0 +1,108 @@
<?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\Converter;
use WerkraumMedia\ThueCat\Domain\Import\Converter\Registry;
/**
* @covers WerkraumMedia\ThueCat\Domain\Import\Converter\Registry
*/
class RegistryTest extends TestCase
{
use ProphecyTrait;
/**
* @test
*/
public function canBeCreated(): void
{
$subject = new Registry();
self::assertInstanceOf(Registry::class, $subject);
}
/**
* @test
*/
public function allowsRegistrationOfConverter(): void
{
$subject = new Registry();
$converter = $this->prophesize(Converter::class);
$subject->registerConverter($converter->reveal());
self::assertTrue(true);
}
/**
* @test
*/
public function returnsConverterForMatchingType(): void
{
$subject = new Registry();
$converter = $this->prophesize(Converter::class);
$converter->canConvert(['thuecat:Entity'])->willReturn(true);
$subject->registerConverter($converter->reveal());
$result = $subject->getConverterBasedOnType(['thuecat:Entity']);
self::assertSame($converter->reveal(), $result);
}
/**
* @test
*/
public function returnsFirstMatchingConverterForMatchingType(): void
{
$subject = new Registry();
$converter1 = $this->prophesize(Converter::class);
$converter1->canConvert(['thuecat:Entity'])->willReturn(true);
$converter2 = $this->prophesize(Converter::class);
$converter2->canConvert(['thuecat:Entity'])->willReturn(true);
$subject->registerConverter($converter1->reveal());
$subject->registerConverter($converter2->reveal());
$result = $subject->getConverterBasedOnType(['thuecat:Entity']);
self::assertSame($converter1->reveal(), $result);
}
/**
* @test
*/
public function returnsNullForNoMatchingConverter(): void
{
$subject = new Registry();
$converter1 = $this->prophesize(Converter::class);
$converter1->canConvert(['thuecat:Entity'])->willReturn(false);
$subject->registerConverter($converter1->reveal());
$result = $subject->getConverterBasedOnType(['thuecat:Entity']);
self::assertSame(null, $result);
}
}

View file

@ -0,0 +1,199 @@
<?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\Converter;
use WerkraumMedia\ThueCat\Domain\Import\Converter\TouristInformation;
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\TouristInformation
* @uses WerkraumMedia\ThueCat\Domain\Import\Model\GenericEntity
*/
class TouristInformationTest extends TestCase
{
use ProphecyTrait;
/**
* @test
*/
public function instanceCanBeCreated(): void
{
$organisationRepository = $this->prophesize(OrganisationRepository::class);
$townRepository = $this->prophesize(TownRepository::class);
$subject = new TouristInformation(
$organisationRepository->reveal(),
$townRepository->reveal()
);
self::assertInstanceOf(TouristInformation::class, $subject);
}
/**
* @test
*/
public function isInstanceOfConverter(): void
{
$organisationRepository = $this->prophesize(OrganisationRepository::class);
$townRepository = $this->prophesize(TownRepository::class);
$subject = new TouristInformation(
$organisationRepository->reveal(),
$townRepository->reveal()
);
self::assertInstanceOf(Converter::class, $subject);
}
/**
* @test
*/
public function canConvertTouristMarketingCompany(): void
{
$organisationRepository = $this->prophesize(OrganisationRepository::class);
$townRepository = $this->prophesize(TownRepository::class);
$subject = new TouristInformation(
$organisationRepository->reveal(),
$townRepository->reveal()
);
self::assertTrue($subject->canConvert([
'thuecat:TouristInformation',
]));
}
/**
* @test
*/
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([
'@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',
],
],
]);
self::assertSame(95, $entity->getTypo3StoragePid());
self::assertSame('tx_thuecat_tourist_information', $entity->getTypo3DatabaseTableName());
self::assertSame('https://example.com/resources/018132452787-ngbe', $entity->getRemoteId());
self::assertSame([
'title' => 'Title',
'description' => 'Description',
'managed_by' => 0,
'town' => 0,
], $entity->getData());
}
/**
* @test
*/
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([
'@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',
],
],
]);
self::assertSame(95, $entity->getTypo3StoragePid());
self::assertSame('tx_thuecat_tourist_information', $entity->getTypo3DatabaseTableName());
self::assertSame('https://example.com/resources/018132452787-ngbe', $entity->getRemoteId());
self::assertSame([
'title' => 'Title',
'description' => 'Description',
'managed_by' => 10,
'town' => 20,
], $entity->getData());
}
}

View file

@ -0,0 +1,141 @@
<?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\Converter;
use WerkraumMedia\ThueCat\Domain\Import\Converter\Town;
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\GenericEntity
*/
class TownTest extends TestCase
{
use ProphecyTrait;
/**
* @test
*/
public function instanceCanBeCreated(): void
{
$organisationRepository = $this->prophesize(OrganisationRepository::class);
$subject = new Town($organisationRepository->reveal());
self::assertInstanceOf(Town::class, $subject);
}
/**
* @test
*/
public function isInstanceOfConverter(): void
{
$organisationRepository = $this->prophesize(OrganisationRepository::class);
$subject = new Town($organisationRepository->reveal());
self::assertInstanceOf(Converter::class, $subject);
}
/**
* @test
*/
public function canConvertTouristMarketingCompany(): void
{
$organisationRepository = $this->prophesize(OrganisationRepository::class);
$subject = new Town($organisationRepository->reveal());
self::assertTrue($subject->canConvert([
'thuecat:Town',
]));
}
/**
* @test
*/
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([
'@id' => 'https://example.com/resources/018132452787-ngbe',
'thuecat:managedBy' => [
'@id' => 'https://example.com/resources/018132452787-xxxx',
],
'schema:name' => [
'@value' => 'Title',
],
'schema:description' => [
'@value' => 'Description',
],
]);
self::assertSame(95, $entity->getTypo3StoragePid());
self::assertSame('tx_thuecat_town', $entity->getTypo3DatabaseTableName());
self::assertSame('https://example.com/resources/018132452787-ngbe', $entity->getRemoteId());
self::assertSame([
'title' => 'Title',
'description' => 'Description',
'managed_by' => 0,
], $entity->getData());
}
/**
* @test
*/
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([
'@id' => 'https://example.com/resources/018132452787-ngbe',
'thuecat:managedBy' => [
'@id' => 'https://example.com/resources/018132452787-xxxx',
],
'schema:name' => [
'@value' => 'Title',
],
'schema:description' => [
'@value' => 'Description',
],
]);
self::assertSame(95, $entity->getTypo3StoragePid());
self::assertSame('tx_thuecat_town', $entity->getTypo3DatabaseTableName());
self::assertSame('https://example.com/resources/018132452787-ngbe', $entity->getRemoteId());
self::assertSame([
'title' => 'Title',
'description' => 'Description',
'managed_by' => 10,
], $entity->getData());
}
}

View file

@ -0,0 +1,118 @@
<?php
declare(strict_types=1);
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 Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestFactoryInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use WerkraumMedia\ThueCat\Domain\Import\Importer\FetchData;
/**
* @covers WerkraumMedia\ThueCat\Domain\Import\Importer\FetchData
*/
class FetchDataTest extends TestCase
{
use ProphecyTrait;
/**
* @test
*/
public function canBeCreated(): void
{
$requestFactory = $this->prophesize(RequestFactoryInterface::class);
$httpClient = $this->prophesize(ClientInterface::class);
$subject = new FetchData(
$requestFactory->reveal(),
$httpClient->reveal()
);
self::assertInstanceOf(FetchData::class, $subject);
}
/**
* @test
*/
public function returnsParsedJsonLdBasedOnUrl(): void
{
$requestFactory = $this->prophesize(RequestFactoryInterface::class);
$httpClient = $this->prophesize(ClientInterface::class);
$request = $this->prophesize(RequestInterface::class);
$response = $this->prophesize(ResponseInterface::class);
$requestFactory->createRequest('GET', 'https://example.com/resources/018132452787-ngbe')
->willReturn($request->reveal());
$httpClient->sendRequest($request->reveal())
->willReturn($response->reveal());
$response->getBody()->willReturn('{"@graph":[{"@id":"https://example.com/resources/018132452787-ngbe"}]}');
$subject = new FetchData(
$requestFactory->reveal(),
$httpClient->reveal()
);
$result = $subject->jsonLDFromUrl('https://example.com/resources/018132452787-ngbe');
self::assertSame([
'@graph' => [
[
'@id' => 'https://example.com/resources/018132452787-ngbe',
],
],
], $result);
}
/**
* @test
*/
public function returnsEmptyArrayInCaseOfError(): void
{
$requestFactory = $this->prophesize(RequestFactoryInterface::class);
$httpClient = $this->prophesize(ClientInterface::class);
$request = $this->prophesize(RequestInterface::class);
$response = $this->prophesize(ResponseInterface::class);
$requestFactory->createRequest('GET', 'https://example.com/resources/018132452787-ngbe')
->willReturn($request->reveal());
$httpClient->sendRequest($request->reveal())
->willReturn($response->reveal());
$response->getBody()->willReturn('');
$subject = new FetchData(
$requestFactory->reveal(),
$httpClient->reveal()
);
$result = $subject->jsonLDFromUrl('https://example.com/resources/018132452787-ngbe');
self::assertSame([], $result);
}
}

View file

@ -0,0 +1,243 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Tests\Unit\Domain\Import;
/*
* 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\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use WerkraumMedia\ThueCat\Domain\Import\Converter\Converter;
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\UrlProvider\Registry as UrlProviderRegistry;
use WerkraumMedia\ThueCat\Domain\Import\UrlProvider\UrlProvider;
use WerkraumMedia\ThueCat\Domain\Model\Backend\ImportConfiguration;
use WerkraumMedia\ThueCat\Domain\Model\Backend\ImportLog;
use WerkraumMedia\ThueCat\Domain\Repository\Backend\ImportLogRepository;
/**
* @covers WerkraumMedia\ThueCat\Domain\Import\Importer
* @uses WerkraumMedia\ThueCat\Domain\Model\Backend\ImportLog
*/
class ImporterTest extends TestCase
{
use ProphecyTrait;
/**
* @test
*/
public function canBeCreated(): 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);
$subject = new Importer(
$urls->reveal(),
$converter->reveal(),
$importLogRepository->reveal(),
$fetchData->reveal(),
$saveData->reveal()
);
self::assertInstanceOf(Importer::class, $subject);
}
/**
* @test
*/
public function importsNothingIfNoUrlProviderIsGiven(): void
{
$urls = $this->prophesize(UrlProviderRegistry::class);
$urlProvider = $this->prophesize(UrlProvider::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($urlProvider->reveal());
$urlProvider->getUrls()->willReturn([]);
$fetchData->jsonLDFromUrl()->shouldNotBeCalled();
$saveData->import()->shouldNotBeCalled();
$subject = new Importer(
$urls->reveal(),
$converter->reveal(),
$importLogRepository->reveal(),
$fetchData->reveal(),
$saveData->reveal()
);
$subject->importConfiguration($configuration->reveal());
}
/**
* @test
*/
public function importsAllUrlsFromAllUrlProvider(): void
{
$urls = $this->prophesize(UrlProviderRegistry::class);
$urlProvider = $this->prophesize(UrlProvider::class);
$converter = $this->prophesize(ConverterRegistry::class);
$concreteConverter = $this->prophesize(Converter::class);
$importLogRepository = $this->prophesize(ImportLogRepository::class);
$fetchData = $this->prophesize(FetchData::class);
$saveData = $this->prophesize(SaveData::class);
$configuration = $this->prophesize(ImportConfiguration::class);
$entity1 = $this->prophesize(Entity::class);
$entity2 = $this->prophesize(Entity::class);
$urls->getProviderForConfiguration($configuration->reveal())->willReturn($urlProvider->reveal());
$urlProvider->getUrls()->willReturn([
'https://example.com/resources/34343-ex',
'https://example.com/resources/34344-es',
]);
$fetchData->jsonLDFromUrl('https://example.com/resources/34343-ex')->willReturn(['@graph' => [
[
'@id' => 'https://example.com/resources/34343-ex',
'@type' => [
'schema:Organization',
'thuecat:TouristMarketingCompany',
],
],
]]);
$fetchData->jsonLDFromUrl('https://example.com/resources/34344-es')->willReturn(['@graph' => [
[
'@id' => 'https://example.com/resources/34344-es',
'@type' => [
'schema:Organization',
'thuecat:TouristMarketingCompany',
],
],
]]);
$converter->getConverterBasedOnType([
'schema:Organization',
'thuecat:TouristMarketingCompany',
])->willReturn($concreteConverter->reveal());
$concreteConverter->convert(Argument::that(function (array $jsonEntity) {
return $jsonEntity['@id'] === 'https://example.com/resources/34343-ex';
}))->willReturn($entity1->reveal());
$concreteConverter->convert(Argument::that(function (array $jsonEntity) {
return $jsonEntity['@id'] === 'https://example.com/resources/34344-es';
}))->willReturn($entity2->reveal());
$saveData->import($entity1->reveal(), Argument::type(ImportLog::class))->shouldBeCalled();
$saveData->import($entity2->reveal(), Argument::type(ImportLog::class))->shouldBeCalled();
$subject = new Importer(
$urls->reveal(),
$converter->reveal(),
$importLogRepository->reveal(),
$fetchData->reveal(),
$saveData->reveal()
);
$subject->importConfiguration($configuration->reveal());
}
/**
* @test
*/
public function handlesMissingConverter(): void
{
$urls = $this->prophesize(UrlProviderRegistry::class);
$urlProvider = $this->prophesize(UrlProvider::class);
$converter = $this->prophesize(ConverterRegistry::class);
$concreteConverter = $this->prophesize(Converter::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($urlProvider->reveal());
$urlProvider->getUrls()->willReturn([
'https://example.com/resources/34343-ex',
]);
$fetchData->jsonLDFromUrl('https://example.com/resources/34343-ex')->willReturn(['@graph' => [
[
'@id' => 'https://example.com/resources/34343-ex',
'@type' => [
'schema:Organization',
'thuecat:TouristMarketingCompany',
],
],
]]);
$converter->getConverterBasedOnType([
'schema:Organization',
'thuecat:TouristMarketingCompany',
])->willReturn(null);
$saveData->import()->shouldNotBeCalled();
$subject = new Importer(
$urls->reveal(),
$converter->reveal(),
$importLogRepository->reveal(),
$fetchData->reveal(),
$saveData->reveal()
);
$subject->importConfiguration($configuration->reveal());
}
/**
* @test
*/
public function handlesEmptyResponse(): void
{
$urls = $this->prophesize(UrlProviderRegistry::class);
$urlProvider = $this->prophesize(UrlProvider::class);
$converter = $this->prophesize(ConverterRegistry::class);
$concreteConverter = $this->prophesize(Converter::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($urlProvider->reveal());
$urlProvider->getUrls()->willReturn([
'https://example.com/resources/34343-ex',
]);
$fetchData->jsonLDFromUrl('https://example.com/resources/34343-ex')->willReturn([]);
$converter->getConverterBasedOnType()->shouldNotBeCalled();
$subject = new Importer(
$urls->reveal(),
$converter->reveal(),
$importLogRepository->reveal(),
$fetchData->reveal(),
$saveData->reveal()
);
$subject->importConfiguration($configuration->reveal());
}
}

View file

@ -0,0 +1,183 @@
<?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 WerkraumMedia\ThueCat\Domain\Import\Model\GenericEntity;
/**
* @covers WerkraumMedia\ThueCat\Domain\Import\Model\GenericEntity
*/
class GenericEntityTest extends TestCase
{
/**
* @test
*/
public function canBeCreated(): void
{
$subject = new GenericEntity(
0,
'',
'',
[]
);
self::assertInstanceOf(GenericEntity::class, $subject);
}
/**
* @test
*/
public function returnsTypo3StoragePid(): void
{
$subject = new GenericEntity(
10,
'',
'',
[]
);
self::assertSame(10, $subject->getTypo3StoragePid());
}
/**
* @test
*/
public function returnsTypo3DatabaseTableName(): void
{
$subject = new GenericEntity(
0,
'tx_thuecat_entity',
'',
[]
);
self::assertSame('tx_thuecat_entity', $subject->getTypo3DatabaseTableName());
}
/**
* @test
*/
public function returnsRemoteId(): void
{
$subject = new GenericEntity(
0,
'',
'https://example.com/resources/333039283321-xxwg',
[]
);
self::assertSame(
'https://example.com/resources/333039283321-xxwg',
$subject->getRemoteId()
);
}
/**
* @test
*/
public function returnsData(): void
{
$subject = new GenericEntity(
0,
'',
'',
[
'column_name_1' => 'value 1',
'column_name_2' => 'value 2',
]
);
self::assertSame(
[
'column_name_1' => 'value 1',
'column_name_2' => 'value 2',
],
$subject->getData()
);
}
/**
* @test
*/
public function returnsNotCreatedByDefault(): void
{
$subject = new GenericEntity(
0,
'',
'',
[]
);
self::assertSame(
false,
$subject->wasCreated()
);
}
/**
* @test
*/
public function returnsZeroAsDefaultTypo3Uid(): void
{
$subject = new GenericEntity(
0,
'',
'',
[]
);
self::assertSame(
0,
$subject->getTypo3Uid()
);
}
/**
* @test
*/
public function canBeMarkedAsImported(): void
{
$subject = new GenericEntity(
0,
'',
'',
[]
);
$subject->setImportedTypo3Uid(10);
self::assertSame(true, $subject->wasCreated());
self::assertSame(10, $subject->getTypo3Uid());
}
/**
* @test
*/
public function canBeMarkedAsExisting(): void
{
$subject = new GenericEntity(
0,
'',
'',
[]
);
$subject->setExistingTypo3Uid(10);
self::assertSame(false, $subject->wasCreated());
self::assertSame(10, $subject->getTypo3Uid());
}
}

View file

@ -0,0 +1,54 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Tests\Unit\Domain\Import;
/*
* 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\RequestFactory;
/**
* @covers WerkraumMedia\ThueCat\Domain\Import\RequestFactory
*/
class RequestFactoryTest extends TestCase
{
/**
* @test
*/
public function canBeCreated(): void
{
$subject = new RequestFactory();
self::assertInstanceOf(RequestFactory::class, $subject);
}
/**
* @test
*/
public function returnsRequestWithJsonIdFormat(): void
{
$subject = new RequestFactory();
$request = $subject->createRequest('GET', 'https://example.com/resources/333039283321-xxwg');
self::assertSame('format=jsonId', $request->getUri()->getQuery());
}
}

View file

@ -0,0 +1,92 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Tests\Unit\Domain\Import\UrlProvider;
/*
* 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\UrlProvider\Registry;
use WerkraumMedia\ThueCat\Domain\Import\UrlProvider\UrlProvider;
use WerkraumMedia\ThueCat\Domain\Model\Backend\ImportConfiguration;
/**
* @covers WerkraumMedia\ThueCat\Domain\Import\UrlProvider\Registry
*/
class RegistryTest extends TestCase
{
use ProphecyTrait;
/**
* @test
*/
public function canBeCreated(): void
{
$subject = new Registry();
self::assertInstanceOf(Registry::class, $subject);
}
/**
* @test
*/
public function allowsRegistrationOfUrlProvider(): void
{
$subject = new Registry();
$provider = $this->prophesize(UrlProvider::class);
$subject->registerProvider($provider->reveal());
self::assertTrue(true);
}
/**
* @test
*/
public function returnsNullIfNoProviderExistsForConfiguration(): void
{
$configuration = $this->prophesize(ImportConfiguration::class);
$subject = new Registry();
$result = $subject->getProviderForConfiguration($configuration->reveal());
self::assertSame(null, $result);
}
/**
* @test
*/
public function returnsProviderForConfiguration(): void
{
$configuration = $this->prophesize(ImportConfiguration::class);
$subject = new Registry();
$provider = $this->prophesize(UrlProvider::class);
$concreteProvider = $this->prophesize(UrlProvider::class);
$provider->canProvideForConfiguration($configuration->reveal())->willReturn(true);
$provider->createWithConfiguration($configuration->reveal())->willReturn($concreteProvider->reveal());
$subject->registerProvider($provider->reveal());
$result = $subject->getProviderForConfiguration($configuration->reveal());
self::assertSame($concreteProvider->reveal(), $result);
}
}

View file

@ -0,0 +1,95 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Tests\Unit\Domain\Import\UrlProvider;
/*
* 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\UrlProvider\StaticUrlProvider;
use WerkraumMedia\ThueCat\Domain\Model\Backend\ImportConfiguration;
/**
* @covers WerkraumMedia\ThueCat\Domain\Import\UrlProvider\StaticUrlProvider
*/
class StaticUrlProviderTest extends TestCase
{
use ProphecyTrait;
/**
* @test
*/
public function canBeCreated(): void
{
$configuration = $this->prophesize(ImportConfiguration::class);
$configuration->getUrls()->willReturn([]);
$subject = new StaticUrlProvider($configuration->reveal());
self::assertInstanceOf(StaticUrlProvider::class, $subject);
}
/**
* @test
*/
public function canProvideForStaticConfiguration(): void
{
$configuration = $this->prophesize(ImportConfiguration::class);
$configuration->getUrls()->willReturn([]);
$configuration->getType()->willReturn('static');
$subject = new StaticUrlProvider($configuration->reveal());
$result = $subject->canProvideForConfiguration($configuration->reveal());
self::assertTrue($result);
}
/**
* @test
*/
public function returnsConcreteProviderForConfiguration(): void
{
$configuration = $this->prophesize(ImportConfiguration::class);
$configuration->getUrls()->willReturn(['https://example.com']);
$subject = new StaticUrlProvider($configuration->reveal());
$result = $subject->createWithConfiguration($configuration->reveal());
self::assertInstanceOf(StaticUrlProvider::class, $subject);
}
/**
* @test
*/
public function concreteProviderReturnsUrls(): void
{
$configuration = $this->prophesize(ImportConfiguration::class);
$configuration->getUrls()->willReturn(['https://example.com']);
$subject = new StaticUrlProvider($configuration->reveal());
$concreteProvider = $subject->createWithConfiguration($configuration->reveal());
$result = $concreteProvider->getUrls();
self::assertSame([
'https://example.com',
], $result);
}
}

View file

@ -0,0 +1,42 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Tests\Unit;
/*
* 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\Extension;
/**
* @covers WerkraumMedia\ThueCat\Extension
* @testdox The extension class
*/
class ExtensionTest extends TestCase
{
/**
* @test
*/
public function returnsLanguagePath(): void
{
self::assertSame('LLL:EXT:thuecat/Resources/Private/Language/', Extension::getLanguagePath());
}
}

View file

@ -15,15 +15,31 @@
"email": "coding@daniel-siepmann.de" "email": "coding@daniel-siepmann.de"
} }
], ],
"autoload": {
"psr-4": {
"WerkraumMedia\\ThueCat\\": "Classes/"
}
},
"autoload-dev": {
"psr-4": {
"WerkraumMedia\\ThueCat\\Tests\\": "Tests/"
}
},
"require": { "require": {
"typo3/cms-core": "^10.4" "php": "^7.4",
"psr/http-client": "^1.0",
"psr/http-factory": "^1.0",
"psr/http-message": "^1.0",
"symfony/console": "^5.2",
"typo3/cms-core": "^10.4",
"typo3/cms-extbase": "^10.4"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^9.5",
"maglnet/composer-require-checker": "^2.1", "maglnet/composer-require-checker": "^2.1",
"phpspec/prophecy-phpunit": "^2.0", "phpspec/prophecy-phpunit": "^2.0",
"typo3/testing-framework": "^6.6", "phpunit/phpunit": "^9.5",
"symplify/easy-coding-standard": "^9.0" "symplify/easy-coding-standard": "^9.0",
"typo3/testing-framework": "^6.6"
}, },
"scripts": { "scripts": {
"post-autoload-dump": [ "post-autoload-dump": [

15
ecs.php
View file

@ -5,6 +5,7 @@ declare(strict_types=1);
use PhpCsFixer\Fixer\ArrayNotation\ArraySyntaxFixer; use PhpCsFixer\Fixer\ArrayNotation\ArraySyntaxFixer;
use PhpCsFixer\Fixer\ArrayNotation\TrailingCommaInMultilineArrayFixer; use PhpCsFixer\Fixer\ArrayNotation\TrailingCommaInMultilineArrayFixer;
use PhpCsFixer\Fixer\Import\FullyQualifiedStrictTypesFixer; use PhpCsFixer\Fixer\Import\FullyQualifiedStrictTypesFixer;
use PhpCsFixer\Fixer\Import\NoUnusedImportsFixer;
use PhpCsFixer\Fixer\PhpUnit\PhpUnitTestAnnotationFixer; use PhpCsFixer\Fixer\PhpUnit\PhpUnitTestAnnotationFixer;
use PhpCsFixer\Fixer\Strict\DeclareStrictTypesFixer; use PhpCsFixer\Fixer\Strict\DeclareStrictTypesFixer;
use PhpCsFixer\Fixer\StringNotation\SingleQuoteFixer; use PhpCsFixer\Fixer\StringNotation\SingleQuoteFixer;
@ -17,8 +18,9 @@ return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services(); $services = $containerConfigurator->services();
$parameters->set(Option::PATHS, [ $parameters->set(Option::PATHS, [
__DIR__ . '/Classes', __DIR__ . '/Classes/',
__DIR__ . '/Tests', __DIR__ . '/Configuration/',
__DIR__ . '/Tests/',
__DIR__ . '/ecs.php', __DIR__ . '/ecs.php',
__DIR__ . '/ext_emconf.php', __DIR__ . '/ext_emconf.php',
]); ]);
@ -32,17 +34,20 @@ return static function (ContainerConfigurator $containerConfigurator): void {
$parameters->set(Option::SKIP, [ $parameters->set(Option::SKIP, [
DeclareStrictTypesFixer::class => [ DeclareStrictTypesFixer::class => [
__DIR__ . '/Configuration/',
__DIR__ . '/ext_emconf.php', __DIR__ . '/ext_emconf.php',
], ],
]); ]);
$services->set(NoUnusedImportsFixer::class);
$services->set(FullyQualifiedStrictTypesFixer::class); $services->set(FullyQualifiedStrictTypesFixer::class);
$services->set(PhpUnitTestAnnotationFixer::class)->call('configure', [[
'style' => 'annotation',
]]);
$services->set(ArraySyntaxFixer::class)->call('configure', [[ $services->set(ArraySyntaxFixer::class)->call('configure', [[
'syntax' => 'short', 'syntax' => 'short',
]]); ]]);
$services->set(SingleQuoteFixer::class); $services->set(SingleQuoteFixer::class);
$services->set(TrailingCommaInMultilineArrayFixer::class); $services->set(TrailingCommaInMultilineArrayFixer::class);
$services->set(PhpUnitTestAnnotationFixer::class)->call('configure', [[
'style' => 'annotation',
]]);
}; };

5
ext_tables.php Normal file
View file

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

42
ext_tables.sql Normal file
View file

@ -0,0 +1,42 @@
CREATE TABLE tx_thuecat_import_configuration (
title varchar(255) DEFAULT '' NOT NULL,
type varchar(255) DEFAULT '' NOT NULL,
configuration text,
);
CREATE TABLE tx_thuecat_import_log (
configuration int(11) unsigned DEFAULT '0' NOT NULL,
log_entries int(11) unsigned DEFAULT '0' NOT NULL,
);
CREATE TABLE tx_thuecat_import_log_entry (
import_log int(11) unsigned DEFAULT '0' NOT NULL,
record_uid int(11) unsigned DEFAULT '0' NOT NULL,
table_name varchar(255) DEFAULT '' NOT NULL,
insertion TINYINT(1) unsigned DEFAULT '0' NOT NULL,
errors text DEFAULT '' NOT NULL,
);
CREATE TABLE tx_thuecat_organisation (
remote_id varchar(255) DEFAULT '' NOT NULL,
title varchar(255) DEFAULT '' NOT NULL,
description text DEFAULT '' NOT NULL,
manages_towns int(11) unsigned DEFAULT '0' NOT NULL,
manages_tourist_information int(11) unsigned DEFAULT '0' NOT NULL,
);
CREATE TABLE tx_thuecat_town (
remote_id varchar(255) DEFAULT '' NOT NULL,
managed_by int(11) unsigned DEFAULT '0' NOT NULL,
tourist_information int(11) unsigned DEFAULT '0' NOT NULL,
title varchar(255) DEFAULT '' NOT NULL,
description text DEFAULT '' NOT NULL,
);
CREATE TABLE tx_thuecat_tourist_information (
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,
);

View file

@ -0,0 +1,9 @@
module {
tx_thuecat {
view {
templateRootPaths {
0 = EXT:thuecat/Resources/Private/Templates/
}
}
}
}

36
phpunit.xml.dist Normal file
View file

@ -0,0 +1,36 @@
<?xml version="1.0"?>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.5/phpunit.xsd"
backupGlobals="false"
backupStaticAttributes="false"
beStrictAboutCoversAnnotation="true"
bootstrap="vendor/typo3/testing-framework/Resources/Core/Build/FunctionalTestsBootstrap.php"
colors="true"
convertErrorsToExceptions="true"
convertWarningsToExceptions="true"
forceCoversAnnotation="false"
processIsolation="false"
stopOnError="false"
stopOnFailure="false"
stopOnIncomplete="false"
stopOnSkipped="false"
verbose="false"
>
<testsuites>
<testsuite name="unit">
<directory>Tests/Unit/</directory>
</testsuite>
</testsuites>
<coverage>
<include>
<directory suffix=".php">Classes</directory>
</include>
</coverage>
<php>
<env name="typo3DatabaseDriver" value="pdo_sqlite"/>
</php>
</phpunit>