activity_stream-1.0.x-dev/src/ActivityMessageFactory.php

src/ActivityMessageFactory.php
<?php

namespace Drupal\activity_stream;

use Drupal\activity_stream\Plugin\ActivityContextManager;
use Drupal\activity_stream\Plugin\ActivityEntityConditionManager;
use Drupal\activity_stream\Entity\NotificationConfigEntityInterface;
use Drupal\Core\Entity\EntityBase;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\field\FieldConfigInterface;
use Drupal\message\Entity\Message;
use Drupal\user\EntityOwnerInterface;
use Drupal\activity_stream\Entity\Activity;

/**
 * Class ActivityMessageFactory.
 *
 * @package Drupal\activity_stream\Service
 * Service that determines which actions need to be performed.
 */
class ActivityMessageFactory {

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

  /**
   * The condition manager.
   *
   * @var \Drupal\activity_stream\Plugin\ActivityEntityConditionManager
   */
  protected $activityEntityConditionManager;

  /**
   * The context manager.
   *
   * @var \Drupal\activity_stream\Plugin\ActivityContextManager
   */
  protected $activityContextManager;

  /**
   * The module handler.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected $moduleHandler;

  /**
   * ActivityLoggerFactory constructor.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   *   The entity type manager.
   * @param \Drupal\activity_stream\Plugin\ActivityEntityConditionManager $activityEntityConditionManager
   *   The condition manager.
   * @param \Drupal\activity_stream\Plugin\ActivityContextManager $activityContextManager
   *   The context manager.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $moduleHandler
   *   The module handler.
   */
  public function __construct(
    EntityTypeManagerInterface $entityTypeManager,
    ActivityEntityConditionManager $activityEntityConditionManager,
    ActivityContextManager $activityContextManager,
    ModuleHandlerInterface $moduleHandler) {
    $this->entityTypeManager = $entityTypeManager;
    $this->activityEntityConditionManager = $activityEntityConditionManager;
    $this->activityContextManager = $activityContextManager;
    $this->moduleHandler = $moduleHandler;
  }

