fix: type mismatches and handle nullable values
This commit is contained in:
@@ -31,12 +31,15 @@ class ResponseParser
|
|||||||
public function parseXmlString(string $type, string $content): mixed
|
public function parseXmlString(string $type, string $content): mixed
|
||||||
{
|
{
|
||||||
$xml = simplexml_load_string($content);
|
$xml = simplexml_load_string($content);
|
||||||
|
if (false === $xml) {
|
||||||
|
throw new ResponseParserException('Unable to parse XML response');
|
||||||
|
}
|
||||||
|
|
||||||
// Override type when present in XML to catch error responses
|
// Override type when present in XML to catch error responses
|
||||||
$responseType = $type;
|
$responseType = $type;
|
||||||
$responseTypeXml = $xml->xpath('satz/@typ');
|
$responseTypeXml = $xml->xpath('satz/@typ') ?: [];
|
||||||
if (0 < count($responseTypeXml)) {
|
if (0 < count($responseTypeXml)) {
|
||||||
$responseType = (string) $xml->xpath('satz/@typ')[0];
|
$responseType = (string) $responseTypeXml[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ($responseType) {
|
switch ($responseType) {
|
||||||
@@ -91,7 +94,12 @@ class ResponseParser
|
|||||||
$gender = 'W' === strtoupper($gender) ? 'F' : strtoupper($gender);
|
$gender = 'W' === strtoupper($gender) ? 'F' : strtoupper($gender);
|
||||||
|
|
||||||
$dateString = (string) $addressXml->geburtsdatum;
|
$dateString = (string) $addressXml->geburtsdatum;
|
||||||
$dateOfBirth = empty($dateString) ? null : \DateTimeImmutable::createFromFormat('d.m.Y', $dateString);
|
$dateOfBirth = null;
|
||||||
|
|
||||||
|
if ('' !== $dateString) {
|
||||||
|
$parsedDate = \DateTimeImmutable::createFromFormat('d.m.Y', $dateString);
|
||||||
|
$dateOfBirth = false === $parsedDate ? null : $parsedDate;
|
||||||
|
}
|
||||||
|
|
||||||
$response = new ProfileResponse();
|
$response = new ProfileResponse();
|
||||||
$response
|
$response
|
||||||
@@ -146,7 +154,7 @@ class ResponseParser
|
|||||||
$personId = (int) $xml->idperson;
|
$personId = (int) $xml->idperson;
|
||||||
|
|
||||||
$updated = false;
|
$updated = false;
|
||||||
$updatedXml = $xml->xpath('änderung|aenderung');
|
$updatedXml = $xml->xpath('änderung|aenderung') ?: [];
|
||||||
if (0 < count($updatedXml)) {
|
if (0 < count($updatedXml)) {
|
||||||
$updated = 'true' === strtolower((string) $updatedXml[0]);
|
$updated = 'true' === strtolower((string) $updatedXml[0]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,18 +32,15 @@ class EditController extends AbstractController
|
|||||||
public function index(EmailTextKey $key, Request $request): Response
|
public function index(EmailTextKey $key, Request $request): Response
|
||||||
{
|
{
|
||||||
$definition = $this->catalog->get($key);
|
$definition = $this->catalog->get($key);
|
||||||
$emailText = $this->emailTextRepository->findByKey($key);
|
$existing = $this->emailTextRepository->findByKey($key);
|
||||||
$isNew = null === $emailText;
|
|
||||||
|
|
||||||
// Editing a mail for the first time starts from the delivered wording rather than
|
// Editing a mail for the first time starts from the delivered wording rather than
|
||||||
// from an empty form, so an admin adjusts a sentence instead of rewriting the mail.
|
// from an empty form, so an admin adjusts a sentence instead of rewriting the mail.
|
||||||
if (true === $isNew) {
|
$emailText = $existing ?? (new EmailText($key))
|
||||||
$emailText = (new EmailText($key))
|
|
||||||
->setSubject($definition->defaultSubject)
|
->setSubject($definition->defaultSubject)
|
||||||
->setHeadline($definition->defaultHeadline)
|
->setHeadline($definition->defaultHeadline)
|
||||||
->setBody($definition->defaultBody)
|
->setBody($definition->defaultBody)
|
||||||
;
|
;
|
||||||
}
|
|
||||||
|
|
||||||
$form = $this->createForm(EmailTextType::class, $emailText, [
|
$form = $this->createForm(EmailTextType::class, $emailText, [
|
||||||
'definition' => $definition,
|
'definition' => $definition,
|
||||||
@@ -51,10 +48,7 @@ class EditController extends AbstractController
|
|||||||
$form->handleRequest($request);
|
$form->handleRequest($request);
|
||||||
|
|
||||||
if ($form->isSubmitted() && $form->isValid()) {
|
if ($form->isSubmitted() && $form->isValid()) {
|
||||||
if (true === $isNew) {
|
|
||||||
$this->entityManager->persist($emailText);
|
$this->entityManager->persist($emailText);
|
||||||
}
|
|
||||||
|
|
||||||
$this->entityManager->flush();
|
$this->entityManager->flush();
|
||||||
|
|
||||||
$this->addFlash('success', 'Der E-Mail-Text wurde aktualisiert');
|
$this->addFlash('success', 'Der E-Mail-Text wurde aktualisiert');
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Controller\Admin\Teamer;
|
namespace App\Controller\Admin\Teamer;
|
||||||
|
|
||||||
|
use App\Controller\Traits\AuthenticatedUserTrait;
|
||||||
use App\Controller\Traits\ReturnUrlTrait;
|
use App\Controller\Traits\ReturnUrlTrait;
|
||||||
use App\Email\MailBodyRenderer;
|
use App\Email\MailBodyRenderer;
|
||||||
use App\Form\TeamerMailingType;
|
use App\Form\TeamerMailingType;
|
||||||
@@ -21,6 +22,7 @@ use Symfony\Component\Security\Http\Attribute\IsGranted;
|
|||||||
|
|
||||||
class MailingController extends AbstractController
|
class MailingController extends AbstractController
|
||||||
{
|
{
|
||||||
|
use AuthenticatedUserTrait;
|
||||||
use ReturnUrlTrait;
|
use ReturnUrlTrait;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
@@ -47,7 +49,7 @@ class MailingController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($form->isSubmitted() && $form->isValid()) {
|
if ($form->isSubmitted() && $form->isValid()) {
|
||||||
$this->mailingService->sendPreview($form->getData(), $this->getUser());
|
$this->mailingService->sendPreview($form->getData(), $this->getAuthenticatedUser());
|
||||||
|
|
||||||
$this->addFlash('success', sprintf(
|
$this->addFlash('success', sprintf(
|
||||||
'Die Vorschau wurde an %s gesendet',
|
'Die Vorschau wurde an %s gesendet',
|
||||||
@@ -164,7 +166,7 @@ class MailingController extends AbstractController
|
|||||||
*/
|
*/
|
||||||
private function renderPreview(TeamerMailingDto $mailingDto): array
|
private function renderPreview(TeamerMailingDto $mailingDto): array
|
||||||
{
|
{
|
||||||
$values = $this->mailingService->placeholderValuesForUser($this->getUser());
|
$values = $this->mailingService->placeholderValuesForUser($this->getAuthenticatedUser());
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'subject' => $this->mailingService->render($mailingDto->getSubject(), $values),
|
'subject' => $this->mailingService->render($mailingDto->getSubject(), $values),
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller\Traits;
|
||||||
|
|
||||||
|
use App\Entity\User;
|
||||||
|
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
||||||
|
|
||||||
|
trait AuthenticatedUserTrait
|
||||||
|
{
|
||||||
|
public function getAuthenticatedUser(): User
|
||||||
|
{
|
||||||
|
$user = $this->getUser();
|
||||||
|
|
||||||
|
if (null === $user) {
|
||||||
|
throw new AuthenticationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $user;
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-2
@@ -172,7 +172,7 @@ class User implements UserInterface, TimestampableEntityInterface, SoftDeletable
|
|||||||
|
|
||||||
public function getInitials(): string
|
public function getInitials(): string
|
||||||
{
|
{
|
||||||
$token = substr($this->getFirstName(), 0, 1).substr($this->getLastName(), 0, 2);
|
$token = substr($this->getFirstName() ?? '', 0, 1).substr($this->getLastName() ?? '', 0, 2);
|
||||||
|
|
||||||
return strtoupper($token);
|
return strtoupper($token);
|
||||||
}
|
}
|
||||||
@@ -328,7 +328,7 @@ class User implements UserInterface, TimestampableEntityInterface, SoftDeletable
|
|||||||
|
|
||||||
public function getUserIdentifier(): string
|
public function getUserIdentifier(): string
|
||||||
{
|
{
|
||||||
return $this->email;
|
return $this->email ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTeamer(): ?Teamer
|
public function getTeamer(): ?Teamer
|
||||||
|
|||||||
@@ -41,9 +41,14 @@ class DeletedUserSubscriber implements EventSubscriberInterface
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = $this->security->getUser();
|
$currentUser = $this->security->getUser();
|
||||||
|
|
||||||
if (false === $user instanceof User || false === $user->isDeleted()) {
|
if (false === $currentUser instanceof User) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var User $currentUser */
|
||||||
|
if (false === $currentUser->isDeleted()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ class AssignmentRepository extends ServiceEntityRepository
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 < count($filterDto->getHotels())) {
|
if (0 < count((array)$filterDto->getHotels())) {
|
||||||
$constraints = [];
|
$constraints = [];
|
||||||
foreach ($filterDto->getHotels() as $index => $hotel) {
|
foreach ($filterDto->getHotels() as $index => $hotel) {
|
||||||
$constraints[] = $qb->expr()->like('destination.hotel', ':hotel'.$index);
|
$constraints[] = $qb->expr()->like('destination.hotel', ':hotel'.$index);
|
||||||
|
|||||||
@@ -56,17 +56,11 @@
|
|||||||
<td class="px-4 py-3 text-right">{{ stat.providedFeedbacks }}</td>
|
<td class="px-4 py-3 text-right">{{ stat.providedFeedbacks }}</td>
|
||||||
<td class="px-4 py-3 text-right">{{ stat.missingFeedbacks }}</td>
|
<td class="px-4 py-3 text-right">{{ stat.missingFeedbacks }}</td>
|
||||||
<td class="px-4 py-3 text-right">
|
<td class="px-4 py-3 text-right">
|
||||||
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium
|
<span class="{{ html_classes('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', {
|
||||||
{% if stat.percentageProvided >= 80 %}
|
'bg-green-100 text-green-800': totalPercentage >= 80,
|
||||||
bg-green-100 text-green-800
|
'bg-yellow-100 text-yellow-800': totalPercentage >= 50,
|
||||||
{% elseif stat.percentageProvided >= 50 %}
|
'bg-red-100 text-red-800': totalPercentage >= 0
|
||||||
bg-yellow-100 text-yellow-800
|
}) }}">{{ stat.percentageProvided|number_format(1, ',', '.') }}%</span>
|
||||||
{% else %}
|
|
||||||
bg-red-100 text-red-800
|
|
||||||
{% endif %}
|
|
||||||
">
|
|
||||||
{{ stat.percentageProvided|number_format(1, ',', '.') }}%
|
|
||||||
</span>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@@ -87,17 +81,11 @@
|
|||||||
<td class="px-4 py-3 text-right">{{ totalProvided }}</td>
|
<td class="px-4 py-3 text-right">{{ totalProvided }}</td>
|
||||||
<td class="px-4 py-3 text-right">{{ totalMissing }}</td>
|
<td class="px-4 py-3 text-right">{{ totalMissing }}</td>
|
||||||
<td class="px-4 py-3 text-right">
|
<td class="px-4 py-3 text-right">
|
||||||
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium
|
<span class="{{ html_classes('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', {
|
||||||
{% if totalPercentage >= 80 %}
|
'bg-green-100 text-green-800': totalPercentage >= 80,
|
||||||
bg-green-100 text-green-800
|
'bg-yellow-100 text-yellow-800': totalPercentage >= 50,
|
||||||
{% elseif totalPercentage >= 50 %}
|
'bg-red-100 text-red-800': totalPercentage >= 0
|
||||||
bg-yellow-100 text-yellow-800
|
}) }}">{{ totalPercentage|number_format(1, ',', '.') }}%</span>
|
||||||
{% else %}
|
|
||||||
bg-red-100 text-red-800
|
|
||||||
{% endif %}
|
|
||||||
">
|
|
||||||
{{ totalPercentage|number_format(1, ',', '.') }}%
|
|
||||||
</span>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tfoot>
|
</tfoot>
|
||||||
|
|||||||
@@ -93,6 +93,9 @@ class EmailTextCatalogTest extends KernelTestCase
|
|||||||
{
|
{
|
||||||
self::bootKernel();
|
self::bootKernel();
|
||||||
|
|
||||||
return self::getContainer()->get(EmailTextCatalog::class);
|
/** @var EmailTextCatalog $catalog */
|
||||||
|
$catalog = self::getContainer()->get(EmailTextCatalog::class);
|
||||||
|
|
||||||
|
return $catalog;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user