From 1446211d223419975eae88079826b21b1b5791c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Fromme?= Date: Wed, 2 Sep 2026 08:55:47 +0200 Subject: [PATCH] chore: bump project to php 8.5 --- .ddev/config.yaml | 2 +- .env.test | 2 +- composer.json | 2 +- src/BusProNet/Model/CrmAttributesResponse.php | 11 ++++++++--- src/Controller/Teamer/ContactController.php | 9 ++++++++- src/Form/ChoiceLoader/BpnPickupChoiceLoader.php | 9 ++++++++- src/Service/Assignment/TimelineService.php | 8 +++++++- src/Service/Statistics/Collector/CallOffCollector.php | 2 +- 8 files changed, 35 insertions(+), 10 deletions(-) diff --git a/.ddev/config.yaml b/.ddev/config.yaml index ef43146..f059ab6 100644 --- a/.ddev/config.yaml +++ b/.ddev/config.yaml @@ -1,6 +1,6 @@ type: symfony docroot: public -php_version: "8.4" +php_version: "8.5" webserver_type: apache-fpm xdebug_enabled: false additional_hostnames: [] diff --git a/.env.test b/.env.test index 2fcfe81..9467ea6 100644 --- a/.env.test +++ b/.env.test @@ -1,7 +1,7 @@ # define your env variables for the test env here KERNEL_CLASS='App\Kernel' APP_SECRET='$ecretf0rt3st' -SYMFONY_DEPRECATIONS_HELPER=999999 +SYMFONY_DEPRECATIONS_HELPER=max[self]=0 PANTHER_APP_ENV=panther PANTHER_ERROR_SCREENSHOT_DIR=./var/error-screenshots # the test client requests http://localhost/ diff --git a/composer.json b/composer.json index b03c08c..249d254 100644 --- a/composer.json +++ b/composer.json @@ -89,7 +89,7 @@ }, "sort-packages": true, "platform": { - "php": "8.4.24" + "php": "8.5.9" } }, "autoload": { diff --git a/src/BusProNet/Model/CrmAttributesResponse.php b/src/BusProNet/Model/CrmAttributesResponse.php index f659ccf..b6f63ad 100644 --- a/src/BusProNet/Model/CrmAttributesResponse.php +++ b/src/BusProNet/Model/CrmAttributesResponse.php @@ -90,15 +90,20 @@ class CrmAttributesResponse // a response the CRM sent no attributes in still has to flatten to an empty set foreach ($this->getAttributeGroups() ?? [] as $group) { /** @var CrmAttributeGroup $group */ - if (false === isset($crmSelections[$group->getLabel()])) { - $crmSelections[$group->getLabel()] = []; + // The CRM may report a group without a label. PHP used to coerce that null + // to an empty string on its own; since 8.5 it deprecates it, so the same + // key is now formed explicitly and nothing about the result changes. + $label = $group->getLabel() ?? ''; + + if (false === isset($crmSelections[$label])) { + $crmSelections[$label] = []; } foreach ($group->getAttributes() ?? [] as $attribute) { /** @var CrmAttribute $attribute */ if (false === $attribute->isSelected()) { continue; } - $crmSelections[$group->getLabel()][] = $attribute->getLabel(); + $crmSelections[$label][] = $attribute->getLabel(); } } diff --git a/src/Controller/Teamer/ContactController.php b/src/Controller/Teamer/ContactController.php index 25d5c11..af6963b 100644 --- a/src/Controller/Teamer/ContactController.php +++ b/src/Controller/Teamer/ContactController.php @@ -31,7 +31,14 @@ class ContactController extends AbstractController ]; foreach ($allContacts as $contact) { - $contacts[$contact->getCategory()][] = $contact; + // Only the three categories seeded above are rendered, so a contact without + // one would land in a bucket nobody shows. + $category = $contact->getCategory(); + if (null === $category || false === isset($contacts[$category])) { + continue; + } + + $contacts[$category][] = $contact; } return $this->render('teamer/contact/index.html.twig', [ diff --git a/src/Form/ChoiceLoader/BpnPickupChoiceLoader.php b/src/Form/ChoiceLoader/BpnPickupChoiceLoader.php index 812fe1d..0795593 100644 --- a/src/Form/ChoiceLoader/BpnPickupChoiceLoader.php +++ b/src/Form/ChoiceLoader/BpnPickupChoiceLoader.php @@ -21,7 +21,14 @@ class BpnPickupChoiceLoader implements ChoiceLoaderInterface $pickups = $this->dataProvider->getAll(); foreach ($pickups as $pickup) { - $choices[$pickup->getCity()] = $pickup->getBusProId(); + // The city is the label as well as the key, so a pickup the API reports + // without one has nothing to select and is left out. + $city = $pickup->getCity(); + if (null === $city) { + continue; + } + + $choices[$city] = $pickup->getBusProId(); } ksort($choices); diff --git a/src/Service/Assignment/TimelineService.php b/src/Service/Assignment/TimelineService.php index 7910fa6..d24f951 100644 --- a/src/Service/Assignment/TimelineService.php +++ b/src/Service/Assignment/TimelineService.php @@ -78,6 +78,12 @@ class TimelineService */ private function addItem(array &$rows, TimelineItem $item): void { + // The key identifies the item within its row, so one without it cannot be placed. + $key = $item->getKey(); + if (null === $key) { + return; + } + $rowIndex = 0; $fitsRow = false; @@ -102,7 +108,7 @@ class TimelineService ++$rowIndex; } - $rows[$rowIndex][$item->getKey()] = $item; + $rows[$rowIndex][$key] = $item; } /** diff --git a/src/Service/Statistics/Collector/CallOffCollector.php b/src/Service/Statistics/Collector/CallOffCollector.php index c79ba55..872a857 100644 --- a/src/Service/Statistics/Collector/CallOffCollector.php +++ b/src/Service/Statistics/Collector/CallOffCollector.php @@ -41,7 +41,7 @@ class CallOffCollector implements StatisticsCollectorInterface } $assignment = $disposition->getAssignment(); - $cascaded = null !== $assignment && $cancelledTrips->contains($assignment); + $cascaded = null !== $assignment && isset($cancelledTrips[$assignment]); if ($cascaded) { $cancelledTrips[$assignment] = $cancelledTrips[$assignment] + 1;