From 01029b35b6fde95813e297c0562cacbb6fe27d6c Mon Sep 17 00:00:00 2001 From: Artem Dmitriiev <a.dmitriiev@1xinternet.de> Date: Wed, 12 Mar 2025 12:24:13 +0100 Subject: [PATCH 1/4] Issue #3512440 by a.dmitriiev: Support project browser 2.0 --- composer.json | 3 ++- src/Plugin/ProjectBrowserSource/Gitlab.php | 24 ++++++---------------- 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/composer.json b/composer.json index ab09267..9b24499 100644 --- a/composer.json +++ b/composer.json @@ -13,6 +13,7 @@ } ], "require": { - "drupal/core": "^10.3 || ^11.1" + "drupal/core": "^10.3 || ^11.1", + "drupal/project_browser": "^2.0" } } diff --git a/src/Plugin/ProjectBrowserSource/Gitlab.php b/src/Plugin/ProjectBrowserSource/Gitlab.php index dd7a61a..cb4fafd 100644 --- a/src/Plugin/ProjectBrowserSource/Gitlab.php +++ b/src/Plugin/ProjectBrowserSource/Gitlab.php @@ -4,6 +4,7 @@ namespace Drupal\project_browser_gitlab\Plugin\ProjectBrowserSource; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Drupal\Core\Url; use Drupal\project_browser\Plugin\ProjectBrowserSourceBase; use Drupal\project_browser\ProjectBrowser\Project; use Drupal\project_browser\ProjectBrowser\ProjectsResultsPage; @@ -161,14 +162,13 @@ class Gitlab extends ProjectBrowserSourceBase implements ContainerFactoryPluginI } $projects[] = new Project( - logo: $logo, + logo: $logo['file']['uri'] ? Url::fromUri($logo['file']['uri']) : NULL, isCompatible: TRUE, isCovered: TRUE, projectUsageTotal: 0, machineName: str_replace('/', '|', $project['path_with_namespace']), body: $project['description'] ? ['value' => $project['description']] : [], title: $project['name'] ?? '', - author: [], packageName: $project['path_with_namespace'], categories: $categories, type: ProjectType::Module, @@ -255,22 +255,10 @@ class Gitlab extends ProjectBrowserSourceBase implements ContainerFactoryPluginI */ public function getSortOptions(): array { return [ - 'created' => [ - 'id' => 'created', - 'text' => $this->t('Newest First'), - ], - 'a_z' => [ - 'id' => 'a_z', - 'text' => $this->t('A-Z'), - ], - 'z_a' => [ - 'id' => 'z_a', - 'text' => $this->t('Z-A'), - ], - 'updated' => [ - 'id' => 'updated', - 'text' => $this->t('Latest Updated First'), - ], + 'created' => $this->t('Newest First'), + 'a_z' => $this->t('A-Z'), + 'z_a' => $this->t('Z-A'), + 'updated' => $this->t('Latest Updated First'), ]; } -- GitLab From 38545c8d2d121b7e28e9fd06e809a4cc7264c056 Mon Sep 17 00:00:00 2001 From: Artem Dmitriiev <a.dmitriiev@1xinternet.de> Date: Wed, 12 Mar 2025 14:46:17 +0100 Subject: [PATCH 2/4] Populate also images array --- src/Plugin/ProjectBrowserSource/Gitlab.php | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/Plugin/ProjectBrowserSource/Gitlab.php b/src/Plugin/ProjectBrowserSource/Gitlab.php index cb4fafd..bba7072 100644 --- a/src/Plugin/ProjectBrowserSource/Gitlab.php +++ b/src/Plugin/ProjectBrowserSource/Gitlab.php @@ -143,15 +143,16 @@ class Gitlab extends ProjectBrowserSourceBase implements ContainerFactoryPluginI } foreach ($response['data'] ?? [] as $project) { - $logo = [ - 'file' => [ - 'uri' => $project['avatar_url'], - 'resource' => 'image', - ], - 'alt' => (string) $this->t('@name logo', [ - '@name' => $project['name'], - ]), - ]; + $images = []; + if (!empty($project['avatar_url'])) { + $logo = [ + 'file' => Url::fromUri($project['avatar_url']), + 'alt' => (string) $this->t('@name logo', [ + '@name' => $project['name'], + ]), + ]; + $images[] = $logo; + } $categories = []; foreach ($project['topics'] as $index => $topic) { @@ -162,7 +163,7 @@ class Gitlab extends ProjectBrowserSourceBase implements ContainerFactoryPluginI } $projects[] = new Project( - logo: $logo['file']['uri'] ? Url::fromUri($logo['file']['uri']) : NULL, + logo: $logo ? $logo['file'] : NULL, isCompatible: TRUE, isCovered: TRUE, projectUsageTotal: 0, @@ -172,6 +173,7 @@ class Gitlab extends ProjectBrowserSourceBase implements ContainerFactoryPluginI packageName: $project['path_with_namespace'], categories: $categories, type: ProjectType::Module, + images: $images, ); } -- GitLab From 4b5a5d93b4235d1166daaaf66d08f2afb2b818b2 Mon Sep 17 00:00:00 2001 From: Artem Dmitriiev <a.dmitriiev@1xinternet.de> Date: Wed, 12 Mar 2025 15:22:25 +0100 Subject: [PATCH 3/4] Add event to allow other modules to modify the project info --- src/Event/ProjectEvent.php | 74 ++++++++++++++++++++++ src/Plugin/ProjectBrowserSource/Gitlab.php | 44 ++++++++----- 2 files changed, 102 insertions(+), 16 deletions(-) create mode 100644 src/Event/ProjectEvent.php diff --git a/src/Event/ProjectEvent.php b/src/Event/ProjectEvent.php new file mode 100644 index 0000000..549a4a9 --- /dev/null +++ b/src/Event/ProjectEvent.php @@ -0,0 +1,74 @@ +<?php + +namespace Drupal\project_browser_gitlab\Event; + +use Drupal\Component\EventDispatcher\Event; +use Drupal\project_browser_gitlab\GitlabSourceInterface; + +/** + * Class for project event to modify the information from Gitlab API if needed. + */ +class ProjectEvent extends Event { + + /** + * The project info from Gitlab. + * + * @var array + */ + protected $project; + + /** + * The gitlab source. + * + * @var \Drupal\project_browser_gitlab\GitlabSourceInterface + */ + protected GitlabSourceInterface $gitlabSource; + + /** + * Constructs the event object. + * + * @param array $project + * The project info from Gitlab API response. + * @param \Drupal\project_browser_gitlab\GitlabSourceInterface $gitlab_source + * The Gitlab Source entity. + */ + public function __construct(array $project, GitlabSourceInterface $gitlab_source) { + $this->project = $project; + $this->gitlabSource = $gitlab_source; + } + + /** + * Gets the project info. + * + * @return array + * The project info. + */ + public function getProject() { + return $this->project; + } + + /** + * Gets the Gitlab Source entity. + * + * @return \Drupal\project_browser_gitlab\GitlabSourceInterface + * The Gitlab Source entity. + */ + public function getGitlabSource() { + return $this->gitlabSource; + } + + /** + * Sets the project. + * + * @param array $project + * The modified project. + * + * @return self + * The event object. + */ + public function setProject(array $project) { + $this->project = $project; + return $this; + } + +} diff --git a/src/Plugin/ProjectBrowserSource/Gitlab.php b/src/Plugin/ProjectBrowserSource/Gitlab.php index bba7072..b858096 100644 --- a/src/Plugin/ProjectBrowserSource/Gitlab.php +++ b/src/Plugin/ProjectBrowserSource/Gitlab.php @@ -10,10 +10,12 @@ use Drupal\project_browser\ProjectBrowser\Project; use Drupal\project_browser\ProjectBrowser\ProjectsResultsPage; use Drupal\project_browser\ProjectType; use Drupal\project_browser_gitlab\Entity\GitlabSource; +use Drupal\project_browser_gitlab\Event\ProjectEvent; use GuzzleHttp\ClientInterface; use GuzzleHttp\Exception\GuzzleException; use Psr\Log\LoggerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** * Project Browser Source Plugin for Gitlab. @@ -48,6 +50,13 @@ class Gitlab extends ProjectBrowserSourceBase implements ContainerFactoryPluginI */ protected GitlabSource $source; + /** + * The event dispatcher. + * + * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface + */ + protected EventDispatcherInterface $eventDispatcher; + /** * Constructor for the plugin. * @@ -60,15 +69,21 @@ class Gitlab extends ProjectBrowserSourceBase implements ContainerFactoryPluginI * @param \GuzzleHttp\ClientInterface $httpClient * The HTTP client. * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager - * The entity type manager. + * The entity type manager. + * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher + * The event dispatcher. * @param \Psr\Log\LoggerInterface $logger * A logger instance. + * + * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException + * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, ClientInterface $httpClient, EntityTypeManagerInterface $entity_type_manager, LoggerInterface $logger) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, ClientInterface $httpClient, EntityTypeManagerInterface $entity_type_manager, EventDispatcherInterface $event_dispatcher, LoggerInterface $logger) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->httpClient = $httpClient; $this->logger = $logger; $this->source = $entity_type_manager->getStorage('project_browser_gitlab_source')->load($plugin_definition['id']); + $this->eventDispatcher = $event_dispatcher; } /** @@ -81,11 +96,11 @@ class Gitlab extends ProjectBrowserSourceBase implements ContainerFactoryPluginI $plugin_definition, $container->get('http_client'), $container->get('entity_type.manager'), + $container->get('event_dispatcher'), $container->get('logger.factory')->get('project_browser'), ); } - /** * {@inheritdoc} * @param array $query @@ -143,15 +158,14 @@ class Gitlab extends ProjectBrowserSourceBase implements ContainerFactoryPluginI } foreach ($response['data'] ?? [] as $project) { - $images = []; + $project['type'] = ProjectType::Module; + // Allow other modules to modify the project info. + $event = new ProjectEvent($project, $this->source); + $this->eventDispatcher->dispatch($event); + $project = $event->getProject(); + $logo = NULL; if (!empty($project['avatar_url'])) { - $logo = [ - 'file' => Url::fromUri($project['avatar_url']), - 'alt' => (string) $this->t('@name logo', [ - '@name' => $project['name'], - ]), - ]; - $images[] = $logo; + $logo = Url::fromUri($project['avatar_url']); } $categories = []; @@ -161,19 +175,17 @@ class Gitlab extends ProjectBrowserSourceBase implements ContainerFactoryPluginI 'name' => $topic, ]; } - $projects[] = new Project( - logo: $logo ? $logo['file'] : NULL, + logo: $logo, isCompatible: TRUE, isCovered: TRUE, projectUsageTotal: 0, - machineName: str_replace('/', '|', $project['path_with_namespace']), + machineName: $project['path'], body: $project['description'] ? ['value' => $project['description']] : [], title: $project['name'] ?? '', packageName: $project['path_with_namespace'], categories: $categories, - type: ProjectType::Module, - images: $images, + type: $project['type'], ); } -- GitLab From ffce35358711061175c410dcf302dd70728dcc17 Mon Sep 17 00:00:00 2001 From: Artem Dmitriiev <a.dmitriiev@1xinternet.de> Date: Wed, 9 Apr 2025 17:58:02 +0200 Subject: [PATCH 4/4] Compatibility with project_browser 2.0.0-beta1 --- src/Plugin/ProjectBrowserSource/Gitlab.php | 38 +++++++++++++++------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/Plugin/ProjectBrowserSource/Gitlab.php b/src/Plugin/ProjectBrowserSource/Gitlab.php index b858096..6e8d80f 100644 --- a/src/Plugin/ProjectBrowserSource/Gitlab.php +++ b/src/Plugin/ProjectBrowserSource/Gitlab.php @@ -4,8 +4,12 @@ namespace Drupal\project_browser_gitlab\Plugin\ProjectBrowserSource; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Drupal\Core\StringTranslation\TranslatableMarkup; use Drupal\Core\Url; +use Drupal\project_browser\Attribute\ProjectBrowserSource; use Drupal\project_browser\Plugin\ProjectBrowserSourceBase; +use Drupal\project_browser\ProjectBrowser\Filter\MultipleChoiceFilter; +use Drupal\project_browser\ProjectBrowser\Filter\TextFilter; use Drupal\project_browser\ProjectBrowser\Project; use Drupal\project_browser\ProjectBrowser\ProjectsResultsPage; use Drupal\project_browser\ProjectType; @@ -19,14 +23,13 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** * Project Browser Source Plugin for Gitlab. - * - * @ProjectBrowserSource( - * id = "project_browser_gitlab", - * label = @Translation("Gitlab"), - * description = @Translation("Source plugin for Project Browser to search Gitlab."), - * deriver = "Drupal\project_browser_gitlab\Plugin\Derivative\GitlabDeriver", - * ) */ +#[ProjectBrowserSource( + id: 'project_browser_gitlab', + label: new TranslatableMarkup('Gitlab'), + description: new TranslatableMarkup('Source plugin for Project Browser to search Gitlab.'), + deriver: 'Drupal\project_browser_gitlab\Plugin\Derivative\GitlabDeriver', +)] class Gitlab extends ProjectBrowserSourceBase implements ContainerFactoryPluginInterface { /** @@ -210,13 +213,10 @@ class Gitlab extends ProjectBrowserSourceBase implements ContainerFactoryPluginI $categories = []; foreach ($response['data'] ?? [] as $category) { - $categories[$category['name']] = [ - 'id' => $category['name'], - 'name' => $category['name'], - ]; + $categories[$category['name']] = $category['name']; } - return array_values($categories); + return $categories; } /** @@ -276,4 +276,18 @@ class Gitlab extends ProjectBrowserSourceBase implements ContainerFactoryPluginI ]; } + /** + * {@inheritdoc} + */ + public function getFilterDefinitions(): array { + $filters = []; + $filters['search'] = new TextFilter('', $this->t('Search')); + $filters['categories'] = new MultipleChoiceFilter( + $this->getCategories(), + [], + $this->t('Categories'), + ); + return $filters; + } + } -- GitLab