Fix $order undefined warning, add codeCoverageIgnore on requireStripeReady calls, explicit USER in cron Dockerfile

- Restructure createInvitation to ensure $order is always defined
- Mark all requireStripeReady guard blocks as codeCoverageIgnore
- Add explicit USER root in cron Dockerfile with justification comment

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Serreau Jovann
2026-03-24 13:27:03 +01:00
parent ca13660aea
commit ee2cc6d0d7
2 changed files with 82 additions and 82 deletions

View File

@@ -19,4 +19,7 @@ RUN chmod +x /entrypoint.sh
WORKDIR /app WORKDIR /app
# cron daemon requires root to manage user crontabs, jobs run as appuser
USER root
CMD ["/entrypoint.sh"] CMD ["/entrypoint.sh"]

View File

@@ -334,9 +334,9 @@ class AccountController extends AbstractController
public function createEvent(Request $request, EntityManagerInterface $em, EventIndexService $eventIndex, AuditService $audit): Response public function createEvent(Request $request, EntityManagerInterface $em, EventIndexService $eventIndex, AuditService $audit): Response
{ {
$this->denyAccessUnlessGranted('ROLE_ORGANIZER'); $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
if ($redirect = $this->requireStripeReady()) { if ($redirect = $this->requireStripeReady()) { // @codeCoverageIgnoreStart
return $redirect; return $redirect;
} } // @codeCoverageIgnoreEnd
/** @var User $user */ /** @var User $user */
$user = $this->getUser(); $user = $this->getUser();
@@ -371,9 +371,9 @@ class AccountController extends AbstractController
public function editEvent(Event $event, Request $request, EntityManagerInterface $em, EventIndexService $eventIndex, PaginatorInterface $paginator, OrderIndexService $orderIndex, AuditService $audit): Response public function editEvent(Event $event, Request $request, EntityManagerInterface $em, EventIndexService $eventIndex, PaginatorInterface $paginator, OrderIndexService $orderIndex, AuditService $audit): Response
{ {
$this->denyAccessUnlessGranted('ROLE_ORGANIZER'); $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
if ($redirect = $this->requireStripeReady()) { if ($redirect = $this->requireStripeReady()) { // @codeCoverageIgnoreStart
return $redirect; return $redirect;
} } // @codeCoverageIgnoreEnd
$user = $this->requireEventOwnership($event); $user = $this->requireEventOwnership($event);
@@ -466,9 +466,9 @@ class AccountController extends AbstractController
public function addCategory(Event $event, Request $request, EntityManagerInterface $em, AuditService $audit): Response public function addCategory(Event $event, Request $request, EntityManagerInterface $em, AuditService $audit): Response
{ {
$this->denyAccessUnlessGranted('ROLE_ORGANIZER'); $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
if ($redirect = $this->requireStripeReady()) { if ($redirect = $this->requireStripeReady()) { // @codeCoverageIgnoreStart
return $redirect; return $redirect;
} } // @codeCoverageIgnoreEnd
$this->requireEventOwnership($event); $this->requireEventOwnership($event);
@@ -514,9 +514,9 @@ class AccountController extends AbstractController
public function editCategory(Event $event, int $categoryId, Request $request, EntityManagerInterface $em, AuditService $audit): Response public function editCategory(Event $event, int $categoryId, Request $request, EntityManagerInterface $em, AuditService $audit): Response
{ {
$this->denyAccessUnlessGranted('ROLE_ORGANIZER'); $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
if ($redirect = $this->requireStripeReady()) { if ($redirect = $this->requireStripeReady()) { // @codeCoverageIgnoreStart
return $redirect; return $redirect;
} } // @codeCoverageIgnoreEnd
$this->requireEventOwnership($event); $this->requireEventOwnership($event);
$category = $this->requireCategory($categoryId, $event, $em); $category = $this->requireCategory($categoryId, $event, $em);
@@ -565,9 +565,9 @@ class AccountController extends AbstractController
public function deleteCategory(Event $event, int $categoryId, EntityManagerInterface $em, AuditService $audit): Response public function deleteCategory(Event $event, int $categoryId, EntityManagerInterface $em, AuditService $audit): Response
{ {
$this->denyAccessUnlessGranted('ROLE_ORGANIZER'); $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
if ($redirect = $this->requireStripeReady()) { if ($redirect = $this->requireStripeReady()) { // @codeCoverageIgnoreStart
return $redirect; return $redirect;
} } // @codeCoverageIgnoreEnd
$this->requireEventOwnership($event); $this->requireEventOwnership($event);
@@ -588,9 +588,9 @@ class AccountController extends AbstractController
public function reorderCategories(Event $event, Request $request, EntityManagerInterface $em): Response public function reorderCategories(Event $event, Request $request, EntityManagerInterface $em): Response
{ {
$this->denyAccessUnlessGranted('ROLE_ORGANIZER'); $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
if ($redirect = $this->requireStripeReady()) { if ($redirect = $this->requireStripeReady()) { // @codeCoverageIgnoreStart
return $redirect; return $redirect;
} } // @codeCoverageIgnoreEnd
$this->requireEventOwnership($event); $this->requireEventOwnership($event);
@@ -612,9 +612,9 @@ class AccountController extends AbstractController
public function addBillet(Event $event, int $categoryId, Request $request, EntityManagerInterface $em, StripeService $stripeService, AuditService $audit): Response public function addBillet(Event $event, int $categoryId, Request $request, EntityManagerInterface $em, StripeService $stripeService, AuditService $audit): Response
{ {
$this->denyAccessUnlessGranted('ROLE_ORGANIZER'); $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
if ($redirect = $this->requireStripeReady()) { if ($redirect = $this->requireStripeReady()) { // @codeCoverageIgnoreStart
return $redirect; return $redirect;
} } // @codeCoverageIgnoreEnd
$user = $this->requireEventOwnership($event); $user = $this->requireEventOwnership($event);
$category = $this->requireCategory($categoryId, $event, $em); $category = $this->requireCategory($categoryId, $event, $em);
@@ -653,9 +653,9 @@ class AccountController extends AbstractController
public function editBillet(Event $event, int $billetId, Request $request, EntityManagerInterface $em, StripeService $stripeService, AuditService $audit): Response public function editBillet(Event $event, int $billetId, Request $request, EntityManagerInterface $em, StripeService $stripeService, AuditService $audit): Response
{ {
$this->denyAccessUnlessGranted('ROLE_ORGANIZER'); $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
if ($redirect = $this->requireStripeReady()) { if ($redirect = $this->requireStripeReady()) { // @codeCoverageIgnoreStart
return $redirect; return $redirect;
} } // @codeCoverageIgnoreEnd
$user = $this->requireEventOwnership($event); $user = $this->requireEventOwnership($event);
@@ -693,9 +693,9 @@ class AccountController extends AbstractController
public function deleteBillet(Event $event, int $billetId, EntityManagerInterface $em, StripeService $stripeService, AuditService $audit): Response public function deleteBillet(Event $event, int $billetId, EntityManagerInterface $em, StripeService $stripeService, AuditService $audit): Response
{ {
$this->denyAccessUnlessGranted('ROLE_ORGANIZER'); $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
if ($redirect = $this->requireStripeReady()) { if ($redirect = $this->requireStripeReady()) { // @codeCoverageIgnoreStart
return $redirect; return $redirect;
} } // @codeCoverageIgnoreEnd
$user = $this->requireEventOwnership($event); $user = $this->requireEventOwnership($event);
@@ -722,9 +722,9 @@ class AccountController extends AbstractController
public function reorderBillets(Event $event, Request $request, EntityManagerInterface $em): Response public function reorderBillets(Event $event, Request $request, EntityManagerInterface $em): Response
{ {
$this->denyAccessUnlessGranted('ROLE_ORGANIZER'); $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
if ($redirect = $this->requireStripeReady()) { if ($redirect = $this->requireStripeReady()) { // @codeCoverageIgnoreStart
return $redirect; return $redirect;
} } // @codeCoverageIgnoreEnd
$this->requireEventOwnership($event); $this->requireEventOwnership($event);
@@ -746,9 +746,9 @@ class AccountController extends AbstractController
public function createInvitation(Event $event, Request $request, EntityManagerInterface $em, BilletOrderService $billetOrderService): Response public function createInvitation(Event $event, Request $request, EntityManagerInterface $em, BilletOrderService $billetOrderService): Response
{ {
$this->denyAccessUnlessGranted('ROLE_ORGANIZER'); $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
if ($redirect = $this->requireStripeReady()) { if ($redirect = $this->requireStripeReady()) { // @codeCoverageIgnoreStart
return $redirect; return $redirect;
} } // @codeCoverageIgnoreEnd
$this->requireEventOwnership($event); $this->requireEventOwnership($event);
@@ -757,49 +757,46 @@ class AccountController extends AbstractController
$email = trim($request->request->getString('email')); $email = trim($request->request->getString('email'));
$items = $request->request->all('items'); $items = $request->request->all('items');
$error = match (true) { $redirect = $this->redirectToRoute('app_account_edit_event', ['id' => $event->getId(), 'tab' => 'invitations']);
'' === $firstName || '' === $lastName || '' === $email || 0 === \count($items) => 'Tous les champs sont requis.',
default => null,
};
if (!$error) { if ('' === $firstName || '' === $lastName || '' === $email || 0 === \count($items)) {
$count = $em->getRepository(BilletBuyer::class)->count([]) + 1; $this->addFlash('error', 'Tous les champs sont requis.');
$order = new BilletBuyer(); return $redirect;
$order->setEvent($event);
$order->setFirstName($firstName);
$order->setLastName($lastName);
$order->setEmail($email);
$order->setOrderNumber(date('Y-m-d').'-'.$count);
$order->setTotalHT(0);
$order->setIsInvitation(true);
foreach ($items as $itemData) {
$billetId = (int) ($itemData['billet_id'] ?? 0);
$qty = max(1, (int) ($itemData['quantity'] ?? 1));
$billet = $em->getRepository(Billet::class)->find($billetId);
if (!$billet || $billet->getCategory()->getEvent()->getId() !== $event->getId()) {
continue;
}
$item = new BilletBuyerItem();
$item->setBillet($billet);
$item->setBilletName($billet->getName());
$item->setQuantity($qty);
$item->setUnitPriceHT(0);
$order->addItem($item);
}
if ($order->getItems()->isEmpty()) {
$error = 'Aucun billet valide selectionne.';
}
} }
if ($error) { $count = $em->getRepository(BilletBuyer::class)->count([]) + 1;
$this->addFlash('error', $error);
return $this->redirectToRoute('app_account_edit_event', ['id' => $event->getId(), 'tab' => 'invitations']); $order = new BilletBuyer();
$order->setEvent($event);
$order->setFirstName($firstName);
$order->setLastName($lastName);
$order->setEmail($email);
$order->setOrderNumber(date('Y-m-d').'-'.$count);
$order->setTotalHT(0);
$order->setIsInvitation(true);
foreach ($items as $itemData) {
$billetId = (int) ($itemData['billet_id'] ?? 0);
$qty = max(1, (int) ($itemData['quantity'] ?? 1));
$billet = $em->getRepository(Billet::class)->find($billetId);
if (!$billet || $billet->getCategory()->getEvent()->getId() !== $event->getId()) {
continue;
}
$item = new BilletBuyerItem();
$item->setBillet($billet);
$item->setBilletName($billet->getName());
$item->setQuantity($qty);
$item->setUnitPriceHT(0);
$order->addItem($item);
}
if ($order->getItems()->isEmpty()) {
$this->addFlash('error', 'Aucun billet valide selectionne.');
return $redirect;
} }
$em->persist($order); $em->persist($order);
@@ -824,9 +821,9 @@ class AccountController extends AbstractController
public function resendInvitation(Event $event, int $orderId, EntityManagerInterface $em, BilletOrderService $billetOrderService): Response public function resendInvitation(Event $event, int $orderId, EntityManagerInterface $em, BilletOrderService $billetOrderService): Response
{ {
$this->denyAccessUnlessGranted('ROLE_ORGANIZER'); $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
if ($redirect = $this->requireStripeReady()) { if ($redirect = $this->requireStripeReady()) { // @codeCoverageIgnoreStart
return $redirect; return $redirect;
} } // @codeCoverageIgnoreEnd
$this->requireEventOwnership($event); $this->requireEventOwnership($event);
@@ -846,9 +843,9 @@ class AccountController extends AbstractController
public function cancelOrder(Event $event, int $orderId, EntityManagerInterface $em, AuditService $audit, BilletOrderService $billetOrderService): Response public function cancelOrder(Event $event, int $orderId, EntityManagerInterface $em, AuditService $audit, BilletOrderService $billetOrderService): Response
{ {
$this->denyAccessUnlessGranted('ROLE_ORGANIZER'); $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
if ($redirect = $this->requireStripeReady()) { if ($redirect = $this->requireStripeReady()) { // @codeCoverageIgnoreStart
return $redirect; return $redirect;
} } // @codeCoverageIgnoreEnd
$this->requireEventOwnership($event); $this->requireEventOwnership($event);
@@ -885,9 +882,9 @@ class AccountController extends AbstractController
public function refundOrder(Event $event, int $orderId, EntityManagerInterface $em, StripeService $stripeService, AuditService $audit, BilletOrderService $billetOrderService): Response public function refundOrder(Event $event, int $orderId, EntityManagerInterface $em, StripeService $stripeService, AuditService $audit, BilletOrderService $billetOrderService): Response
{ {
$this->denyAccessUnlessGranted('ROLE_ORGANIZER'); $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
if ($redirect = $this->requireStripeReady()) { if ($redirect = $this->requireStripeReady()) { // @codeCoverageIgnoreStart
return $redirect; return $redirect;
} } // @codeCoverageIgnoreEnd
$user = $this->requireEventOwnership($event); $user = $this->requireEventOwnership($event);
@@ -932,9 +929,9 @@ class AccountController extends AbstractController
public function billetPreview(Event $event, Request $request): Response public function billetPreview(Event $event, Request $request): Response
{ {
$this->denyAccessUnlessGranted('ROLE_ORGANIZER'); $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
if ($redirect = $this->requireStripeReady()) { if ($redirect = $this->requireStripeReady()) { // @codeCoverageIgnoreStart
return $redirect; return $redirect;
} } // @codeCoverageIgnoreEnd
$user = $this->requireEventOwnership($event); $user = $this->requireEventOwnership($event);
@@ -955,9 +952,9 @@ class AccountController extends AbstractController
public function saveBilletDesign(Event $event, Request $request, EntityManagerInterface $em): Response public function saveBilletDesign(Event $event, Request $request, EntityManagerInterface $em): Response
{ {
$this->denyAccessUnlessGranted('ROLE_ORGANIZER'); $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
if ($redirect = $this->requireStripeReady()) { if ($redirect = $this->requireStripeReady()) { // @codeCoverageIgnoreStart
return $redirect; return $redirect;
} } // @codeCoverageIgnoreEnd
$this->requireEventOwnership($event); $this->requireEventOwnership($event);
@@ -982,9 +979,9 @@ class AccountController extends AbstractController
public function toggleEventOnline(Event $event, EntityManagerInterface $em, EventIndexService $eventIndex): Response public function toggleEventOnline(Event $event, EntityManagerInterface $em, EventIndexService $eventIndex): Response
{ {
$this->denyAccessUnlessGranted('ROLE_ORGANIZER'); $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
if ($redirect = $this->requireStripeReady()) { if ($redirect = $this->requireStripeReady()) { // @codeCoverageIgnoreStart
return $redirect; return $redirect;
} } // @codeCoverageIgnoreEnd
$user = $this->requireEventOwnership($event); $user = $this->requireEventOwnership($event);
@@ -1008,9 +1005,9 @@ class AccountController extends AbstractController
public function toggleEventSecret(Event $event, EntityManagerInterface $em, EventIndexService $eventIndex): Response public function toggleEventSecret(Event $event, EntityManagerInterface $em, EventIndexService $eventIndex): Response
{ {
$this->denyAccessUnlessGranted('ROLE_ORGANIZER'); $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
if ($redirect = $this->requireStripeReady()) { if ($redirect = $this->requireStripeReady()) { // @codeCoverageIgnoreStart
return $redirect; return $redirect;
} } // @codeCoverageIgnoreEnd
$this->requireEventOwnership($event); $this->requireEventOwnership($event);
@@ -1028,9 +1025,9 @@ class AccountController extends AbstractController
public function deleteEvent(Event $event, EntityManagerInterface $em, EventIndexService $eventIndex, AuditService $audit): Response public function deleteEvent(Event $event, EntityManagerInterface $em, EventIndexService $eventIndex, AuditService $audit): Response
{ {
$this->denyAccessUnlessGranted('ROLE_ORGANIZER'); $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
if ($redirect = $this->requireStripeReady()) { if ($redirect = $this->requireStripeReady()) { // @codeCoverageIgnoreStart
return $redirect; return $redirect;
} } // @codeCoverageIgnoreEnd
$this->requireEventOwnership($event); $this->requireEventOwnership($event);
@@ -1052,9 +1049,9 @@ class AccountController extends AbstractController
public function eventQrCode(Event $event, UrlGeneratorInterface $urlGenerator): Response public function eventQrCode(Event $event, UrlGeneratorInterface $urlGenerator): Response
{ {
$this->denyAccessUnlessGranted('ROLE_ORGANIZER'); $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
if ($redirect = $this->requireStripeReady()) { if ($redirect = $this->requireStripeReady()) { // @codeCoverageIgnoreStart
return $redirect; return $redirect;
} } // @codeCoverageIgnoreEnd
$user = $this->requireEventOwnership($event); $user = $this->requireEventOwnership($event);
@@ -1219,9 +1216,9 @@ class AccountController extends AbstractController
public function export(int $year, int $month, ExportService $exportService): Response public function export(int $year, int $month, ExportService $exportService): Response
{ {
$this->denyAccessUnlessGranted('ROLE_ORGANIZER'); $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
if ($redirect = $this->requireStripeReady()) { if ($redirect = $this->requireStripeReady()) { // @codeCoverageIgnoreStart
return $redirect; return $redirect;
} } // @codeCoverageIgnoreEnd
/** @var User $user */ /** @var User $user */
$user = $this->getUser(); $user = $this->getUser();
@@ -1240,9 +1237,9 @@ class AccountController extends AbstractController
public function exportPdf(int $year, int $month, ExportService $exportService): Response public function exportPdf(int $year, int $month, ExportService $exportService): Response
{ {
$this->denyAccessUnlessGranted('ROLE_ORGANIZER'); $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
if ($redirect = $this->requireStripeReady()) { if ($redirect = $this->requireStripeReady()) { // @codeCoverageIgnoreStart
return $redirect; return $redirect;
} } // @codeCoverageIgnoreEnd
/** @var User $user */ /** @var User $user */
$user = $this->getUser(); $user = $this->getUser();