diff --git a/Classes/Domain/Import/Converter/TouristAttraction.php b/Classes/Domain/Import/Converter/TouristAttraction.php
index 8302652..ffbc121 100644
--- a/Classes/Domain/Import/Converter/TouristAttraction.php
+++ b/Classes/Domain/Import/Converter/TouristAttraction.php
@@ -72,6 +72,7 @@ class TouristAttraction implements Converter
'town' => $town ? $town->getUid() : 0,
'opening_hours' => json_encode($this->parser->getOpeningHours($jsonLD)),
'address' => json_encode($this->parser->getAddress($jsonLD)),
+ 'media' => json_encode($this->parser->getMedia($jsonLD)),
]
);
$entities->add($entity);
diff --git a/Classes/Domain/Import/Importer/FetchData.php b/Classes/Domain/Import/Importer/FetchData.php
index 7f7fcd8..637fe71 100644
--- a/Classes/Domain/Import/Importer/FetchData.php
+++ b/Classes/Domain/Import/Importer/FetchData.php
@@ -25,28 +25,39 @@ namespace WerkraumMedia\ThueCat\Domain\Import\Importer;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestFactoryInterface;
+use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface as CacheFrontendInterface;
class FetchData
{
private RequestFactoryInterface $requestFactory;
private ClientInterface $httpClient;
+ private CacheFrontendInterface $cache;
public function __construct(
RequestFactoryInterface $requestFactory,
- ClientInterface $httpClient
+ ClientInterface $httpClient,
+ CacheFrontendInterface $cache
) {
$this->requestFactory = $requestFactory;
$this->httpClient = $httpClient;
+ $this->cache = $cache;
}
public function jsonLDFromUrl(string $url): array
{
+ $cacheIdentifier = sha1($url);
+ $cacheEntry = $this->cache->get($cacheIdentifier);
+ if (is_array($cacheEntry)) {
+ return $cacheEntry;
+ }
+
$request = $this->requestFactory->createRequest('GET', $url);
$response = $this->httpClient->sendRequest($request);
- $json = json_decode((string) $response->getBody(), true);
- if (is_array($json)) {
- return $json;
+ $jsonLD = json_decode((string) $response->getBody(), true);
+ if (is_array($jsonLD)) {
+ $this->cache->set($cacheIdentifier, $jsonLD);
+ return $jsonLD;
}
return [];
diff --git a/Classes/Domain/Import/JsonLD/Parser.php b/Classes/Domain/Import/JsonLD/Parser.php
index 2d50b0e..c3cb46b 100644
--- a/Classes/Domain/Import/JsonLD/Parser.php
+++ b/Classes/Domain/Import/JsonLD/Parser.php
@@ -24,20 +24,25 @@ namespace WerkraumMedia\ThueCat\Domain\Import\JsonLD;
*/
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\Address;
+use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\Media;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\OpeningHours;
class Parser
{
private OpeningHours $openingHours;
private Address $address;
+ private Media $media;
public function __construct(
OpeningHours $openingHours,
- Address $address
+ Address $address,
+ Media $media
) {
$this->openingHours = $openingHours;
$this->address = $address;
+ $this->media = $media;
}
+
public function getId(array $jsonLD): string
{
return $jsonLD['@id'];
@@ -78,6 +83,11 @@ class Parser
return $this->address->get($jsonLD);
}
+ public function getMedia(array $jsonLD): array
+ {
+ return $this->media->get($jsonLD);
+ }
+
/**
* @return string[]
*/
diff --git a/Classes/Domain/Import/JsonLD/Parser/Address.php b/Classes/Domain/Import/JsonLD/Parser/Address.php
index 3d9b70a..b203060 100644
--- a/Classes/Domain/Import/JsonLD/Parser/Address.php
+++ b/Classes/Domain/Import/JsonLD/Parser/Address.php
@@ -26,9 +26,7 @@ class Address
public function get(array $jsonLD): array
{
$address = $jsonLD['schema:address'] ?? [];
- if (isset($address['@id']) === false) {
- return [];
- }
+ $geo = $jsonLD['schema:geo'] ?? [];
return [
'street' => $this->getStreet($address),
@@ -37,6 +35,7 @@ class Address
'email' => $this->getEmail($address),
'phone' => $this->getPhone($address),
'fax' => $this->getFax($address),
+ 'geo' => $this->getGeo($geo),
];
}
@@ -69,4 +68,12 @@ class Address
{
return $address['schema:faxNumber']['@value'] ?? '';
}
+
+ private function getGeo(array $geo): array
+ {
+ return [
+ 'latitude' => floatval($geo['schema:latitude']['@value'] ?? 0.00),
+ 'longitude' => floatval($geo['schema:longitude']['@value'] ?? 0.00),
+ ];
+ }
}
diff --git a/Classes/Domain/Import/JsonLD/Parser/Media.php b/Classes/Domain/Import/JsonLD/Parser/Media.php
new file mode 100644
index 0000000..9b4a7e5
--- /dev/null
+++ b/Classes/Domain/Import/JsonLD/Parser/Media.php
@@ -0,0 +1,93 @@
+
+ *
+ * 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\FetchData;
+
+class Media
+{
+ private FetchData $fetchData;
+
+ public function __construct(
+ FetchData $fetchData
+ ) {
+ $this->fetchData = $fetchData;
+ }
+
+ public function get(array $jsonLD): array
+ {
+ $media = [];
+
+ if (isset($jsonLD['schema:photo']['@id'])) {
+ $media[] = array_merge(
+ [
+ 'mainImage' => true,
+ ],
+ $this->getMedia($jsonLD['schema:photo']['@id'])
+ );
+ }
+
+ if (isset($jsonLD['schema:image']['@id'])) {
+ $media[] = array_merge(
+ [
+ 'mainImage' => false,
+ ],
+ $this->getMedia($jsonLD['schema:image']['@id'])
+ );
+ }
+
+ if (
+ isset($jsonLD['schema:image'])
+ && isset($jsonLD['schema:image']['@id']) === false
+ && is_array($jsonLD['schema:image'])
+ ) {
+ foreach ($jsonLD['schema:image'] as $image) {
+ $media[] = array_merge(
+ [
+ 'mainImage' => false,
+ ],
+ $this->getMedia($image['@id'])
+ );
+ }
+ }
+
+ return $media;
+ }
+
+ private function getMedia(string $resourceId): array
+ {
+ $jsonLD = $this->fetchData->jsonLDFromUrl($resourceId);
+ $resource = $jsonLD['@graph'][0] ?? [];
+
+ return [
+ 'type' => 'image',
+ 'title' => $resource['schema:name']['@value'] ?? '',
+ 'description' => $resource['schema:description']['@value'] ?? '',
+ 'url' => $resource['schema:url']['@value'] ?? '',
+ 'copyrightYear' => intval($resource['schema:copyrightYear']['@value'] ?? 0),
+ 'license' => [
+ 'type' => $resource['schema:license']['@value'] ?? '',
+ 'author' => $resource['thuecat:licenseAuthor']['@value'] ?? '',
+ ],
+ ];
+ }
+}
diff --git a/Classes/Domain/Import/RequestFactory.php b/Classes/Domain/Import/RequestFactory.php
index 2080442..a2773f0 100644
--- a/Classes/Domain/Import/RequestFactory.php
+++ b/Classes/Domain/Import/RequestFactory.php
@@ -32,7 +32,7 @@ class RequestFactory extends Typo3RequestFactory
public function createRequest(string $method, $uri): RequestInterface
{
$uri = new Uri((string) $uri);
- $uri = $uri->withQuery('?format=jsonId');
+ $uri = $uri->withQuery('?format=jsonld');
// TODO: Add api key from site
diff --git a/Classes/Domain/Model/Frontend/Address.php b/Classes/Domain/Model/Frontend/Address.php
index 5c73811..f1ecdfc 100644
--- a/Classes/Domain/Model/Frontend/Address.php
+++ b/Classes/Domain/Model/Frontend/Address.php
@@ -66,6 +66,16 @@ class Address implements TypeInterface
return $this->data['fax'] ?? '';
}
+ public function getLatitute(): float
+ {
+ return $this->data['geo']['latitude'] ?? 0.0;
+ }
+
+ public function getLongitude(): float
+ {
+ return $this->data['geo']['longitude'] ?? 0.0;
+ }
+
public function __toString(): string
{
return $this->serialized;
diff --git a/Classes/Domain/Model/Frontend/Media.php b/Classes/Domain/Model/Frontend/Media.php
new file mode 100644
index 0000000..d8be397
--- /dev/null
+++ b/Classes/Domain/Model/Frontend/Media.php
@@ -0,0 +1,64 @@
+
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+use TYPO3\CMS\Core\Type\TypeInterface;
+
+class Media implements TypeInterface
+{
+ private string $serialized;
+ private array $data;
+
+ public function __construct(string $serialized)
+ {
+ $this->serialized = $serialized;
+ $this->data = json_decode($serialized, true);
+ }
+
+ public function getMainImage(): array
+ {
+ foreach ($this->data as $media) {
+ if (
+ $media['type'] === 'image'
+ && $media['mainImage'] === true
+ ) {
+ return $media;
+ }
+ }
+
+ return [];
+ }
+
+ public function getImages(): array
+ {
+ return array_filter($this->data, function (array $media) {
+ return $media['type'] === 'image';
+ });
+ }
+
+ public function __toString(): string
+ {
+ return $this->serialized;
+ }
+}
diff --git a/Classes/Domain/Model/Frontend/TouristAttraction.php b/Classes/Domain/Model/Frontend/TouristAttraction.php
index e29f1d3..9207cb9 100644
--- a/Classes/Domain/Model/Frontend/TouristAttraction.php
+++ b/Classes/Domain/Model/Frontend/TouristAttraction.php
@@ -32,6 +32,7 @@ class TouristAttraction extends AbstractEntity
protected ?OpeningHours $openingHours = null;
protected ?Address $address = null;
protected ?Town $town = null;
+ protected ?Media $media = null;
public function getTitle(): string
{
@@ -57,4 +58,9 @@ class TouristAttraction extends AbstractEntity
{
return $this->town;
}
+
+ public function getMedia(): ?Media
+ {
+ return $this->media;
+ }
}
diff --git a/Classes/Extension.php b/Classes/Extension.php
index 293a135..1845db5 100644
--- a/Classes/Extension.php
+++ b/Classes/Extension.php
@@ -23,6 +23,7 @@ namespace WerkraumMedia\ThueCat;
* 02110-1301, USA.
*/
+use TYPO3\CMS\Core\Cache\Backend\TransientMemoryBackend;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Extbase\Utility\ExtensionUtility;
use WerkraumMedia\ThueCat\Controller\Backend\ImportController;
@@ -61,6 +62,12 @@ class Extension
}
public static function registerConfig(): void
+ {
+ self::addCaching();
+ self::addContentElements();
+ }
+
+ private static function addContentElements(): void
{
$languagePath = self::getLanguagePath() . 'locallang_tca.xlf:tt_content';
@@ -81,4 +88,15 @@ class Extension
}
');
}
+
+ private static function addCaching(): void
+ {
+ $cacheIdentifier = 'thuecat_fetchdata';
+ if (!is_array($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations'][$cacheIdentifier])) {
+ $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations'][$cacheIdentifier] = [];
+ }
+ if (!isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations'][$cacheIdentifier]['backend'])) {
+ $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations'][$cacheIdentifier]['backend'] = TransientMemoryBackend::class;
+ }
+ }
}
diff --git a/Configuration/Services.yaml b/Configuration/Services.yaml
index 0f313d9..66412d7 100644
--- a/Configuration/Services.yaml
+++ b/Configuration/Services.yaml
@@ -10,7 +10,16 @@ services:
WerkraumMedia\ThueCat\Domain\Import\Importer\FetchData:
arguments:
$requestFactory: '@WerkraumMedia\ThueCat\Domain\Import\RequestFactory'
+ $cache: '@cache.thuecat_fetchdata'
WerkraumMedia\ThueCat\Frontend\DataProcessing\:
resource: '../Classes/Frontend/DataProcessing/*'
public: true
+
+ 'cache.thuecat_fetchdata':
+ class: 'TYPO3\CMS\Core\Cache\Frontend\FrontendInterface'
+ factory:
+ - '@TYPO3\CMS\Core\Cache\CacheManager'
+ - 'getCache'
+ arguments:
+ - 'thuecat_fetchdata'
diff --git a/Configuration/TCA/tx_thuecat_tourist_attraction.php b/Configuration/TCA/tx_thuecat_tourist_attraction.php
index 534a536..f4ee0a2 100644
--- a/Configuration/TCA/tx_thuecat_tourist_attraction.php
+++ b/Configuration/TCA/tx_thuecat_tourist_attraction.php
@@ -49,6 +49,13 @@ return (static function (string $extensionKey, string $tableName) {
'readOnly' => true,
],
],
+ 'media' => [
+ 'label' => $languagePath . '.media',
+ 'config' => [
+ 'type' => 'text',
+ 'readOnly' => true,
+ ],
+ ],
'remote_id' => [
'label' => $languagePath . '.remote_id',
'config' => [
@@ -89,7 +96,7 @@ return (static function (string $extensionKey, string $tableName) {
],
'types' => [
'0' => [
- 'showitem' => 'title, description, opening_hours, address, remote_id, town, managed_by',
+ 'showitem' => 'title, description, opening_hours, address, media, remote_id, town, managed_by',
],
],
];
diff --git a/Resources/Private/Templates/Frontend/ContentElement/TouristAttraction.html b/Resources/Private/Templates/Frontend/ContentElement/TouristAttraction.html
index 043d89f..87ce4f1 100644
--- a/Resources/Private/Templates/Frontend/ContentElement/TouristAttraction.html
+++ b/Resources/Private/Templates/Frontend/ContentElement/TouristAttraction.html
@@ -4,6 +4,10 @@
diff --git a/Tests/Unit/Domain/Import/Converter/TouristAttractionTest.php b/Tests/Unit/Domain/Import/Converter/TouristAttractionTest.php
index 0017cd6..7f7db10 100644
--- a/Tests/Unit/Domain/Import/Converter/TouristAttractionTest.php
+++ b/Tests/Unit/Domain/Import/Converter/TouristAttractionTest.php
@@ -118,6 +118,7 @@ class TouristAttractionTest extends TestCase
$parser->getDescription($jsonLD, 'de')->willReturn('Description');
$parser->getOpeningHours($jsonLD)->willReturn([]);
$parser->getAddress($jsonLD)->willReturn([]);
+ $parser->getMedia($jsonLD)->willReturn([]);
$organisationRepository = $this->prophesize(OrganisationRepository::class);
$townRepository = $this->prophesize(TownRepository::class);
@@ -144,6 +145,7 @@ class TouristAttractionTest extends TestCase
'town' => 0,
'opening_hours' => '[]',
'address' => '[]',
+ 'media' => '[]',
], $entity->getData());
}
@@ -187,6 +189,7 @@ class TouristAttractionTest extends TestCase
$parser->getDescription($jsonLD, 'de')->willReturn('Description');
$parser->getOpeningHours($jsonLD)->willReturn([]);
$parser->getAddress($jsonLD)->willReturn([]);
+ $parser->getMedia($jsonLD)->willReturn([]);
$organisation = $this->prophesize(Organisation::class);
$organisation->getUid()->willReturn(10);
@@ -223,6 +226,7 @@ class TouristAttractionTest extends TestCase
'town' => 20,
'opening_hours' => '[]',
'address' => '[]',
+ 'media' => '[]',
], $entity->getData());
}
}
diff --git a/Tests/Unit/Domain/Import/Importer/FetchDataTest.php b/Tests/Unit/Domain/Import/Importer/FetchDataTest.php
index a6698bd..a9ffd82 100644
--- a/Tests/Unit/Domain/Import/Importer/FetchDataTest.php
+++ b/Tests/Unit/Domain/Import/Importer/FetchDataTest.php
@@ -29,6 +29,7 @@ use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestFactoryInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
+use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
use WerkraumMedia\ThueCat\Domain\Import\Importer\FetchData;
/**
@@ -45,10 +46,12 @@ class FetchDataTest extends TestCase
{
$requestFactory = $this->prophesize(RequestFactoryInterface::class);
$httpClient = $this->prophesize(ClientInterface::class);
+ $cache = $this->prophesize(FrontendInterface::class);
$subject = new FetchData(
$requestFactory->reveal(),
- $httpClient->reveal()
+ $httpClient->reveal(),
+ $cache->reveal()
);
self::assertInstanceOf(FetchData::class, $subject);
@@ -61,6 +64,7 @@ class FetchDataTest extends TestCase
{
$requestFactory = $this->prophesize(RequestFactoryInterface::class);
$httpClient = $this->prophesize(ClientInterface::class);
+ $cache = $this->prophesize(FrontendInterface::class);
$request = $this->prophesize(RequestInterface::class);
$response = $this->prophesize(ResponseInterface::class);
@@ -75,7 +79,8 @@ class FetchDataTest extends TestCase
$subject = new FetchData(
$requestFactory->reveal(),
- $httpClient->reveal()
+ $httpClient->reveal(),
+ $cache->reveal()
);
$result = $subject->jsonLDFromUrl('https://example.com/resources/018132452787-ngbe');
@@ -95,6 +100,7 @@ class FetchDataTest extends TestCase
{
$requestFactory = $this->prophesize(RequestFactoryInterface::class);
$httpClient = $this->prophesize(ClientInterface::class);
+ $cache = $this->prophesize(FrontendInterface::class);
$request = $this->prophesize(RequestInterface::class);
$response = $this->prophesize(ResponseInterface::class);
@@ -109,10 +115,44 @@ class FetchDataTest extends TestCase
$subject = new FetchData(
$requestFactory->reveal(),
- $httpClient->reveal()
+ $httpClient->reveal(),
+ $cache->reveal()
);
$result = $subject->jsonLDFromUrl('https://example.com/resources/018132452787-ngbe');
self::assertSame([], $result);
}
+
+ /**
+ * @test
+ */
+ public function returnsResultFromCacheIfAvailable(): void
+ {
+ $requestFactory = $this->prophesize(RequestFactoryInterface::class);
+ $httpClient = $this->prophesize(ClientInterface::class);
+ $cache = $this->prophesize(FrontendInterface::class);
+
+ $cache->get('03c8a7eb2a06e47c28883d95f7e834089baf9c3e')->willReturn([
+ '@graph' => [
+ [
+ '@id' => 'https://example.com/resources/018132452787-ngbe',
+ ],
+ ],
+ ]);
+
+ $subject = new FetchData(
+ $requestFactory->reveal(),
+ $httpClient->reveal(),
+ $cache->reveal()
+ );
+
+ $result = $subject->jsonLDFromUrl('https://example.com/resources/018132452787-ngbe');
+ self::assertSame([
+ '@graph' => [
+ [
+ '@id' => 'https://example.com/resources/018132452787-ngbe',
+ ],
+ ],
+ ], $result);
+ }
}
diff --git a/Tests/Unit/Domain/Import/JsonLD/Parser/AddressTest.php b/Tests/Unit/Domain/Import/JsonLD/Parser/AddressTest.php
index 09672ad..89577b3 100644
--- a/Tests/Unit/Domain/Import/JsonLD/Parser/AddressTest.php
+++ b/Tests/Unit/Domain/Import/JsonLD/Parser/AddressTest.php
@@ -21,8 +21,8 @@ namespace WerkraumMedia\ThueCat\Tests\Unit\Domain\Import\JsonLD\Parser;
* 02110-1301, USA.
*/
-use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\Address;
use PHPUnit\Framework\TestCase;
+use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\Address;
/**
* @covers WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\Address
@@ -43,14 +43,125 @@ class AddressTest extends TestCase
/**
* @test
*/
- public function returnsEmptyArrayAsFallback(): void
+ public function returnsFallback(): void
{
$subject = new Address(
);
$result = $subject->get([]);
- self::assertSame([], $result);
+ self::assertSame([
+ 'street' => '',
+ 'zip' => '',
+ 'city' => '',
+ 'email' => '',
+ 'phone' => '',
+ 'fax' => '',
+ 'geo' => [
+ 'latitude' => 0.0,
+ 'longitude' => 0.0,
+ ],
+ ], $result);
+ }
+
+ /**
+ * @test
+ */
+ public function returnsAddress(): void
+ {
+ $subject = new Address(
+ );
+
+ $result = $subject->get([
+ 'schema:address' => [
+ '@id' => 'genid-28b33237f71b41e3ad54a99e1da769b9-b0',
+ 'schema:addressLocality' => [
+ '@language' => 'de',
+ '@value' => 'Erfurt',
+ ],
+ 'schema:addressCountry' => [
+ '@type' => 'thuecat:AddressCountry',
+ '@value' => 'thuecat:Germany',
+ ],
+ 'schema:postalCode' => [
+ '@language' => 'de',
+ '@value' => '99084',
+ ],
+ 'schema:addressRegion' => [
+ '@type' => 'thuecat:AddressFederalState',
+ '@value' => 'thuecat:Thuringia',
+ ],
+ 'schema:telephone' => [
+ '@language' => 'de',
+ '@value' => '+49 361 999999',
+ ],
+ 'schema:email' => [
+ '@language' => 'de',
+ '@value' => 'altesynagoge@example.com',
+ ],
+ 'schema:streetAddress' => [
+ '@language' => 'de',
+ '@value' => 'Waagegasse 8',
+ ],
+ 'schema:faxNumber' => [
+ '@language' => 'de',
+ '@value' => '+49 361 999998',
+ ],
+ 'thuecat:typOfAddress' => [
+ '@type' => 'thuecat:TypOfAddress',
+ '@value' => 'thuecat:HouseAddress',
+ ],
+ ],
+ ]);
+
+ self::assertSame([
+ 'street' => 'Waagegasse 8',
+ 'zip' => '99084',
+ 'city' => 'Erfurt',
+ 'email' => 'altesynagoge@example.com',
+ 'phone' => '+49 361 999999',
+ 'fax' => '+49 361 999998',
+ 'geo' => [
+ 'latitude' => 0.0,
+ 'longitude' => 0.0,
+ ],
+ ], $result);
+ }
+
+ /**
+ * @test
+ */
+ public function returnsGeo(): void
+ {
+ $subject = new Address(
+ );
+
+ $result = $subject->get([
+ 'schema:geo' => [
+ '@id' => 'genid-28b33237f71b41e3ad54a99e1da769b9-b4',
+ 'schema:longitude' => [
+ '@type' => 'schema:Number',
+ '@value' => '11.029133',
+ ],
+ 'schema:latitude' => [
+ '@type' => 'schema:Number',
+ '@value' => '50.978765',
+ ],
+ ],
+ ]);
+
+ self::assertSame([
+ 'street' => '',
+ 'zip' => '',
+ 'city' => '',
+ 'email' => '',
+ 'phone' => '',
+ 'fax' => '',
+ 'geo' => [
+ 'latitude' => 50.978765,
+ 'longitude' => 11.029133,
+ ],
+ ], $result);
}
/**
@@ -99,7 +210,18 @@ class AddressTest extends TestCase
'thuecat:typOfAddress' => [
'@type' => 'thuecat:TypOfAddress',
'@value' => 'thuecat:HouseAddress',
- ]
+ ],
+ ],
+ 'schema:geo' => [
+ '@id' => 'genid-28b33237f71b41e3ad54a99e1da769b9-b4',
+ 'schema:longitude' => [
+ '@type' => 'schema:Number',
+ '@value' => '11.029133',
+ ],
+ 'schema:latitude' => [
+ '@type' => 'schema:Number',
+ '@value' => '50.978765',
+ ],
],
]);
@@ -110,6 +232,10 @@ class AddressTest extends TestCase
'email' => 'altesynagoge@example.com',
'phone' => '+49 361 999999',
'fax' => '+49 361 999998',
+ 'geo' => [
+ 'latitude' => 50.978765,
+ 'longitude' => 11.029133,
+ ],
], $result);
}
}
diff --git a/Tests/Unit/Domain/Import/JsonLD/Parser/MediaTest.php b/Tests/Unit/Domain/Import/JsonLD/Parser/MediaTest.php
new file mode 100644
index 0000000..da8f285
--- /dev/null
+++ b/Tests/Unit/Domain/Import/JsonLD/Parser/MediaTest.php
@@ -0,0 +1,251 @@
+
+ *
+ * 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\Importer\FetchData;
+use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\Media;
+
+/**
+ * @covers WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\Media
+ */
+class MediaTest extends TestCase
+{
+ use ProphecyTrait;
+
+ /**
+ * @test
+ */
+ public function canBeCreated(): void
+ {
+ $fetchData = $this->prophesize(FetchData::class);
+
+ $subject = new Media(
+ $fetchData->reveal()
+ );
+
+ self::assertInstanceOf(Media::class, $subject);
+ }
+
+ /**
+ * @test
+ */
+ public function returnsFallback(): void
+ {
+ $fetchData = $this->prophesize(FetchData::class);
+
+ $subject = new Media(
+ $fetchData->reveal()
+ );
+
+ $result = $subject->get([]);
+
+ self::assertSame([], $result);
+ }
+
+ /**
+ * @test
+ */
+ public function returnsPhotoAndImage(): void
+ {
+ $fetchData = $this->prophesize(FetchData::class);
+
+ $fetchData->jsonLDFromUrl('https://thuecat.org/resources/dms_5099196')->willReturn([
+ '@graph' => [
+ 0 => [
+ 'schema:name' => [
+ '@language' => 'de',
+ '@value' => 'Erfurt-Alte Synagoge',
+ ],
+ 'schema:description' => [
+ '@language' => 'de',
+ '@value' => 'Frontaler Blick auf die Hausfront/Hausfassade im Innenhof mit Zugang über die Waagegasse',
+ ],
+ 'schema:copyrightYear' => [
+ '@language' => 'de',
+ '@value' => '2009',
+ ],
+ 'schema:url' => [
+ '@type' => 'xsd:anyURI',
+ '@value' => 'https://cms.thuecat.org/o/adaptive-media/image/5099196/Preview-1280x0/image',
+ ],
+ 'schema:license' => [
+ '@language' => 'de',
+ '@value' => 'https://creativecommons.org/licenses/by/4.0/',
+ ],
+ 'thuecat:licenseAuthor' => [
+ '@language' => 'de',
+ '@value' => 'F:\Bilddatenbank\Museen und Ausstellungen\Alte Synagoge',
+ ],
+ ],
+ ],
+ ]);
+
+ $subject = new Media(
+ $fetchData->reveal()
+ );
+
+ $result = $subject->get([
+ 'schema:photo' => [
+ '@id' => 'https://thuecat.org/resources/dms_5099196',
+ ],
+ 'schema:image' => [
+ '@id' => 'https://thuecat.org/resources/dms_5099196',
+ ],
+ ]);
+
+ self::assertSame([
+ [
+ 'mainImage' => true,
+ 'type' => 'image',
+ 'title' => 'Erfurt-Alte Synagoge',
+ 'description' => 'Frontaler Blick auf die Hausfront/Hausfassade im Innenhof mit Zugang über die Waagegasse',
+ 'url' => 'https://cms.thuecat.org/o/adaptive-media/image/5099196/Preview-1280x0/image',
+ 'copyrightYear' => 2009,
+ 'license' => [
+ 'type' => 'https://creativecommons.org/licenses/by/4.0/',
+ 'author' => 'F:\Bilddatenbank\Museen und Ausstellungen\Alte Synagoge',
+ ],
+ ],
+ [
+ 'mainImage' => false,
+ 'type' => 'image',
+ 'title' => 'Erfurt-Alte Synagoge',
+ 'description' => 'Frontaler Blick auf die Hausfront/Hausfassade im Innenhof mit Zugang über die Waagegasse',
+ 'url' => 'https://cms.thuecat.org/o/adaptive-media/image/5099196/Preview-1280x0/image',
+ 'copyrightYear' => 2009,
+ 'license' => [
+ 'type' => 'https://creativecommons.org/licenses/by/4.0/',
+ 'author' => 'F:\Bilddatenbank\Museen und Ausstellungen\Alte Synagoge',
+ ],
+ ],
+ ], $result);
+ }
+
+ /**
+ * @test
+ */
+ public function returnsMultipleImages(): void
+ {
+ $fetchData = $this->prophesize(FetchData::class);
+
+ $fetchData->jsonLDFromUrl('https://thuecat.org/resources/dms_5159186')->willReturn([
+ '@graph' => [
+ 0 => [
+ 'schema:description' => [
+ '@language' => 'de',
+ '@value' => 'Sicht auf Dom St. Marien, St. Severikirche sowie die davor liegenden Klostergebäude und einem Ausschnitt des Biergartens umgeben von einem dämmerungsverfärten Himmel',
+ ],
+ 'schema:name' => [
+ '@language' => 'de',
+ '@value' => 'Erfurt-Dom-und-Severikirche.jpg',
+ ],
+ 'schema:url' => [
+ '@type' => 'xsd:anyURI',
+ '@value' => 'https://cms.thuecat.org/o/adaptive-media/image/5159186/Preview-1280x0/image',
+ ],
+ 'schema:copyrightYear' => [
+ '@language' => 'de',
+ '@value' => '2020',
+ ],
+ 'schema:license' => [
+ '@language' => 'de',
+ '@value' => 'https://creativecommons.org/licenses/by/4.0/',
+ ],
+ 'thuecat:licenseAuthor' => [
+ '@language' => 'de',
+ '@value' => '',
+ ],
+ ],
+ ],
+ ]);
+ $fetchData->jsonLDFromUrl('https://thuecat.org/resources/dms_5159216')->willReturn([
+ '@graph' => [
+ 0 => [
+ 'schema:name' => [
+ '@language' => 'de',
+ '@value' => 'Erfurt-Dom und Severikirche-beleuchtet.jpg',
+ ],
+ 'schema:copyrightYear' => [
+ '@language' => 'de',
+ '@value' => '2016',
+ ],
+ 'schema:url' => [
+ '@type' => 'xsd:anyURI',
+ '@value' => 'https://cms.thuecat.org/o/adaptive-media/image/5159216/Preview-1280x0/image',
+ ],
+ 'schema:license' => [
+ '@language' => 'de',
+ '@value' => 'https://creativecommons.org/licenses/by/4.0/',
+ ],
+ 'thuecat:licenseAuthor' => [
+ '@language' => 'de',
+ '@value' => '',
+ ],
+ ],
+ ],
+ ]);
+
+ $subject = new Media(
+ $fetchData->reveal()
+ );
+
+ $result = $subject->get([
+ 'schema:image' => [
+ 0 => [
+ '@id' => 'https://thuecat.org/resources/dms_5159186',
+ ],
+ 1 => [
+ '@id' => 'https://thuecat.org/resources/dms_5159216',
+ ],
+ ],
+ ]);
+
+ self::assertSame([
+ [
+ 'mainImage' => false,
+ 'type' => 'image',
+ 'title' => 'Erfurt-Dom-und-Severikirche.jpg',
+ 'description' => 'Sicht auf Dom St. Marien, St. Severikirche sowie die davor liegenden Klostergebäude und einem Ausschnitt des Biergartens umgeben von einem dämmerungsverfärten Himmel',
+ 'url' => 'https://cms.thuecat.org/o/adaptive-media/image/5159186/Preview-1280x0/image',
+ 'copyrightYear' => 2020,
+ 'license' => [
+ 'type' => 'https://creativecommons.org/licenses/by/4.0/',
+ 'author' => '',
+ ],
+ ],
+ [
+ 'mainImage' => false,
+ 'type' => 'image',
+ 'title' => 'Erfurt-Dom und Severikirche-beleuchtet.jpg',
+ 'description' => '',
+ 'url' => 'https://cms.thuecat.org/o/adaptive-media/image/5159216/Preview-1280x0/image',
+ 'copyrightYear' => 2016,
+ 'license' => [
+ 'type' => 'https://creativecommons.org/licenses/by/4.0/',
+ 'author' => '',
+ ],
+ ],
+ ], $result);
+ }
+}
diff --git a/Tests/Unit/Domain/Import/JsonLD/ParserTest.php b/Tests/Unit/Domain/Import/JsonLD/ParserTest.php
index efb1288..5d48316 100644
--- a/Tests/Unit/Domain/Import/JsonLD/ParserTest.php
+++ b/Tests/Unit/Domain/Import/JsonLD/ParserTest.php
@@ -27,6 +27,7 @@ use PHPUnit\Framework\TestCase;
use Prophecy\PhpUnit\ProphecyTrait;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\Address;
+use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\Media;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\OpeningHours;
/**
@@ -43,9 +44,11 @@ class ParserTest extends TestCase
{
$openingHours = $this->prophesize(OpeningHours::class);
$address = $this->prophesize(Address::class);
+ $media = $this->prophesize(Media::class);
$subject = new Parser(
$openingHours->reveal(),
- $address->reveal()
+ $address->reveal(),
+ $media->reveal()
);
self::assertInstanceOf(Parser::class, $subject);
@@ -58,9 +61,11 @@ class ParserTest extends TestCase
{
$openingHours = $this->prophesize(OpeningHours::class);
$address = $this->prophesize(Address::class);
+ $media = $this->prophesize(Media::class);
$subject = new Parser(
$openingHours->reveal(),
- $address->reveal()
+ $address->reveal(),
+ $media->reveal()
);
$result = $subject->getId([
@@ -77,9 +82,11 @@ class ParserTest extends TestCase
{
$openingHours = $this->prophesize(OpeningHours::class);
$address = $this->prophesize(Address::class);
+ $media = $this->prophesize(Media::class);
$subject = new Parser(
$openingHours->reveal(),
- $address->reveal()
+ $address->reveal(),
+ $media->reveal()
);
$result = $subject->getManagerId([
@@ -99,9 +106,11 @@ class ParserTest extends TestCase
{
$openingHours = $this->prophesize(OpeningHours::class);
$address = $this->prophesize(Address::class);
+ $media = $this->prophesize(Media::class);
$subject = new Parser(
$openingHours->reveal(),
- $address->reveal()
+ $address->reveal(),
+ $media->reveal()
);
$result = $subject->getTitle($jsonLD, $language);
@@ -224,9 +233,11 @@ class ParserTest extends TestCase
{
$openingHours = $this->prophesize(OpeningHours::class);
$address = $this->prophesize(Address::class);
+ $media = $this->prophesize(Media::class);
$subject = new Parser(
$openingHours->reveal(),
- $address->reveal()
+ $address->reveal(),
+ $media->reveal()
);
$result = $subject->getDescription($jsonLD, $language);
@@ -348,9 +359,11 @@ class ParserTest extends TestCase
{
$openingHours = $this->prophesize(OpeningHours::class);
$address = $this->prophesize(Address::class);
+ $media = $this->prophesize(Media::class);
$subject = new Parser(
$openingHours->reveal(),
- $address->reveal()
+ $address->reveal(),
+ $media->reveal()
);
$result = $subject->getContainedInPlaceIds([
@@ -379,9 +392,11 @@ class ParserTest extends TestCase
{
$openingHours = $this->prophesize(OpeningHours::class);
$address = $this->prophesize(Address::class);
+ $media = $this->prophesize(Media::class);
$subject = new Parser(
$openingHours->reveal(),
- $address->reveal()
+ $address->reveal(),
+ $media->reveal()
);
$result = $subject->getLanguages([
@@ -415,9 +430,11 @@ class ParserTest extends TestCase
{
$openingHours = $this->prophesize(OpeningHours::class);
$address = $this->prophesize(Address::class);
+ $media = $this->prophesize(Media::class);
$subject = new Parser(
$openingHours->reveal(),
- $address->reveal()
+ $address->reveal(),
+ $media->reveal()
);
$this->expectExceptionCode(1612367481);
@@ -438,9 +455,11 @@ class ParserTest extends TestCase
{
$openingHours = $this->prophesize(OpeningHours::class);
$address = $this->prophesize(Address::class);
+ $media = $this->prophesize(Media::class);
$subject = new Parser(
$openingHours->reveal(),
- $address->reveal()
+ $address->reveal(),
+ $media->reveal()
);
$result = $subject->getLanguages([]);
@@ -473,9 +492,11 @@ class ParserTest extends TestCase
$openingHours = $this->prophesize(OpeningHours::class);
$openingHours->get($jsonLD)->willReturn($generatedOpeningHours);
$address = $this->prophesize(Address::class);
+ $media = $this->prophesize(Media::class);
$subject = new Parser(
$openingHours->reveal(),
- $address->reveal()
+ $address->reveal(),
+ $media->reveal()
);
$result = $subject->getOpeningHours($jsonLD);
@@ -509,14 +530,72 @@ class ParserTest extends TestCase
$openingHours = $this->prophesize(OpeningHours::class);
$address = $this->prophesize(Address::class);
$address->get($jsonLD)->willReturn($generatedAddress);
+ $media = $this->prophesize(Media::class);
$subject = new Parser(
$openingHours->reveal(),
- $address->reveal()
+ $address->reveal(),
+ $media->reveal()
);
$result = $subject->getAddress($jsonLD);
self::assertSame($generatedAddress, $result);
}
+
+ /**
+ * @test
+ */
+ public function returnsMedia(): void
+ {
+ $jsonLD = [
+ 'schema:photo' => [
+ '@id' => 'https://thuecat.org/resources/dms_5099196',
+ ],
+ 'schema:image' => [
+ '@id' => 'https://thuecat.org/resources/dms_5099196',
+ ],
+ ];
+ $generatedMedia = [
+ [
+ 'mainImage' => true,
+ 'type' => 'image',
+ 'title' => 'Erfurt-Alte Synagoge',
+ 'description' => 'Frontaler Blick auf die Hausfront/Hausfassade im Innenhof mit Zugang über die Waagegasse',
+ 'url' => 'https://cms.thuecat.org/o/adaptive-media/image/5099196/Preview-1280x0/image',
+ 'copyrightYear' => 2009,
+ 'license' => [
+ 'type' => 'https://creativecommons.org/licenses/by/4.0/',
+ 'author' => 'F:\Bilddatenbank\Museen und Ausstellungen\Alte Synagoge',
+ ],
+ ],
+ [
+ 'mainImage' => false,
+ 'type' => 'image',
+ 'title' => 'Erfurt-Alte Synagoge',
+ 'description' => 'Frontaler Blick auf die Hausfront/Hausfassade im Innenhof mit Zugang über die Waagegasse',
+ 'url' => 'https://cms.thuecat.org/o/adaptive-media/image/5099196/Preview-1280x0/image',
+ 'copyrightYear' => 2009,
+ 'license' => [
+ 'type' => 'https://creativecommons.org/licenses/by/4.0/',
+ 'author' => 'F:\Bilddatenbank\Museen und Ausstellungen\Alte Synagoge',
+ ],
+ ],
+ ];
+
+ $openingHours = $this->prophesize(OpeningHours::class);
+ $address = $this->prophesize(Address::class);
+ $media = $this->prophesize(Media::class);
+ $media->get($jsonLD)->willReturn($generatedMedia);
+
+ $subject = new Parser(
+ $openingHours->reveal(),
+ $address->reveal(),
+ $media->reveal()
+ );
+
+ $result = $subject->getMedia($jsonLD);
+
+ self::assertSame($generatedMedia, $result);
+ }
}
diff --git a/Tests/Unit/Domain/Import/RequestFactoryTest.php b/Tests/Unit/Domain/Import/RequestFactoryTest.php
index 69e5197..e222263 100644
--- a/Tests/Unit/Domain/Import/RequestFactoryTest.php
+++ b/Tests/Unit/Domain/Import/RequestFactoryTest.php
@@ -49,6 +49,6 @@ class RequestFactoryTest extends TestCase
$subject = new RequestFactory();
$request = $subject->createRequest('GET', 'https://example.com/resources/333039283321-xxwg');
- self::assertSame('format=jsonId', $request->getUri()->getQuery());
+ self::assertSame('format=jsonld', $request->getUri()->getQuery());
}
}
diff --git a/Tests/Unit/Domain/Model/Frontend/AddressTest.php b/Tests/Unit/Domain/Model/Frontend/AddressTest.php
index 56a0b2a..9d112a1 100644
--- a/Tests/Unit/Domain/Model/Frontend/AddressTest.php
+++ b/Tests/Unit/Domain/Model/Frontend/AddressTest.php
@@ -21,8 +21,8 @@ namespace WerkraumMedia\ThueCat\Tests\Unit\Domain\Model\Frontend;
* 02110-1301, USA.
*/
-use WerkraumMedia\ThueCat\Domain\Model\Frontend\Address;
use PHPUnit\Framework\TestCase;
+use WerkraumMedia\ThueCat\Domain\Model\Frontend\Address;
/**
* @covers WerkraumMedia\ThueCat\Domain\Model\Frontend\Address
@@ -114,6 +114,26 @@ class AddressTest extends TestCase
self::assertSame('+49 361 99998', $subject->getFax());
}
+ /**
+ * @test
+ */
+ public function returnsLatitude(): void
+ {
+ $subject = new Address('{"geo": {"latitude": 50.978765}}');
+
+ self::assertSame(50.978765, $subject->getLatitute());
+ }
+
+ /**
+ * @test
+ */
+ public function returnsLongitude(): void
+ {
+ $subject = new Address('{"geo": {"longitude": 11.029133}}');
+
+ self::assertSame(11.029133, $subject->getLongitude());
+ }
+
/**
* @test
*/
diff --git a/Tests/Unit/Domain/Model/Frontend/MediaTest.php b/Tests/Unit/Domain/Model/Frontend/MediaTest.php
new file mode 100644
index 0000000..a300f3c
--- /dev/null
+++ b/Tests/Unit/Domain/Model/Frontend/MediaTest.php
@@ -0,0 +1,86 @@
+
+ *
+ * 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\Model\Frontend\Media;
+
+/**
+ * @covers WerkraumMedia\ThueCat\Domain\Model\Frontend\Media
+ */
+class MediaTest extends TestCase
+{
+ /**
+ * @test
+ */
+ public function canBeCreated(): void
+ {
+ $subject = new Media('[]');
+
+ self::assertInstanceOf(Media::class, $subject);
+ }
+
+ /**
+ * @test
+ */
+ public function returnsMainImageIfPresent(): void
+ {
+ $subject = new Media('[{"mainImage":false,"type":"image","title":"Erfurt-Dom-und-Severikirche.jpg"},{"mainImage":true,"type":"image","title":"Erfurt-Dom und Severikirche-beleuchtet.jpg"}]');
+
+ self::assertSame([
+ 'mainImage' => true,
+ 'type' => 'image',
+ 'title' => 'Erfurt-Dom und Severikirche-beleuchtet.jpg',
+ ], $subject->getMainImage());
+ }
+
+ /**
+ * @test
+ */
+ public function returnsEmptyArrayAsMainImageFallback(): void
+ {
+ $subject = new Media('[]');
+
+ self::assertSame([], $subject->getMainImage());
+ }
+
+ /**
+ * @test
+ */
+ public function returnsImagesAsArray(): void
+ {
+ $subject = new Media('[{"mainImage":false,"type":"image","title":"Erfurt-Dom-und-Severikirche.jpg"},{"mainImage":true,"type":"image","title":"Erfurt-Dom und Severikirche-beleuchtet.jpg"}]');
+
+ self::assertSame([
+ [
+ 'mainImage' => false,
+ 'type' => 'image',
+ 'title' => 'Erfurt-Dom-und-Severikirche.jpg',
+ ],
+ [
+ 'mainImage' => true,
+ 'type' => 'image',
+ 'title' => 'Erfurt-Dom und Severikirche-beleuchtet.jpg',
+ ],
+ ], $subject->getImages());
+ }
+}
diff --git a/ext_tables.sql b/ext_tables.sql
index 6153f81..a037a06 100644
--- a/ext_tables.sql
+++ b/ext_tables.sql
@@ -49,4 +49,5 @@ CREATE TABLE tx_thuecat_tourist_attraction (
description text DEFAULT '' NOT NULL,
opening_hours text DEFAULT '' NOT NULL,
address text DEFAULT '' NOT NULL,
+ media text DEFAULT '' NOT NULL,
);