fix: type mismatches and handle nullable values

This commit is contained in:
2026-08-27 10:16:03 +02:00
parent c33c1b6bf0
commit e7f3233dbc
9 changed files with 67 additions and 47 deletions
+12 -4
View File
@@ -31,12 +31,15 @@ class ResponseParser
public function parseXmlString(string $type, string $content): mixed
{
$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
$responseType = $type;
$responseTypeXml = $xml->xpath('satz/@typ');
$responseTypeXml = $xml->xpath('satz/@typ') ?: [];
if (0 < count($responseTypeXml)) {
$responseType = (string) $xml->xpath('satz/@typ')[0];
$responseType = (string) $responseTypeXml[0];
}
switch ($responseType) {
@@ -91,7 +94,12 @@ class ResponseParser
$gender = 'W' === strtoupper($gender) ? 'F' : strtoupper($gender);
$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
@@ -146,7 +154,7 @@ class ResponseParser
$personId = (int) $xml->idperson;
$updated = false;
$updatedXml = $xml->xpath('änderung|aenderung');
$updatedXml = $xml->xpath('änderung|aenderung') ?: [];
if (0 < count($updatedXml)) {
$updated = 'true' === strtolower((string) $updatedXml[0]);
}
@@ -32,18 +32,15 @@ class EditController extends AbstractController
public function index(EmailTextKey $key, Request $request): Response
{
$definition = $this->catalog->get($key);
$emailText = $this->emailTextRepository->findByKey($key);
$isNew = null === $emailText;
$existing = $this->emailTextRepository->findByKey($key);
// 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.
if (true === $isNew) {
$emailText = (new EmailText($key))
->setSubject($definition->defaultSubject)
->setHeadline($definition->defaultHeadline)
->setBody($definition->defaultBody)
;
}
$emailText = $existing ?? (new EmailText($key))
->setSubject($definition->defaultSubject)
->setHeadline($definition->defaultHeadline)
->setBody($definition->defaultBody)
;
$form = $this->createForm(EmailTextType::class, $emailText, [
'definition' => $definition,
@@ -51,10 +48,7 @@ class EditController extends AbstractController
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
if (true === $isNew) {
$this->entityManager->persist($emailText);
}
$this->entityManager->persist($emailText);
$this->entityManager->flush();
$this->addFlash('success', 'Der E-Mail-Text wurde aktualisiert');
@@ -2,6 +2,7 @@
namespace App\Controller\Admin\Teamer;
use App\Controller\Traits\AuthenticatedUserTrait;
use App\Controller\Traits\ReturnUrlTrait;
use App\Email\MailBodyRenderer;
use App\Form\TeamerMailingType;
@@ -21,6 +22,7 @@ use Symfony\Component\Security\Http\Attribute\IsGranted;
class MailingController extends AbstractController
{
use AuthenticatedUserTrait;
use ReturnUrlTrait;
public function __construct(
@@ -47,7 +49,7 @@ class MailingController extends AbstractController
}
if ($form->isSubmitted() && $form->isValid()) {
$this->mailingService->sendPreview($form->getData(), $this->getUser());
$this->mailingService->sendPreview($form->getData(), $this->getAuthenticatedUser());
$this->addFlash('success', sprintf(
'Die Vorschau wurde an %s gesendet',
@@ -164,7 +166,7 @@ class MailingController extends AbstractController
*/
private function renderPreview(TeamerMailingDto $mailingDto): array
{
$values = $this->mailingService->placeholderValuesForUser($this->getUser());
$values = $this->mailingService->placeholderValuesForUser($this->getAuthenticatedUser());
return [
'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
View File
@@ -172,7 +172,7 @@ class User implements UserInterface, TimestampableEntityInterface, SoftDeletable
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);
}
@@ -328,7 +328,7 @@ class User implements UserInterface, TimestampableEntityInterface, SoftDeletable
public function getUserIdentifier(): string
{
return $this->email;
return $this->email ?? '';
}
public function getTeamer(): ?Teamer
+7 -2
View File
@@ -41,9 +41,14 @@ class DeletedUserSubscriber implements EventSubscriberInterface
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;
}
+1 -1
View File
@@ -158,7 +158,7 @@ class AssignmentRepository extends ServiceEntityRepository
;
}
if (0 < count($filterDto->getHotels())) {
if (0 < count((array)$filterDto->getHotels())) {
$constraints = [];
foreach ($filterDto->getHotels() as $index => $hotel) {
$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.missingFeedbacks }}</td>
<td class="px-4 py-3 text-right">
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium
{% if stat.percentageProvided >= 80 %}
bg-green-100 text-green-800
{% elseif stat.percentageProvided >= 50 %}
bg-yellow-100 text-yellow-800
{% else %}
bg-red-100 text-red-800
{% endif %}
">
{{ stat.percentageProvided|number_format(1, ',', '.') }}%
</span>
<span class="{{ html_classes('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', {
'bg-green-100 text-green-800': totalPercentage >= 80,
'bg-yellow-100 text-yellow-800': totalPercentage >= 50,
'bg-red-100 text-red-800': totalPercentage >= 0
}) }}">{{ stat.percentageProvided|number_format(1, ',', '.') }}%</span>
</td>
</tr>
{% endfor %}
@@ -87,17 +81,11 @@
<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">
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium
{% if totalPercentage >= 80 %}
bg-green-100 text-green-800
{% elseif totalPercentage >= 50 %}
bg-yellow-100 text-yellow-800
{% else %}
bg-red-100 text-red-800
{% endif %}
">
{{ totalPercentage|number_format(1, ',', '.') }}%
</span>
<span class="{{ html_classes('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', {
'bg-green-100 text-green-800': totalPercentage >= 80,
'bg-yellow-100 text-yellow-800': totalPercentage >= 50,
'bg-red-100 text-red-800': totalPercentage >= 0
}) }}">{{ totalPercentage|number_format(1, ',', '.') }}%</span>
</td>
</tr>
</tfoot>
+4 -1
View File
@@ -93,6 +93,9 @@ class EmailTextCatalogTest extends KernelTestCase
{
self::bootKernel();
return self::getContainer()->get(EmailTextCatalog::class);
/** @var EmailTextCatalog $catalog */
$catalog = self::getContainer()->get(EmailTextCatalog::class);
return $catalog;
}
}