You are here

views_natural_sort.module in Views Natural Sort 8.2

File

views_natural_sort.module
View source
<?php

/**
 * @file
 * Contains views_natural_sort.module..
 */
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\views_natural_sort\IndexRecordType;

/**
 * Implements hook_help().
 */
function views_natural_sort_help($route_name, RouteMatchInterface $route_match) {
  switch ($route_name) {

    // Main module help for the views_natural_sort module.
    case 'help.page.views_natural_sort':
      $output = '<h3>' . t('About') . '</h3>';
      $output .= '<p>' . t('Sort results naturally on a node&#039;s title skipping articles like &quot;the&quot; and &quot;a.&quot;') . '</p>';
      return $output;
    default:
  }
}

/**
 * Implements hook_module_implements_alter().
 */
function views_natural_sort_module_implements_alter(&$implements, $hook) {
  if ($hook == 'views_data_alter') {

    // Make views natural sort always last so we get all the up to date info.
    $group = $implements['views_natural_sort'];
    unset($implements['views_natural_sort']);
    $implements['views_natural_sort'] = $group;
  }
}

/**
 * Implements hook_views_natural_sort_get_entry_types().
 *
 * @Not-Rewritten
 */
function views_natural_sort_views_natural_sort_get_entry_types() {
  $service = Drupal::service('views_natural_sort.service');
  $supported_entity_properties = $service
    ->getViewsSupportedEntityProperties();
  $entry_types = [];
  foreach ($supported_entity_properties as $entity_type => $properties) {
    foreach ($properties as $property => $schema_info) {
      $entry_types[] = new IndexRecordType($entity_type, $property);
    }
  }
  return $entry_types;
}

/**
 * Implements hook_views_natural_sort_queue_rebuild_data().
 */
function views_natural_sort_views_natural_sort_queue_rebuild_data(IndexRecordType $entry_type) {
  $service = Drupal::service('views_natural_sort.service');
  $supported_entity_properties = $service
    ->getViewsSupportedEntityProperties();
  $entity_type = $entry_type
    ->getEntityType();
  $field = $entry_type
    ->getField();
  if (empty($supported_entity_properties[$entity_type]) || empty($supported_entity_properties[$entity_type][$field])) {
    return;
  }
  $queue = Drupal::queue('views_natural_sort_entity_index');
  $query = Drupal::entityQuery($entity_type);
  $entity_ids = $query
    ->execute();
  foreach ($entity_ids as $entity_id) {
    $queue
      ->createItem([
      'entity_type' => $entity_type,
      'entity_id' => $entity_id,
    ]);
  }
  return 'views_natural_sort_entity_index';
}

/**
 * Implements hook_entity_insert().
 *
 * This keeps our natural sort index up to date.
 */
function views_natural_sort_entity_insert(EntityInterface $entity) {
  $service = Drupal::service('views_natural_sort.service');
  $supported_entity_properties = $service
    ->getViewsSupportedEntityProperties();
  if (isset($supported_entity_properties[$entity
    ->getEntityTypeId()])) {
    $service
      ->storeIndexRecordsFromEntity($entity);
  }
}

/**
 * Implements hook_entity_update().
 *
 * This keeps our natural sort index up to date.
 */
function views_natural_sort_entity_update(EntityInterface $entity) {
  views_natural_sort_entity_insert($entity);
}

/**
 * Implements hook_entity_delete().
 *
 * This keeps our natural sort index clean.
 */
function views_natural_sort_entity_delete(EntityInterface $entity) {
  views_natural_sort_remove($entry = [
    'eid' => $entity
      ->id(),
    'entity_type' => $entity
      ->getEntityTypeId(),
  ]);
}

