Add prices to tourist attraction

Import prices, show them in records and make them accessible in
frontend.
This commit is contained in:
Daniel Siepmann 2021-02-18 14:54:00 +01:00
parent 775db67efa
commit 442a6842ec
23 changed files with 1205 additions and 302 deletions

View file

@ -26,6 +26,7 @@ namespace WerkraumMedia\ThueCat\Domain\Import\Converter;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use WerkraumMedia\ThueCat\Domain\Import\Importer\LanguageHandling;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\Offers;
use WerkraumMedia\ThueCat\Domain\Import\Model\EntityCollection;
use WerkraumMedia\ThueCat\Domain\Import\Model\GenericEntity;
use WerkraumMedia\ThueCat\Domain\Model\Backend\ImportConfiguration;
@ -35,17 +36,20 @@ use WerkraumMedia\ThueCat\Domain\Repository\Backend\TownRepository;
class TouristAttraction implements Converter
{
private Parser $parser;
private Offers $parserForOffers;
private LanguageHandling $language;
private OrganisationRepository $organisationRepository;
private TownRepository $townRepository;
public function __construct(
Parser $parser,
Offers $parserForOffers,
LanguageHandling $language,
OrganisationRepository $organisationRepository,
TownRepository $townRepository
) {
$this->parser = $parser;
$this->parserForOffers = $parserForOffers;
$this->language = $language;
$this->organisationRepository = $organisationRepository;
$this->townRepository = $townRepository;
@ -77,6 +81,7 @@ class TouristAttraction implements Converter
'opening_hours' => json_encode($this->parser->getOpeningHours($jsonLD)),
'address' => json_encode($this->parser->getAddress($jsonLD)),
'media' => json_encode($this->parser->getMedia($jsonLD)),
'offers' => json_encode($this->parserForOffers->get($jsonLD, $language)),
]
);
$entities->add($entity);

View file

