entity_activity-8.x-1.0-beta13/src/EntityActivityManager.php

src/EntityActivityManager.php
<?php

namespace Drupal\entity_activity;

use Drupal\Component\Datetime\Time;
use Drupal\Component\Plugin\Exception\PluginException;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\ContentEntityTypeInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityRepositoryInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Queue\QueueFactory;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\Site\Settings;
use Drupal\Core\State\StateInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\entity_activity\Entity\SubscriptionInterface;
use Drupal\entity_activity\Event\EntityActivityEvent;
use Drupal\entity_activity\Event\EntityActivityEvents;
use Drupal\entity_activity\Event\EntityActivitySupportEntityTypeEvent;
use Drupal\entity_activity\Plugin\LogGeneratorInterface;
use Drupal\entity_activity\Plugin\LogGeneratorManagerInterface;
use Drupal\user\UserInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;

/**
 * Class EntityActivityManager.
 */
class EntityActivityManager implements EntityActivityManagerInterface {

  use StringTranslationTrait;

  /**
   * Drupal\Core\Config\ConfigFactoryInterface definition.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

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

  /**
   * The entity repository.
   *
   * @var \Drupal\Core\Entity\EntityRepositoryInterface
   */
  protected $entityRepository;

  /**
   * The language manager.
   *
   * @var \Drupal\Core\Language\LanguageManagerInterface
   */
  protected $languageManager;

  /**
   * The current route match service.
   *
   * @var \Drupal\Core\Routing\CurrentRouteMatch
   */
  protected $currentRouteMatch;

  /**
   * The entity field manager.
   *
   * @var \Drupal\Core\Entity\EntityFieldManagerInterface
   */
  protected $entityFieldManager;

  /**
   * The log generator manager.
   *
   * @var \Drupal\entity_activity\Plugin\LogGeneratorManagerInterface
   */
  protected $logManager;

  /**
   * The current user.
   *
   * @var \Drupal\Core\Session\AccountProxyInterface
   */
  protected $currentUser;

  /**
   * The entity type bundle info service.
   *
   * @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface
   */
  protected $entityTypeBundleInfo;

  /**
   * The event dispatcher.
   *
   * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
   */
  protected $eventDispatcher;

  /**
   * Queue factory.
   *
   * @var \Drupal\Core\Queue\QueueFactory
   */
  protected $queueFactory;

  /**
   * The time service.
   *
   * @var \Drupal\Component\Datetime\Time
   */
  protected $time;

  /**
   * The state service.
   *
   * @var \Drupal\Core\State\StateInterface
   */
  protected $state;

  /**
   * The subscription storage.
   *
   * @var \Drupal\entity_activity\SubscriptionStorageInterface
   */
  protected $subscriptionStorage;

  /**
   * The log storage.
   *
   * @var \Drupal\entity_activity\LogStorageInterface
   */
  protected $logStorage;

