Add new import configuration based on containsPlace (#98)

Adds a new type of import configuration.
This configuration allows to define a single resource.
All the resources referenced via schema:containsPlace will be imported.

Relates: #10237
This commit is contained in:
Daniel Siepmann 2022-12-15 10:42:41 +01:00 committed by GitHub
parent d7c7d8eaee
commit 61ae59c127
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 515 additions and 32 deletions

View file

@ -23,6 +23,8 @@ declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Domain\Import;
use TYPO3\CMS\Core\Log\LogManager;
use TYPO3\CMS\Core\Log\Logger;
use WerkraumMedia\ThueCat\Domain\Import\EntityMapper\EntityRegistry;
use WerkraumMedia\ThueCat\Domain\Import\EntityMapper\JsonDecode;
use WerkraumMedia\ThueCat\Domain\Import\Entity\MapsToType;
@ -78,6 +80,11 @@ class Importer
*/
private $importLogRepository;
/**
* @var Logger
*/
private $logger;
/**
* @var Import
*/
@ -91,7 +98,8 @@ class Importer
Languages $languages,
ImportLogRepository $importLogRepository,
FetchData $fetchData,
SaveData $saveData
SaveData $saveData,
LogManager $logManager
) {
$this->urls = $urls;
$this->converter = $converter;
@ -101,6 +109,7 @@ class Importer
$this->importLogRepository = $importLogRepository;
$this->fetchData = $fetchData;
$this->saveData = $saveData;
$this->logger = $logManager->getLogger(__CLASS__);
$this->import = new Import();
}
@ -111,6 +120,13 @@ class Importer
$this->import->end();
if ($this->import->done()) {
$this->logger->info(
'Finished import.',
[
'errors' => $this->import->getLog()->getListOfErrors(),
'summary' => $this->import->getLog()->getSummaryOfEntries(),
]
);
$this->importLogRepository->addLog($this->import->getLog());
}
@ -131,12 +147,15 @@ class Importer
private function importResourceByUrl(string $url): void
{
$this->logger->info('Process url.', ['url' => $url]);
if ($this->import->handledRemoteId($url)) {
$this->logger->notice('Skip Url as we already handled it during import.', ['url' => $url]);
return;
}
$content = $this->fetchData->jsonLDFromUrl($url);
if ($content === []) {
$this->logger->notice('Skip Url as we did not receive any content.', ['url' => $url]);
return;
}
@ -153,12 +172,14 @@ class Importer
$targetEntity = $this->entityRegistry->getEntityByTypes($jsonEntity['@type']);
if ($targetEntity === '') {
$this->logger->notice('Skip entity, no target entity found.', ['types' => $jsonEntity['@type']]);
return;
}
$entities = new EntityCollection();
foreach ($this->languages->getAvailable($this->import->getConfiguration()) as $language) {
$this->logger->info('Process entity for language.', ['language' => $language, 'targetEntity' => $targetEntity]);
$mappedEntity = $this->entityMapper->mapDataToEntity(
$jsonEntity,
$targetEntity,
@ -167,6 +188,7 @@ class Importer
]
);
if (!$mappedEntity instanceof MapsToType) {
$this->logger->alert('Mapping did not result in an MapsToType instance.', ['class' => get_class($mappedEntity)]);
continue;
}
$convertedEntity = $this->converter->convert(
@ -176,6 +198,7 @@ class Importer
);
if ($convertedEntity === null) {
$this->logger->alert('Could not convert entity.', ['language' => $language, 'targetEntity' => $targetEntity]);
continue;
}
$entities->add($convertedEntity);
@ -199,6 +222,7 @@ class Importer
}
}
$this->logger->notice('Deny entity as type is not allowed.', ['types' => $jsonEntity['@type']]);
return false;
}
}

View file

@ -76,6 +76,11 @@ class FetchData
);
}
public function getFullResourceUrl(string $id): string
{
return $this->getResourceEndpoint() . ltrim($id, '/');
}
public function jsonLDFromUrl(string $url): array
{
$cacheIdentifier = sha1($url);
@ -98,7 +103,7 @@ class FetchData
return [];
}
public function getResourceEndpoint(): string
private function getResourceEndpoint(): string
{
return $this->urlPrefix . '/resources/';
}

