WIP
This commit is contained in:
@@ -7,6 +7,7 @@
|
|||||||
"php": ">=8.1",
|
"php": ">=8.1",
|
||||||
"ext-ctype": "*",
|
"ext-ctype": "*",
|
||||||
"ext-iconv": "*",
|
"ext-iconv": "*",
|
||||||
|
"ext-simplexml": "*",
|
||||||
"doctrine/doctrine-bundle": "^2.10",
|
"doctrine/doctrine-bundle": "^2.10",
|
||||||
"doctrine/doctrine-migrations-bundle": "^3.2",
|
"doctrine/doctrine-migrations-bundle": "^3.2",
|
||||||
"doctrine/orm": "^2.15",
|
"doctrine/orm": "^2.15",
|
||||||
|
|||||||
@@ -32,7 +32,4 @@
|
|||||||
<listeners>
|
<listeners>
|
||||||
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener" />
|
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener" />
|
||||||
</listeners>
|
</listeners>
|
||||||
|
|
||||||
<extensions>
|
|
||||||
</extensions>
|
|
||||||
</phpunit>
|
</phpunit>
|
||||||
|
|||||||
@@ -2,16 +2,9 @@
|
|||||||
|
|
||||||
namespace App\BusProNet;
|
namespace App\BusProNet;
|
||||||
|
|
||||||
use App\BusProNet\Model\CrmAttributeSelection;
|
use App\BusProNet\Model\BaseResponse;
|
||||||
use App\BusProNet\Model\Profile;
|
|
||||||
use App\BusProNet\Model\ErrorResponse;
|
|
||||||
use App\BusProNet\Model\Result;
|
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
use Symfony\Component\Serializer\SerializerInterface;
|
use Symfony\Component\Serializer\SerializerInterface;
|
||||||
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
|
|
||||||
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
|
|
||||||
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
|
|
||||||
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
|
|
||||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||||
|
|
||||||
class ApiClient
|
class ApiClient
|
||||||
@@ -29,7 +22,7 @@ class ApiClient
|
|||||||
/**
|
/**
|
||||||
* @throws ApiClientException
|
* @throws ApiClientException
|
||||||
*/
|
*/
|
||||||
public function getProfile(string $email, string $password): mixed
|
public function getProfile(string $email, string $password): BaseResponse
|
||||||
{
|
{
|
||||||
$data = [
|
$data = [
|
||||||
'anfrage' => [
|
'anfrage' => [
|
||||||
@@ -56,11 +49,7 @@ class ApiClient
|
|||||||
|
|
||||||
$xml = $response->getContent();
|
$xml = $response->getContent();
|
||||||
|
|
||||||
if (str_contains($xml, 'HINWEIS')) {
|
return (new ResponseParser())->parseXmlString($xml);
|
||||||
return $this->serializer->deserialize($xml, ErrorResponse::class, 'xml');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->serializer->deserialize($xml, Profile::class, 'xml');
|
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +62,7 @@ class ApiClient
|
|||||||
/**
|
/**
|
||||||
* @throws ApiClientException
|
* @throws ApiClientException
|
||||||
*/
|
*/
|
||||||
public function getCrmSelection(string $email, string $password): mixed
|
public function getCrmAttributes(string $email, string $password): BaseResponse
|
||||||
{
|
{
|
||||||
$data = [
|
$data = [
|
||||||
'anfrage' => [
|
'anfrage' => [
|
||||||
@@ -100,20 +89,13 @@ class ApiClient
|
|||||||
|
|
||||||
$xml = $response->getContent();
|
$xml = $response->getContent();
|
||||||
|
|
||||||
if (str_contains($xml, 'HINWEIS')) {
|
return (new ResponseParser())->parseXmlString($xml);
|
||||||
return $this->serializer->deserialize($xml, ErrorResponse::class, 'xml');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->serializer->deserialize($xml, CrmAttributeSelection::class, 'xml');
|
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new ApiClientException($e->getMessage());
|
throw new ApiClientException($e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @Creates key for BusPro API access according to documentation
|
|
||||||
*/
|
|
||||||
private function createKey(string $username, string $password, string $type): string
|
private function createKey(string $username, string $password, string $type): string
|
||||||
{
|
{
|
||||||
$date = (new \DateTimeImmutable())->format('Ymd');
|
$date = (new \DateTimeImmutable())->format('Ymd');
|
||||||
|
|||||||
@@ -2,20 +2,11 @@
|
|||||||
|
|
||||||
namespace App\BusProNet\Model;
|
namespace App\BusProNet\Model;
|
||||||
|
|
||||||
use Symfony\Component\Serializer\Annotation\SerializedName;
|
|
||||||
|
|
||||||
class Address
|
class Address
|
||||||
{
|
{
|
||||||
#[SerializedName('strasse')]
|
|
||||||
private ?string $street = null;
|
private ?string $street = null;
|
||||||
|
|
||||||
#[SerializedName('plz')]
|
|
||||||
private ?string $postCode = null;
|
private ?string $postCode = null;
|
||||||
|
|
||||||
#[SerializedName('ort')]
|
|
||||||
private ?string $city = null;
|
private ?string $city = null;
|
||||||
|
|
||||||
#[SerializedName('land')]
|
|
||||||
private ?string $country = null;
|
private ?string $country = null;
|
||||||
|
|
||||||
public function getStreet(): ?string
|
public function getStreet(): ?string
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\BusProNet\Model;
|
||||||
|
|
||||||
|
class BaseResponse
|
||||||
|
{
|
||||||
|
private ?int $code;
|
||||||
|
private ?string $message;
|
||||||
|
|
||||||
|
public function __construct(int $code = null, string $message = null)
|
||||||
|
{
|
||||||
|
$this->code = $code;
|
||||||
|
$this->message = $message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCode(): ?int
|
||||||
|
{
|
||||||
|
return $this->code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMessage(): ?string
|
||||||
|
{
|
||||||
|
return $this->message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isSuccessful(): bool
|
||||||
|
{
|
||||||
|
// Successful responses don't carry codes and messages
|
||||||
|
if (null === $this->getCode() && null === $this->getMessage()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// These weird and contradictory looking assertions are required because
|
||||||
|
// of the stupid API implementation that doesn't distinguish between error
|
||||||
|
// and success responses.
|
||||||
|
$responseIsError = 100 <= $this->getCode() || $this->getMessage() === 'Daten konnten nicht gesendet werden.';
|
||||||
|
$responseIsSuccess = 650 === $this->getCode() && false === stripos($this->getMessage(), 'fehler');
|
||||||
|
|
||||||
|
return false === $responseIsError && true === $responseIsSuccess;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,13 +6,8 @@ use Symfony\Component\Serializer\Annotation\SerializedName;
|
|||||||
|
|
||||||
class Communication
|
class Communication
|
||||||
{
|
{
|
||||||
#[SerializedName('telefonprivat')]
|
|
||||||
private ?string $phone = null;
|
private ?string $phone = null;
|
||||||
|
|
||||||
#[SerializedName('telefonmobil')]
|
|
||||||
private ?string $mobile = null;
|
private ?string $mobile = null;
|
||||||
|
|
||||||
#[SerializedName('email')]
|
|
||||||
private ?string $email = null;
|
private ?string $email = null;
|
||||||
|
|
||||||
public function getPhone(): ?string
|
public function getPhone(): ?string
|
||||||
|
|||||||
@@ -2,19 +2,11 @@
|
|||||||
|
|
||||||
namespace App\BusProNet\Model;
|
namespace App\BusProNet\Model;
|
||||||
|
|
||||||
use Symfony\Component\Serializer\Annotation\Ignore;
|
|
||||||
use Symfony\Component\Serializer\Annotation\SerializedName;
|
|
||||||
|
|
||||||
class CrmAttribute
|
class CrmAttribute
|
||||||
{
|
{
|
||||||
#[SerializedName('@id')]
|
|
||||||
private ?int $id = null;
|
private ?int $id = null;
|
||||||
|
|
||||||
#[SerializedName('@bezeichnung')]
|
|
||||||
private ?string $label = null;
|
private ?string $label = null;
|
||||||
|
private bool $selected = false;
|
||||||
#[SerializedName('@auswahl')]
|
|
||||||
private ?string $selectedAsString = null;
|
|
||||||
|
|
||||||
public function getId(): ?int
|
public function getId(): ?int
|
||||||
{
|
{
|
||||||
@@ -40,26 +32,14 @@ class CrmAttribute
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSelectedAsString(): ?string
|
|
||||||
{
|
|
||||||
return $this->selectedAsString;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setSelectedAsString(?string $selectedAsString): static
|
|
||||||
{
|
|
||||||
$this->selectedAsString = $selectedAsString;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function isSelected(): bool
|
public function isSelected(): bool
|
||||||
{
|
{
|
||||||
return 'true' === strtolower($this->selectedAsString);
|
return $this->selected;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setSelected(bool $selected): static
|
public function setSelected(bool $selected): static
|
||||||
{
|
{
|
||||||
$this->selectedAsString = $selected ? 'True' : 'False';
|
$this->selected = $selected;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-13
@@ -2,14 +2,9 @@
|
|||||||
|
|
||||||
namespace App\BusProNet\Model;
|
namespace App\BusProNet\Model;
|
||||||
|
|
||||||
use Symfony\Component\Serializer\Annotation\SerializedName;
|
class CrmAttributeGroup
|
||||||
|
|
||||||
class CrmAttributeSelectionGroup
|
|
||||||
{
|
{
|
||||||
#[SerializedName('@bezeichnung')]
|
|
||||||
private ?string $label = null;
|
private ?string $label = null;
|
||||||
|
|
||||||
#[SerializedName('selektion')]
|
|
||||||
private ?array $attributes = null;
|
private ?array $attributes = null;
|
||||||
|
|
||||||
public function getLabel(): ?string
|
public function getLabel(): ?string
|
||||||
@@ -24,18 +19,11 @@ class CrmAttributeSelectionGroup
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return CrmAttribute[]|null
|
|
||||||
*/
|
|
||||||
public function getAttributes(): ?array
|
public function getAttributes(): ?array
|
||||||
{
|
{
|
||||||
return $this->attributes;
|
return $this->attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param CrmAttribute[]|null $attributes
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function setAttributes(?array $attributes): static
|
public function setAttributes(?array $attributes): static
|
||||||
{
|
{
|
||||||
$this->attributes = $attributes;
|
$this->attributes = $attributes;
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\BusProNet\Model;
|
|
||||||
|
|
||||||
use Symfony\Component\Serializer\Annotation\SerializedPath;
|
|
||||||
|
|
||||||
class CrmAttributeSelection
|
|
||||||
{
|
|
||||||
#[SerializedPath('[selektionsmerkmale][selektionsgruppe]')]
|
|
||||||
private ?array $selectionGroups = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return CrmAttributeSelectionGroup[]|null
|
|
||||||
*/
|
|
||||||
public function getSelectionGroups(): ?array
|
|
||||||
{
|
|
||||||
return $this->selectionGroups;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param CrmAttributeSelectionGroup[]|null $selectionGroups
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function setSelectionGroups(?array $selectionGroups): static
|
|
||||||
{
|
|
||||||
$this->selectionGroups = $selectionGroups;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\BusProNet\Model;
|
||||||
|
|
||||||
|
class CrmAttributesResponse extends BaseResponse
|
||||||
|
{
|
||||||
|
private ?array $attributeGroups = null;
|
||||||
|
private bool $teamer = false;
|
||||||
|
|
||||||
|
public function getAttributeGroups(): ?array
|
||||||
|
{
|
||||||
|
return $this->attributeGroups;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setAttributeGroups(?array $attributeGroups): static{
|
||||||
|
$this->attributeGroups = $attributeGroups;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isTeamer(): bool
|
||||||
|
{
|
||||||
|
return $this->teamer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setTeamer(bool $teamer): static
|
||||||
|
{
|
||||||
|
$this->teamer = $teamer;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\BusProNet\Model;
|
|
||||||
|
|
||||||
use Symfony\Component\Serializer\Annotation\SerializedPath;
|
|
||||||
|
|
||||||
class ErrorResponse
|
|
||||||
{
|
|
||||||
#[SerializedPath('[satz][nr]')]
|
|
||||||
private ?string $code;
|
|
||||||
|
|
||||||
#[SerializedPath('[satz][text]')]
|
|
||||||
private ?string $type;
|
|
||||||
|
|
||||||
public function getCode(): ?string
|
|
||||||
{
|
|
||||||
return $this->code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setCode(?string $code): static
|
|
||||||
{
|
|
||||||
$this->code = $code;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getType(): ?string
|
|
||||||
{
|
|
||||||
return $this->type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setType(?string $type): static
|
|
||||||
{
|
|
||||||
$this->type = $type;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,41 +2,17 @@
|
|||||||
|
|
||||||
namespace App\BusProNet\Model;
|
namespace App\BusProNet\Model;
|
||||||
|
|
||||||
use Symfony\Component\Serializer\Annotation\Context;
|
class ProfileResponse extends BaseResponse
|
||||||
use Symfony\Component\Serializer\Annotation\SerializedPath;
|
|
||||||
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
|
|
||||||
|
|
||||||
class Profile
|
|
||||||
{
|
{
|
||||||
#[SerializedPath('[idadresse]')]
|
|
||||||
private ?int $addressId = null;
|
private ?int $addressId = null;
|
||||||
|
|
||||||
#[SerializedPath('[idperson]')]
|
|
||||||
private ?int $personId = null;
|
private ?int $personId = null;
|
||||||
|
|
||||||
#[SerializedPath('[adressdaten][name]')]
|
|
||||||
private ?string $name = null;
|
private ?string $name = null;
|
||||||
|
|
||||||
#[SerializedPath('[adressdaten][vorname]')]
|
|
||||||
private ?string $firstName = null;
|
private ?string $firstName = null;
|
||||||
|
|
||||||
#[SerializedPath('[adressdaten][anrede]')]
|
|
||||||
private ?string $salutation = null;
|
private ?string $salutation = null;
|
||||||
|
|
||||||
#[SerializedPath('[adressdaten][titel]')]
|
|
||||||
private ?string $title = null;
|
private ?string $title = null;
|
||||||
|
|
||||||
#[SerializedPath('[adressdaten][geschlecht]')]
|
|
||||||
private ?string $gender = null;
|
private ?string $gender = null;
|
||||||
|
|
||||||
#[SerializedPath('[adressdaten][geburtsdatum]')]
|
|
||||||
#[Context([DateTimeNormalizer::FORMAT_KEY => 'd.m.Y'])]
|
|
||||||
private ?\DateTimeImmutable $dateOfBirth = null;
|
private ?\DateTimeImmutable $dateOfBirth = null;
|
||||||
|
|
||||||
#[SerializedPath('[adressdaten][anschrift]')]
|
|
||||||
private ?Address $address = null;
|
private ?Address $address = null;
|
||||||
|
|
||||||
#[SerializedPath('[adressdaten][kommunikation]')]
|
|
||||||
private ?Communication $communication = null;
|
private ?Communication $communication = null;
|
||||||
|
|
||||||
public function getAddressId(): ?int
|
public function getAddressId(): ?int
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\BusProNet;
|
||||||
|
|
||||||
|
use App\BusProNet\Model\Address;
|
||||||
|
use App\BusProNet\Model\Communication;
|
||||||
|
use App\BusProNet\Model\CrmAttribute;
|
||||||
|
use App\BusProNet\Model\CrmAttributesResponse;
|
||||||
|
use App\BusProNet\Model\CrmAttributeGroup;
|
||||||
|
use App\BusProNet\Model\ProfileResponse;
|
||||||
|
use App\BusProNet\Model\BaseResponse;
|
||||||
|
|
||||||
|
class ResponseParser
|
||||||
|
{
|
||||||
|
public const ATTR_ID_TEAMER = 1070;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws ResponseParserException
|
||||||
|
*/
|
||||||
|
public function parseXmlString(string $content): BaseResponse
|
||||||
|
{
|
||||||
|
$xml = simplexml_load_string($content);
|
||||||
|
$type = (string) $xml->xpath('satz/@typ')[0];
|
||||||
|
|
||||||
|
switch ($type) {
|
||||||
|
case 'HINWEIS':
|
||||||
|
return $this->createBaseResponse($xml);
|
||||||
|
case 'KUNDENKONTO':
|
||||||
|
$subType = (string) $xml->xpath('art')[0];
|
||||||
|
switch ($subType) {
|
||||||
|
case 'Adressdaten':
|
||||||
|
return $this->createProfileResponse($xml);
|
||||||
|
case 'SelektionCRM':
|
||||||
|
return $this->createCrmAttributesResponse($xml);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ResponseParserException('Unable to parse XML response');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createBaseResponse(\SimpleXMLElement $xml): BaseResponse
|
||||||
|
{
|
||||||
|
$code = (int) $xml->xpath('satz/nr')[0];
|
||||||
|
$message = (string) $xml->xpath('satz/text')[0];
|
||||||
|
|
||||||
|
return new BaseResponse($code, $message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createProfileResponse(\SimpleXMLElement $xml): ProfileResponse
|
||||||
|
{
|
||||||
|
$addressId = (int) $xml->xpath('idadresse')[0];
|
||||||
|
$personId = (int) $xml->xpath('idperson')[0];
|
||||||
|
|
||||||
|
$lastName = (string) $xml->xpath('adressdaten/name')[0];
|
||||||
|
$firstName = (string) $xml->xpath('adressdaten/vorname')[0];
|
||||||
|
$salutation = (string) $xml->xpath('adressdaten/anrede')[0];
|
||||||
|
$title = (string) $xml->xpath('adressdaten/titel')[0];
|
||||||
|
|
||||||
|
$gender = (string) $xml->xpath('adressdaten/geschlecht')[0];
|
||||||
|
$gender = $gender === 'W' ? 'f' : strtolower($gender);
|
||||||
|
|
||||||
|
$date = $xml->xpath('adressdaten/geburtsdatum');
|
||||||
|
$dateOfBirth = $date ?\DateTimeImmutable::createFromFormat('d.m.Y', (string) $date[0]) : null;
|
||||||
|
|
||||||
|
$response = new ProfileResponse();
|
||||||
|
$response
|
||||||
|
->setAddressId($addressId)
|
||||||
|
->setPersonId($personId)
|
||||||
|
->setFirstName($firstName)
|
||||||
|
->setName($lastName)
|
||||||
|
->setTitle($title)
|
||||||
|
->setSalutation($salutation)
|
||||||
|
->setGender($gender)
|
||||||
|
->setDateOfBirth($dateOfBirth)
|
||||||
|
;
|
||||||
|
|
||||||
|
$postalAddressStreet = $xml->xpath('adressdaten/anschrift/strasse');
|
||||||
|
$postalAddressPostcode = $xml->xpath('adressdaten/anschrift/plz');
|
||||||
|
$postalAddressCity = $xml->xpath('adressdaten/anschrift/ort');
|
||||||
|
$postalAddressCountry = $xml->xpath('adressdaten/anschrift/land');
|
||||||
|
|
||||||
|
$address = new Address();
|
||||||
|
$address
|
||||||
|
->setStreet($postalAddressStreet ? (string) $postalAddressStreet[0] : null)
|
||||||
|
->setPostCode($postalAddressPostcode ? (string) $postalAddressPostcode[0] : null)
|
||||||
|
->setCity($postalAddressCity ? (string) $postalAddressCity[0] : null)
|
||||||
|
->setCountry($postalAddressCountry ? (string) $postalAddressCountry[0] : null)
|
||||||
|
;
|
||||||
|
|
||||||
|
$response->setAddress($address);
|
||||||
|
|
||||||
|
$phone = $xml->xpath('adressdaten/kommunikation/telefonprivat');
|
||||||
|
$mobile = $xml->xpath('adressdaten/kommunikation/telefonmobil');
|
||||||
|
$email = $xml->xpath('adressdaten/kommunikation/email');
|
||||||
|
|
||||||
|
$communication = new Communication();
|
||||||
|
$communication
|
||||||
|
->setPhone($phone ? (string) $phone[0] : null)
|
||||||
|
->setMobile($mobile ? (string) $mobile[0] : null)
|
||||||
|
->setEmail($email ? (string) $email[0] : null)
|
||||||
|
;
|
||||||
|
|
||||||
|
$response->setCommunication($communication);
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createCrmAttributesResponse(\SimpleXMLElement $xml): CrmAttributesResponse
|
||||||
|
{
|
||||||
|
$groups = [];
|
||||||
|
$isTeam = false;
|
||||||
|
|
||||||
|
foreach ($xml->xpath('selektionsmerkmale/selektionsgruppe') as $item) {
|
||||||
|
$group = new CrmAttributeGroup();
|
||||||
|
$group->setLabel($item->attributes()['bezeichnung']);
|
||||||
|
$attributes = [];
|
||||||
|
|
||||||
|
foreach ($item->xpath('selektion') as $subItem) {
|
||||||
|
$attribute = new CrmAttribute();
|
||||||
|
$attribute
|
||||||
|
->setId((int) $subItem->attributes()['id'])
|
||||||
|
->setLabel((string) $subItem->attributes()['bezeichnung'])
|
||||||
|
->setSelected('True' === (string) $subItem->attributes()['auswahl'])
|
||||||
|
;
|
||||||
|
$attributes[] = $attribute;
|
||||||
|
|
||||||
|
if (static::ATTR_ID_TEAMER === $attribute->getId() && true === $attribute->isSelected()) {
|
||||||
|
$isTeam = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$group->setAttributes($attributes);
|
||||||
|
$groups[] = $group;
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = new CrmAttributesResponse();
|
||||||
|
$response
|
||||||
|
->setAttributeGroups($groups)
|
||||||
|
->setTeamer($isTeam)
|
||||||
|
;
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\BusProNet;
|
||||||
|
|
||||||
|
class ResponseParserException extends \Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
+1
-1
@@ -132,7 +132,7 @@ class User implements UserInterface
|
|||||||
|
|
||||||
public function getRoles(): array
|
public function getRoles(): array
|
||||||
{
|
{
|
||||||
return ['ROLE_USER'];
|
return ['ROLE_USER', $this->getRole()];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function eraseCredentials(): void
|
public function eraseCredentials(): void
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ namespace App\Security;
|
|||||||
|
|
||||||
use App\BusProNet\ApiClient;
|
use App\BusProNet\ApiClient;
|
||||||
use App\BusProNet\ApiClientException;
|
use App\BusProNet\ApiClientException;
|
||||||
use App\BusProNet\Model\ErrorResponse;
|
use App\BusProNet\Model\CrmAttributesResponse;
|
||||||
use App\BusProNet\Model\Profile;
|
use App\BusProNet\Model\ProfileResponse;
|
||||||
use App\Entity\User;
|
use App\Entity\User;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
@@ -53,7 +53,7 @@ class BpnAuthenticator extends AbstractLoginFormAuthenticator implements Authent
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($response instanceof ErrorResponse) {
|
if (false === $response instanceof ProfileResponse) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ class BpnAuthenticator extends AbstractLoginFormAuthenticator implements Authent
|
|||||||
return new RedirectResponse($url);
|
return new RedirectResponse($url);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getOrCreateLocalUser(Profile $profile, string $email, string $password): User
|
private function getOrCreateLocalUser(ProfileResponse $profile, string $email, string $password): ?User
|
||||||
{
|
{
|
||||||
$repository = $this->entityManager->getRepository(User::class);
|
$repository = $this->entityManager->getRepository(User::class);
|
||||||
|
|
||||||
@@ -95,20 +95,25 @@ class BpnAuthenticator extends AbstractLoginFormAuthenticator implements Authent
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$response = $this->apiClient->getCrmSelection($email, $password);
|
/** @var CrmAttributesResponse $crmAttributes */
|
||||||
|
$crmAttributes = $this->apiClient->getCrmAttributes($email, $password);
|
||||||
} catch (ApiClientException $e) {
|
} catch (ApiClientException $e) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = new User();
|
$user = new User();
|
||||||
$user
|
$user
|
||||||
->setBusProAddressId($profile->getAddressId())
|
->setBusProAddressId($profile->getAddressId())
|
||||||
->setBusProPersonId($profile->getPersonId())
|
->setBusProPersonId($profile->getPersonId())
|
||||||
->setRole('ROLE_FOO')
|
|
||||||
->setEmail($profile->getCommunication()->getEmail())
|
->setEmail($profile->getCommunication()->getEmail())
|
||||||
->setFirstName($profile->getFirstName())
|
->setFirstName($profile->getFirstName())
|
||||||
->setLastName($profile->getName())
|
->setLastName($profile->getName())
|
||||||
;
|
;
|
||||||
|
|
||||||
|
if ($crmAttributes->isTeamer()) {
|
||||||
|
$user->setRole('ROLE_TEAMER');
|
||||||
|
}
|
||||||
|
|
||||||
$this->entityManager->persist($user);
|
$this->entityManager->persist($user);
|
||||||
$this->entityManager->flush();
|
$this->entityManager->flush();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Tests\BusProNet;
|
||||||
|
|
||||||
|
use App\BusProNet\Model\CrmAttributesResponse;
|
||||||
|
use App\BusProNet\Model\ProfileResponse;
|
||||||
|
use App\BusProNet\ResponseParser;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class ResponseParserTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testParseUnsuccessfulResponse(): void
|
||||||
|
{
|
||||||
|
$content = '<?xml version="1.0" encoding="utf-8"?><ergebnis><satz typ="HINWEIS"><nr>853</nr><text>ID, EMail oder Passwort falsch</text></satz></ergebnis>';
|
||||||
|
|
||||||
|
$parser = new ResponseParser();
|
||||||
|
$response = $parser->parseXmlString($content);
|
||||||
|
|
||||||
|
$this->assertEquals(853, $response->getCode());
|
||||||
|
$this->assertEquals('ID, EMail oder Passwort falsch', $response->getMessage());
|
||||||
|
$this->assertFalse($response->isSuccessful());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testParseSuccessfulProfileResponse(): void
|
||||||
|
{
|
||||||
|
$content = '<?xml version="1.0" encoding="utf-8"?><ergebnis><satz typ="KUNDENKONTO"></satz><art>Adressdaten</art><idadresse>141747</idadresse><idperson>224526</idperson><adressdaten><name>Fromme</name><vorname>Björn</vorname><anrede>Herr</anrede><titel></titel><geschlecht>M</geschlecht><geburtsdatum>16.04.1972</geburtsdatum><nationalitaet>D</nationalitaet><anschrift><id>119447</id><strasse>Emilienstraße 57</strasse><plz>42853</plz><ort>Remscheid</ort><ortsteil></ortsteil><land>D</land></anschrift><kommunikation><telefonmobil></telefonmobil><email>[email protected]</email><newsletter>False</newsletter><telefonprivat>02191-4615837</telefonprivat></kommunikation></adressdaten></ergebnis>';
|
||||||
|
|
||||||
|
$parser = new ResponseParser();
|
||||||
|
$response = $parser->parseXmlString($content);
|
||||||
|
|
||||||
|
$this->assertInstanceOf(ProfileResponse::class, $response);
|
||||||
|
$this->assertNull($response->getCode());
|
||||||
|
$this->assertNull($response->getMessage());
|
||||||
|
$this->assertTrue($response->isSuccessful());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testParseSuccessfulCrmAttributesResponse(): void
|
||||||
|
{
|
||||||
|
$content = '<?xml version="1.0" encoding="utf-8"?><ergebnis><satz typ="KUNDENKONTO"></satz><art>SelektionCRM</art><idadresse>141747</idadresse><idperson>224526</idperson><selektionsmerkmale><selektionsgruppe id="6" bezeichnung="Gruppen - Art (NUR direkt dem GR-Kunden zuordnen)"><selektion id="1156" bezeichnung="Gruppen-Buchungsportal" aenderbar="False" auswahl="True"></selektion></selektionsgruppe><selektionsgruppe id="10" bezeichnung="TEAM"><selektion id="1070" bezeichnung="E&P Teamer - allg. Merkmal" aenderbar="False" auswahl="True"></selektion></selektionsgruppe><selektionsgruppe id="83" bezeichnung="Interessen"><selektion id="1064" bezeichnung="Sportclub-Reisen" aenderbar="True" auswahl="False"></selektion><selektion id="1065" bezeichnung="Individual-Ferienwohnungen/Gasthöfe" aenderbar="True" auswahl="False"></selektion><selektion id="1066" bezeichnung="Kurztrips" aenderbar="True" auswahl="False"></selektion><selektion id="1067" bezeichnung="Eventreisen" aenderbar="True" auswahl="False"></selektion><selektion id="1068" bezeichnung="Gruppen-Angebote" aenderbar="True" auswahl="False"></selektion><selektion id="1069" bezeichnung="Firmen-Angebote" aenderbar="True" auswahl="False"></selektion></selektionsgruppe></selektionsmerkmale><crmaktionen><crmaktion id="428" code="18DDW40" bezeichnung="Deal Der Woche KW40-2018" aenderbar="False" auswahl="False"></crmaktion><crmaktion id="276" code="NOMAIL" bezeichnung="Ich möchte keine Werbung per Mail erhalten" aenderbar="True" auswahl="True"></crmaktion></crmaktionen></ergebnis>';
|
||||||
|
|
||||||
|
$parser = new ResponseParser();
|
||||||
|
$response = $parser->parseXmlString($content);
|
||||||
|
|
||||||
|
$this->assertInstanceOf(CrmAttributesResponse::class, $response);
|
||||||
|
$this->assertNull($response->getCode());
|
||||||
|
$this->assertNull($response->getMessage());
|
||||||
|
$this->assertTrue($response->isSuccessful());
|
||||||
|
$this->assertCount(3, $response->getAttributeGroups());
|
||||||
|
$this->assertTrue($response->isTeamer());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user