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/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/db/seeds/Session.php b/db/seeds/Session.php index 883939f95..de07cbe90 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/afup.org/post/3mjk3hmqxxe2d', ], [ 'session_id' => 3, 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/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; 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' %}
diff --git a/tests/behat/features/Admin/Events/Conferences.feature b/tests/behat/features/Admin/Events/Conferences.feature index cb22925b2..7b677e68b 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.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 "3mjmmwpp34f2r" + @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..db8a89bac 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 "3mjk3hmqxxe2d" + @reloadDbWithTestData Scenario: Accès à la liste des vidéos d'un speaker When I go to "/talks/?fR[speakers.label][0]=Un Speaker"