View file

@ -0,0 +1,76 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2022 Daniel Siepmann <coding@daniel-siepmann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
namespace WerkraumMedia\ThueCat\Domain\Import\UrlProvider;
use WerkraumMedia\ThueCat\Domain\Import\ImportConfiguration;
use WerkraumMedia\ThueCat\Domain\Import\Importer\FetchData;
class ContainsPlaceUrlProvider implements UrlProvider
{
/**
* @var FetchData
*/
private $fetchData;
/**
* @var string
*/
private $containsPlaceId = '';
public function __construct(
FetchData $fetchData
) {
$this->fetchData = $fetchData;
}
public function canProvideForConfiguration(
ImportConfiguration $configuration
): bool {
return $configuration->getType() === 'containsPlace';
}
public function createWithConfiguration(
ImportConfiguration $configuration
): UrlProvider {
if (method_exists($configuration, 'getContainsPlaceId') === false) {
throw new \InvalidArgumentException('Received incompatible import configuration.', 1629709276);
}
$instance = clone $this;
$instance->containsPlaceId = $configuration->getContainsPlaceId();
return $instance;
}
public function getUrls(): array
{
$response = $this->fetchData->jsonLDFromUrl(
$this->fetchData->getFullResourceUrl($this->containsPlaceId)
);
$resources = array_values($response['@graph'][0]['schema:containsPlace'] ?? []);
return array_map(function (array $resource) {
return $resource['@id'] ?? '';
}, $resources);
}
}

View file

@ -65,13 +65,10 @@ class SyncScopeUrlProvider implements UrlProvider
public function getUrls(): array
{
$response = $this->fetchData->updatedNodes($this->syncScopeId);
$resourceIds = array_values($response['data']['createdOrUpdated'] ?? []);
$urls = array_map(function (string $id) {
return $this->fetchData->getResourceEndpoint() . $id;
return array_map(function (string $id) {
return $this->fetchData->getFullResourceUrl($id);
}, $resourceIds);
return $urls;
}
}

View file

@ -106,14 +106,7 @@ class ImportConfiguration extends AbstractEntity implements ImportConfigurationI
public function getStoragePid(): int
{
if ($this->configuration === '') {
return 0;
}
$storagePid = ArrayUtility::getValueByPath(
GeneralUtility::xml2array($this->configuration),
'data/sDEF/lDEF/storagePid/vDEF'
);
$storagePid = $this->getConfigurationValueFromFlexForm('storagePid');
if (is_numeric($storagePid) && $storagePid > 0) {
return intval($storagePid);
@ -148,21 +141,16 @@ class ImportConfiguration extends AbstractEntity implements ImportConfigurationI
public function getSyncScopeId(): string
{
if ($this->configuration === '') {
return '';
return $this->getConfigurationValueFromFlexForm('syncScopeId');
}
$configurationAsArray = $this->getConfigurationAsArray();
$arrayPath = 'data/sDEF/lDEF/syncScopeId/vDEF';
if (ArrayUtility::isValidPath($configurationAsArray, $arrayPath) === false) {
return '';
public function getContainsPlaceId(): string
{
$containsPlaceId = $this->getConfigurationValueFromFlexForm('containsPlaceId');
if (!is_string($containsPlaceId)) {
throw new \Exception('Could not fetch containsPlaceId.', 1671027015);
}
return ArrayUtility::getValueByPath(
$configurationAsArray,
$arrayPath
);
return $containsPlaceId;
}
private function getEntries(): array
@ -198,4 +186,26 @@ class ImportConfiguration extends AbstractEntity implements ImportConfigurationI
$configuration->allowedTypes = $allowedTypes;
return $configuration;
}
/**
* @return mixed
*/
private function getConfigurationValueFromFlexForm(string $fieldName)
{
if ($this->configuration === '') {
return '';
}
$configurationAsArray = $this->getConfigurationAsArray();
$arrayPath = 'data/sDEF/lDEF/' . $fieldName . '/vDEF';
if (ArrayUtility::isValidPath($configurationAsArray, $arrayPath) === false) {
return '';
}
return ArrayUtility::getValueByPath(
$configurationAsArray,
$arrayPath
);
}
}

View file

@ -0,0 +1,36 @@
<T3DataStructure>
<meta>
<langDisable>1</langDisable>
</meta>
<sheets>
<sDEF>
<ROOT>
<TCEforms>
<sheetTitle>LLL:EXT:thuecat/Resources/Private/Language/locallang_flexform.xlf:importConfiguration.containsPlace.sheetTitle</sheetTitle>
</TCEforms>
<type>array</type>
<el>
<storagePid>
<TCEforms>
<label>LLL:EXT:thuecat/Resources/Private/Language/locallang_flexform.xlf:importConfiguration.containsPlace.storagePid</label>
<config>
<type>input</type>
<eval>int,required</eval>
</config>
</TCEforms>
</storagePid>
<containsPlaceId>
<TCEforms>
<label>LLL:EXT:thuecat/Resources/Private/Language/locallang_flexform.xlf:importConfiguration.containsPlace.containsPlaceId</label>
<description>LLL:EXT:thuecat/Resources/Private/Language/locallang_flexform.xlf:importConfiguration.containsPlace.containsPlaceId.description</description>
<config>
<type>input</type>
<eval>trim,required</eval>
</config>
</TCEforms>
</containsPlaceId>
</el>
</ROOT>
</sDEF>
</sheets>
</T3DataStructure>

View file

@ -45,6 +45,10 @@ return (static function (string $extensionKey, string $tableName) {
$languagePath . '.type.syncScope',
'syncScope',
],
[
$languagePath . '.type.containsPlace',
'containsPlace',
],
],
],
],
@ -57,6 +61,7 @@ return (static function (string $extensionKey, string $tableName) {
'default' => $flexFormConfigurationPath . 'ImportConfiguration/Static.xml',
'static' => $flexFormConfigurationPath . 'ImportConfiguration/Static.xml',
'syncScope' => $flexFormConfigurationPath . 'ImportConfiguration/SyncScope.xml',
'containsPlace' => $flexFormConfigurationPath . 'ImportConfiguration/ContainsPlace.xml',
],
],
],

