Skip to content

Commit

Permalink
feat: base plugin system for the content importers
Browse files Browse the repository at this point in the history
Refs: RW-1127
  • Loading branch information
orakili committed Dec 2, 2024
1 parent 459ea6a commit 8baba96
Show file tree
Hide file tree
Showing 8 changed files with 346 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Importer plugin base settings.
reliefweb_import.plugin.importer:
type: mapping
label: 'ReliefWeb importer plugin base settings.'
mapping:
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@ services:
reliefweb_import.job_feeds_importer:
class: \Drupal\reliefweb_import\Service\JobFeedsImporter
arguments: ['@database', '@entity_type.manager', '@account_switcher', '@http_client', '@logger.factory', '@state']

plugin.manager.reliefweb_import.importer:
class: Drupal\reliefweb_import\Plugin\ImporterPluginManager
parent: default_plugin_manager
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

namespace Drupal\reliefweb_import\Attribute;

use Drupal\Component\Plugin\Attribute\Plugin;
use Drupal\Core\StringTranslation\TranslatableMarkup;

/**
* Defines a classifier plugin attribute object.
*
* Plugin Namespace: Plugin\ReliefWebImporter.
*
* @see \Drupal\reliefweb_import\Plugin\ReliefWebImporterPluginBase
* @see \Drupal\reliefweb_import\Plugin\ReliefWebImporterPluginInterface
* @see \Drupal\reliefweb_import\Plugin\ReliefWebImporterPluginManager
* @see plugin_api
*
* @Attribute
*/
#[\Attribute(\Attribute::TARGET_CLASS)]
class ReliefWebImporter extends Plugin {

/**
* Constructor.
*
* @param string $id
* The plugin ID.
* @param \Drupal\Core\StringTranslation\TranslatableMarkup $label
* The label of the plugin.
* @param \Drupal\Core\StringTranslation\TranslatableMarkup $description
* The description of the plugin.
*/
public function __construct(
public readonly string $id,
public readonly TranslatableMarkup $label,
public readonly TranslatableMarkup $description,
) {}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace Drupal\reliefweb_import\Exception;

/**
* Invalid configuration.
*/
class InvalidConfigurationException extends \Exception implements ExceptionInterface {}
171 changes: 171 additions & 0 deletions html/modules/custom/reliefweb_import/src/Plugin/ImporterPluginBase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
<?php

declare(strict_types=1);

namespace Drupal\reliefweb_import\Plugin;

use Drupal\Component\Plugin\ConfigurableInterface;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Plugin\PluginBase;
use Drupal\Core\Plugin\PluginFormInterface;
use Drupal\reliefweb_import\Exception\InvalidConfigurationException;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
* Base importer plugin class.
*/
abstract class ImporterPluginBase extends PluginBase implements ImporterPluginInterface, ContainerFactoryPluginInterface, PluginFormInterface, ConfigurableInterface {

/**
* Logger.
*
* @var \Psr\Log\LoggerInterface
*/
protected LoggerInterface $logger;

/**
* Constructor.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* The config factory service.
* @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $loggerFactory
* The logger factory service.
*/
public function __construct(
array $configuration,
$plugin_id,
$plugin_definition,
protected ConfigFactoryInterface $configFactory,
protected LoggerChannelFactoryInterface $loggerFactory,
) {
parent::__construct(
$configuration,
$plugin_id,
$plugin_definition,
);
}

/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('config.factory'),
$container->get('logger.factory'),
);
}

/**
* {@inheritdoc}
*/
public function getPluginLabel(): string {
$definition = $this->getPluginDefinition();
return (string) ($definition['label'] ?? $this->getPluginId());
}

/**
* {@inheritdoc}
*/
public function getPluginType(): string {
return 'reliefweb_importer';
}

/**
* {@inheritdoc}
*/
public function getLogger(): LoggerInterface {
if (!isset($this->logger)) {
$this->logger = $this->loggerFactory->get(implode('.', [
'reliefweb_import',
$this->getPluginType(),
$this->getPluginId(),
]));
}
return $this->logger;
}

/**
* {@inheritdoc}
*/
public function getPluginSetting(string $key, mixed $default = NULL, bool $throw_if_null = TRUE): mixed {
if (empty($key)) {
return NULL;
}

$configuration = $this->getConfiguration();

$parts = explode('.', $key);
if (count($parts) === 1) {
$setting = $configuration[$key] ?? $default;
}
else {
$value = NestedArray::getValue($configuration, $parts, $key_exists);
$setting = $key_exists ? $value : $default;
}

if (is_null($setting) && $throw_if_null) {
throw new InvalidConfigurationException(strtr('Missing @key for @type plugin @id', [
'@key' => $key,
'@type' => $this->getPluginType(),
'@id' => $this->getPluginId(),
]));
}
return $setting;
}

/**
* {@inheritdoc}
*/
public function getConfiguration(): array {
return $this->configuration ?? [];
}

/**
* {@inheritdoc}
*/
public function setConfiguration(array $configuration): void {
$this->configuration = $configuration;
}

/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {
return $form;
}

/**
* {@inheritdoc}
*/
public function validateConfigurationForm(array &$form, FormStateInterface $form_state): void {
}

/**
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state): void {
$this->setConfiguration($form_state->getValues());
}

/**
* {@inheritdoc}
*/
public function defaultConfiguration(): array {
return [];
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

declare(strict_types=1);

namespace Drupal\reliefweb_import\Plugin;

use Psr\Log\LoggerInterface;

/**
* Interface for the importer plugins.
*/
interface ImporterPluginInterface {

/**
* Get the plugin label.
*
* @return string
* The plugin label.
*/
public function getPluginLabel(): string;

/**
* Get the plugin type.
*
* @return string
* The plugin type.
*/
public function getPluginType(): string;

/**
* Get the plugin logger.
*
* @return \Psr\Log\LoggerInterface
* Logger.
*/
public function getLogger(): LoggerInterface;

/**
* Get a plugin setting.
*
* @param string $key
* The setting name. It can be nested in the form "a.b.c" to retrieve "c".
* @param mixed $default
* Default value if the setting is missing.
* @param bool $throw_if_null
* If TRUE and both the setting and default are NULL then an exception
* is thrown. Use this for example for mandatory settings.
*
* @return mixed
* The plugin setting for the key or the provided default.
*
* @throws \Drupal\reliefweb_import\Exception\InvalidConfigurationException
* Throws an exception if no setting could be found (= NULL).
*/
public function getPluginSetting(string $key, mixed $default = NULL, bool $throw_if_null = TRUE): mixed;

/**
* Import newest and update content.
*
* @param int $limit
* Number of documents to import at once (batch).
*
* @return bool
* TRUE if the batch import was successful.
*/
public function importContent(int $limit = 50): bool;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace Drupal\reliefweb_import\Plugin;

use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Plugin\DefaultPluginManager;
use Drupal\reliefweb_import\Attribute\Importer;

/**
* Plugin manager for the importer plugins.
*/
class ImporterPluginManager extends DefaultPluginManager implements ImporterPluginManagerInterface {

/**
* {@inheritdoc}
*/
public function __construct(
\Traversable $namespaces,
CacheBackendInterface $cache_backend,
ModuleHandlerInterface $module_handler,
) {
parent::__construct(
'Plugin/ReliefWebImporter',
$namespaces,
$module_handler,
ImporterPluginInterface::class,
Importer::class
);

$this->setCacheBackend($cache_backend, 'reliefweb_import_reliefweb_importer_plugins');
$this->alterInfo('reliefweb_import_reliefweb_importer_info');
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace Drupal\reliefweb_import\Plugin;

/**
* Interface for the importer plugin manager.
*/
interface ImporterPluginManagerInterface {}

0 comments on commit 8baba96

Please sign in to comment.