@ -24,20 +24,24 @@ namespace WerkraumMedia\ThueCat\Domain\Import\JsonLD;
*/
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\Address;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\GenericFields;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\Media;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\OpeningHours;
class Parser
{
private GenericFields $genericFields;
private OpeningHours $openingHours;
private Address $address;
private Media $media;
public function __construct(
GenericFields $genericFields,
OpeningHours $openingHours,
Address $address,
Media $media
) {
$this->genericFields = $genericFields;
$this->openingHours = $openingHours;
$this->address = $address;
$this->media = $media;
@ -50,12 +54,12 @@ class Parser
public function getTitle(array $jsonLD, string $language = ''): string
{
return $this->getValueForLanguage($jsonLD['schema:name'], $language);
return $this->genericFields->getTitle($jsonLD, $language);
}
public function getDescription(array $jsonLD, string $language = ''): string
{
return $this->getValueForLanguage($jsonLD['schema:description'], $language);
return $this->genericFields->getDescription($jsonLD, $language);
}
public function getManagerId(array $jsonLD): string
@ -108,6 +112,7 @@ class Parser
$languages = array_map(function (array $language) {
$language = $language['@value'];
// TODO: Make configurable / easier to extend
if ($language === 'thuecat:German') {
return 'de';
}
@ -123,37 +128,4 @@ class Parser
return $languages;
}
private function getValueForLanguage(
array $property,
string $language
): string {
if (
$this->doesLanguageMatch($property, $language)
&& isset($property['@value'])
) {
return $property['@value'];
}
foreach ($property as $languageEntry) {
if (
is_array($languageEntry)
&& $this->doesLanguageMatch($languageEntry, $language)
) {
return $languageEntry['@value'];
}
}
return '';
}
private function doesLanguageMatch(array $property, string $language): bool
{
return isset($property['@language'])
&& (
$property['@language'] === $language
|| $language === ''
)
;
}
}

View file

@ -0,0 +1,43 @@
<?php
namespace WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser;
/*
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
class GenericFields
{
private LanguageValues $languageValues;
public function __construct(
LanguageValues $languageValues
) {
$this->languageValues = $languageValues;
}
public function getTitle(array $jsonLD, string $language = ''): string
{
return $this->languageValues->getValueForLanguage($jsonLD['schema:name'] ?? [], $language);
}
public function getDescription(array $jsonLD, string $language = ''): string
{
return $this->languageValues->getValueForLanguage($jsonLD['schema:description'] ?? [], $language);
}
}

View file

@ -0,0 +1,60 @@
<?php
namespace WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser;
/*
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
class LanguageValues
{
public function getValueForLanguage(
array $property,
string $language
): string {
if (
$this->doesLanguageMatch($property, $language)
&& isset($property['@value'])
) {
return $property['@value'];
}
foreach ($property as $languageEntry) {
if (
is_array($languageEntry)
&& $this->doesLanguageMatch($languageEntry, $language)
) {
return $languageEntry['@value'];
}
}
return '';
}
private function doesLanguageMatch(
array $property,
string $language
): bool {
return isset($property['@language'])
&& (
$property['@language'] === $language
|| $language === ''
)
;
}
}

View file

@ -0,0 +1,103 @@
<?php
namespace WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser;
/*
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
class Offers
{
private GenericFields $genericFields;
public function __construct(
GenericFields $genericFields
) {
$this->genericFields = $genericFields;
}
public function get(array $jsonLD, string $language): array
{
$offers = [];
$jsonLDOffers = $jsonLD['schema:makesOffer'] ?? [];
foreach ($jsonLDOffers as $jsonLDOffer) {
$offer = $this->getOffer($jsonLDOffer, $language);
if ($offer !== []) {
$offers[] = $offer;
}
}
return $offers;
}
private function getOffer(array $jsonLD, string $language): array
{
return [
'title' => $this->genericFields->getTitle($jsonLD, $language),
'description' => $this->genericFields->getDescription($jsonLD, $language),
'prices' => $this->getPrices($jsonLD, $language),
];
}
private function getPrices(array $jsonLD, string $language): array
{
$prices = [];
$jsonLDPrices = $jsonLD['schema:priceSpecification'] ?? [];
foreach ($jsonLDPrices as $jsonLDPrice) {
$price = $this->getPrice($jsonLDPrice, $language);
if ($price !== []) {
$prices[] = $price;
}
}
return $prices;
}
private function getPrice(array $jsonLD, string $language): array
{
return [
'title' => $this->genericFields->getTitle($jsonLD, $language),
'description' => $this->genericFields->getDescription($jsonLD, $language),
'price' => $this->getPriceValue($jsonLD),
'currency' => $this->getCurrencyValue($jsonLD),
'rule' => $this->getRuleValue($jsonLD),
];
}
private function getPriceValue(array $jsonLD): float
{
$price = $jsonLD['schema:price']['@value'] ?? 0.0;
$price = floatval($price);
return $price;
}
private function getCurrencyValue(array $jsonLD): string
{
$currency = $jsonLD['schema:priceCurrency']['@value'] ?? '';
$currency = str_replace('thuecat:', '', $currency);
return $currency;
}
private function getRuleValue(array $jsonLD): string
{
$rule = $jsonLD['thuecat:calculationRule']['@value'] ?? '';
$rule = str_replace('thuecat:', '', $rule);
return $rule;
}
}

View file

@ -0,0 +1,70 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Domain\Model\Frontend;
/*
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
class Offer
{
private string $title;
private string $description;
private array $prices;
private function __construct(
string $title,
string $description,
array $prices
) {
$this->title = $title;
$this->description = $description;
$this->prices = $prices;
}
public static function createFromArray(array $rawData): self
{
$prices = [];
foreach ($rawData['prices'] as $price) {
$prices[] = Price::createFromArray($price);
}
return new self(
$rawData['title'],
$rawData['description'],
$prices
);
}
public function getTitle(): string
{
return $this->title;
}
public function getDescription(): string
{
return $this->description;
}
public function getPrices(): array
{
return $this->prices;
}
}

View file

@ -0,0 +1,75 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Domain\Model\Frontend;
/*
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
use TYPO3\CMS\Core\Type\TypeInterface;
/**
* @implements \Iterator<int, Offer>
*/
class Offers implements TypeInterface, \Iterator
{
private string $serialized = '';
private array $array = [];
private int $position = 0;
public function __construct(string $serialized)
{
$this->serialized = $serialized;
$this->array = array_map(
[Offer::class, 'createFromArray'],
json_decode($serialized, true)
);
}
public function __toString(): string
{
return $this->serialized;
}
public function current(): Offer
{
return $this->array[$this->position];
}
public function next(): void
{
++$this->position;
}
public function key(): int
{
return $this->position;
}
public function valid(): bool
{
return isset($this->array[$this->position]);
}
public function rewind(): void
{
$this->position = 0;
}
}

View file

@ -0,0 +1,83 @@
<?php
declare(strict_types=1);
namespace WerkraumMedia\ThueCat\Domain\Model\Frontend;
/*
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
class Price
{
private string $title;
private string $description;
private float $price;
private string $currency;
private string $rule;
private function __construct(
string $title,
string $description,
float $price,
string $currency,
string $rule
) {
$this->title = $title;
$this->description = $description;
$this->price = $price;
$this->currency = $currency;
$this->rule = $rule;
}
public static function createFromArray(array $rawData): self
{
return new self(
$rawData['title'],
$rawData['description'],
$rawData['price'],
$rawData['currency'],
$rawData['rule']
);
}
public function getTitle(): string
{
return $this->title;
}
public function getDescription(): string
{
return $this->description;
}
public function getPrice(): float
{
return $this->price;
}
public function getCurrency(): string
{
return $this->currency;
}
public function getRule(): string
{
return $this->rule;
}
}

View file

@ -30,6 +30,7 @@ class TouristAttraction extends AbstractEntity
protected string $title = '';
protected string $description = '';
protected ?OpeningHours $openingHours = null;
protected ?Offers $offers = null;
protected ?Address $address = null;
protected ?Town $town = null;
protected ?Media $media = null;
@ -49,6 +50,11 @@ class TouristAttraction extends AbstractEntity
return $this->openingHours;
}
public function getOffers(): ?Offers
{
return $this->offers;
}
public function getAddress(): ?Address
{
return $this->address;

View file

@ -14,8 +14,7 @@ defined('TYPO3') or die();
],
'types' => [
$cType => [
'showitem' =>
'--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general,'
'showitem' => '--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general,'
. '--palette--;;general,'
. '--palette--;;headers,'
. 'records,'

View file

@ -101,6 +101,14 @@ return (static function (string $extensionKey, string $tableName) {
'readOnly' => true,
],
],
'offers' => [
'label' => $languagePath . '.offers',
'l10n_mode' => 'exclude',
'config' => [
'type' => 'text',
'readOnly' => true,
],
],
'remote_id' => [
'label' => $languagePath . '.remote_id',
'l10n_mode' => 'exclude',
@ -150,7 +158,7 @@ return (static function (string $extensionKey, string $tableName) {
],
'types' => [
'0' => [
'showitem' => '--palette--;;language, title, description, opening_hours, address, media, remote_id, --div--;' . $languagePath . '.tab.relations, town, managed_by',
'showitem' => '--palette--;;language, title, description, opening_hours, offers, address, media, remote_id, --div--;' . $languagePath . '.tab.relations, town, managed_by',
],
],
];

View file

@ -106,6 +106,16 @@
<trans-unit id="controller.backend.import.import.error.text" xml:space="preserve">
<source>Imported configuration "%1$s". But had at least one error.</source>
</trans-unit>
<trans-unit id="content.price.rule.PerPackage" xml:space="preserve">
<source>pro Paket</source>
</trans-unit>
<trans-unit id="content.price.rule.PerGroup" xml:space="preserve">
<source>pro Gruppe</source>
</trans-unit>
<trans-unit id="content.price.rule.PerPerson" xml:space="preserve">
<source>pro Person</source>
</trans-unit>
</body>
</file>
</xliff>

View file

@ -102,6 +102,9 @@
<trans-unit id="tx_thuecat_tourist_attraction.media" xml:space="preserve">
<source>Media</source>
</trans-unit>
<trans-unit id="tx_thuecat_tourist_attraction.offers" xml:space="preserve">
<source>Offers</source>
</trans-unit>
<trans-unit id="tx_thuecat_tourist_attraction.town" xml:space="preserve">
<source>Town</source>
</trans-unit>

View file

@ -27,5 +27,22 @@
{entity.address.fax}
</p>
</f:if>
<f:if condition="{entity.offers}">
<f:for each="{entity.offers}" as="offer">
<h3>{offer.title}</h3>
<f:if condition="{offer.description}">
<p>{offer.description}</p>
</f:if>
<f:for each="{offer.prices}" as="price">
<h4>{price.title}</h4>
<f:if condition="{price.description}">
<p>{price.description}</p>
</f:if>
{price.price -> f:format.currency(decimalSeparator: ',', thousandsSeparator: '.', decimals: 2, currencySign: price.currency)}
{f:translate(id: 'content.price.rule.{price.rule}', default: price.rule, extensionName: 'Thuecat')}
</f:for>
</f:for>
</f:if>
</f:for>
</html>

View file

@ -1,10 +1,10 @@
tx_thuecat_tourist_attraction
,"uid","pid","sys_language_uid","l18n_parent","l10n_source","l10n_state","remote_id","title","managed_by","town","address"
,1,10,0,0,0,\NULL,"https://thuecat.org/resources/835224016581-dara","Dom St. Marien",1,1,"{""street"":""Domstufen 1"",""zip"":""99084"",""city"":""Erfurt"",""email"":""dominformation@domberg-erfurt.de"",""phone"":""+49 361 6461265"",""fax"":"""",""geo"":{""latitude"":50.975955358589545,""longitude"":11.023667024961856}}"
,2,10,1,1,1,\NULL,"https://thuecat.org/resources/835224016581-dara","Cathedral of St. Mary",1,1,"{""street"":""Domstufen 1"",""zip"":""99084"",""city"":""Erfurt"",""email"":""dominformation@domberg-erfurt.de"",""phone"":""+49 361 6461265"",""fax"":"""",""geo"":{""latitude"":50.975955358589545,""longitude"":11.023667024961856}}"
,3,10,0,0,0,\NULL,"https://thuecat.org/resources/165868194223-zmqf","Alte Synagoge",1,1,"{""street"":""Waagegasse 8"",""zip"":""99084"",""city"":""Erfurt"",""email"":""altesynagoge@erfurt.de"",""phone"":""+49 361 6551520"",""fax"":""+49 361 6551669"",""geo"":{""latitude"":50.978765,""longitude"":11.029133}}"
,4,10,1,3,3,\NULL,"https://thuecat.org/resources/165868194223-zmqf","Old Synagogue",1,1,"{""street"":""Waagegasse 8"",""zip"":""99084"",""city"":""Erfurt"",""email"":""altesynagoge@erfurt.de"",""phone"":""+49 361 6551520"",""fax"":""+49 361 6551669"",""geo"":{""latitude"":50.978765,""longitude"":11.029133}}"
,5,10,2,3,3,\NULL,"https://thuecat.org/resources/165868194223-zmqf","La vieille synagogue",1,1,"{""street"":""Waagegasse 8"",""zip"":""99084"",""city"":""Erfurt"",""email"":""altesynagoge@erfurt.de"",""phone"":""+49 361 6551520"",""fax"":""+49 361 6551669"",""geo"":{""latitude"":50.978765,""longitude"":11.029133}}"
,6,10,0,0,0,\NULL,"https://thuecat.org/resources/215230952334-yyno","Krämerbrücke",1,1,"{""street"":""Benediktsplatz 1"",""zip"":""99084"",""city"":""Erfurt"",""email"":""service@erfurt-tourismus.de"",""phone"":""+49 361 66 400"",""fax"":"""",""geo"":{""latitude"":50.978772,""longitude"":11.031622}}"
,7,10,1,6,6,\NULL,"https://thuecat.org/resources/215230952334-yyno","Merchants' Bridge",1,1,"{""street"":""Benediktsplatz 1"",""zip"":""99084"",""city"":""Erfurt"",""email"":""service@erfurt-tourismus.de"",""phone"":""+49 361 66 400"",""fax"":"""",""geo"":{""latitude"":50.978772,""longitude"":11.031622}}"
,8,10,2,6,6,\NULL,"https://thuecat.org/resources/215230952334-yyno","Pont de l'épicier",1,1,"{""street"":""Benediktsplatz 1"",""zip"":""99084"",""city"":""Erfurt"",""email"":""service@erfurt-tourismus.de"",""phone"":""+49 361 66 400"",""fax"":"""",""geo"":{""latitude"":50.978772,""longitude"":11.031622}}"
,"uid","pid","sys_language_uid","l18n_parent","l10n_source","l10n_state","remote_id","title","managed_by","town","address","offers"
,1,10,0,0,0,\NULL,"https://thuecat.org/resources/835224016581-dara","Dom St. Marien",1,1,"{""street"":""Domstufen 1"",""zip"":""99084"",""city"":""Erfurt"",""email"":""dominformation@domberg-erfurt.de"",""phone"":""+49 361 6461265"",""fax"":"""",""geo"":{""latitude"":50.975955358589545,""longitude"":11.023667024961856}}","[]"
,2,10,1,1,1,\NULL,"https://thuecat.org/resources/835224016581-dara","Cathedral of St. Mary",1,1,"{""street"":""Domstufen 1"",""zip"":""99084"",""city"":""Erfurt"",""email"":""dominformation@domberg-erfurt.de"",""phone"":""+49 361 6461265"",""fax"":"""",""geo"":{""latitude"":50.975955358589545,""longitude"":11.023667024961856}}","[]"
,3,10,0,0,0,\NULL,"https://thuecat.org/resources/165868194223-zmqf","Alte Synagoge",1,1,"{""street"":""Waagegasse 8"",""zip"":""99084"",""city"":""Erfurt"",""email"":""altesynagoge@erfurt.de"",""phone"":""+49 361 6551520"",""fax"":""+49 361 6551669"",""geo"":{""latitude"":50.978765,""longitude"":11.029133}}","[{""title"":""F\u00fchrungen"",""description"":""Immer samstags, um 11:15 Uhr findet eine \u00f6ffentliche F\u00fchrung durch das Museum statt. Dauer etwa 90 Minuten"",""prices"":[{""title"":""Erwachsene"",""description"":"""",""price"":8,""currency"":""EUR"",""rule"":""PerPerson""},{""title"":""Erm\u00e4\u00dfigt"",""description"":""als erm\u00e4\u00dfigt gelten schulpflichtige Kinder, Auszubildende, Studierende, Rentner\/-innen, Menschen mit Behinderungen, Inhaber Sozialausweis der Landeshauptstadt Erfurt"",""price"":5,""currency"":""EUR"",""rule"":""PerPerson""}]},{""title"":""Eintritt"",""description"":""Schulklassen und Kitagruppen im Rahmen des Unterrichts: Eintritt frei\nAn jedem ersten Dienstag im Monat: Eintritt frei"",""prices"":[{""title"":""Erm\u00e4\u00dfigt"",""description"":""als erm\u00e4\u00dfigt gelten schulpflichtige Kinder, Auszubildende, Studierende, Rentner\/-innen, Menschen mit Behinderungen, Inhaber Sozialausweis der Landeshauptstadt Erfurt"",""price"":5,""currency"":""EUR"",""rule"":""PerPerson""},{""title"":""Familienkarte"",""description"":"""",""price"":17,""currency"":""EUR"",""rule"":""PerGroup""},{""title"":""ErfurtCard"",""description"":"""",""price"":14.9,""currency"":""EUR"",""rule"":""PerPackage""},{""title"":""Erwachsene"",""description"":"""",""price"":8,""currency"":""EUR"",""rule"":""PerPerson""}]}]"
,4,10,1,3,3,\NULL,"https://thuecat.org/resources/165868194223-zmqf","Old Synagogue",1,1,"{""street"":""Waagegasse 8"",""zip"":""99084"",""city"":""Erfurt"",""email"":""altesynagoge@erfurt.de"",""phone"":""+49 361 6551520"",""fax"":""+49 361 6551669"",""geo"":{""latitude"":50.978765,""longitude"":11.029133}}","[{""title"":""F\u00fchrungen"",""description"":""Immer samstags, um 11:15 Uhr findet eine \u00f6ffentliche F\u00fchrung durch das Museum statt. Dauer etwa 90 Minuten"",""prices"":[{""title"":""Erwachsene"",""description"":"""",""price"":8,""currency"":""EUR"",""rule"":""PerPerson""},{""title"":""Erm\u00e4\u00dfigt"",""description"":""als erm\u00e4\u00dfigt gelten schulpflichtige Kinder, Auszubildende, Studierende, Rentner\/-innen, Menschen mit Behinderungen, Inhaber Sozialausweis der Landeshauptstadt Erfurt"",""price"":5,""currency"":""EUR"",""rule"":""PerPerson""}]},{""title"":""Eintritt"",""description"":""Schulklassen und Kitagruppen im Rahmen des Unterrichts: Eintritt frei\nAn jedem ersten Dienstag im Monat: Eintritt frei"",""prices"":[{""title"":""Erm\u00e4\u00dfigt"",""description"":""als erm\u00e4\u00dfigt gelten schulpflichtige Kinder, Auszubildende, Studierende, Rentner\/-innen, Menschen mit Behinderungen, Inhaber Sozialausweis der Landeshauptstadt Erfurt"",""price"":5,""currency"":""EUR"",""rule"":""PerPerson""},{""title"":""Familienkarte"",""description"":"""",""price"":17,""currency"":""EUR"",""rule"":""PerGroup""},{""title"":""ErfurtCard"",""description"":"""",""price"":14.9,""currency"":""EUR"",""rule"":""PerPackage""},{""title"":""Erwachsene"",""description"":"""",""price"":8,""currency"":""EUR"",""rule"":""PerPerson""}]}]"
,5,10,2,3,3,\NULL,"https://thuecat.org/resources/165868194223-zmqf","La vieille synagogue",1,1,"{""street"":""Waagegasse 8"",""zip"":""99084"",""city"":""Erfurt"",""email"":""altesynagoge@erfurt.de"",""phone"":""+49 361 6551520"",""fax"":""+49 361 6551669"",""geo"":{""latitude"":50.978765,""longitude"":11.029133}}","[{""title"":""F\u00fchrungen"",""description"":""Immer samstags, um 11:15 Uhr findet eine \u00f6ffentliche F\u00fchrung durch das Museum statt. Dauer etwa 90 Minuten"",""prices"":[{""title"":""Erwachsene"",""description"":"""",""price"":8,""currency"":""EUR"",""rule"":""PerPerson""},{""title"":""Erm\u00e4\u00dfigt"",""description"":""als erm\u00e4\u00dfigt gelten schulpflichtige Kinder, Auszubildende, Studierende, Rentner\/-innen, Menschen mit Behinderungen, Inhaber Sozialausweis der Landeshauptstadt Erfurt"",""price"":5,""currency"":""EUR"",""rule"":""PerPerson""}]},{""title"":""Eintritt"",""description"":""Schulklassen und Kitagruppen im Rahmen des Unterrichts: Eintritt frei\nAn jedem ersten Dienstag im Monat: Eintritt frei"",""prices"":[{""title"":""Erm\u00e4\u00dfigt"",""description"":""als erm\u00e4\u00dfigt gelten schulpflichtige Kinder, Auszubildende, Studierende, Rentner\/-innen, Menschen mit Behinderungen, Inhaber Sozialausweis der Landeshauptstadt Erfurt"",""price"":5,""currency"":""EUR"",""rule"":""PerPerson""},{""title"":""Familienkarte"",""description"":"""",""price"":17,""currency"":""EUR"",""rule"":""PerGroup""},{""title"":""ErfurtCard"",""description"":"""",""price"":14.9,""currency"":""EUR"",""rule"":""PerPackage""},{""title"":""Erwachsene"",""description"":"""",""price"":8,""currency"":""EUR"",""rule"":""PerPerson""}]}]"
,6,10,0,0,0,\NULL,"https://thuecat.org/resources/215230952334-yyno","Krämerbrücke",1,1,"{""street"":""Benediktsplatz 1"",""zip"":""99084"",""city"":""Erfurt"",""email"":""service@erfurt-tourismus.de"",""phone"":""+49 361 66 400"",""fax"":"""",""geo"":{""latitude"":50.978772,""longitude"":11.031622}}","[]"
,7,10,1,6,6,\NULL,"https://thuecat.org/resources/215230952334-yyno","Merchants' Bridge",1,1,"{""street"":""Benediktsplatz 1"",""zip"":""99084"",""city"":""Erfurt"",""email"":""service@erfurt-tourismus.de"",""phone"":""+49 361 66 400"",""fax"":"""",""geo"":{""latitude"":50.978772,""longitude"":11.031622}}","[]"
,8,10,2,6,6,\NULL,"https://thuecat.org/resources/215230952334-yyno","Pont de l'épicier",1,1,"{""street"":""Benediktsplatz 1"",""zip"":""99084"",""city"":""Erfurt"",""email"":""service@erfurt-tourismus.de"",""phone"":""+49 361 66 400"",""fax"":"""",""geo"":{""latitude"":50.978772,""longitude"":11.031622}}","[]"

Can't render this file because it has a wrong number of fields in line 2.

View file

@ -55,7 +55,10 @@ use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase as TestCase;
* @uses WerkraumMedia\ThueCat\Domain\Import\Importer\LanguageHandling
* @uses WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser
* @uses WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\Address
* @uses WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\GenericFields
* @uses WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\LanguageValues
* @uses WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\Media
* @uses WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\Offers
* @uses WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\OpeningHours
* @uses WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\OpeningHours
* @uses WerkraumMedia\ThueCat\Domain\Import\Model\EntityCollection

View file

@ -28,6 +28,7 @@ use Prophecy\PhpUnit\ProphecyTrait;
use WerkraumMedia\ThueCat\Domain\Import\Converter\TouristAttraction;
use WerkraumMedia\ThueCat\Domain\Import\Importer\LanguageHandling;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\Offers;
use WerkraumMedia\ThueCat\Domain\Import\Model\EntityCollection;
use WerkraumMedia\ThueCat\Domain\Model\Backend\ImportConfiguration;
use WerkraumMedia\ThueCat\Domain\Model\Backend\Organisation;
@ -50,12 +51,14 @@ class TouristAttractionTest extends TestCase
public function canBeCreated(): void
{
$parser = $this->prophesize(Parser::class);
$parserForOffers = $this->prophesize(Offers::class);
$language = $this->prophesize(LanguageHandling::class);
$organisationRepository = $this->prophesize(OrganisationRepository::class);
$townRepository = $this->prophesize(TownRepository::class);
$subject = new TouristAttraction(
$parser->reveal(),
$parserForOffers->reveal(),
$language->reveal(),
$organisationRepository->reveal(),
$townRepository->reveal()
@ -70,12 +73,14 @@ class TouristAttractionTest extends TestCase
public function canConvert(): void
{
$parser = $this->prophesize(Parser::class);
$parserForOffers = $this->prophesize(Offers::class);
$language = $this->prophesize(LanguageHandling::class);
$organisationRepository = $this->prophesize(OrganisationRepository::class);
$townRepository = $this->prophesize(TownRepository::class);
$subject = new TouristAttraction(
$parser->reveal(),
$parserForOffers->reveal(),
$language->reveal(),
$organisationRepository->reveal(),
$townRepository->reveal()
@ -126,6 +131,9 @@ class TouristAttractionTest extends TestCase
$parser->getAddress($jsonLD)->willReturn([]);
$parser->getMedia($jsonLD)->willReturn([]);
$parserForOffers = $this->prophesize(Offers::class);
$parserForOffers->get($jsonLD, 'de')->willReturn([]);
$language = $this->prophesize(LanguageHandling::class);
$language->isUnknown('de', 10)->willReturn(false);
$language->getSystemUid('de', 10)->willReturn(0);
@ -138,6 +146,7 @@ class TouristAttractionTest extends TestCase
$subject = new TouristAttraction(
$parser->reveal(),
$parserForOffers->reveal(),
$language->reveal(),
$organisationRepository->reveal(),
$townRepository->reveal()
@ -160,6 +169,7 @@ class TouristAttractionTest extends TestCase
'opening_hours' => '[]',
'address' => '[]',
'media' => '[]',
'offers' => '[]',
], $entity->getData());
}
@ -205,6 +215,9 @@ class TouristAttractionTest extends TestCase
$parser->getAddress($jsonLD)->willReturn([]);
$parser->getMedia($jsonLD)->willReturn([]);
$parserForOffers = $this->prophesize(Offers::class);
$parserForOffers->get($jsonLD, 'de')->willReturn([]);
$language = $this->prophesize(LanguageHandling::class);
$language->isUnknown('de', 10)->willReturn(false);
$language->getSystemUid('de', 10)->willReturn(0);
@ -227,6 +240,7 @@ class TouristAttractionTest extends TestCase
$subject = new TouristAttraction(
$parser->reveal(),
$parserForOffers->reveal(),
$language->reveal(),
$organisationRepository->reveal(),
$townRepository->reveal()
@ -249,6 +263,7 @@ class TouristAttractionTest extends TestCase
'opening_hours' => '[]',
'address' => '[]',
'media' => '[]',
'offers' => '[]',
], $entity->getData());
}
}

View file

@ -0,0 +1,95 @@
<?php
namespace WerkraumMedia\ThueCat\Tests\Unit\Domain\Import\JsonLD\Parser;
/*
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
use PHPUnit\Framework\TestCase;
use Prophecy\PhpUnit\ProphecyTrait;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\GenericFields;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\LanguageValues;
/**
* @covers WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\GenericFields
*/
class GenericFieldsTest extends TestCase
{
use ProphecyTrait;
/**
* @test
*/
public function canBeCreated(): void
{
$languageValues = $this->prophesize(LanguageValues::class);
$subject = new GenericFields(
$languageValues->reveal()
);
self::assertInstanceOf(GenericFields::class, $subject);
}
/**
* @test
*/
public function returnsTitle(): void
{
$languageValues = $this->prophesize(LanguageValues::class);
$languageValues->getValueForLanguage([
'@value' => 'DE Title',
], 'de')->willReturn('DE Title');
$subject = new GenericFields(
$languageValues->reveal()
);
$result = $subject->getTitle([
'schema:name' => [
'@value' => 'DE Title',
],
], 'de');
self::assertSame('DE Title', $result);
}
/**
* @test
*/
public function returnsDescription(): void
{
$languageValues = $this->prophesize(LanguageValues::class);
$languageValues->getValueForLanguage([
'@value' => 'DE Description',
], 'de')->willReturn('DE Description');
$subject = new GenericFields(
$languageValues->reveal()
);
$result = $subject->getDescription([
'schema:description' => [
'@value' => 'DE Description',
],
], 'de');
self::assertSame('DE Description', $result);
}
}

View file

@ -0,0 +1,147 @@
<?php
namespace WerkraumMedia\ThueCat\Tests\Unit\Domain\Import\JsonLD\Parser;
/*
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
use PHPUnit\Framework\TestCase;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\LanguageValues;
/**
* @covers WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\LanguageValues
*/
class LanguageValuesTest extends TestCase
{
/**
* @test
*/
public function canBeCreated(): void
{
$subject = new LanguageValues(
);
self::assertInstanceOf(LanguageValues::class, $subject);
}
/**
* @test
* @dataProvider setups
*/
public function returnsValue(array $jsonLD, string $language, string $expected): void
{
$subject = new LanguageValues(
);
$result = $subject->getValueForLanguage($jsonLD, $language);
self::assertSame($expected, $result);
}
public function setups(): array
{
return [
'has multiple lanugages, one matches' => [
'jsonLD' => [
[
'@language' => 'de',
'@value' => 'DE value',
],
[
'@language' => 'fr',
'@value' => 'FR value',
],
],
'language' => 'de',
'expected' => 'DE value',
],
'has multiple lanugages, no language specified' => [
'jsonLD' => [
[
'@language' => 'de',
'@value' => 'DE value',
],
[
'@language' => 'fr',
'@value' => 'FR value',
],
],
'language' => '',
'expected' => 'DE value',
],
'has multiple languages, none matches' => [
'jsonLD' => [
[
'@language' => 'de',
'@value' => 'DE value',
],
[
'@language' => 'fr',
'@value' => 'FR value',
],
],
'language' => 'en',
'expected' => '',
],
'has multiple languages, missing @language key' => [
'jsonLD' => [
[
'@value' => 'DE value',
],
[
'@value' => 'FR value',
],
],
'language' => 'en',
'expected' => '',
],
'has single language, that one matches' => [
'jsonLD' => [
'@language' => 'de',
'@value' => 'DE value',
],
'language' => 'de',
'expected' => 'DE value',
],
'has single language, but another is requested' => [
'jsonLD' => [
'@language' => 'de',
'@value' => 'DE value',
],
'language' => 'en',
'expected' => '',
],
'has single language, no language specified' => [
'jsonLD' => [
'@language' => 'de',
'@value' => 'DE value',
],
'language' => '',
'expected' => 'DE value',
],
'has single language, missing @language key' => [
'jsonLD' => [
'@value' => 'DE value',
],
'language' => '',
'expected' => '',
],
];
}
}

View file

@ -0,0 +1,349 @@
<?php
namespace WerkraumMedia\ThueCat\Tests\Unit\Domain\Import\JsonLD\Parser;
/*
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
use PHPUnit\Framework\TestCase;
use Prophecy\PhpUnit\ProphecyTrait;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\GenericFields;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\Offers;
/**
* @covers WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\Offers
*/
class OffersTest extends TestCase
{
use ProphecyTrait;
/**
* @test
*/
public function canBeCreated(): void
{
$genericFields = $this->prophesize(GenericFields::class);
$subject = new Offers(
$genericFields->reveal()
);
self::assertInstanceOf(Offers::class, $subject);
}
/**
* @test
*/
public function returnsEmptyArrayIfNoOfferExists(): void
{
$genericFields = $this->prophesize(GenericFields::class);
$subject = new Offers(
$genericFields->reveal()
);
$result = $subject->get([], '');
self::assertSame([], $result);
}
/**
* @test
*/
public function returnsSingleOfferWithSinglePrice(): void
{
$jsonLD = [
'schema:makesOffer' => [
[
'@id' => 'genid-28b33237f71b41e3ad54a99e1da769b9-b5',
'@type' => [
0 => 'schema:Intangible',
1 => 'schema:Thing',
2 => 'schema:Offer',
],
'rdfs:label' => [
'@language' => 'de',
'@value' => 'Führungen',
],
'schema:description' => [
'@language' => 'de',
'@value' => 'Immer samstags, um 11:15 Uhr findet eine öffentliche Führung durch das Museum statt. Dauer etwa 90 Minuten',
],
'schema:name' => [
'@language' => 'de',
'@value' => 'Führungen',
],
'schema:offeredBy' => [
'@id' => 'https://thuecat.org/resources/165868194223-zmqf',
],
'schema:priceSpecification' => [
[
'@id' => 'genid-28b33237f71b41e3ad54a99e1da769b9-b6',
'@type' => [
0 => 'schema:Intangible',
1 => 'schema:StructuredValue',
2 => 'schema:PriceSpecification',
3 => 'schema:Thing',
],
'rdfs:label' => [
'@language' => 'de',
'@value' => 'Erwachsene',
],
'schema:name' => [
'@language' => 'de',
'@value' => 'Erwachsene',
],
'schema:price' => [
'@type' => 'schema:Number',
'@value' => '8',
],
'schema:priceCurrency' => [
'@type' => 'thuecat:Currency',
'@value' => 'thuecat:EUR',
],
'thuecat:calculationRule' => [
'@type' => 'thuecat:CalculationRule',
'@value' => 'thuecat:PerPerson',
],
],
[
'@id' => 'genid-28b33237f71b41e3ad54a99e1da769b9-b7',
'@type' => [
0 => 'schema:Intangible',
1 => 'schema:StructuredValue',
2 => 'schema:PriceSpecification',
3 => 'schema:Thing',
],
'rdfs:label' => [
'@language' => 'de',
'@value' => 'Ermäßigt',
],
'schema:description' => [
'@language' => 'de',
'@value' => 'als ermäßigt gelten schulpflichtige Kinder, Auszubildende, Studierende, Rentner/-innen, Menschen mit Behinderungen, Inhaber Sozialausweis der Landeshauptstadt Erfurt',
],
'schema:name' => [
'@language' => 'de',
'@value' => 'Ermäßigt',
],
'schema:price' => [
'@type' => 'schema:Number',
'@value' => '5',
],
'schema:priceCurrency' => [
'@type' => 'thuecat:Currency',
'@value' => 'thuecat:EUR',
],
'thuecat:calculationRule' => [
'@type' => 'thuecat:CalculationRule',
'@value' => 'thuecat:PerPerson',
],
],
],
'thuecat:offerType' => [
'@type' => 'thuecat:OfferType',
'@value' => 'thuecat:GuidedTourOffer',
],
],
[
'@id' => 'genid-28b33237f71b41e3ad54a99e1da769b9-b8',
'@type' => [
0 => 'schema:Intangible',
1 => 'schema:Thing',
2 => 'schema:Offer',
],
'rdfs:label' => [
'@language' => 'de',
'@value' => 'Eintritt',
],
'schema:description' => [
'@language' => 'de',
'@value' => "Schulklassen und Kitagruppen im Rahmen des Unterrichts: Eintritt frei\nAn jedem ersten Dienstag im Monat: Eintritt frei",
],
'schema:name' => [
'@language' => 'de',
'@value' => 'Eintritt',
],
'schema:offeredBy' => [
'@id' => 'https://thuecat.org/resources/165868194223-zmqf',
],
'schema:priceSpecification' => [
[
'@id' => 'genid-28b33237f71b41e3ad54a99e1da769b9-b10',
'@type' => [
0 => 'schema:Intangible',
1 => 'schema:StructuredValue',
2 => 'schema:PriceSpecification',
3 => 'schema:Thing',
],
'rdfs:label' => [
'@language' => 'de',
'@value' => 'Ermäßigt',
],
'schema:description' => [
'@language' => 'de',
'@value' => 'als ermäßigt gelten schulpflichtige Kinder, Auszubildende, Studierende, Rentner/-innen, Menschen mit Behinderungen, Inhaber Sozialausweis der Landeshauptstadt Erfurt',
],
'schema:name' => [
'@language' => 'de',
'@value' => 'Ermäßigt',
],
'schema:price' => [
'@type' => 'schema:Number',
'@value' => '5',
],
'schema:priceCurrency' => [
'@type' => 'thuecat:Currency',
'@value' => 'thuecat:EUR',
],
'thuecat:calculationRule' => [
'@type' => 'thuecat:CalculationRule',
'@value' => 'thuecat:PerPerson',
],
],
[
'@id' => 'genid-28b33237f71b41e3ad54a99e1da769b9-b11',
'@type' => [
0 => 'schema:Intangible',
1 => 'schema:StructuredValue',
2 => 'schema:PriceSpecification',
3 => 'schema:Thing',
],
'rdfs:label' => [
'@language' => 'de',
'@value' => 'Familienkarte',
],
'schema:name' => [
'@language' => 'de',
'@value' => 'Familienkarte',
],
'schema:price' => [
'@type' => 'schema:Number',
'@value' => '17',
],
'schema:priceCurrency' => [
'@type' => 'thuecat:Currency',
'@value' => 'thuecat:EUR',
],
'thuecat:calculationRule' => [
'@type' => 'thuecat:CalculationRule',
'@value' => 'thuecat:PerGroup',
],
],
],
'thuecat:offerType' => [
'@type' => 'thuecat:OfferType',
'@value' => 'thuecat:EntryOffer',
],
],
],
];
$genericFields = $this->prophesize(GenericFields::class);
// Offer 1
$genericFields->getTitle($jsonLD['schema:makesOffer'][0], 'de')->willReturn('Führungen');
$genericFields->getDescription($jsonLD['schema:makesOffer'][0], 'de')->willReturn('Immer samstags, um 11:15 Uhr findet eine öffentliche Führung durch das Museum statt. Dauer etwa 90 Minuten');
$genericFields->getTitle(
$jsonLD['schema:makesOffer'][0]['schema:priceSpecification'][0],
'de'
)->willReturn('Erwachsene');
$genericFields->getDescription(
$jsonLD['schema:makesOffer'][0]['schema:priceSpecification'][0],
'de'
)->willReturn('');
$genericFields->getTitle(
$jsonLD['schema:makesOffer'][0]['schema:priceSpecification'][1],
'de'
)->willReturn('Ermäßigt');
$genericFields->getDescription(
$jsonLD['schema:makesOffer'][0]['schema:priceSpecification'][1],
'de'
)->willReturn('als ermäßigt gelten schulpflichtige Kinder, Auszubildende, Studierende, Rentner/-innen, Menschen mit Behinderungen, Inhaber Sozialausweis der Landeshauptstadt Erfurt');
// Offer2
$genericFields->getTitle($jsonLD['schema:makesOffer'][1], 'de')->willReturn('Eintritt');
$genericFields->getDescription($jsonLD['schema:makesOffer'][1], 'de')->willReturn("Schulklassen und Kitagruppen im Rahmen des Unterrichts: Eintritt frei\nAn jedem ersten Dienstag im Monat: Eintritt frei");
$genericFields->getTitle(
$jsonLD['schema:makesOffer'][1]['schema:priceSpecification'][0],
'de'
)->willReturn('Ermäßigt');
$genericFields->getDescription(
$jsonLD['schema:makesOffer'][1]['schema:priceSpecification'][0],
'de'
)->willReturn('als ermäßigt gelten schulpflichtige Kinder, Auszubildende, Studierende, Rentner/-innen, Menschen mit Behinderungen, Inhaber Sozialausweis der Landeshauptstadt Erfurt');
$genericFields->getTitle(
$jsonLD['schema:makesOffer'][1]['schema:priceSpecification'][1],
'de'
)->willReturn('Familienkarte');
$genericFields->getDescription(
$jsonLD['schema:makesOffer'][1]['schema:priceSpecification'][1],
'de'
)->willReturn('');
$subject = new Offers(
$genericFields->reveal()
);
$result = $subject->get($jsonLD, 'de');
self::assertSame([
[
'title' => 'Führungen',
'description' => 'Immer samstags, um 11:15 Uhr findet eine öffentliche Führung durch das Museum statt. Dauer etwa 90 Minuten',
'prices' => [
[
'title' => 'Erwachsene',
'description' => '',
'price' => 8.0,
'currency' => 'EUR',
'rule' => 'PerPerson',
],
[
'title' => 'Ermäßigt',
'description' => 'als ermäßigt gelten schulpflichtige Kinder, Auszubildende, Studierende, Rentner/-innen, Menschen mit Behinderungen, Inhaber Sozialausweis der Landeshauptstadt Erfurt',
'price' => 5.0,
'currency' => 'EUR',
'rule' => 'PerPerson',
],
],
],
[
'title' => 'Eintritt',
'description' => "Schulklassen und Kitagruppen im Rahmen des Unterrichts: Eintritt frei\nAn jedem ersten Dienstag im Monat: Eintritt frei",
'prices' => [
[
'title' => 'Ermäßigt',
'description' => 'als ermäßigt gelten schulpflichtige Kinder, Auszubildende, Studierende, Rentner/-innen, Menschen mit Behinderungen, Inhaber Sozialausweis der Landeshauptstadt Erfurt',
'price' => 5.0,
'currency' => 'EUR',
'rule' => 'PerPerson',
],
[
'title' => 'Familienkarte',
'description' => '',
'price' => 17.0,
'currency' => 'EUR',
'rule' => 'PerGroup',
],
],
],
], $result);
}
}

View file

@ -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\GenericFields;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\Media;
use WerkraumMedia\ThueCat\Domain\Import\JsonLD\Parser\OpeningHours;
@ -42,10 +43,13 @@ class ParserTest extends TestCase
*/
public function canBeCreated(): void
{
$genericFields = $this->prophesize(GenericFields::class);
$openingHours = $this->prophesize(OpeningHours::class);
$address = $this->prophesize(Address::class);
$media = $this->prophesize(Media::class);
$subject = new Parser(
$genericFields->reveal(),
$openingHours->reveal(),
$address->reveal(),
$media->reveal()
@ -59,10 +63,13 @@ class ParserTest extends TestCase
*/
public function returnsId(): void
{
$genericFields = $this->prophesize(GenericFields::class);
$openingHours = $this->prophesize(OpeningHours::class);
$address = $this->prophesize(Address::class);
$media = $this->prophesize(Media::class);
$subject = new Parser(
$genericFields->reveal(),
$openingHours->reveal(),
$address->reveal(),
$media->reveal()
@ -78,12 +85,77 @@ class ParserTest extends TestCase
/**
* @test
*/
public function returnsManagerId(): void
public function returnsTitle(): void
{
$jsonLD = [
'schema:name' => [
'@language' => 'de',
'@value' => 'Erfurt',
],
];
$genericFields = $this->prophesize(GenericFields::class);
$genericFields->getTitle($jsonLD, 'de')->willReturn('Erfurt');
$openingHours = $this->prophesize(OpeningHours::class);
$address = $this->prophesize(Address::class);
$media = $this->prophesize(Media::class);
$subject = new Parser(
$genericFields->reveal(),
$openingHours->reveal(),
$address->reveal(),
$media->reveal()
);
$result = $subject->getTitle($jsonLD, 'de');
self::assertSame('Erfurt', $result);
}
/**
* @test
*/
public function returnsDescription(): void
{
$jsonLD = [
'schema:description' => [
'@language' => 'de',
'@value' => 'Erfurt',
],
];
$genericFields = $this->prophesize(GenericFields::class);
$genericFields->getDescription($jsonLD, 'de')->willReturn('Erfurt');
$openingHours = $this->prophesize(OpeningHours::class);
$address = $this->prophesize(Address::class);
$media = $this->prophesize(Media::class);
$subject = new Parser(
$genericFields->reveal(),
$openingHours->reveal(),
$address->reveal(),
$media->reveal()
);
$result = $subject->getDescription($jsonLD, 'de');
self::assertSame('Erfurt', $result);
}
/**
* @test
*/
public function returnsManagerId(): void
{
$genericFields = $this->prophesize(GenericFields::class);
$openingHours = $this->prophesize(OpeningHours::class);
$address = $this->prophesize(Address::class);
$media = $this->prophesize(Media::class);
$subject = new Parser(
$genericFields->reveal(),
$openingHours->reveal(),
$address->reveal(),
$media->reveal()
@ -98,269 +170,18 @@ class ParserTest extends TestCase
self::assertSame('https://example.com/resources/165868194223-manager', $result);
}
/**
* @test
* @dataProvider titles
*/
public function returnsTitle(array $jsonLD, string $language, string $expected): void
{
$openingHours = $this->prophesize(OpeningHours::class);
$address = $this->prophesize(Address::class);
$media = $this->prophesize(Media::class);
$subject = new Parser(
$openingHours->reveal(),
$address->reveal(),
$media->reveal()
);
$result = $subject->getTitle($jsonLD, $language);
self::assertSame($expected, $result);
}
public function titles(): array
{
return [
'json has multiple lanugages, one matches' => [
'jsonLD' => [
'schema:name' => [
[
'@language' => 'de',
'@value' => 'DE Title',
],
[
'@language' => 'fr',
'@value' => 'FR Title',
],
],
],
'language' => 'de',
'expected' => 'DE Title',
],
'json has multiple lanugages, no language specified' => [
'jsonLD' => [
'schema:name' => [
[
'@language' => 'de',
'@value' => 'DE Title',
],
[
'@language' => 'fr',
'@value' => 'FR Title',
],
],
],
'language' => '',
'expected' => 'DE Title',
],
'json has multiple languages, none matches' => [
'jsonLD' => [
'schema:name' => [
[
'@language' => 'de',
'@value' => 'DE Title',
],
[
'@language' => 'fr',
'@value' => 'FR Title',
],
],
],
'language' => 'en',
'expected' => '',
],
'json has multiple languages, missing @language key' => [
'jsonLD' => [
'schema:name' => [
[
'@value' => 'DE Title',
],
[
'@value' => 'FR Title',
],
],
],
'language' => 'en',
'expected' => '',
],
'json has single language, that one matches' => [
'jsonLD' => [
'schema:name' => [
'@language' => 'de',
'@value' => 'DE Title',
],
],
'language' => 'de',
'expected' => 'DE Title',
],
'json contains single language, but another is requested' => [
'jsonLD' => [
'schema:name' => [
'@language' => 'de',
'@value' => 'DE Title',
],
],
'language' => 'en',
'expected' => '',
],
'json contains single language, no language specified' => [
'jsonLD' => [
'schema:name' => [
'@language' => 'de',
'@value' => 'DE Title',
],
],
'language' => '',
'expected' => 'DE Title',
],
'json contains single language, missing @language key' => [
'jsonLD' => [
'schema:name' => [
'@value' => 'DE Title',
],
],
'language' => '',
'expected' => '',
],
];
}
/**
* @test
* @dataProvider descriptions
*/
public function returnsDescription(array $jsonLD, string $language, string $expected): void
{
$openingHours = $this->prophesize(OpeningHours::class);
$address = $this->prophesize(Address::class);
$media = $this->prophesize(Media::class);
$subject = new Parser(
$openingHours->reveal(),
$address->reveal(),
$media->reveal()
);
$result = $subject->getDescription($jsonLD, $language);
self::assertSame($expected, $result);
}
public function descriptions(): array
{
return [
'json has multiple lanugages, one matches' => [
'jsonLD' => [
'schema:description' => [
[
'@language' => 'de',
'@value' => 'DE Description',
],
[
'@language' => 'fr',
'@value' => 'FR Description',
],
],
],
'language' => 'de',
'expected' => 'DE Description',
],
'json has multiple lanugages, no language specified' => [
'jsonLD' => [
'schema:description' => [
[
'@language' => 'de',
'@value' => 'DE Description',
],
[
'@language' => 'fr',
'@value' => 'FR Description',
],
],
],
'language' => '',
'expected' => 'DE Description',
],
'json has multiple languages, none matches' => [
'jsonLD' => [
'schema:description' => [
[
'@language' => 'de',
'@value' => 'DE Description',
],
[
'@language' => 'fr',
'@value' => 'FR Description',
],
],
],
'language' => 'en',
'expected' => '',
],
'json has multiple languages, missing @language key' => [
'jsonLD' => [
'schema:description' => [
[
'@value' => 'DE Description',
],
[
'@value' => 'FR Description',
],
],
],
'language' => 'en',
'expected' => '',
],
'json has single language, that one matches' => [
'jsonLD' => [
'schema:description' => [
'@language' => 'de',
'@value' => 'DE Description',
],
],
'language' => 'de',
'expected' => 'DE Description',
],
'json contains single language, but another is requested' => [
'jsonLD' => [
'schema:description' => [
'@language' => 'de',
'@value' => 'DE Description',
],
],
'language' => 'en',
'expected' => '',
],
'json contains single language, no language specified' => [
'jsonLD' => [
'schema:description' => [
'@language' => 'de',
'@value' => 'DE Description',
],
],
'language' => '',
'expected' => 'DE Description',
],
'json contains single language, missing @language key' => [
'jsonLD' => [
'schema:description' => [
'@value' => 'DE Description',
],
],
'language' => '',
'expected' => '',
],
];
}
/**
* @test
*/
public function returnsContainedInPlaceIds(): void
{
$genericFields = $this->prophesize(GenericFields::class);
$openingHours = $this->prophesize(OpeningHours::class);
$address = $this->prophesize(Address::class);
$media = $this->prophesize(Media::class);
$subject = new Parser(
$genericFields->reveal(),
$openingHours->reveal(),
$address->reveal(),
$media->reveal()
@ -390,10 +211,13 @@ class ParserTest extends TestCase
*/
public function returnsLanguages(): void
{
$genericFields = $this->prophesize(GenericFields::class);
$openingHours = $this->prophesize(OpeningHours::class);
$address = $this->prophesize(Address::class);
$media = $this->prophesize(Media::class);
$subject = new Parser(
$genericFields->reveal(),
$openingHours->reveal(),
$address->reveal(),
$media->reveal()
@ -428,10 +252,13 @@ class ParserTest extends TestCase
*/
public function throwsExceptionOnUnkownLanguage(): void
{
$genericFields = $this->prophesize(GenericFields::class);
$openingHours = $this->prophesize(OpeningHours::class);
$address = $this->prophesize(Address::class);
$media = $this->prophesize(Media::class);
$subject = new Parser(
$genericFields->reveal(),
$openingHours->reveal(),
$address->reveal(),
$media->reveal()
@ -453,10 +280,13 @@ class ParserTest extends TestCase
*/
public function returnsNoLanguagesIfInfoIsMissing(): void
{
$genericFields = $this->prophesize(GenericFields::class);
$openingHours = $this->prophesize(OpeningHours::class);
$address = $this->prophesize(Address::class);
$media = $this->prophesize(Media::class);
$subject = new Parser(
$genericFields->reveal(),
$openingHours->reveal(),
$address->reveal(),
$media->reveal()
@ -489,11 +319,14 @@ class ParserTest extends TestCase
'daysOfWeek' => [],
];
$genericFields = $this->prophesize(GenericFields::class);
$openingHours = $this->prophesize(OpeningHours::class);
$openingHours->get($jsonLD)->willReturn($generatedOpeningHours);
$address = $this->prophesize(Address::class);
$media = $this->prophesize(Media::class);
$subject = new Parser(
$genericFields->reveal(),
$openingHours->reveal(),
$address->reveal(),
$media->reveal()
@ -527,12 +360,14 @@ class ParserTest extends TestCase
'fax' => '',
];
$genericFields = $this->prophesize(GenericFields::class);
$openingHours = $this->prophesize(OpeningHours::class);
$address = $this->prophesize(Address::class);
$address->get($jsonLD)->willReturn($generatedAddress);
$media = $this->prophesize(Media::class);
$subject = new Parser(
$genericFields->reveal(),
$openingHours->reveal(),
$address->reveal(),
$media->reveal()
@ -583,12 +418,14 @@ class ParserTest extends TestCase
],
];
$genericFields = $this->prophesize(GenericFields::class);
$openingHours = $this->prophesize(OpeningHours::class);
$address = $this->prophesize(Address::class);
$media = $this->prophesize(Media::class);
$media->get($jsonLD)->willReturn($generatedMedia);
$subject = new Parser(
$genericFields->reveal(),
$openingHours->reveal(),
$address->reveal(),
$media->reveal()

View file

@ -3,6 +3,7 @@
declare(strict_types=1);
use PhpCsFixer\Fixer\ArrayNotation\ArraySyntaxFixer;
use PhpCsFixer\Fixer\ArrayNotation\NoMultilineWhitespaceAroundDoubleArrowFixer;
use PhpCsFixer\Fixer\ArrayNotation\TrailingCommaInMultilineArrayFixer;
use PhpCsFixer\Fixer\Import\FullyQualifiedStrictTypesFixer;
use PhpCsFixer\Fixer\Import\NoUnusedImportsFixer;
@ -39,6 +40,7 @@ return static function (ContainerConfigurator $containerConfigurator): void {
$services->set(NoUnusedImportsFixer::class);
$services->set(FullyQualifiedStrictTypesFixer::class);
$services->set(NoMultilineWhitespaceAroundDoubleArrowFixer::class);
$services->set(ArraySyntaxFixer::class)->call('configure', [[
'syntax' => 'short',
]]);

View file

@ -55,4 +55,5 @@ CREATE TABLE tx_thuecat_tourist_attraction (
opening_hours text DEFAULT '' NOT NULL,
address text DEFAULT '' NOT NULL,
media text DEFAULT '' NOT NULL,
offers text DEFAULT '' NOT NULL,
);