/**
 * Remove a views_natural_sort index entry based on keys.
 *
 * @param array $index_entry
 *   Mirrors the views_natural_sort table
 *     $eid - Entity Id of the item referenced
 *     $entity_type - The Entity Type. Ex. node
 *     $field - (optional) reference to the property or field name
 *     $delta - (optional)the item number in that field or property
 *   If an optional parameter doesn't exist, this is treated as a wild card
 *   delete.
 *
 * @Not-Rewritten
 */
function views_natural_sort_remove(array $index_entry) {
  $query = \Drupal::database()
    ->delete('views_natural_sort')
    ->condition('eid', $index_entry['eid'])
    ->condition('entity_type', $index_entry['entity_type']);
  if (isset($index_entry['field'])) {
    $query
      ->condition('field', $index_entry['field']);
  }
  if (isset($index_entry['delta'])) {
    $query
      ->condition('delta', $index_entry['delta']);
  }
  $query
    ->execute();
}

/**
 * Views_natural_sort_queue_data_for_rebuild description.
 *
 * @param array $entry_types
 *   Description.
 */
function views_natural_sort_queue_data_for_rebuild(array $entry_types = []) {
  $moduleHandler = \Drupal::moduleHandler();
  if (empty($entry_types)) {
    $entry_types = $moduleHandler
      ->invokeAll('views_natural_sort_get_entry_types');
  }
  $queues = [];
  foreach ($entry_types as $entry_type) {
    $queues = array_unique(array_merge($queues, array_filter($moduleHandler
      ->invokeAll('views_natural_sort_queue_rebuild_data', [
      $entry_type,
    ]))));
  }
  $operations = [];
  foreach ($queues as $queue) {
    $operations[] = [
      'views_natural_sort_rebuild_index',
      [
        $queue,
      ],
    ];
  }
  $batch = [
    'operations' => $operations,
    'title' => t('Rebuilding Views Natural Sort Indexing Entries'),
    'finished' => 'views_natural_sort_finish_rebuild',
  ];
  batch_set($batch);
}
function views_natural_sort_rebuild_index($queue_name, &$context) {

  /** @var QueueInterface $queue */
  $queue = \Drupal::queue($queue_name);

  /** @var QueueWorkerInterface $queue_worker */
  $queue_worker = \Drupal::service('plugin.manager.queue_worker')
    ->createInstance($queue_name);
  $config = \Drupal::configFactory()
    ->get('views_natural_sort.settings');

  // Alias sandbox for easier referencing.
  $sandbox =& $context['sandbox'];

  // Alias results for easier referencing.
  $results =& $context['results'];
  if (empty($sandbox)) {
    $sandbox['current'] = 0;
    $sandbox['max'] = $queue
      ->numberOfItems();
    $sandbox['items_per_batch'] = $config
      ->get('rebuild_items_per_batch');
  }
  for ($i = 0; $i < $sandbox['items_per_batch'] && $sandbox['current'] < $sandbox['max']; $i++) {
    if ($item = $queue
      ->claimItem(10)) {
      try {
        $queue_worker
          ->processItem($item->data);
        $queue
          ->deleteItem($item);
      } catch (SuspendQueueException $e) {
        $queue
          ->releaseItem($item);
        break;
      } catch (\Exception $e) {
        watchdog_exception('views_natural_sort', $e);
      }
    }
    $sandbox['current']++;
  }
  $results['entries'] = $sandbox['current'];
  if ($sandbox['current'] != $sandbox['max']) {
    $context['finished'] = $sandbox['current'] / $sandbox['max'];
    $context['message'] = t('Processed %current out of %max records.', [
      '%current' => $sandbox['current'],
      '%max' => $sandbox['max'],
    ]);
  }
}
function views_natural_sort_finish_rebuild($success, $results, $operations) {
  if ($success) {
    $messenger = \Drupal::messenger();
    $messenger
      ->addStatus(t('Index rebuild has completed.'));
    $messenger
      ->addStatus(t('Indexed %count.', [
      '%count' => \Drupal::translation()
        ->formatPlural($results['entries'], '1 entry', '@count entries'),
    ]));
  }
}

Functions