View file

@ -13,6 +13,10 @@ Features
* Last import date is now shown within backend module beside each import configuration.
* New import configuration type "Contains Place".
This allows to provide a single entity, e.g. a Town that has multiple ``schema:containsPlace`` entries.
Each of them will be imported.
* Import author of media. This allows to either render the license author or the author.
* Filter and sort opening hours.

View file

@ -28,6 +28,20 @@
<source>syncScopeId</source>
</trans-unit>
<!-- Contains Place Import Configuration -->
<trans-unit id="importConfiguration.containsPlace.sheetTitle" xml:space="preserve">
<source>Contains place import configuration</source>
</trans-unit>
<trans-unit id="importConfiguration.containsPlace.storagePid" xml:space="preserve">
<source>Storage Page UID</source>
</trans-unit>
<trans-unit id="importConfiguration.containsPlace.containsPlaceId" xml:space="preserve">
<source>Contains Place ID</source>
</trans-unit>
<trans-unit id="importConfiguration.containsPlace.containsPlaceId.description" xml:space="preserve">
<source>Only ID, not full URL e.g. 043064193523-jcyt</source>
</trans-unit>
<trans-unit id="pages.tourist_attraction.sheetTitle" xml:space="preserve">
<source>Tourist Attraction</source>
</trans-unit>

View file

@ -242,6 +242,9 @@
<trans-unit id="tx_thuecat_import_configuration.type.syncScope" xml:space="preserve">
<source>Synchronization area</source>
</trans-unit>
<trans-unit id="tx_thuecat_import_configuration.type.containsPlace" xml:space="preserve">
<source>Contains Place</source>
</trans-unit>
<trans-unit id="tx_thuecat_import_configuration.configuration" xml:space="preserve">
<source>Configuration</source>
</trans-unit>

View file