  /**
   * EntityActivityManager constructor.
   *
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The config factory.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository
   *   The entity repository.
   * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
   *   The language manager.
   * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
   *   The entity field manager.
   * @param |Drupal\entity_activity\Plugin\LogGeneratorManagerInterface $manager
   *   The log generator manager.
   * @param \Drupal\Core\Session\AccountProxyInterface $current_user
   *   The current user.
   * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info
   *   The entity type bundle info service.
   * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
   *   The event dispatcher.
   * @param \Drupal\Core\Queue\QueueFactory $queue
   *   The queue factory.
   * @param \Drupal\Component\Datetime\Time $time
   *   The time service.
   * @param \Drupal\Core\State\StateInterface $state
   *   The state service.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function __construct(ConfigFactoryInterface $config_factory, EntityTypeManagerInterface $entity_type_manager, EntityRepositoryInterface $entity_repository, LanguageManagerInterface $language_manager, EntityFieldManagerInterface $entity_field_manager, LogGeneratorManagerInterface $manager, AccountProxyInterface $current_user, EntityTypeBundleInfoInterface $entity_type_bundle_info, EventDispatcherInterface $event_dispatcher, QueueFactory $queue, Time $time, StateInterface $state) {
    $this->configFactory = $config_factory;
    $this->entityTypeManager = $entity_type_manager;
    $this->entityRepository = $entity_repository;
    $this->languageManager = $language_manager;
    $this->entityFieldManager = $entity_field_manager;
    $this->logManager = $manager;
    $this->currentUser = $current_user;
    $this->entityTypeBundleInfo = $entity_type_bundle_info;
    $this->eventDispatcher = $event_dispatcher;
    $this->queueFactory = $queue;
    $this->time = $time;
    $this->state = $state;
    $this->subscriptionStorage = $this->entityTypeManager->getStorage('entity_activity_subscription');
    $this->logStorage = $this->entityTypeManager->getStorage('entity_activity_log');
  }

  /**
   * {@inheritdoc}
   */
  public function getSupportedContentEntityTypes($return_object = FALSE) {
    /** @var \Drupal\Core\Entity\ContentEntityTypeInterface[] $entity_types */
    $entity_types = $this->entityTypeManager->getDefinitions();
    foreach ($entity_types as $entity_type_id => $entity_type) {
      if (!$entity_type instanceof ContentEntityTypeInterface) {
        unset($entity_types[$entity_type_id]);
        continue;
      }
      if (!method_exists($entity_type, 'getBundleEntityType')
        || !$entity_type->hasLinkTemplate('canonical')) {
        // Custom modules can want to support content entity type without a
        // canonical link template, and then they must manage programmatically
        // subscriptions to these entities which can not have a "subscribe on"
        // button.
        $support_entity_type = new EntityActivitySupportEntityTypeEvent($entity_type_id);
        $this->eventDispatcher->dispatch(EntityActivityEvents::ENTITY_ACTIVITY_SUPPORT_ENTITY_TYPE, $support_entity_type);
        if ($support_entity_type->isSupported()) {
          continue;
        }
        unset($entity_types[$entity_type_id]);
      }
    }
    if ($return_object) {
      return $entity_types;
    }
    else {
      return array_keys($entity_types);
    }
  }

  /**
   * {@inheritdoc}
   */
  public function getContentEntityTypesEnabled() {
    $entity_types = [];
    $entity_type_settings = $this->configFactory->get('entity_activity.settings')->get('entity_type');
    foreach ($entity_type_settings as $entity_type_id => $value) {
      if ($value['enable']) {
        $entity_types[] = $entity_type_id;
      }
    }
    return $entity_types;
  }

  /**
   * {@inheritdoc}
   */
  public function getBundlesPerEntityType($entity_type_id) {
    $bundles = $this->entityTypeBundleInfo->getBundleInfo($entity_type_id);
    return $bundles;
  }

  /**
   * {@inheritdoc}
   */
  public function dispatch($event_name, ContentEntityInterface $entity) {
    $entity_type_enabled = $this->getContentEntityTypesEnabled();
    $is_enabled = in_array($entity->getEntityTypeId(), $entity_type_enabled);
    if ($is_enabled) {
      $event = new EntityActivityEvent($entity);
      $this->eventDispatcher->dispatch($event_name, $event);
    }
  }

  /**
   * {@inheritdoc}
   */
  public function getLogGenerators($entity_type_id, $langcode = NULL) {
    $log_generator_instances = [];
    $generators = $this->entityTypeManager->getStorage('entity_activity_generator')->loadMultiple();
    /** @var \Drupal\entity_activity\Entity\GeneratorInterface $generator */
    foreach ($generators as $generator) {
      $generator = $this->entityRepository->getTranslationFromContext($generator, $langcode);
      if (!$generator->status()) {
        continue;
      }
      $log_generators = $generator->getLogGenerators();
      foreach ($log_generators as $plugin_id => $log_generator_config) {
        try {
          $log_generator = $this->logManager->createInstance($plugin_id, $log_generator_config);
        }
        catch (PluginException $e) {
          $log_generator = NULL;
          // @todo log the error.
        }
        if ($log_generator instanceof LogGeneratorInterface
          && $log_generator->getSourceEntityType() == $entity_type_id) {
          $log_generator_instances[$generator->id()][$plugin_id] = $log_generator;
        }
      }
    }
    return $log_generator_instances;
  }

