entity_change_notifier-8.x-1.0/src/EntityPublisher.php

src/EntityPublisher.php
<?php

namespace Drupal\entity_change_notifier;

use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Logger\RfcLogLevel;
use Drupal\Core\Queue\QueueFactory;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Utility\Error;
use Drupal\entity_change_notifier\Entity\DestinationInterface;
use Drupal\entity_change_notifier\Plugin\MessageDestination\MessageDestinationPluginManager;
use Drupal\entity_change_notifier\Plugin\MessageDestination\NotifyException;
use Drupal\entity_change_notifier\Plugin\QueueWorker\FailedItem;
use Psr\Log\LoggerInterface;

/**
 * Send entity notifications to all publishers, handling failed messages.
 */
class EntityPublisher implements EntityPublisherInterface {

  /**
   * The service used to load Publisher config entities.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * The queue used to retry failed publishing actions.
   *
   * @var \Drupal\Core\Queue\QueueInterface
   */
  protected $retryQueue;

  /**
   * The logger used to notify admins of failed messages.
   *
   * @var \Psr\Log\LoggerInterface
   */
  protected $logger;

  /**
   * The Destination plugin manager.
   *
   * @var \Drupal\entity_change_notifier\Plugin\MessageDestination\MessageDestinationPluginManager
   */
  protected $destinationPluginManager;

  /**
   * The service used to get the request time.
   *
   * @var \Drupal\Component\Datetime\TimeInterface
   */
  protected $time;

  /**
   * Constructs a new EntityPublisher.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager used to load publisher config entities.
   * @param \Drupal\Core\Queue\QueueFactory $queue_factory
   *   The queue factory used to retrieve the "retry" queue.
   * @param \Psr\Log\LoggerInterface $logger
   *   The logger used to notify admins of failed messages.
   * @param \Drupal\entity_change_notifier\Plugin\MessageDestination\MessageDestinationPluginManager $destinationManager
   *   The destination plugin manager.
   * @param \Drupal\Component\Datetime\TimeInterface $time
   *   The service used to get the request time.
   */
  public function __construct(EntityTypeManagerInterface $entity_type_manager, QueueFactory $queue_factory, LoggerInterface $logger, MessageDestinationPluginManager $destinationManager, TimeInterface $time) {
    $this->entityTypeManager = $entity_type_manager;
    $this->retryQueue = $queue_factory->get('entity_change_notifier_retry');
    $this->logger = $logger;
    $this->destinationPluginManager = $destinationManager;
    $this->time = $time;
  }

  /**
   * {@inheritdoc}
   */
  public function notifyMultiple($action, EntityInterface $entity) {
    /** @var \Drupal\entity_change_notifier\Entity\PublisherInterface[] $publishers */
    $publishers = $this->entityTypeManager->getStorage('ecn_publisher')->loadMultiple();

    /** @var \Drupal\entity_change_notifier\Entity\PublisherInterface $publisher */
    foreach ($publishers as $publisher) {
      try {
        $publisher->notify($action, $entity);
      }
      catch (NotifyException $e) {
        /** @var \Drupal\entity_change_notifier\Entity\DestinationInterface $destination */
        $destination = $this->entityTypeManager->getStorage('ecn_destination')->load($publisher->getDestination());
        $failedItem = $this->logRetry($destination, $e, $entity);
        $this->retryQueue->createItem($failedItem);
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function logRetry(DestinationInterface $destination, NotifyException $e, EntityInterface $entity = NULL) {
    $failedItem = FailedItem::fromNotifyException($e, $this->time->getRequestTime() + $destination->getMessageExpiry());

    // We want to log the underlying error and not just the generic fact that
    // a notification failed.
    $this->watchdogException($e->getPrevious(), '%title failed to send to %destination (%id) and will be retried later: %type: @message in %function (line %line of %file).', $this->logPlaceholders($destination, $entity), RfcLogLevel::WARNING);

    return $failedItem;
  }

  /**
   * {@inheritdoc}
   */
  public function logDropped(DestinationInterface $destination, NotifyException $e, EntityInterface $entity = NULL) {
    // We want to log the underlying error and not just the generic fact that
    // a notification failed.
    $this->watchdogException($e->getPrevious(), '%title failed to send to %destination (%id) and has been dropped: @message', $this->logPlaceholders($destination, $entity), RfcLogLevel::WARNING);
  }

  /**
   * {@inheritdoc}
   */
  public function retryNotification(DestinationInterface $destination, array $data) {
    /** @var \Drupal\entity_change_notifier\Plugin\MessageDestination\MessageDestinationInterface $messageDestination */
    $messageDestination = $this->destinationPluginManager->createInstance($destination->getMessageDestination(), $destination->getMessageDestinationSettings());
    $messageDestination->setDestinationConfigurationEntity($destination->id());
    $messageDestination->notifyDirect($data);
  }

  /**
   * Helper to log an exception to the watchdog.
   *
   * @param \Exception $exception
   *   The exception that is going to be logged.
   * @param string $message
   *   The message to store in the log. If empty, a text that contains all
   *   useful information about the passed-in exception is used.
   * @param array $variables
   *   Array of variables to replace in the message on display or
   *   NULL if message is already translated or not possible to
   *   translate.
   * @param int $severity
   *   The severity of the message, as per RFC 3164.
   * @param string $link
   *   A link to associate with the message.
   *
   * @see watchdog_exception
   */
  private function watchdogException(\Exception $exception, $message = NULL, array $variables = [], $severity = RfcLogLevel::ERROR, $link = NULL) {
    // Use a default value if $message is not set.
    if (empty($message)) {
      $message = '%type: @message in %function (line %line of %file).';
    }

    if ($link) {
      $variables['link'] = $link;
    }

    $variables += Error::decodeException($exception);

    $this->logger->log($severity, $message, $variables);
  }

  /**
   * Return common log placeholders.
   *
   * @param \Drupal\entity_change_notifier\Entity\DestinationInterface $destination
   *   The destination configuration entity associated with the log message.
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   (optional) The entity that failed to notify.
   *
   * @return array
   *   An array of placeholders containing:
   *     - '%destination'
   *     - '%id'
   *     - '%title'
   *     - 'link', if one exists
   */
  private function logPlaceholders(DestinationInterface $destination, EntityInterface $entity = NULL) {
    return [
      '%destination' => $destination->label(),
      '%id' => $destination->id(),
    ] + $this->entityPlaceholders($entity);
  }

  /**
   * Generate placeholders for use in log messages.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   (optional) The entity that the notification failed to send for.
   *
   * @return array
   *   An array of placeholders containing:
   *     - '%title'
   *     - 'link', if one exists
   */
  private function entityPlaceholders(EntityInterface $entity = NULL) {
    $entityPlaceholders = [
      '%title' => isset($entity) ? $entity->label() : 'Unknown title',
    ];

    // NULL is the default parameter for watchdogException().
    $link = NULL;
    if ($entity && $entity->hasLinkTemplate('canonical')) {
      $link = new TranslatableMarkup('<a href="@url">View</a>', [
        '@url' => $entity->toUrl('canonical')->toString(),
      ]);
      $entityPlaceholders['link'] = $link;
    }
    return $entityPlaceholders;
  }

}

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

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