@ -0,0 +1,182 @@
{
"@context": {
"cdb": "https://thuecat.org/ontology/cdb/1.0/",
"dachkg": "https://thuecat.org/ontology/dachkg/1.0/",
"dbo": "http://dbpedia.org/ontology/",
"dsv": "http://ontologies.sti-innsbruck.at/dsv/",
"foaf": "http://xmlns.com/foaf/0.1/",
"owl": "http://www.w3.org/2002/07/owl#",
"rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
"schema": "http://schema.org/",
"sh": "http://www.w3.org/ns/shacl#",
"thuecat": "https://thuecat.org/ontology/thuecat/1.0/",
"ttgds": "https://thuecat.org/ontology/ttgds/1.0/",
"xsd": "http://www.w3.org/2001/XMLSchema#"
},
"@graph": [
{
"@id": "https://thuecat.org/resources/043064193523-contains",
"@type": [
"schema:AdministrativeArea",
"schema:Place",
"schema:Thing",
"schema:City",
"ttgds:Destination",
"thuecat:Town"
],
"schema:address": {
"@id": "genid-c3843c2db4f74da2bc4a1785b63143b2-b0",
"@type": [
"schema:Intangible",
"schema:PostalAddress",
"schema:StructuredValue",
"schema:Thing",
"schema:ContactPoint"
],
"schema:addressCountry": {
"@type": "thuecat:AddressCountry",
"@value": "thuecat:Germany"
},
"schema:addressLocality": {
"@language": "de",
"@value": "Erfurt"
},
"schema:addressRegion": {
"@type": "thuecat:AddressFederalState",
"@value": "thuecat:Thuringia"
},
"schema:postalCode": {
"@language": "de",
"@value": "99084"
}
},
"schema:containsPlace": [
{
"@id": "https://thuecat.org/resources/835224016581-dara"
},
{
"@id": "https://thuecat.org/resources/165868194223-zmqf"
},
{
"@id": "https://thuecat.org/resources/215230952334-yyno"
}
],
"schema:description": [
{
"@language": "de",
"@value": "Kr\u00e4merbr\u00fccke, Dom, Alte Synagoge \u2013 die Th\u00fcringer Landeshauptstadt Erfurt hat viele Kultursch\u00e4tze. Und ein wunderbar junges, studentisches Flair.Eine gute Mischung f\u00fcr alle, die beim Schlendern und Bummeln gerne St\u00e4dte entdecken: Denn in Erfurt findet man einen wunderbaren mittelalterlichen Stadtkern \u2013 mit vielen netten L\u00e4den, Caf\u00e8s und Restaurants. Urlauber wie Einheimische bummeln durch die Gassen der Altstadt, aus allen Ecken wispern Geschichte und alte Geschichten. Stolze historische B\u00fcgerh\u00e4user bilden eine der sch\u00f6nsten Altst\u00e4dte Europas, mittendrin das neugotische Rathaus aus den 1870er-Jahren am Fischmarkt, die spitzt\u00fcrmige St. Severikirche und der m\u00e4chtige Dom, 1117 erstmals urkundlich erw\u00e4hnt \u2013 auf seiner schier endlosen, kaskadenf\u00f6rmigen Freitreppe chillen Jung und Alt gern in der Abendsonne. Ehe sie weiter ziehen zum Tagesausklang in eine der coolen Kneipen und Bars (Tipp: Oma Lilo oder Caf\u00e8 Hilgenfeld), in die Wein-Destille am benachbarten Petersberg oder in eins der l\u00e4ssigen Restaurants (Tipp: Mathilda oder Ballenberger), wo zum freundlichen Miteinander eine frische und moderne K\u00fcche serviert wird.In Erfurt pulsiert das Leben, lassen Sie sich einfach treiben. Von Ihrer Neugierde ..."
},
{
"@id": "genid-c3843c2db4f74da2bc4a1785b63143b2-b1",
"@type": [
"thuecat:Html"
],
"schema:value": {
"@language": "de",
"@value": "Kr\u00e4merbr\u00fccke, Dom, Alte Synagoge \u2013 die Th\u00fcringer Landeshauptstadt Erfurt hat viele Kultursch\u00e4tze. Und ein wunderbar junges, studentisches Flair.Eine gute Mischung f\u00fcr alle, die beim Schlendern und Bummeln gerne St\u00e4dte entdecken: Denn in Erfurt findet man einen wunderbaren mittelalterlichen Stadtkern \u2013 mit vielen netten L\u00e4den, Caf\u00e8s und Restaurants. Urlauber wie Einheimische bummeln durch die Gassen der Altstadt, aus allen Ecken wispern Geschichte und alte Geschichten. Stolze historische B\u00fcgerh\u00e4user bilden eine der sch\u00f6nsten Altst\u00e4dte Europas, mittendrin das neugotische Rathaus aus den 1870er-Jahren am Fischmarkt, die spitzt\u00fcrmige St. Severikirche und der m\u00e4chtige Dom, 1117 erstmals urkundlich erw\u00e4hnt \u2013 auf seiner schier endlosen, kaskadenf\u00f6rmigen Freitreppe chillen Jung und Alt gern in der Abendsonne. Ehe sie weiter ziehen zum Tagesausklang in eine der coolen Kneipen und Bars (Tipp: Oma Lilo oder Caf\u00e8 Hilgenfeld), in die Wein-Destille am benachbarten Petersberg oder in eins der l\u00e4ssigen Restaurants (Tipp: Mathilda oder Ballenberger), wo zum freundlichen Miteinander eine frische und moderne K\u00fcche serviert wird.In Erfurt pulsiert das Leben, lassen Sie sich einfach treiben. Von Ihrer Neugierde ..."
}
}
],
"schema:geo": {
"@id": "genid-c3843c2db4f74da2bc4a1785b63143b2-b2",
"@type": [
"schema:Intangible",
"schema:StructuredValue",
"schema:Thing",
"schema:GeoCoordinates"
],
"schema:latitude": {
"@type": "schema:Number",
"@value": "50.97658847089682"
},
"schema:longitude": {
"@type": "schema:Number",
"@value": "11.02752685546875"
}
},
"schema:hasMap": {
"@type": "schema:URL",
"@value": "https://www.google.com/maps/search/?api=1&query=11.02752685546875,11.02752685546875"
},
"schema:identifier": [
{
"@type": "schema:URL",
"@value": "https://www.thueringen-entdecken.de/urlaub-hotel-reisen/erfurt-102097.html"
},
{
"@id": "genid-c3843c2db4f74da2bc4a1785b63143b2-b3",
"@type": [
"schema:Intangible",
"schema:StructuredValue",
"schema:Thing",
"schema:PropertyValue"
],
"schema:name": {
"@language": "de",
"@value": "TOMASID"
},
"schema:value": {
"@language": "de",
"@value": "TTG00020050000218774"
}
}
],
"schema:name": {
"@language": "de",
"@value": "Erfurt"
},
"schema:sameAs": {
"@type": "schema:URL",
"@value": "http://www.erfurt-tourismus.de"
},
"schema:url": {
"@type": "schema:URL",
"@value": "http://www.erfurt-tourismus.de"
},
"thuecat:contentResponsible": {
"@id": "https://thuecat.org/resources/018132452787-ngbe"
},
"thuecat:destinationManagementOrganisation": {
"@id": "https://thuecat.org/resources/018132452787-ngbe"
},
"thuecat:managedBy": {
"@id": "https://thuecat.org/resources/018132452787-ngbe"
},
"thuecat:monumentEnum": {
"@type": "thuecat:MonumentEnum",
"@value": "thuecat:ZeroInformationMemorialClass"
},
"thuecat:regionalKey": {
"@language": "de",
"@value": "160510000000"
},
"thuecat:tomasLocationID": {
"@language": "de",
"@value": "TTG00020050000218774"
},
"thuecat:trafficConnection": [
{
"@type": "thuecat:TrafficConnection",
"@value": "thuecat:BusRoute"
},
{
"@type": "thuecat:TrafficConnection",
"@value": "thuecat:RoadConnection"
},
{
"@type": "thuecat:TrafficConnection",
"@value": "thuecat:RailwayStationEnuMem"
},
{
"@type": "thuecat:TrafficConnection",
"@value": "thuecat:MotorwayConnection"
},
{
"@type": "thuecat:TrafficConnection",
"@value": "thuecat:Airport"
}
]
}
]
}