  /**
   * {@inheritdoc}
   */
  public function deleteSubscriptions(ContentEntityInterface $entity) {
    $subscriptions = $this->subscriptionStorage->loadMultipleByEntityAnyLangcode($entity);
    foreach ($subscriptions as $subscription) {
      $subscription->delete();
    }
  }

  /**
   * {@inheritdoc}
   */
  public function deleteUserSubscriptions(UserInterface $user) {
    $subscriptions = $this->subscriptionStorage->loadMultipleByOwner($user);
    foreach ($subscriptions as $subscription) {
      $subscription->delete();
    }
  }

  /**
   * {@inheritdoc}
   */
  public function deleteUserLogs(UserInterface $user) {
    $logs = $this->logStorage->loadMultipleByOwner($user);
    foreach ($logs as $log) {
      $log->delete();
    }
  }

  /**
   * {@inheritdoc}
   */
  public function getEntityLangcode(ContentEntityInterface $entity) {
    if ($entity->isTranslatable()) {
      $langcode = $entity->language()->getId();
    }
    else {
      $langcode = $this->languageManager->getDefaultLanguage()->getId();
    }
    return $langcode;
  }

  /**
   * {@inheritdoc}
   */
  public function purgeLog() {
    $queue = $this->queueFactory->get('entity_activity_purge_log_worker');
    $config = $this->configFactory->get('entity_activity.settings')->get('purge');

    if (empty($config['method'])) {
      return;
    }

    elseif ($config['method'] == 'time' && !empty($config['time']['number']) && !empty($config['time']['unit'])) {
      $current_date = new DrupalDateTime('now');
      $interval = new Interval($config['time']['number'], $config['time']['unit']);
      $expiration_date = $interval->subtract($current_date);
      $expiration = $expiration_date->getTimestamp();
      // Logs to be purged in groups of 50.
      $query = $this->logStorage->getQuery()
        ->accessCheck(FALSE)
        ->condition('created', $expiration, '<=')
        ->sort('created', 'ASC')
        ->range(0, 200);
      if ($config['read_only']) {
        $query->condition('read', TRUE);
      }
      $ids = $query->execute();

      if (!empty($ids)) {
        $data = array_chunk($ids, 50);
        foreach ($data as $chunk) {
          $queue->createItem($chunk);
        }

      }
    }

    elseif ($config['method'] == 'limit' && !empty($config['limit']['max'])) {
      // Heavy process. We run it only once per day.
      // @todo make this configurable.
      $request_time = $this->time->getCurrentTime();
      $next_process = $this->state->get('entity_activity.next_purge_log', 0);
      $purge_user_always = Settings::get('entity_activity_purge_user_always');
      if ($purge_user_always) {
        $next_process = 0;
      }
      if ($next_process < $request_time) {
        $tomorrow = strtotime('tomorrow 0:59:00');
        $this->state->set('entity_activity.next_purge_log', $tomorrow);

        // Let's go !
        $max = $config['limit']['max'];
        $users = $this->entityTypeManager->getStorage('user')->loadMultiple();
        /** @var \Drupal\user\UserInterface $user */
        foreach ($users as $user) {
          $data = [];
          $query = $this->logStorage->getQuery()
            ->accessCheck(FALSE)
            ->condition('uid', $user->id())
            ->sort('created', 'DESC')
            ->range($max, 200);
          $ids = $query->execute();

          if (!empty($ids)) {
            $data = array_chunk($ids, 50);
            foreach ($data as $chunk) {
              $queue->createItem($chunk);
            }
          }
        }
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function invalidateCache(ContentEntityInterface $entity) {
    if ($entity instanceof SubscriptionInterface) {
      Cache::invalidateTags(['entity_activity_subscription:' . $entity->getEntityTypeId() . ':' . $entity->id()]);
    }
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc