Commit 897e981b authored by Sándor Juhász's avatar Sándor Juhász Committed by Ramesh M
Browse files

Issue #3300305: Mark the node for reindexing when counter is increased

parent 0009d6f4
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
reindex_node: 0
reindex_node_views: 5
+12 −0
Original line number Diff line number Diff line
# Schema for the configuration files of the searchapi_nodeview_count module.

searchapi_nodeview_count.settings:
  type: config_object
  label: 'Search Api Node View Count settings'
  mapping:
    reindex_node:
      type: integer
      label: 'Re-index node'
    reindex_node_views:
      type: integer
      label: 'Number of views'
+47 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
 * Contains searchapi_nodeview_count.module.
 */

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;

/**
@@ -22,3 +23,49 @@ function searchapi_nodeview_count_help($route_name, RouteMatchInterface $route_m
    default:
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function searchapi_nodeview_count_form_statistics_settings_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  $config = \Drupal::configFactory()->get('searchapi_nodeview_count.settings');

  $form['searchapi'] = [
    '#type'  => 'details',
    '#title' => t('Search API'),
    '#open'  => TRUE,
  ];

  $form['searchapi']['reindex_node'] = [
    '#type'          => 'checkbox',
    '#title'         => t('Re-index node'),
    '#default_value' => $config->get('reindex_node'),
    '#description'   => t('Mark the node for re-indexing when counter is increased.'),
  ];

  $form['searchapi']['reindex_node_views'] = [
    '#type'          => 'number',
    '#title'         => t('Number of views'),
    '#default_value' => $config->get('reindex_node_views'),
    '#description'   => t('Mark the node for re-indexing, for example after every fifth viewing.'),
    '#min'           => 1,
    '#states'        => [
      'visible' => [
        ':input[name="reindex_node"]' => ['checked' => TRUE],
      ],
    ],
  ];

  $form['actions']['submit']['#submit'][] = '_searchapi_nodeview_count_form_statistics_settings_form_submit';
}

/**
 * Form submit callback.
 */
function _searchapi_nodeview_count_form_statistics_settings_form_submit(&$form, FormStateInterface $form_state) {
  \Drupal::configFactory()
    ->getEditable('searchapi_nodeview_count.settings')
    ->set('reindex_node', (int) $form_state->getValue('reindex_node', 0))
    ->set('reindex_node_views', (int) $form_state->getValue('reindex_node_views', 1))
    ->save();
}
+110 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\searchapi_nodeview_count;

use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\State\StateInterface;
use Drupal\search_api\Plugin\search_api\datasource\ContentEntityTrackingManager;
use Drupal\statistics\NodeStatisticsDatabaseStorage;
use Symfony\Component\HttpFoundation\RequestStack;

/**
 * Provides the default database storage backend for statistics.
 */
class AlteredNodeStatisticsDatabaseStorage extends NodeStatisticsDatabaseStorage {

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * The tracking manager service.
   *
   * @var \Drupal\search_api\Plugin\search_api\datasource\ContentEntityTrackingManager
   */
  protected $trackingManager;

  /**
   * The config object.
   *
   * @var \Drupal\Core\Config\ImmutableConfig
   */
  protected $config;

  /**
   * Constructs the statistics storage.
   *
   * @param \Drupal\Core\Database\Connection $connection
   *   The database connection for the node view storage.
   * @param \Drupal\Core\State\StateInterface $state
   *   The state service.
   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
   *   The request stack.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_manager
   *   The entity type manager.
   * @param \Drupal\search_api\Plugin\search_api\datasource\ContentEntityTrackingManager $tracking_manager
   *   The tracking manager service provides hook implementations on behalf of
   *   the Content Entity datasource.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config
   *   The config factory.
   */
  public function __construct(Connection $connection, StateInterface $state, RequestStack $request_stack, EntityTypeManagerInterface $entity_manager, ContentEntityTrackingManager $tracking_manager, ConfigFactoryInterface $config) {
    parent::__construct($connection, $state, $request_stack);

    $this->entityTypeManager = $entity_manager;
    $this->trackingManager = $tracking_manager;
    $this->config = $config->get('searchapi_nodeview_count.settings');
  }

  /**
   * {@inheritdoc}
   */
  public function recordView($id) {
    $return = parent::recordView($id);

    if ($this->config->get('reindex_node') && $views = $this->config->get('reindex_node_views')) {
      $query = $this->connection->select('node_counter', 'n');
      $query->addField('n', 'totalcount');
      $query->condition('n.nid', $id);
      $total = (int) $query->execute()->fetchField();

      // Marks the node for re-index after every fifth viewing (if $views = 5).
      if ($views > 0 && $total % $views === 0) {
        $this->reindex($id);
      }
    }

    return $return;
  }

  /**
   * Marks the node and its items changed for indexes.
   *
   * @param $id
   *   Node ID.
   *
   * @return void
   */
  public function reindex($id) {
    try {
      $storage = $this->entityTypeManager->getStorage('node');
      $entity = $storage->load($id);
    } catch (InvalidPluginDefinitionException|PluginNotFoundException $e) {
      return;
    }

    if ($entity) {
      // @see search_api_entity_update()
      // Call this hook on behalf of the Content Entity datasource.
      $this->trackingManager->entityUpdate($entity);
    }
  }

}
+32 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\searchapi_nodeview_count;

use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceProviderBase;
use Symfony\Component\DependencyInjection\Reference;

/**
 * Class SearchapiNodeviewCountServiceProvider.
 *
 * @package Drupal\searchapi_nodeview_count
 */
class SearchapiNodeviewCountServiceProvider extends ServiceProviderBase {

  /**
   * {@inheritdoc}
   */
  public function alter(ContainerBuilder $container) {
    $definition = $container->getDefinition('statistics.storage.node');
    $definition->setClass('Drupal\searchapi_nodeview_count\AlteredNodeStatisticsDatabaseStorage');
    $definition->setArguments([
      new Reference('database'),
      new Reference('state'),
      new Reference('request_stack'),
      new Reference('entity_type.manager'),
      new Reference('search_api.entity_datasource.tracking_manager'),
      new Reference('config.factory'),
    ]);
  }

}