View file

@ -0,0 +1,16 @@
"tx_thuecat_tourist_attraction",,,,,
,"uid","pid","sys_language_uid","remote_id","title"
,1,10,0,"https://thuecat.org/resources/835224016581-dara","Dom St. Marien"
,2,10,1,"https://thuecat.org/resources/835224016581-dara","Cathedral of St. Mary"
,3,10,0,"https://thuecat.org/resources/165868194223-zmqf","Alte Synagoge"
,4,10,1,"https://thuecat.org/resources/165868194223-zmqf","Old Synagogue"
,5,10,2,"https://thuecat.org/resources/165868194223-zmqf","La vieille synagogue"
,6,10,0,"https://thuecat.org/resources/215230952334-yyno","Krämerbrücke"
,7,10,1,"https://thuecat.org/resources/215230952334-yyno","Merchants' Bridge"
,8,10,2,"https://thuecat.org/resources/215230952334-yyno","Pont de l'épicier"
"tx_thuecat_organisation",,,,,
,"uid","pid","remote_id","title",
,1,10,"https://thuecat.org/resources/018132452787-ngbe","Erfurt Tourismus und Marketing GmbH",
"tx_thuecat_town",,,,,
,"uid","pid","remote_id","title",
,1,10,"https://thuecat.org/resources/043064193523-jcyt","Erfurt",
1 tx_thuecat_tourist_attraction
2 uid pid sys_language_uid remote_id title
3 1 10 0 https://thuecat.org/resources/835224016581-dara Dom St. Marien
4 2 10 1 https://thuecat.org/resources/835224016581-dara Cathedral of St. Mary
5 3 10 0 https://thuecat.org/resources/165868194223-zmqf Alte Synagoge
6 4 10 1 https://thuecat.org/resources/165868194223-zmqf Old Synagogue
7 5 10 2 https://thuecat.org/resources/165868194223-zmqf La vieille synagogue
8 6 10 0 https://thuecat.org/resources/215230952334-yyno Krämerbrücke
9 7 10 1 https://thuecat.org/resources/215230952334-yyno Merchants' Bridge
10 8 10 2 https://thuecat.org/resources/215230952334-yyno Pont de l'épicier
11 tx_thuecat_organisation
12 uid pid remote_id title
13 1 10 https://thuecat.org/resources/018132452787-ngbe Erfurt Tourismus und Marketing GmbH
14 tx_thuecat_town
15 uid pid remote_id title
16 1 10 https://thuecat.org/resources/043064193523-jcyt Erfurt