  /**
   * Create message entities.
   *
   * @param \Drupal\Core\Entity\EntityBase $entity
   *   Entity object to create a message for.
   * @param string $action
   *   Action string. Defaults to 'create'.
   */
  public function createMessages(EntityBase $entity, $action): void {

    $helper_service = \Drupal::service('activity_stream.helper');

    // Get all activity configs that are responsible for creating items.
    $activity_types = $this->getActivtyConfig($action, $entity);
    // Loop through those message types and create messages.
    foreach ($activity_types as $activity_type => $values) {

      $activity_date_value = $values['activity_date'];
      if (isset($activity_date_value) && !empty($activity_date_value)) {
        // Check if that field would be available in the given entity.
        // And check if group relationship present.
        if ($entity->getEntityTypeId() === 'group_relationship') {
          $related_entity = $entity->getEntity();
          if ($related_entity->hasField($activity_date_value)) {            
            $activity_date = $related_entity->$activity_date_value->value;            
          }
        }
        else {
          if ($entity->hasField($activity_date_value)) {
            $activity_date = $entity->$activity_date_value->value;
          }
        }
      }

      // Create the ones applicable for this bundle.
      // Determine destinations.
      $destinations = [];
      if (!empty($values['destinations']) && is_array($values['destinations'])) {
        foreach ($values['destinations'] as $destination) {
          $destinations[] = ['target_id' => $destination];
        }
      }

      // Get context
      $activity_context = $values['context'];

      // Get message template
      if (isset($values['message_template']) && !empty($values['message_template'])) {
        // Set the values.
        $new_message['template'] = $values['message_template'];

        // Get the owner or default to anonymous.
        if ($entity instanceof EntityOwnerInterface && $entity->getOwner() !== NULL) {
          $new_message['uid'] = (string) $entity->getOwner()->id();
        }
        else {
          $new_message['uid'] = '0';
        }

        if ($entity instanceof NotificationConfigEntityInterface) {
          $new_message['field_message_related_object'] = [
            'target_type' => $entity->getEntityTypeId(),
            'target_id' => $entity->getUniqueId(),
          ];
          $new_message['created'] = $entity->getCreatedTime();
        }
        else {
          $new_message['field_message_related_object'] = [
            'target_type' => $entity->getEntityTypeId(),
            'target_id' => $entity->id(),
          ];
          // The flagging entity does not implement getCreatedTime().
          if ($entity->getEntityTypeId() === 'flagging') {
            $new_message['created'] = $entity->get('created')->value;
          }
          elseif ($entity->getEntityTypeId() === 'organizer') {
            $new_message['created'] = $entity->get('created')->value;
          }
          else {
            $new_message['created'] = $entity->getCreatedTime();
          }
        } 
        
        $new_message['field_message_context'] = $activity_context;
        $new_message['field_message_destination'] = $destinations;

        // Create the message only if it doesn't exist.
        if (!$this->checkIfMessageExist($new_message['template'], $new_message['field_message_context'], $new_message['field_message_destination'], $new_message['field_message_related_object'], $new_message['uid'])) {
        
          $message = Message::create($new_message);
          $message->save();
          if ($message instanceof Message) {
            $data = [
              'activity_config' => $activity_type,
              'mid' => $message->id(),
              'message_template' => $message->getTemplate()->id(),
              'actor' => $message->getOwner()->id(),
              'context' => $activity_context,
              'destination' => $destinations,
              'related_object' => $new_message['field_message_related_object'],
              'last_uid' => 0,
              'status' => NULL,
            ];

            if (isset($activity_date)) {
              $data['activity_date'] = $activity_date;
            }



            if ($helper_service->isActivityDirect($activity_type)) {
              $activities = \Drupal::service('activity_stream.activity_factory')->createActivities($data);
            }
            else {
              $queue = \Drupal::queue('activity_stream_activities');
              $queue->createItem($data); 
            }
          } 
        }
      }
      else {

        $data = [
          'activity_config' => $activity_type,
          'actor' => $entity->getOwner()->id(),
          'context' => $activity_context,
          'destination' => $destinations,
          'related_object' => [
            'target_type' => $entity->getEntityTypeId(),
            'target_id' => $entity->id(),            
          ],
          'last_uid' => 0,
          'status' => NULL,
        ];        

        if (isset($activity_date)) {
          $data['activity_date'] = $activity_date;
        }   

       
        if ($helper_service->isActivityDirect($activity_type)) {
          $activities = \Drupal::service('activity_stream.activity_factory')->createActivities($data);
        }
        else {
          $queue = \Drupal::queue('activity_stream_activities');
          $queue->createItem($data); 
        }

      }
    }
  }

  /**
   * Get message templates for action and entity.
   *
   * @param string $action
   *   Action string, e.g. 'create'.
   * @param \Drupal\Core\Entity\EntityBase $entity
   *   Entity object.
   *
   * @return array
   *   Array of message types.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   * @throws \Drupal\Component\Plugin\Exception\PluginException
   */
  public function getActivtyConfig($action, EntityBase $entity) {
    // Init.
    $activity_types = [];

    // Message type storage.
    $activity_config_storage = $this->entityTypeManager->getStorage('activity_config');

    // Check all enabled messages.
    foreach ($activity_config_storage->loadByProperties(['status' => '1']) as $key => $activity_type) {
      $activity_entity_bundles = $activity_type->get('activity_bundle_entities');
      $activity_entity_action = $activity_type->get('activity_entity_action');
      $activity_context = $activity_type->get('activity_context');
      $activity_destinations = $activity_type->get('activity_destinations');
      $activity_entity_condition = $activity_type->get('activity_entity_condition');
      $activity_message_template = $activity_type->get('activity_message_template');
      $activity_direct = $activity_type->get('activity_direct');
      $activity_aggregate = $activity_type->get('activity_aggregate');
      $activity_date = $activity_type->get('activity_date');

      if ($activity_message_template === '_none') {
        $activity_message_template = NULL;
      }

      if ($activity_entity_action !== $action) {
        continue;
      }

      $entity_bundle_name = $entity->getEntityTypeId() . '-' . $entity->bundle();
      if (!in_array($entity_bundle_name, $activity_entity_bundles, TRUE)) {
        continue;
      }

      if (!$this->activityContextManager->hasDefinition($activity_context)) {
        continue;
      }

      if (
        !empty($activity_entity_condition)
        && $this->activityEntityConditionManager->hasDefinition($activity_entity_condition)
        && !$this->activityEntityConditionManager->createInstance($activity_entity_condition)->isValidEntityCondition($entity)
      ) {
        continue;
      }

      $context_plugin = $this->activityContextManager->createInstance($activity_context);
      if ($context_plugin->isValidEntity($entity)) {
        $activity_types[$key] = [
          'activity_type' => $activity_type,
          'bundle' => $entity_bundle_name,
          'destinations' => $activity_destinations,
          'context' => $activity_context,
          'message_template' => $activity_message_template,
          'activity_direct' => $activity_direct,
          'activity_aggregate' => $activity_aggregate,
          'activity_date' => $activity_date,
        ];
      }
    }

    // Return the message types that belong to the requested action.
    return $activity_types;

  }

