pluginreference-2.0.0/src/Plugin/PluginReferenceSelection/DefaultSelection.php
src/Plugin/PluginReferenceSelection/DefaultSelection.php
<?php
namespace Drupal\pluginreference\Plugin\PluginReferenceSelection;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\pluginreference\Attribute\PluginReferenceSelection;
use Drupal\pluginreference\Plugin\Field\FieldType\PluginReferenceItem;
use Drupal\pluginreference\PluginReferenceSelectionBase;
use Drupal\pluginreference\PluginTypeHelperInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Default plugin implementation of the Plugin Reference Selection plugin.
*
* Also serves as a base class for specific types of plugin Reference
* Selection plugins.
*
* @see \Drupal\pluginreference\PluginReferenceSelectionManager
* @see \Drupal\pluginreference\PluginReferenceSelectionInterface
* @see \Drupal\pluginreference\PluginReferenceSelectionInterface
* @see \Drupal\pluginreference\Plugin\Derivative\DefaultSelectionDeriver
* @see plugin_api
*/
#[PluginReferenceSelection(
id: 'default',
label: new TranslatableMarkup('Default'),
group: 'default',
weight: 0,
deriver: 'Drupal\pluginreference\Plugin\Derivative\DefaultSelectionDeriver',
)]
class DefaultSelection extends PluginReferenceSelectionBase implements ContainerFactoryPluginInterface {
/**
* The plugin type helper service.
*
* @var \Drupal\pluginreference\PluginTypeHelperInterface
*/
protected $pluginTypeHelper;
/**
* {@inheritdoc}
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, PluginTypeHelperInterface $plugin_type_helper) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->pluginTypeHelper = $plugin_type_helper;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('plugin_reference.plugin_type_helper')
);
}
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
return [
'sort' => [
'key' => 'label',
'direction' => 'ASC',
],
] + parent::defaultConfiguration();
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$form = parent::buildConfigurationForm($form, $form_state);
$configuration = $this->getConfiguration();
$form['sort'] = [
'#type' => 'fieldset',
'#title' => $this->t('Sort options'),
];
$form['sort']['key'] = [
'#type' => 'select',
'#title' => $this->t('Sort by'),
'#options' => $this->getSortableKeys(),
'#empty_value' => '_none',
'#sort_options' => TRUE,
'#limit_validation_errors' => [],
'#default_value' => $configuration['sort']['key'],
];
$form['sort']['settings'] = [
'#type' => 'container',
'#attributes' => ['class' => ['plugin_reference-settings']],
'#process' => [[PluginReferenceItem::class, 'formProcessMergeParent']],
];
$form['sort']['settings']['direction'] = [
'#type' => 'select',
'#title' => $this->t('Sort direction'),
'#required' => TRUE,
'#options' => [
'ASC' => $this->t('Ascending'),
'DESC' => $this->t('Descending'),
],
'#default_value' => $configuration['sort']['direction'],
'#states' => [
'visible' => [
':input[name="settings[handler_settings][sort][key]"]' => [
'!value' => '_none',
],
],
],
];
return $form;
}
/**
* {@inheritdoc}
*/
public function getReferenceablePlugins(?string $match = NULL, string $match_operator = 'CONTAINS', int $limit = 0): array {
$target_type = $this->getConfiguration()['target_type'];
$plugin_definitions = $this->pluginTypeHelper->getPluginDefinitions($target_type);
$this->filterReferenceablePluginDefinitions($plugin_definitions);
$this->sortPluginDefinitions($plugin_definitions);
$return = [];
foreach ($plugin_definitions as $plugin_id => $plugin_definition) {
$plugin_label = $this->pluginTypeHelper->getPluginLabel($plugin_definition);
if (empty($match)) {
$return[$plugin_id] = $plugin_label;
}
elseif ($match_operator === 'CONTAINS' && (stripos($plugin_label, $match) !== FALSE || stripos($plugin_id, $match) !== FALSE)) {
$return[$plugin_id] = $plugin_label;
}
elseif ($match_operator === 'STARTS_WITH' && (stripos($plugin_label, $match) === 0 || stripos($plugin_id, $match) === 0)) {
$return[$plugin_id] = $plugin_label;
}
}
if ($limit > 0) {
$return = array_slice($return, 0, $limit);
}
return $return;
}
/**
* Get all keys that are supported to sort on.
*
* @return array
* An array of keys that are allowed to sort on.
*/
protected function getSortableKeys(): array {
return [
'id' => $this->t('ID'),
'label' => $this->t('Label'),
];
}
/**
* Sort the given plugin definitions by the configured key and direction.
*
* @param array $plugin_definitions
* An array of plugin definitions.
*/
protected function sortPluginDefinitions(array &$plugin_definitions): void {
$sort_key = $this->getConfiguration()['sort']['key'];
$sort_direction = $this->getConfiguration()['sort']['direction'];
if (empty($sort_key)) {
return;
}
/** @var \Drupal\pluginreference\PluginTypeHelperInterface $plugin_type_helper */
$plugin_type_helper = $this->pluginTypeHelper;
if ($sort_key === 'label') {
uasort($plugin_definitions, function (array $a, array $b) use ($plugin_type_helper) {
$a_label = $plugin_type_helper->getPluginLabel($a);
$b_label = $plugin_type_helper->getPluginLabel($b);
return strnatcasecmp($a_label, $b_label);
});
}
else {
uasort($plugin_definitions, function (array $a, array $b) use ($sort_key) {
return strnatcasecmp($a[$sort_key], $b[$sort_key]);
});
}
if ($sort_direction === 'DESC') {
$plugin_definitions = array_reverse($plugin_definitions, TRUE);
}
}
/**
* Helper method that makes it possible to filter the plugin definitions.
*
* @param array $plugin_definitions
* An array of plugin definitions.
*/
protected function filterReferenceablePluginDefinitions(array &$plugin_definitions): void {}
}