View file

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<dataset>
<pages>
<uid>1</uid>
<pid>0</pid>
<tstamp>1613400587</tstamp>
<crdate>1613400558</crdate>
<cruser_id>1</cruser_id>
<doktype>4</doktype>
<title>Rootpage</title>
<is_siteroot>1</is_siteroot>
</pages>
<pages>
<uid>10</uid>
<pid>1</pid>
<tstamp>1613400587</tstamp>
<crdate>1613400558</crdate>
<cruser_id>1</cruser_id>
<doktype>254</doktype>
<title>Storage folder</title>
</pages>
<sys_language>
<uid>1</uid>
<pid>0</pid>
<title>English</title>
<flag>en-us-gb</flag>
<language_isocode>en</language_isocode>
</sys_language>
<sys_language>
<uid>2</uid>
<pid>0</pid>
<title>French</title>
<flag>fr</flag>
<language_isocode>fr</language_isocode>
</sys_language>
<tx_thuecat_import_configuration>
<uid>1</uid>
<pid>0</pid>
<tstamp>1613400587</tstamp>
<crdate>1613400558</crdate>
<cruser_id>1</cruser_id>
<disable>0</disable>
<title>Contains Place</title>
<type>containsPlace</type>
<configuration><![CDATA[<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<T3FlexForms>
<data>
<sheet index="sDEF">
<language index="lDEF">
<field index="storagePid">
<value index="vDEF">10</value>
</field>
<field index="containsPlaceId">
<value index="vDEF">043064193523-contains</value>
</field>
</language>
</sheet>
</data>
</T3FlexForms>]]></configuration>
</tx_thuecat_import_configuration>
</dataset>

View file

