diff --git a/.github/workflows/php-sandbox.yml b/.github/workflows/php-sandbox.yml index 2a83b97..2383c3d 100644 --- a/.github/workflows/php-sandbox.yml +++ b/.github/workflows/php-sandbox.yml @@ -2,7 +2,7 @@ name: Build & deploy sandbox on: push: - branches: [ "develop" ] + branches: [ "develop", "add-crowd-compatibility" ] workflow_dispatch: permissions: @@ -69,7 +69,7 @@ jobs: - name: Tar run : | - tar czvf artifact.tar.gz migrations public src vendor .env cron.php + tar czv --ignore-failed-read -f artifact.tar.gz migrations public src vendor .env cron.php 2>/dev/null || tar czv -f artifact.tar.gz migrations public src vendor .env cron.php - name: Upload run : | diff --git a/migrations/15-add-form-type.sql b/migrations/15-add-form-type.sql new file mode 100644 index 0000000..9794960 --- /dev/null +++ b/migrations/15-add-form-type.sql @@ -0,0 +1,3 @@ +ALTER TABLE {prefix}charity_stream ADD COLUMN form_type VARCHAR(50) NOT NULL DEFAULT 'Donation' AFTER form_slug; + + diff --git a/src/Assets/js/admin.js b/src/Assets/js/admin.js index b02b40c..2a32d78 100644 --- a/src/Assets/js/admin.js +++ b/src/Assets/js/admin.js @@ -100,6 +100,12 @@ if (cardWidgetForm) { } if (goalEl) goalEl.innerHTML = `Objectif : ${goalValue} €`; if (pct) pct.textContent = '50%'; + + const cta = document.getElementById('cardPreviewCta'); + if (cta) { + cta.style.color = tagColor; + cta.style.backgroundColor = tagBgColor; + } } bindPreviewInputs( diff --git a/src/Controllers/AdminController.php b/src/Controllers/AdminController.php index e679066..a8fdb15 100644 --- a/src/Controllers/AdminController.php +++ b/src/Controllers/AdminController.php @@ -316,7 +316,7 @@ public function newStream(Request $request, Response $response): Response $event = $this->eventRepository->selectByUserAndId($user, $parentEvent); } - $stream = $this->streamRepository->insert($data['form_slug'], $data['organization_slug'], $data['title'], $event->id ?? null); + $stream = $this->streamRepository->insert($data['form_slug'], $data['organization_slug'], $data['title'], $event->id ?? null, $data['form_type'] ?? 'Donation'); $this->userRepository->insertRight($owner, $stream, null); if ($event !== null && $parentStyle) { @@ -376,7 +376,8 @@ public function editStream(Request $request, Response $response, array $args): R $availableEvents = $this->eventRepository->selectListByUser($user); } - $donationUrl = $_SERVER['HA_URL'] . '/associations/' . $charityStream->organization_slug . '/formulaires/' . $charityStream->form_slug; + $formTypeUrlSegment = ($charityStream->form_type === 'CrowdFunding') ? 'collectes' : 'formulaires'; + $donationUrl = $_SERVER['HA_URL'] . '/associations/' . $charityStream->organization_slug . '/' . $formTypeUrlSegment . '/' . $charityStream->form_slug; $routeParser = RouteContext::fromRequest($request)->getRouteParser(); $data = [ @@ -552,8 +553,8 @@ public function streamAuthCallback(Request $request, Response $response): Respon // Stocker / mettre à jour les tokens $this->apiWrapper->storeOrUpdateToken($tokenData); - // Récupérer les formulaires de don - $forms = $this->apiWrapper->getDonationForms($organizationSlug); + // Récupérer les formulaires de don et de crowdfunding + $forms = $this->apiWrapper->getOrganizationForms($organizationSlug, ['Donation', 'CrowdFunding']); } catch (Exception $e) { $response->getBody()->write($this->buildCallbackPage(null, [], $e->getMessage())); return $response; diff --git a/src/Controllers/ApiController.php b/src/Controllers/ApiController.php index 8d2bf07..d8bcd66 100644 --- a/src/Controllers/ApiController.php +++ b/src/Controllers/ApiController.php @@ -23,13 +23,20 @@ public function new(Request $request, Response $response): Response $formSlug = $data['form_slug'] ?? null; $organizationSlug = $data['organization_slug'] ?? null; $title = $data['title'] ?? null; + $formType = $data['form_type'] ?? 'Donation'; + + // Valider le form_type + $allowedFormTypes = ['Donation', 'CrowdFunding']; + if (!in_array($formType, $allowedFormTypes)) { + $formType = 'Donation'; + } if (!$ownerEmail || !$formSlug || !$organizationSlug || !$title) { $response->getBody()->write(json_encode(['error' => 'all fields are mandatory'])); return $response->withStatus(400)->withHeader('Content-Type', 'application/json'); } - $stream = $this->streamRepository->insert($formSlug, $organizationSlug, $title); + $stream = $this->streamRepository->insert($formSlug, $organizationSlug, $title, null, $formType); $user = $this->userRepository->findOrCreate($ownerEmail); $this->userRepository->insertRight($user, $stream, null); $this->userRepository->insertResetToken($user); diff --git a/src/Controllers/WidgetController.php b/src/Controllers/WidgetController.php index 5f92caf..b4ce212 100644 --- a/src/Controllers/WidgetController.php +++ b/src/Controllers/WidgetController.php @@ -55,6 +55,14 @@ private function requireIdArg(array $args, string $label): string return $id; } + private function renderWidgetError(Response $response, string $message, Exception $e): Response + { + error_log('[Widget] ' . $message . ' : ' . $e->getMessage() . "\n" . $e->getTraceAsString()); + return $this->view->render($response, 'widget/error.html.twig', [ + 'message' => $message, + ]); + } + /** * Agrège les montants de tous les streams d'un event via le cache par stream. */ @@ -87,7 +95,8 @@ private function aggregateEventStreams(array $streams, array $cacheData, bool $t $stream->organization_slug, $stream->form_slug, $streamCache['amount'], - $streamCache['continuation_token'] + $streamCache['continuation_token'], + $stream->form_type ?? 'Donation' ); $streamCache['amount'] = $result['amount']; @@ -145,6 +154,7 @@ private function fetchStreamDonationData(string $streamGuid): array $charityStream->form_slug, $cacheData['amount'], $cacheData['continuation_token'], + $charityStream->form_type ?? 'Donation', ); if ($cacheData['continuation_token'] !== $result['continuation_token'] @@ -234,6 +244,7 @@ private function fetchStreamCardData(string $streamGuid): array $charityStream->form_slug, $cacheData['amount'], $cacheData['continuation_token'], + $charityStream->form_type ?? 'Donation', ); $newDonors = count($result['donations'] ?? []); @@ -302,31 +313,35 @@ private function fetchEventCardData(string $eventGuid): array public function widgetEventDonation(Request $request, Response $response, array $args): Response { - $eventGuid = $this->requireIdArg($args, 'Event'); + try { + $eventGuid = $this->requireIdArg($args, 'Event'); - $donationGoalWidget = $this->widgetRepository->selectDonationWidgetByGuid(null, $eventGuid); - if (!$donationGoalWidget) { - throw new Exception("Aucun widget trouvé pour le Event ID fourni."); - } + $donationGoalWidget = $this->widgetRepository->selectDonationWidgetByGuid(null, $eventGuid); + if (!$donationGoalWidget) { + throw new Exception("Aucun widget trouvé pour le Event ID fourni."); + } - try { - $data = $this->fetchEventDonationData($eventGuid); - $currentAmount = $data['cacheData']['amount']; - $event = $data['event']; + try { + $data = $this->fetchEventDonationData($eventGuid); + $currentAmount = $data['cacheData']['amount']; + $event = $data['event']; + } catch (Exception $e) { + error_log('[WidgetEventDonation] Erreur API init pour event ' . $eventGuid . ' : ' . $e->getMessage()); + $event = $this->eventRepository->selectByGuid($eventGuid); + $cacheData = $this->widgetRepository->selectEventDonationWidgetCacheData($event); + $currentAmount = $cacheData['amount'] ?? 0; + } + + return $this->view->render($response, 'widget/donation.html.twig', [ + 'donationGoalWidget' => $donationGoalWidget, + 'currentAmount' => $currentAmount, + 'goal' => $event->goal, + 'event' => 1, + 'isTestMode' => (bool) $event->is_test_mode, + ]); } catch (Exception $e) { - error_log('[WidgetEventDonation] Erreur API init pour event ' . $eventGuid . ' : ' . $e->getMessage()); - $event = $this->eventRepository->selectByGuid($eventGuid); - $cacheData = $this->widgetRepository->selectEventDonationWidgetCacheData($event); - $currentAmount = $cacheData['amount'] ?? 0; - } - - return $this->view->render($response, 'widget/donation.html.twig', [ - 'donationGoalWidget' => $donationGoalWidget, - 'currentAmount' => $currentAmount, - 'goal' => $event->goal, - 'event' => 1, - 'isTestMode' => (bool) $event->is_test_mode, - ]); + return $this->renderWidgetError($response, 'Impossible de charger le widget de don.', $e); + } } public function widgetEventDonationFetch(Request $request, Response $response, array $args): Response @@ -353,55 +368,60 @@ public function widgetEventDonationFetch(Request $request, Response $response, a public function widgetAlert(Request $request, Response $response, array $args): Response { - $charityStreamId = $this->requireIdArg($args, 'Charity Stream'); + try { + $charityStreamId = $this->requireIdArg($args, 'Charity Stream'); - $alertBoxWidget = $this->widgetRepository->selectAlertWidgetByGuid($charityStreamId); - if (!$alertBoxWidget) { - throw new Exception("Aucun widget trouvé pour le Charity Stream ID fourni."); - } + $alertBoxWidget = $this->widgetRepository->selectAlertWidgetByGuid($charityStreamId); + if (!$alertBoxWidget) { + throw new Exception("Aucun widget trouvé pour le Charity Stream ID fourni."); + } - $charityStream = $this->streamRepository->selectByGuid($charityStreamId); - if (!$charityStream) { - throw new Exception("Charity Stream non trouvé."); - } + $charityStream = $this->streamRepository->selectByGuid($charityStreamId); + if (!$charityStream) { + throw new Exception("Charity Stream non trouvé."); + } - // En mode test, on ne fait pas d'appel API pour l'init - if (!$charityStream->is_test_mode) { - $cacheData = $this->widgetRepository->selectAlertWidgetCacheData($charityStream) - ?? ['continuation_token' => '']; - - if (!$this->widgetRepository->isCacheFresh($cacheData, $this->cacheTtl)) { - try { - $result = $this->apiWrapper->getAllOrders( - $charityStream->organization_slug, - $charityStream->form_slug, - 0, - $cacheData['continuation_token'], - ); - - if ($cacheData['continuation_token'] !== $result['continuation_token']) { - $this->widgetRepository->updateAlertWidgetCacheData($charityStream->guid, [ - 'continuation_token' => $result['continuation_token'], - ]); - } else { - $this->widgetRepository->updateAlertWidgetCacheData($charityStream->guid, [ - 'continuation_token' => $cacheData['continuation_token'], - ]); + // En mode test, on ne fait pas d'appel API pour l'init + if (!$charityStream->is_test_mode) { + $cacheData = $this->widgetRepository->selectAlertWidgetCacheData($charityStream) + ?? ['continuation_token' => '']; + + if (!$this->widgetRepository->isCacheFresh($cacheData, $this->cacheTtl)) { + try { + $result = $this->apiWrapper->getAllOrders( + $charityStream->organization_slug, + $charityStream->form_slug, + 0, + $cacheData['continuation_token'], + $charityStream->form_type ?? 'Donation', + ); + + if ($cacheData['continuation_token'] !== $result['continuation_token']) { + $this->widgetRepository->updateAlertWidgetCacheData($charityStream->guid, [ + 'continuation_token' => $result['continuation_token'], + ]); + } else { + $this->widgetRepository->updateAlertWidgetCacheData($charityStream->guid, [ + 'continuation_token' => $cacheData['continuation_token'], + ]); + } + } catch (Exception $e) { + // Token invalide ou erreur API : on rend le widget avec le cache existant + // Le polling (fetch) réessaiera automatiquement + error_log('[WidgetAlert] Erreur API init pour stream ' . $charityStream->guid . ' : ' . $e->getMessage()); } - } catch (Exception $e) { - // Token invalide ou erreur API : on rend le widget avec le cache existant - // Le polling (fetch) réessaiera automatiquement - error_log('[WidgetAlert] Erreur API init pour stream ' . $charityStream->guid . ' : ' . $e->getMessage()); } } - } - return $this->view->render($response, 'widget/alert.html.twig', [ - 'alertBoxWidget' => $alertBoxWidget, - 'alertBoxWidgetPictureUrl' => $this->fileManager->getPictureUrl($alertBoxWidget->image), - 'alertBoxWidgetSoundUrl' => $this->fileManager->getSoundUrl($alertBoxWidget->sound), - 'isTestMode' => (bool) $charityStream->is_test_mode, - ]); + return $this->view->render($response, 'widget/alert.html.twig', [ + 'alertBoxWidget' => $alertBoxWidget, + 'alertBoxWidgetPictureUrl' => $this->fileManager->getPictureUrl($alertBoxWidget->image), + 'alertBoxWidgetSoundUrl' => $this->fileManager->getSoundUrl($alertBoxWidget->sound), + 'isTestMode' => (bool) $charityStream->is_test_mode, + ]); + } catch (Exception $e) { + return $this->renderWidgetError($response, 'Impossible de charger le widget d\'alerte.', $e); + } } public function widgetAlertFetch(Request $request, Response $response, array $args): Response @@ -442,7 +462,8 @@ public function widgetAlertFetch(Request $request, Response $response, array $ar $charityStream->organization_slug, $charityStream->form_slug, 0, - $cacheData['continuation_token'] + $cacheData['continuation_token'], + $charityStream->form_type ?? 'Donation' ); if ($cacheData['continuation_token'] !== $result['continuation_token']) { @@ -471,32 +492,36 @@ public function widgetAlertFetch(Request $request, Response $response, array $ar public function widgetDonation(Request $request, Response $response, array $args): Response { - $streamGuid = $this->requireIdArg($args, 'Charity Stream'); + try { + $streamGuid = $this->requireIdArg($args, 'Charity Stream'); - $donationGoalWidget = $this->widgetRepository->selectDonationWidgetByGuid($streamGuid, null); - if (!$donationGoalWidget) { - throw new Exception("Aucun widget trouvé pour le Charity Stream ID fourni."); - } + $donationGoalWidget = $this->widgetRepository->selectDonationWidgetByGuid($streamGuid, null); + if (!$donationGoalWidget) { + throw new Exception("Aucun widget trouvé pour le Charity Stream ID fourni."); + } - try { - $data = $this->fetchStreamDonationData($streamGuid); - $currentAmount = $data['result']['amount']; - $stream = $data['stream']; + try { + $data = $this->fetchStreamDonationData($streamGuid); + $currentAmount = $data['result']['amount']; + $stream = $data['stream']; + } catch (Exception $e) { + // Token invalide ou erreur API : on rend le widget avec le cache existant + error_log('[WidgetDonation] Erreur API init pour stream ' . $streamGuid . ' : ' . $e->getMessage()); + $stream = $this->streamRepository->selectByGuid($streamGuid); + $cacheData = $this->widgetRepository->selectStreamDonationWidgetCacheData($stream); + $currentAmount = $cacheData['amount'] ?? 0; + } + + return $this->view->render($response, 'widget/donation.html.twig', [ + 'donationGoalWidget' => $donationGoalWidget, + 'currentAmount' => $currentAmount, + 'goal' => $stream->goal, + 'stream' => 1, + 'isTestMode' => (bool) $stream->is_test_mode, + ]); } catch (Exception $e) { - // Token invalide ou erreur API : on rend le widget avec le cache existant - error_log('[WidgetDonation] Erreur API init pour stream ' . $streamGuid . ' : ' . $e->getMessage()); - $stream = $this->streamRepository->selectByGuid($streamGuid); - $cacheData = $this->widgetRepository->selectStreamDonationWidgetCacheData($stream); - $currentAmount = $cacheData['amount'] ?? 0; - } - - return $this->view->render($response, 'widget/donation.html.twig', [ - 'donationGoalWidget' => $donationGoalWidget, - 'currentAmount' => $currentAmount, - 'goal' => $stream->goal, - 'stream' => 1, - 'isTestMode' => (bool) $stream->is_test_mode, - ]); + return $this->renderWidgetError($response, 'Impossible de charger le widget de don.', $e); + } } public function widgetDonationFetch(Request $request, Response $response, array $args): Response @@ -528,37 +553,47 @@ public function widgetDonationFetch(Request $request, Response $response, array public function widgetStreamCard(Request $request, Response $response, array $args): Response { - $streamGuid = $this->requireIdArg($args, 'Charity Stream'); + try { + $streamGuid = $this->requireIdArg($args, 'Charity Stream'); - $cardWidget = $this->widgetRepository->selectCardWidgetByGuid($streamGuid, null); - if (!$cardWidget) { - throw new Exception("Aucun widget card trouvé pour le Charity Stream ID fourni."); - } + $cardWidget = $this->widgetRepository->selectCardWidgetByGuid($streamGuid, null); + if (!$cardWidget) { + throw new Exception("Aucun widget card trouvé pour le Charity Stream ID fourni."); + } - try { - $data = $this->fetchStreamCardData($streamGuid); - $currentAmount = $data['amount']; - $donors = $data['donors']; - $stream = $data['stream']; + try { + $data = $this->fetchStreamCardData($streamGuid); + $currentAmount = $data['amount']; + $donors = $data['donors']; + $stream = $data['stream']; + } catch (Exception $e) { + // Token invalide ou erreur API : on rend le widget avec le cache existant + error_log('[WidgetCard] Erreur API init pour stream ' . $streamGuid . ' : ' . $e->getMessage()); + $stream = $this->streamRepository->selectByGuid($streamGuid); + $cacheData = $this->widgetRepository->selectStreamCardWidgetCacheData($stream); + $currentAmount = $cacheData['amount'] ?? 0; + $donors = $cacheData['donors'] ?? 0; + } + + $formTypeUrlSegment = ($stream->form_type === 'CrowdFunding') ? 'collectes' : 'formulaires'; + $donationUrl = ($_SERVER['HA_URL'] ?? 'https://www.helloasso.com') + . '/associations/' . $stream->organization_slug + . '/' . $formTypeUrlSegment . '/' . $stream->form_slug; + + return $this->view->render($response, 'widget/card.html.twig', [ + 'cardWidget' => $cardWidget, + 'cardWidgetPictureUrl' => $cardWidget->image ? $this->fileManager->getPictureUrl($cardWidget->image) : null, + 'currentAmount' => $currentAmount, + 'donorCount' => $donors, + 'percentage' => $this->calculatePercentage($currentAmount, $stream->goal), + 'goal' => $stream->goal ?: 1, + 'stream' => 1, + 'isTestMode' => (bool) $stream->is_test_mode, + 'donationUrl' => $donationUrl, + ]); } catch (Exception $e) { - // Token invalide ou erreur API : on rend le widget avec le cache existant - error_log('[WidgetCard] Erreur API init pour stream ' . $streamGuid . ' : ' . $e->getMessage()); - $stream = $this->streamRepository->selectByGuid($streamGuid); - $cacheData = $this->widgetRepository->selectStreamCardWidgetCacheData($stream); - $currentAmount = $cacheData['amount'] ?? 0; - $donors = $cacheData['donors'] ?? 0; - } - - return $this->view->render($response, 'widget/card.html.twig', [ - 'cardWidget' => $cardWidget, - 'cardWidgetPictureUrl' => $cardWidget->image ? $this->fileManager->getPictureUrl($cardWidget->image) : null, - 'currentAmount' => $currentAmount, - 'donorCount' => $donors, - 'percentage' => $this->calculatePercentage($currentAmount, $stream->goal), - 'goal' => $stream->goal ?: 1, - 'stream' => 1, - 'isTestMode' => (bool) $stream->is_test_mode, - ]); + return $this->renderWidgetError($response, 'Impossible de charger le widget carte.', $e); + } } public function widgetStreamCardFetch(Request $request, Response $response, array $args): Response @@ -585,36 +620,40 @@ public function widgetStreamCardFetch(Request $request, Response $response, arra public function widgetEventCard(Request $request, Response $response, array $args): Response { - $eventGuid = $this->requireIdArg($args, 'Event'); + try { + $eventGuid = $this->requireIdArg($args, 'Event'); - $cardWidget = $this->widgetRepository->selectCardWidgetByGuid(null, $eventGuid); - if (!$cardWidget) { - throw new Exception("Aucun widget card trouvé pour le Event ID fourni."); - } + $cardWidget = $this->widgetRepository->selectCardWidgetByGuid(null, $eventGuid); + if (!$cardWidget) { + throw new Exception("Aucun widget card trouvé pour le Event ID fourni."); + } - try { - $data = $this->fetchEventCardData($eventGuid); - $currentAmount = $data['amount']; - $donors = $data['donors']; - $event = $data['event']; + try { + $data = $this->fetchEventCardData($eventGuid); + $currentAmount = $data['amount']; + $donors = $data['donors']; + $event = $data['event']; + } catch (Exception $e) { + error_log('[WidgetEventCard] Erreur API init pour event ' . $eventGuid . ' : ' . $e->getMessage()); + $event = $this->eventRepository->selectByGuid($eventGuid); + $cacheData = $this->widgetRepository->selectEventCardWidgetCacheData($event); + $currentAmount = $cacheData['amount'] ?? 0; + $donors = $cacheData['donors'] ?? 0; + } + + return $this->view->render($response, 'widget/card.html.twig', [ + 'cardWidget' => $cardWidget, + 'cardWidgetPictureUrl' => $cardWidget->image ? $this->fileManager->getPictureUrl($cardWidget->image) : null, + 'currentAmount' => $currentAmount, + 'donorCount' => $donors, + 'percentage' => $this->calculatePercentage($currentAmount, $event->goal), + 'goal' => $event->goal ?: 1, + 'event' => 1, + 'isTestMode' => (bool) $event->is_test_mode, + ]); } catch (Exception $e) { - error_log('[WidgetEventCard] Erreur API init pour event ' . $eventGuid . ' : ' . $e->getMessage()); - $event = $this->eventRepository->selectByGuid($eventGuid); - $cacheData = $this->widgetRepository->selectEventCardWidgetCacheData($event); - $currentAmount = $cacheData['amount'] ?? 0; - $donors = $cacheData['donors'] ?? 0; - } - - return $this->view->render($response, 'widget/card.html.twig', [ - 'cardWidget' => $cardWidget, - 'cardWidgetPictureUrl' => $cardWidget->image ? $this->fileManager->getPictureUrl($cardWidget->image) : null, - 'currentAmount' => $currentAmount, - 'donorCount' => $donors, - 'percentage' => $this->calculatePercentage($currentAmount, $event->goal), - 'goal' => $event->goal ?: 1, - 'event' => 1, - 'isTestMode' => (bool) $event->is_test_mode, - ]); + return $this->renderWidgetError($response, 'Impossible de charger le widget carte.', $e); + } } public function widgetEventCardFetch(Request $request, Response $response, array $args): Response diff --git a/src/Models/Stream.php b/src/Models/Stream.php index a2be287..2377a83 100644 --- a/src/Models/Stream.php +++ b/src/Models/Stream.php @@ -10,6 +10,7 @@ class Stream public $title; public $goal; public $form_slug; + public $form_type = 'Donation'; public $organization_slug; public $creation_date; public $last_update; diff --git a/src/Repositories/StreamRepository.php b/src/Repositories/StreamRepository.php index b9e9e4c..1d97a0b 100644 --- a/src/Repositories/StreamRepository.php +++ b/src/Repositories/StreamRepository.php @@ -109,19 +109,20 @@ public function selectByUserAndGuid(User $user, string $guid): ?Stream return $stream ?: null; } - public function insert(string $form_slug, string $organization_slug, string $title, ?int $parent = null): Stream + public function insert(string $form_slug, string $organization_slug, string $title, ?int $parent = null, string $form_type = 'Donation'): Stream { $guid = bin2hex(random_bytes(16)); $this->pdo->beginTransaction(); try { - $query = 'INSERT INTO ' . $this->prefix . 'charity_stream (guid, form_slug, organization_slug, title, charity_event_id) - VALUES (:guid, :form_slug, :organization_slug, :title, :charity_event_id)'; + $query = 'INSERT INTO ' . $this->prefix . 'charity_stream (guid, form_slug, form_type, organization_slug, title, charity_event_id) + VALUES (:guid, :form_slug, :form_type, :organization_slug, :title, :charity_event_id)'; $stmt = $this->pdo->prepare($query); $stmt->execute([ ':guid' => $guid, ':form_slug' => $form_slug, + ':form_type' => $form_type, ':organization_slug' => $organization_slug, ':title' => $title, ':charity_event_id' => $parent @@ -158,6 +159,7 @@ public function insert(string $form_slug, string $organization_slug, string $tit $stream->id = $id; $stream->guid = $guid; $stream->form_slug = $form_slug; + $stream->form_type = $form_type; $stream->organization_slug = $organization_slug; $stream->title = $title; return $stream; diff --git a/src/Services/ApiWrapper.php b/src/Services/ApiWrapper.php index 2532a3b..a720803 100644 --- a/src/Services/ApiWrapper.php +++ b/src/Services/ApiWrapper.php @@ -363,31 +363,49 @@ public function generateAuthorizationUrl(?string $organizationSlug, ?string $red } /** - * Récupère la liste des formulaires de don d'une organisation. + * Récupère la liste des formulaires d'une organisation pour les types donnés. * * @param string $organizationSlug + * @param array $formTypes Liste des types de formulaires à récupérer (ex: ['Donation', 'CrowdFunding']) * @return array */ - public function getDonationForms(string $organizationSlug): array + public function getOrganizationForms(string $organizationSlug, array $formTypes = ['Donation', 'CrowdFunding']): array { $tokenData = $this->getOrganizationAccessToken($organizationSlug); - $response = $this->httpRequest('GET', "{$this->apiUrl}/organizations/{$organizationSlug}/forms", [ - 'query' => [ - 'formTypes' => 'Donation', - 'pageSize' => 50, - ], + // Construire la query string manuellement car Guzzle sérialise les arrays + // avec des indices PHP (formTypes[0]=...) que l'API HelloAsso ne supporte pas. + // L'API attend : formTypes=Donation&formTypes=CrowdFunding + $queryParts = []; + foreach ($formTypes as $type) { + $queryParts[] = 'formTypes=' . urlencode($type); + } + $queryParts[] = 'pageSize=50'; + $queryString = implode('&', $queryParts); + + $response = $this->httpRequest('GET', "{$this->apiUrl}/organizations/{$organizationSlug}/forms?{$queryString}", [ 'headers' => [ 'Authorization' => 'Bearer ' . $tokenData->access_token, 'accept' => 'application/json', ], - ], "la récupération des formulaires de don pour {$organizationSlug}"); + ], "la récupération des formulaires pour {$organizationSlug}"); $data = $this->decodeJsonResponse($response); return $data['data'] ?? []; } + /** + * Récupère la liste des formulaires de don d'une organisation. + * + * @param string $organizationSlug + * @return array + */ + public function getDonationForms(string $organizationSlug): array + { + return $this->getOrganizationForms($organizationSlug, ['Donation']); + } + /** * Configure le domaine du client API pour une organisation donnée en utilisant un token d'accès valide. * @@ -480,16 +498,18 @@ public function exchangeAuthorizationCode(string $code, string $redirectUri, str * @param [type] $continuationToken * @return array */ - private function getDonationFormOrders(string $organizationSlug, string $donationSlug, string $accessToken, ?string $continuationToken = null): array + private function getDonationFormOrders(string $organizationSlug, string $donationSlug, string $accessToken, ?string $continuationToken = null, string $formType = 'Donation'): array { $query = ['withDetails' => 'true', 'sortOrder' => 'asc', 'pageSize' => 100]; if ($continuationToken) { $query['continuationToken'] = $continuationToken; } + $formTypePath = $formType ?: 'Donation'; + $response = $this->httpRequest( 'GET', - "{$this->apiUrl}/organizations/{$organizationSlug}/forms/donation/{$donationSlug}/orders", + "{$this->apiUrl}/organizations/{$organizationSlug}/forms/{$formTypePath}/{$donationSlug}/orders", [ 'query' => $query, 'headers' => [ @@ -512,7 +532,7 @@ private function getDonationFormOrders(string $organizationSlug, string $donatio * @param [type] $continuationToken * @return array */ - public function getAllOrders(string $organizationSlug, string $formSlug, int $currentAmount = 0, ?string $continuationToken = null): array + public function getAllOrders(string $organizationSlug, string $formSlug, int $currentAmount = 0, ?string $continuationToken = null, string $formType = 'Donation'): array { $previousToken = ''; $donations = []; @@ -539,7 +559,8 @@ public function getAllOrders(string $organizationSlug, string $formSlug, int $cu $organizationSlug, $formSlug, $organizationAccessToken->access_token, - $continuationToken + $continuationToken, + $formType ); if (!isset($formOrdersData['data'])) { diff --git a/src/views/stream/_modal-create-stream.html.twig b/src/views/stream/_modal-create-stream.html.twig index 7ed26f3..eb52bf0 100644 --- a/src/views/stream/_modal-create-stream.html.twig +++ b/src/views/stream/_modal-create-stream.html.twig @@ -88,15 +88,24 @@
{{ message|default('Une erreur est survenue lors du chargement du widget.') }}
+