View source
<?php
namespace Drupal\linkit\Plugin\Linkit\Matcher;
use Drupal\Component\Utility\Html;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\linkit\ConfigurableMatcherBase;
use Drupal\linkit\MatcherTokensTrait;
use Drupal\linkit\Utility\LinkitXss;
use Symfony\Component\DependencyInjection\ContainerInterface;
class EntityMatcher extends ConfigurableMatcherBase {
use MatcherTokensTrait;
protected $database;
protected $entityManager;
protected $moduleHandler;
protected $currentUser;
protected $target_type;
public function __construct(array $configuration, $plugin_id, $plugin_definition, Connection $database, EntityManagerInterface $entity_manager, ModuleHandlerInterface $module_handler, AccountInterface $current_user) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
if (empty($plugin_definition['target_entity'])) {
throw new \InvalidArgumentException("Missing required 'target_entity' property for a matcher.");
}
$this->database = $database;
$this->entityManager = $entity_manager;
$this->moduleHandler = $module_handler;
$this->currentUser = $current_user;
$this->target_type = $plugin_definition['target_entity'];
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('database'), $container
->get('entity.manager'), $container
->get('module_handler'), $container
->get('current_user'));
}
public function getSummary() {
$summery = parent::getSummary();
$entity_type = $this->entityManager
->getDefinition($this->target_type);
$result_description = $this->configuration['result_description'];
if (!empty($result_description)) {
$summery[] = $this
->t('Result description: @result_description', [
'@result_description' => $result_description,
]);
}
if ($entity_type
->hasKey('bundle')) {
$has_bundle_filter = !empty($this->configuration['bundles']);
$bundles = [];
if ($has_bundle_filter) {
$bundles_info = $this->entityManager
->getBundleInfo($this->target_type);
foreach ($this->configuration['bundles'] as $bundle) {
$bundles[] = $bundles_info[$bundle]['label'];
}
}
$summery[] = $this
->t('Bundle filter: @bundle_filter', [
'@bundle_filter' => $has_bundle_filter ? implode(', ', $bundles) : t('None'),
]);
$summery[] = $this
->t('Group by bundle: @bundle_grouping', [
'@bundle_grouping' => $this->configuration['group_by_bundle'] ? $this
->t('Yes') : $this
->t('No'),
]);
}
return $summery;
}
public function defaultConfiguration() {
return parent::defaultConfiguration() + [
'result_description' => '',
'bundles' => [],
'group_by_bundle' => FALSE,
];
}
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$entity_type = $this->entityManager
->getDefinition($this->target_type);
$form['result_description'] = [
'#title' => $this
->t('Result description'),
'#type' => 'textfield',
'#default_value' => $this->configuration['result_description'],
'#size' => 120,
'#maxlength' => 255,
'#weight' => -100,
];
$this
->insertTokenList($form, [
$this->target_type,
]);
if ($entity_type
->hasKey('bundle')) {
$bundle_options = [];
foreach ($this->entityManager
->getBundleInfo($this->target_type) as $bundle_name => $bundle_info) {
$bundle_options[$bundle_name] = $bundle_info['label'];
}
$form['bundles'] = [
'#type' => 'checkboxes',
'#title' => $this
->t('Restrict to the selected bundles'),
'#options' => $bundle_options,
'#default_value' => $this->configuration['bundles'],
'#description' => $this
->t('If none of the checkboxes is checked, allow all bundles.'),
'#element_validate' => [
[
get_class($this),
'elementValidateFilter',
],
],
'#weight' => -50,
];
$form['group_by_bundle'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Group by bundle'),
'#default_value' => $this->configuration['group_by_bundle'],
'#weight' => -50,
];
}
return $form;
}
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
}
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
$this->configuration['result_description'] = $form_state
->getValue('result_description');
$this->configuration['bundles'] = $form_state
->getValue('bundles');
$this->configuration['group_by_bundle'] = $form_state
->getValue('group_by_bundle');
}
public static function elementValidateFilter(&$element, FormStateInterface $form_state) {
$element['#value'] = array_filter($element['#value']);
$form_state
->setValueForElement($element, $element['#value']);
}
public function getMatches($string) {
$query = $this
->buildEntityQuery($string);
$result = $query
->execute();
if (empty($result)) {
return [];
}
$matches = [];
$entities = $this->entityManager
->getStorage($this->target_type)
->loadMultiple($result);
foreach ($entities as $entity_id => $entity) {
$access = $entity
->access('view', $this->currentUser, TRUE);
if (!$access
->isAllowed()) {
continue;
}
$matches[] = [
'title' => $this
->buildLabel($entity),
'description' => $this
->buildDescription($entity),
'path' => $this
->buildPath($entity),
'group' => $this
->buildGroup($entity),
];
}
return $matches;
}
protected function buildEntityQuery($match) {
$match = $this->database
->escapeLike($match);
$entity_type = $this->entityManager
->getDefinition($this->target_type);
$query = $this->entityManager
->getStorage($this->target_type)
->getQuery();
$label_key = $entity_type
->getKey('label');
if ($label_key) {
$query
->condition($label_key, '%' . $match . '%', 'LIKE');
$query
->sort($label_key, 'ASC');
}
if (!empty($this->configuration['bundles']) && ($bundle_key = $entity_type
->getKey('bundle'))) {
$query
->condition($bundle_key, $this->configuration['bundles'], 'IN');
}
$query
->addTag('linkit_entity_autocomplete');
$query
->addTag('linkit_entity_' . $this->target_type . '_autocomplete');
$query
->addTag('entity_access');
$query
->addTag($this->target_type . '_access');
return $query;
}
protected function buildLabel($entity) {
return Html::escape($entity
->label());
}
protected function buildDescription($entity) {
$description = \Drupal::token()
->replace($this->configuration['result_description'], [
$this->target_type => $entity,
], []);
return LinkitXss::descriptionFilter($description);
}
protected function buildPath($entity) {
return $entity
->toUrl()
->toString();
}
protected function buildGroup($entity) {
$group = $entity
->getEntityType()
->getLabel();
if ($this->configuration['group_by_bundle']) {
$bundles = $this->entityManager
->getBundleInfo($entity
->getEntityTypeId());
$bundle_label = $bundles[$entity
->bundle()]['label'];
$group .= ' - ' . $bundle_label;
}
return $group;
}
}