View source
<?php
namespace Drupal\views_natural_sort;
use Drupal\Core\Config\ConfigFactory;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Database\Connection;
use Drupal\Core\Messenger\Messenger;
use Drupal\Core\StringTranslation\TranslationManager;
use Drupal\views_natural_sort\Plugin\IndexRecordContentTransformationManager as TransformationManager;
use Drupal\views\ViewsData;
use Drupal\Core\Queue\QueueWorkerManagerInterface;
use Drupal\Core\Queue\QueueFactory;
class ViewsNaturalSortService {
protected $messenger;
protected $translator;
public function __construct(TransformationManager $transformationManager, ConfigFactory $configFactory, ModuleHandlerInterface $moduleHandler, LoggerChannelFactoryInterface $loggerFactory, Connection $database, ViewsData $viewsData, QueueFactory $queue, QueueWorkerManagerInterface $queueManager, EntityFieldManagerInterface $entityFieldManager, EntityTypeManagerInterface $entityTypeManager, Messenger $messenger, TranslationManager $translator) {
$this->configFactory = $configFactory;
$this->moduleHandler = $moduleHandler;
$this->loggerFactory = $loggerFactory
->get('views_natural_sort');
$this->transformationManager = $transformationManager;
$this->database = $database;
$this->viewsData = $viewsData;
$this->queue = $queue;
$this->queueManager = $queueManager;
$this->entityFieldManager = $entityFieldManager;
$this->entityTypeManager = $entityTypeManager;
$this->messenger = $messenger;
$this->translator = $translator;
}
public function getTransformations(IndexRecord $record) {
$transformations = $this
->getDefaultTransformations();
$this->moduleHandler
->alter('views_natural_sort_transformations', $transformations, $record);
return $transformations;
}
public function getDefaultTransformations() {
$default_transformations = [
'remove_beginning_words',
'remove_words',
'remove_symbols',
'numbers',
'days_of_the_week',
];
$config = $this->configFactory
->get('views_natural_sort.settings');
$transformations = [];
foreach ($default_transformations as $plugin_id) {
if ($config
->get('transformation_settings.' . $plugin_id . '.enabled')) {
$transformations[] = $this->transformationManager
->createInstance($plugin_id, $config
->get('transformation_settings.' . $plugin_id));
}
}
return $transformations;
}
public function getSupportedEntityProperties() {
static $supported_properties = [];
if (empty($supported_properties)) {
foreach ($this->entityFieldManager
->getFieldMap() as $entity_type => $info) {
foreach ($info as $field_name => $field_info) {
if ($field_info['type'] == 'string') {
$field_configs = empty($field_info['bundles']) ? $this->entityFieldManager
->getBaseFieldDefinitions($entity_type) : $this->entityFieldManager
->getFieldDefinitions($entity_type, reset($field_info['bundles']));
if (!isset($field_configs[$field_name])) {
continue;
}
$field_config = $field_configs[$field_name];
if (empty($supported_properties[$entity_type])) {
$supported_properties[$entity_type] = [];
}
$base_table = $this
->getViewsBaseTable($field_config);
if (empty($base_table)) {
continue;
}
$supported_properties[$entity_type][$field_name] = [
'base_table' => $base_table,
'schema_field' => $field_name,
];
}
}
}
}
return $supported_properties;
}
public function getViewsSupportedEntityProperties() {
static $views_supported_properties = [];
if (empty($views_supported_properties)) {
$supported_entity_properties = $this
->getSupportedEntityProperties();
$views_data = $this->viewsData
->getAll();
if (empty($views_data)) {
return FALSE;
}
foreach ($supported_entity_properties as $entity => $properties) {
foreach ($properties as $property => $schema_info) {
if (!empty($views_data[$schema_info['base_table']][$schema_info['schema_field']]) && !empty($views_data[$schema_info['base_table']][$schema_info['schema_field']]['sort']) && !empty($views_data[$schema_info['base_table']][$schema_info['schema_field']]['sort']['id']) && $views_data[$schema_info['base_table']][$schema_info['schema_field']]['sort']['id'] == 'natural') {
$views_supported_properties[$entity][$property] = $schema_info;
}
}
}
}
return $views_supported_properties;
}
public function storeIndexRecordsFromEntity(EntityInterface $entity) {
$entity_type = $entity
->getEntityTypeId();
$supported_entity_properties = $this
->getViewsSupportedEntityProperties();
foreach ($supported_entity_properties[$entity_type] as $field => $field_info) {
if (!isset($entity->{$field})) {
continue;
}
foreach ($entity
->get($field)
->getValue() as $delta => $value) {
$record = $this
->createIndexRecord([
'eid' => $entity
->id(),
'entity_type' => $entity_type,
'field' => $field,
'delta' => $delta,
'content' => $value['value'],
]);
$record
->save();
}
}
}
public function queueDataForRebuild(array $entry_types = []) {
if (empty($entry_types)) {
$entry_types = $this->moduleHandler
->invokeAll('views_natural_sort_get_entry_types');
}
$queues = [];
foreach ($entry_types as $entry_type) {
$queues = array_unique(array_merge($queues, array_filter($this->moduleHandler
->invokeAll('views_natural_sort_queue_rebuild_data', $entry_type))));
}
$operations = [];
foreach ($queues as $queue) {
$operations[] = [
[
$this,
'rebuildIndex',
],
[
$queue,
],
];
}
$batch = [
'operations' => $operations,
'title' => t('Rebuilding Views Natural Sort Indexing Entries'),
'finished' => [
$this,
'finishRebuild',
],
];
batch_set($batch);
}
public function finishRebuild($success, $results, $operations) {
if ($success) {
$this->messenger
->addMessage($this->translator
->translate('Index rebuild has completed.'));
$this->messenger
->addMessage($this->translator
->translate('Indexed %count.', [
'%count' => $this->translator
->formatPlural($results['entries'], '1 entry', '@count entries'),
]));
}
}
public function createIndexRecord(array $values = []) {
$record = new IndexRecord($this->database, $values);
$transformations = $this
->getTransformations($record);
$record
->setTransformations($transformations);
return $record;
}
public function getViewsBaseTable($fieldDefinition) {
$entityType = $this->entityTypeManager
->getDefinition($fieldDefinition
->getTargetEntityTypeId());
$base_table = $entityType
->getBaseTable() ?: $entityType
->id();
$views_revision_base_table = NULL;
$revisionable = $entityType
->isRevisionable();
$base_field = $entityType
->getKey('id');
$revision_table = '';
if ($revisionable) {
$revision_table = $entityType
->getRevisionTable() ?: $entityType
->id() . '_revision';
}
$translatable = $entityType
->isTranslatable();
$data_table = '';
if ($translatable) {
$data_table = $entityType
->getDataTable() ?: $entityType
->id() . '_field_data';
}
$revision_data_table = '';
if ($revisionable && $translatable) {
$revision_data_table = $entityType
->getRevisionDataTable() ?: $entityType
->id() . '_field_revision';
}
$revision_field = $entityType
->getKey('revision');
$views_base_table = $base_table;
if ($data_table) {
$views_base_table = $data_table;
}
return $views_base_table;
}
}