View source
<?php
namespace Drupal\pathauto\Plugin\pathauto\AliasType;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\KeyValueStore\KeyValueFactoryInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Plugin\Context\Context;
use Drupal\Core\Plugin\ContextAwarePluginBase;
use Drupal\Core\Messenger\MessengerTrait;
use Drupal\pathauto\AliasTypeBatchUpdateInterface;
use Drupal\pathauto\AliasTypeInterface;
use Drupal\pathauto\PathautoState;
use Symfony\Component\DependencyInjection\ContainerInterface;
class EntityAliasTypeBase extends ContextAwarePluginBase implements AliasTypeInterface, AliasTypeBatchUpdateInterface, ContainerFactoryPluginInterface {
use MessengerTrait;
protected $moduleHandler;
protected $languageManager;
protected $entityTypeManager;
protected $keyValue;
protected $database;
protected $prefix;
public function __construct(array $configuration, $plugin_id, $plugin_definition, ModuleHandlerInterface $module_handler, LanguageManagerInterface $language_manager, EntityTypeManagerInterface $entity_type_manager, KeyValueFactoryInterface $key_value, Connection $database) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->moduleHandler = $module_handler;
$this->languageManager = $language_manager;
$this->entityTypeManager = $entity_type_manager;
$this->keyValue = $key_value;
$this->database = $database;
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('module_handler'), $container
->get('language_manager'), $container
->get('entity_type.manager'), $container
->get('keyvalue'), $container
->get('database'));
}
public function getLabel() {
$definition = $this
->getPluginDefinition();
return (string) $definition['label'];
}
public function getTokenTypes() {
$definition = $this
->getPluginDefinition();
return $definition['types'];
}
public function batchUpdate($action, &$context) {
if (!isset($context['sandbox']['current'])) {
$context['sandbox']['count'] = 0;
$context['sandbox']['current'] = 0;
}
$entity_type = $this->entityTypeManager
->getDefinition($this
->getEntityTypeId());
$id_key = $entity_type
->getKey('id');
$query = $this->database
->select($entity_type
->get('base_table'), 'base_table');
$query
->leftJoin($this
->getTableInfo()['table'], 'pa', "CONCAT('" . $this
->getSourcePrefix() . "' , base_table.{$id_key}) = pa.{$this->getTableInfo()['fields']['path']}");
$query
->addField('base_table', $id_key, 'id');
switch ($action) {
case 'create':
$query
->isNull("pa.{$this->getTableInfo()['fields']['path']}");
break;
case 'update':
$query
->isNotNull("pa.{$this->getTableInfo()['fields']['path']}");
break;
case 'all':
break;
default:
return;
}
$query
->condition('base_table.' . $id_key, $context['sandbox']['current'], '>');
$query
->orderBy('base_table.' . $id_key);
$query
->addTag('pathauto_bulk_update');
$query
->addMetaData('entity', $this
->getEntityTypeId());
if (!isset($context['sandbox']['total'])) {
$context['sandbox']['total'] = $query
->countQuery()
->execute()
->fetchField();
if (!$context['sandbox']['total']) {
$context['finished'] = 1;
return;
}
}
$query
->range(0, 25);
$ids = $query
->execute()
->fetchCol();
$updates = $this
->bulkUpdate($ids);
$context['sandbox']['count'] += count($ids);
$context['sandbox']['current'] = !empty($ids) ? max($ids) : 0;
$context['results']['updates'] += $updates;
$context['message'] = $this
->t('Updated alias for %label @id.', [
'%label' => $entity_type
->getLabel(),
'@id' => end($ids),
]);
if ($context['sandbox']['count'] != $context['sandbox']['total']) {
$context['finished'] = $context['sandbox']['count'] / $context['sandbox']['total'];
}
}
public function batchDelete(&$context) {
if (!isset($context['sandbox']['current'])) {
$context['sandbox']['count'] = 0;
$context['sandbox']['current'] = 0;
}
$entity_type = $this->entityTypeManager
->getDefinition($this
->getEntityTypeId());
$id_key = $entity_type
->getKey('id');
$query = $this->database
->select($entity_type
->get('base_table'), 'base_table');
$query
->innerJoin($this
->getTableInfo()['table'], 'pa', "CONCAT('" . $this
->getSourcePrefix() . "' , base_table.{$id_key}) = pa.{$this->getTableInfo()['fields']['path']}");
$query
->addField('base_table', $id_key, 'id');
$query
->addField('pa', $this
->getTableInfo()['fields']['id']);
$query
->condition("pa.{$this->getTableInfo()['fields']['id']}}", $context['sandbox']['current'], '>');
$query
->orderBy("pa.{$this->getTableInfo()['fields']['id']}}");
$query
->addTag('pathauto_bulk_delete');
$query
->addMetaData('entity', $this
->getEntityTypeId());
if (!isset($context['sandbox']['total'])) {
$context['sandbox']['total'] = $query
->countQuery()
->execute()
->fetchField();
if (!$context['sandbox']['total']) {
$context['finished'] = 1;
return;
}
}
$query
->range(0, 100);
$pids_by_id = $query
->execute()
->fetchAllKeyed();
PathautoState::bulkDelete($this
->getEntityTypeId(), $pids_by_id);
$context['sandbox']['count'] += count($pids_by_id);
$context['sandbox']['current'] = !empty($pids_by_id) ? max($pids_by_id) : 0;
$context['results']['deletions'][] = $this
->getLabel();
if ($context['sandbox']['count'] != $context['sandbox']['total']) {
$context['finished'] = $context['sandbox']['count'] / $context['sandbox']['total'];
}
}
protected function getEntityTypeId() {
return $this
->getDerivativeId();
}
protected function bulkUpdate(array $ids, array $options = []) {
$options += [
'message' => FALSE,
];
$updates = 0;
$entities = $this->entityTypeManager
->getStorage($this
->getEntityTypeId())
->loadMultiple($ids);
foreach ($entities as $entity) {
foreach ($entity
->getTranslationLanguages() as $langcode => $language) {
$translated_entity = $entity
->getTranslation($langcode);
$result = \Drupal::service('pathauto.generator')
->updateEntityAlias($translated_entity, 'bulkupdate', $options);
if ($result) {
$updates++;
}
}
}
if (!empty($options['message'])) {
$this->messenger
->addMessage($this->translationManager
->formatPlural(count($ids), 'Updated 1 %label URL alias.', 'Updated @count %label URL aliases.'), [
'%label' => $this
->getLabel(),
]);
}
return $updates;
}
protected function bulkDelete(array $pids_by_id) {
PathautoState::bulkDelete($this
->getEntityTypeId(), $pids_by_id);
}
public function calculateDependencies() {
$dependencies = [];
$dependencies['module'][] = $this->entityTypeManager
->getDefinition($this
->getEntityTypeId())
->getProvider();
return $dependencies;
}
public function applies($object) {
return $object instanceof FieldableEntityInterface && $object
->getEntityTypeId() == $this
->getEntityTypeId();
}
public function getSourcePrefix() {
if (empty($this->prefix)) {
$entity_type = $this->entityTypeManager
->getDefinition($this
->getEntityTypeId());
$path = $entity_type
->getLinkTemplate('canonical');
$this->prefix = substr($path, 0, strpos($path, '{'));
}
return $this->prefix;
}
public function setContextValue($name, $value) {
$this->context[$name] = new Context($this
->getContextDefinition($name), $value);
return $this;
}
private function getTableInfo() {
if (version_compare(\Drupal::VERSION, '8.8', '<')) {
return [
'table' => 'url_alias',
'fields' => [
'id' => 'pid',
'path' => 'source',
'alias' => 'alias',
'langcode' => 'langcode',
],
];
}
else {
return [
'table' => 'path_alias',
'fields' => [
'id' => 'id',
'path' => 'path',
'alias' => 'alias',
'langcode' => 'langcode',
],
];
}
}
}