From 8dd856a471914f0ddac77206b3f71c5b10fcfafe Mon Sep 17 00:00:00 2001 From: Maxime Date: Tue, 21 Apr 2026 15:11:42 +0200 Subject: [PATCH 1/6] feat: add bluesky_posts field to Talk model and migration --- .../20260421000000_talk_bluesky_posts.php | 13 +++++++ .../Event/Model/Repository/TalkRepository.php | 5 +++ sources/AppBundle/Event/Model/Talk.php | 36 +++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 db/migrations/20260421000000_talk_bluesky_posts.php diff --git a/db/migrations/20260421000000_talk_bluesky_posts.php b/db/migrations/20260421000000_talk_bluesky_posts.php new file mode 100644 index 000000000..e59e5eb29 --- /dev/null +++ b/db/migrations/20260421000000_talk_bluesky_posts.php @@ -0,0 +1,13 @@ +execute("ALTER TABLE `afup_sessions` ADD `bluesky_posts` text DEFAULT NULL AFTER `tweets`"); + } +} diff --git a/sources/AppBundle/Event/Model/Repository/TalkRepository.php b/sources/AppBundle/Event/Model/Repository/TalkRepository.php index 513127fa3..9130c7f94 100644 --- a/sources/AppBundle/Event/Model/Repository/TalkRepository.php +++ b/sources/AppBundle/Event/Model/Repository/TalkRepository.php @@ -567,6 +567,11 @@ public static function initMetadata(SerializerFactoryInterface $serializerFactor 'fieldName' => 'tweets', 'type' => 'string', ]) + ->addField([ + 'columnName' => 'bluesky_posts', + 'fieldName' => 'blueskyPosts', + 'type' => 'string', + ]) ->addField([ 'columnName' => 'transcript', 'fieldName' => 'transcript', diff --git a/sources/AppBundle/Event/Model/Talk.php b/sources/AppBundle/Event/Model/Talk.php index df57ca4ea..49ae8b264 100644 --- a/sources/AppBundle/Event/Model/Talk.php +++ b/sources/AppBundle/Event/Model/Talk.php @@ -83,6 +83,8 @@ class Talk implements NotifyPropertyInterface private ?string $tweets = null; + private ?string $blueskyPosts = null; + private ?string $transcript = null; private ?string $verbatim = null; @@ -615,6 +617,40 @@ public function getTweetsHasArray(): array return $returnedTweets; } + public function getBlueskyPosts(): ?string + { + return $this->blueskyPosts; + } + + public function setBlueskyPosts(?string $blueskyPosts): self + { + $this->propertyChanged('blueskyPosts', $this->blueskyPosts, $blueskyPosts); + $this->blueskyPosts = $blueskyPosts; + + return $this; + } + + /** + * @return array + */ + public function getBlueskyPostsAsArray(): array + { + if (!$this->getBlueskyPosts()) { + return []; + } + $returnedPosts = []; + foreach (explode(PHP_EOL, $this->getBlueskyPosts()) as $post) { + $post = trim($post); + if ($post === '' || $post === '0') { + continue; + } + + $returnedPosts[] = $post; + } + + return $returnedPosts; + } + public function getHasAllowedToSharingWithLocalOffices(): bool { return $this->hasAllowedToSharingWithLocalOffices; From e664e25ee9cccde26da5d6f54cbf64f6c603b8fc Mon Sep 17 00:00:00 2001 From: Maxime Date: Tue, 21 Apr 2026 15:11:57 +0200 Subject: [PATCH 2/6] feat: add blueskyPosts field to Talk form --- sources/AppBundle/Event/Form/TalkAdminType.php | 4 ++++ templates/admin/talk/form.html.twig | 1 + 2 files changed, 5 insertions(+) diff --git a/sources/AppBundle/Event/Form/TalkAdminType.php b/sources/AppBundle/Event/Form/TalkAdminType.php index 69f454754..cedf80916 100644 --- a/sources/AppBundle/Event/Form/TalkAdminType.php +++ b/sources/AppBundle/Event/Form/TalkAdminType.php @@ -77,6 +77,10 @@ public function buildForm(FormBuilderInterface $builder, array $options): void 'label' => 'Tweets', 'required' => false, ]) + ->add('blueskyPosts', TextareaType::class, [ + 'label' => 'Posts Bluesky', + 'required' => false, + ]) ->add('submittedOn', DateTimeType::class, [ 'label' => 'Date de soumission', ]) diff --git a/templates/admin/talk/form.html.twig b/templates/admin/talk/form.html.twig index 0e5a5e30e..440e74294 100644 --- a/templates/admin/talk/form.html.twig +++ b/templates/admin/talk/form.html.twig @@ -30,6 +30,7 @@ {{ form_row(form.interviewUrl) }} {{ form_row(form.languageCode) }} {{ form_row(form.tweets) }} + {{ form_row(form.blueskyPosts) }} {{ form_row(form.verbatim, {attr: {class: 'simplemde'}}) }}
From 9eda52f28922106fb08fd7b6eefc9d7f40e95dc8 Mon Sep 17 00:00:00 2001 From: Maxime Date: Tue, 21 Apr 2026 15:12:03 +0200 Subject: [PATCH 3/6] feat: add Bluesky posts embedding to Talk show page --- app/config/packages/http_client.yaml | 2 + .../Bluesky/BlueskyOembedClient.php | 42 +++++++++++++++++++ sources/AppBundle/Twig/TwigExtension.php | 6 +++ templates/site/talks/show.html.twig | 24 +++++++++++ 4 files changed, 74 insertions(+) create mode 100644 sources/AppBundle/SocialNetwork/Bluesky/BlueskyOembedClient.php diff --git a/app/config/packages/http_client.yaml b/app/config/packages/http_client.yaml index 6b931592b..99b4c1f4b 100644 --- a/app/config/packages/http_client.yaml +++ b/app/config/packages/http_client.yaml @@ -11,3 +11,5 @@ framework: Content-Type: 'application/json' http_client.bluesky: base_uri: 'https://bsky.social' + http_client.bluesky_embed: + base_uri: 'https://embed.bsky.app' diff --git a/sources/AppBundle/SocialNetwork/Bluesky/BlueskyOembedClient.php b/sources/AppBundle/SocialNetwork/Bluesky/BlueskyOembedClient.php new file mode 100644 index 000000000..7b94c0ae6 --- /dev/null +++ b/sources/AppBundle/SocialNetwork/Bluesky/BlueskyOembedClient.php @@ -0,0 +1,42 @@ +cache->getItem('bluesky_oembed_' . md5($url)); + + if (!$cacheItem->isHit()) { + try { + $response = $this->httpClient->request('GET', '/oembed', [ + 'query' => ['url' => $url, 'format' => 'json'], + ]); + $data = $response->toArray(); + // Strip the embed.js +
+ {% endif %} + {% if comments|length > 0 %} {% include 'common/star.html.twig' %}
From c247baa19595807cb89be9e644ff3e2e1f0e7509 Mon Sep 17 00:00:00 2001 From: Maxime Date: Tue, 21 Apr 2026 15:12:18 +0200 Subject: [PATCH 4/6] feat: add Bluesky posts support to Session seeder and update related tests --- db/seeds/Session.php | 1 + .../behat/features/Admin/Events/Conferences.feature | 12 ++++++++++++ tests/behat/features/PublicSite/Talks.feature | 6 ++++++ 3 files changed, 19 insertions(+) diff --git a/db/seeds/Session.php b/db/seeds/Session.php index 883939f95..ec31edc74 100644 --- a/db/seeds/Session.php +++ b/db/seeds/Session.php @@ -79,6 +79,7 @@ public function run(): void 'joindin' => 24138, 'date_publication' => (new \DateTime())->modify('-1 days')->format('Y-m-d H:i:s'), 'has_allowed_to_sharing_with_local_offices' => 1, + 'bluesky_posts' => 'https://bsky.app/profile/us.theguardian.com/post/3mjxal5k3rs2t', ], [ 'session_id' => 3, diff --git a/tests/behat/features/Admin/Events/Conferences.feature b/tests/behat/features/Admin/Events/Conferences.feature index cb22925b2..042d45f86 100644 --- a/tests/behat/features/Admin/Events/Conferences.feature +++ b/tests/behat/features/Admin/Events/Conferences.feature @@ -36,6 +36,18 @@ Feature: Administration - Évènements - Conférences And I should see "Une autre conference" And I should see "Adrien Gallou" + @reloadDbWithTestData + Scenario: Ajout de posts Bluesky à une conférence + Given I am logged in as admin and on the Administration + And I follow "Conférences" + When I follow the button of tooltip "Modifier la conférence Jouons tous ensemble à un petit jeu" + Then I fill in "talk_admin[blueskyPosts]" with "https://bsky.app/profile/afup.bsky.social/post/3lnuwy2cces2g" + And I press "Soumettre" + Then I should see "La conférence a été modifiée" + When I go to "/talks/1-jouons-tous-ensemble-a-un-petit-jeu" + Then I should see "Posts Bluesky" + And the response should contain "https://bsky.app/profile/afup.bsky.social/post/3lnuwy2cces2g" + @reloadDbWithTestData Scenario: Modification d'une conférence Given I am logged in as admin and on the Administration diff --git a/tests/behat/features/PublicSite/Talks.feature b/tests/behat/features/PublicSite/Talks.feature index 5fa9c018b..6baab90ce 100644 --- a/tests/behat/features/PublicSite/Talks.feature +++ b/tests/behat/features/PublicSite/Talks.feature @@ -21,6 +21,12 @@ Feature: Site Public - Talks And the response should contain "" + @reloadDbWithTestData + Scenario: Affichage des posts Bluesky sur la page d'un talk + When I go to "/talks/2-rest-ou-graphql-exemples-illustres-avec-symfony-et-api-platform" + Then I should see "Posts Bluesky" + And the response should contain "bsky.app/profile/us.theguardian.com/post/3mjxal5k3rs2t" + @reloadDbWithTestData Scenario: Accès à la liste des vidéos d'un speaker When I go to "/talks/?fR[speakers.label][0]=Un Speaker" From 4604607ac1ac92a53874524c8305c2a10b816f72 Mon Sep 17 00:00:00 2001 From: Maxime Date: Wed, 22 Apr 2026 08:56:40 +0200 Subject: [PATCH 5/6] fix: assert on post rkey instead of handle URL in Bluesky Behat tests oEmbed API resolves handles to DIDs in its HTML output, so handle-based URLs are not present in the response. --- tests/behat/features/Admin/Events/Conferences.feature | 2 +- tests/behat/features/PublicSite/Talks.feature | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/behat/features/Admin/Events/Conferences.feature b/tests/behat/features/Admin/Events/Conferences.feature index 042d45f86..4bab01d01 100644 --- a/tests/behat/features/Admin/Events/Conferences.feature +++ b/tests/behat/features/Admin/Events/Conferences.feature @@ -46,7 +46,7 @@ Feature: Administration - Évènements - Conférences Then I should see "La conférence a été modifiée" When I go to "/talks/1-jouons-tous-ensemble-a-un-petit-jeu" Then I should see "Posts Bluesky" - And the response should contain "https://bsky.app/profile/afup.bsky.social/post/3lnuwy2cces2g" + And the response should contain "3lnuwy2cces2g" @reloadDbWithTestData Scenario: Modification d'une conférence diff --git a/tests/behat/features/PublicSite/Talks.feature b/tests/behat/features/PublicSite/Talks.feature index 6baab90ce..c0abf0772 100644 --- a/tests/behat/features/PublicSite/Talks.feature +++ b/tests/behat/features/PublicSite/Talks.feature @@ -25,7 +25,7 @@ Feature: Site Public - Talks Scenario: Affichage des posts Bluesky sur la page d'un talk When I go to "/talks/2-rest-ou-graphql-exemples-illustres-avec-symfony-et-api-platform" Then I should see "Posts Bluesky" - And the response should contain "bsky.app/profile/us.theguardian.com/post/3mjxal5k3rs2t" + And the response should contain "3mjxal5k3rs2t" @reloadDbWithTestData Scenario: Accès à la liste des vidéos d'un speaker From f8bd3fec69e2b95987c169a21b4f2787aebe32e8 Mon Sep 17 00:00:00 2001 From: Maxime Date: Wed, 22 Apr 2026 09:33:51 +0200 Subject: [PATCH 6/6] fix: use AFUP-controlled Bluesky posts in seeds and Behat tests --- db/seeds/Session.php | 2 +- tests/behat/features/Admin/Events/Conferences.feature | 4 ++-- tests/behat/features/PublicSite/Talks.feature | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/db/seeds/Session.php b/db/seeds/Session.php index ec31edc74..de07cbe90 100644 --- a/db/seeds/Session.php +++ b/db/seeds/Session.php @@ -79,7 +79,7 @@ public function run(): void 'joindin' => 24138, 'date_publication' => (new \DateTime())->modify('-1 days')->format('Y-m-d H:i:s'), 'has_allowed_to_sharing_with_local_offices' => 1, - 'bluesky_posts' => 'https://bsky.app/profile/us.theguardian.com/post/3mjxal5k3rs2t', + 'bluesky_posts' => 'https://bsky.app/profile/afup.org/post/3mjk3hmqxxe2d', ], [ 'session_id' => 3, diff --git a/tests/behat/features/Admin/Events/Conferences.feature b/tests/behat/features/Admin/Events/Conferences.feature index 4bab01d01..7b677e68b 100644 --- a/tests/behat/features/Admin/Events/Conferences.feature +++ b/tests/behat/features/Admin/Events/Conferences.feature @@ -41,12 +41,12 @@ Feature: Administration - Évènements - Conférences Given I am logged in as admin and on the Administration And I follow "Conférences" When I follow the button of tooltip "Modifier la conférence Jouons tous ensemble à un petit jeu" - Then I fill in "talk_admin[blueskyPosts]" with "https://bsky.app/profile/afup.bsky.social/post/3lnuwy2cces2g" + Then I fill in "talk_admin[blueskyPosts]" with "https://bsky.app/profile/afup.org/post/3mjmmwpp34f2r" And I press "Soumettre" Then I should see "La conférence a été modifiée" When I go to "/talks/1-jouons-tous-ensemble-a-un-petit-jeu" Then I should see "Posts Bluesky" - And the response should contain "3lnuwy2cces2g" + And the response should contain "3mjmmwpp34f2r" @reloadDbWithTestData Scenario: Modification d'une conférence diff --git a/tests/behat/features/PublicSite/Talks.feature b/tests/behat/features/PublicSite/Talks.feature index c0abf0772..db8a89bac 100644 --- a/tests/behat/features/PublicSite/Talks.feature +++ b/tests/behat/features/PublicSite/Talks.feature @@ -25,7 +25,7 @@ Feature: Site Public - Talks Scenario: Affichage des posts Bluesky sur la page d'un talk When I go to "/talks/2-rest-ou-graphql-exemples-illustres-avec-symfony-et-api-platform" Then I should see "Posts Bluesky" - And the response should contain "3mjxal5k3rs2t" + And the response should contain "3mjk3hmqxxe2d" @reloadDbWithTestData Scenario: Accès à la liste des vidéos d'un speaker