@ -299,6 +299,50 @@ class ImportTest extends TestCase
$this->assertCSVDataSet('EXT:thuecat/Tests/Functional/Fixtures/Import/ImportsSyncScope.csv');
}
/**
* @test
*/
public function importsBasedOnContainsPlace(): void
{
$this->importDataSet(__DIR__ . '/Fixtures/Import/ImportsContainsPlace.xml');
GuzzleClientFaker::appendResponseFromFile(__DIR__ . '/Fixtures/Import/Guzzle/thuecat.org/resources/043064193523-contains.json');
GuzzleClientFaker::appendResponseFromFile(__DIR__ . '/Fixtures/Import/Guzzle/thuecat.org/resources/835224016581-dara.json');
GuzzleClientFaker::appendResponseFromFile(__DIR__ . '/Fixtures/Import/Guzzle/thuecat.org/resources/018132452787-ngbe.json');
GuzzleClientFaker::appendResponseFromFile(__DIR__ . '/Fixtures/Import/Guzzle/thuecat.org/resources/043064193523-jcyt.json');
GuzzleClientFaker::appendResponseFromFile(__DIR__ . '/Fixtures/Import/Guzzle/thuecat.org/resources/573211638937-gmqb.json');
GuzzleClientFaker::appendResponseFromFile(__DIR__ . '/Fixtures/Import/Guzzle/thuecat.org/resources/508431710173-wwne.json');
for ($i = 1; $i <= 4; $i++) {
GuzzleClientFaker::appendNotFoundResponse();
}
GuzzleClientFaker::appendResponseFromFile(__DIR__ . '/Fixtures/Import/Guzzle/thuecat.org/resources/396420044896-drzt.json');
for ($i = 1; $i <= 10; $i++) {
GuzzleClientFaker::appendNotFoundResponse();
}
GuzzleClientFaker::appendResponseFromFile(__DIR__ . '/Fixtures/Import/Guzzle/thuecat.org/resources/165868194223-zmqf.json');
GuzzleClientFaker::appendResponseFromFile(__DIR__ . '/Fixtures/Import/Guzzle/thuecat.org/resources/497839263245-edbm.json');
for ($i = 1; $i <= 2; $i++) {
GuzzleClientFaker::appendNotFoundResponse();
}
GuzzleClientFaker::appendResponseFromFile(__DIR__ . '/Fixtures/Import/Guzzle/thuecat.org/resources/e_23bec7f80c864c358da033dd75328f27-rfa.json');
for ($i = 1; $i <= 4; $i++) {
GuzzleClientFaker::appendNotFoundResponse();
}
GuzzleClientFaker::appendResponseFromFile(__DIR__ . '/Fixtures/Import/Guzzle/thuecat.org/resources/215230952334-yyno.json');
GuzzleClientFaker::appendResponseFromFile(__DIR__ . '/Fixtures/Import/Guzzle/thuecat.org/resources/052821473718-oxfq.json');
for ($i = 1; $i <= 4; $i++) {
GuzzleClientFaker::appendNotFoundResponse();
}
GuzzleClientFaker::appendResponseFromFile(__DIR__ . '/Fixtures/Import/Guzzle/thuecat.org/resources/440055527204-ocar.json');
for ($i = 1; $i <= 14; $i++) {
GuzzleClientFaker::appendNotFoundResponse();
}
$configuration = $this->get(ImportConfigurationRepository::class)->findByUid(1);
$this->get(Importer::class)->importConfiguration($configuration);
$this->assertCSVDataSet('EXT:thuecat/Tests/Functional/Fixtures/Import/ImportsContainsPlace.csv');
}
/**
* @test
* @testdox Referencing the same thing multiple times only adds it once.

View file

@ -101,7 +101,10 @@ class SyncScopeUrlProviderTest extends TestCase
$configuration->_setProperty('syncScopeId', 10);
$fetchData = $this->createStub(FetchData::class);
$fetchData->method('getResourceEndpoint')->willReturn('https://example.com/api/');
$fetchData->method('getFullResourceUrl')->willReturnOnConsecutiveCalls(
'https://example.com/api/835224016581-dara',
'https://example.com/api/165868194223-zmqf'
);
$fetchData->method('updatedNodes')->willReturn([
'data' => [
'createdOrUpdated' => [

View file

@ -326,11 +326,11 @@ parameters:
-
message: "#^Cannot call method findByUid\\(\\) on mixed\\.$#"
count: 10
count: 11
path: Tests/Functional/ImportTest.php
-
message: "#^Cannot call method importConfiguration\\(\\) on mixed\\.$#"
count: 10
count: 11
path: Tests/Functional/ImportTest.php