  /**
   * Checks that a message template is compatible with the activity system.
   *
   * To support activities, various fields need to exist on a message template,
   * with the right configuration. Below are the most important configurations
   * for a field that are checked, though these are not complete examples of
   * a field config.
   *
   * ```yaml
   * message.<message_type>.field_message_context:
   *   langcode: en
   *   status: TRUE
   *   id: message.<message_type>.field_message_context
   *   field_type: list_string
   *   module: ['options']
   *   field_name: field_message_context
   *   required: FALSE
   *   translatable: FALSE
   *
   * message.<message_type>.field_message_destination:
   *   langcode: en
   *   status: TRUE
   *   id: message.<message_type>.field_message_destination
   *   field_type: list_string
   *   module: ['options']
   *   field_name: field_message_destination
   *   required: FALSE
   *   translatable: FALSE
   *
   * message.<message_type>.field_message_related_object:
   *   langcode: en
   *   status: TRUE
   *   id: message.<message_type>.field_message_related_object
   *   field_type: dynamic_entity_reference
   *   module: ['dynamic_entity_reference']
   *   field_name: field_message_related_object
   *   required: FALSE
   *   translatable: FALSE
   * ```
   *
   * @param string $message_type
   *   The ID of the message type to check for.
   *
   * @return bool
   *   Whether the message type is compatible.
   */
  private function debugMessageTemplateIsCompatible(string $message_type) : bool {
    $config_storage = $this->entityTypeManager
      ->getStorage('field_config');

    $field_message_context = $config_storage->load("message.$message_type.field_message_context");
    if (!$field_message_context instanceof FieldConfigInterface) {
      return FALSE;
    }

    $field_message_destination = $config_storage->load("message.$message_type.field_message_destination");
    if (!$field_message_destination instanceof FieldConfigInterface) {
      return FALSE;
    }    

    $field_message_related_object = $config_storage->load("message.$message_type.field_message_related_object");
    if (!$field_message_related_object instanceof FieldConfigInterface) {
      return FALSE;
    }    

    return TRUE;

  }


  /**
   * Checks if a message already exists.
   *
   * @param string $message_type
   *   The message type.
   * @param string $context
   *   The context of the message.
   * @param array $destination
   *   The array of destinations to check for, include delta as well.
   * @param array $related_object
   *   The related object, include target_type and target_id in array.
   * @param string $uid
   *   The uid of the message.
   *
   * @return bool
   *   Returns true if the message exists.
   */
  public function checkIfMessageExist(string $message_type, string $context, array $destination, array $related_object, string $uid): bool {
    $exists = FALSE;
    $query = $this->entityTypeManager->getStorage('message')->getQuery();
    $query->condition('template', $message_type);
    $query->condition('field_message_related_object.target_id', $related_object['target_id']);
    $query->condition('field_message_related_object.target_type', $related_object['target_type']);
    $query->condition('field_message_context', $context);
    $query->condition('uid', $uid);
    foreach ($destination as $delta => $dest_value) {
      $query->condition('field_message_destination.target_id', $delta);     
    }
    $query->accessCheck(FALSE);



    $ids = $query->execute();

    $allowed_duplicates = ['moved_content_between_groups'];
    $this->moduleHandler->alter('activity_allowed_duplicates', $allowed_duplicates);

    if (!empty($ids) && !in_array($message_type, $allowed_duplicates)) {
      $exists = TRUE;
    }
    return $exists;
  }

}

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

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