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

src/Helper.php
<?php declare(strict_types = 1);

namespace Drupal\activity_stream;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\activity_stream\ActivityDestinationInterface;
use Drupal\Core\Logger\LoggerChannelTrait;
use Drupal\Core\Entity\ContentEntityTypeInterface;
use Drupal\field\FieldConfigInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\user\UserInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\activity_stream\ActivityConfigInterface;
use Drupal\Core\Config\Entity\ConfigEntityInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemList;

/**
 * @todo Add class description.
 */
final class Helper {

  use LoggerChannelTrait;
  use StringTranslationTrait;

  /**
   * Constructs a Helper object.
   */
  public function __construct(
    private readonly EntityTypeManagerInterface $entityTypeManager,
    private readonly EntityFieldManagerInterface $entityFieldManager,
    private readonly ConfigFactoryInterface $configFactory,
  ) {}

  /**
   * Create activity
   *
   * @param [type] $entity
   * @param [type] $recipients
   * @param [type] $destinations
   * @param [type] $activity_date
   * @return void
   */
  public function createActivity($entity, $recipients, $destinations, $activity_date = NULL): void {
    // Read the entity Type from the Entity
    $entity_type_id = $entity->getEntityTypeId();
    // Read current user
    $current_user = \Drupal::currentUser();
    $storage_activity = $this->entityTypeManager->getStorage('activity_stream_activity')->create();
    $storage_activity->field_activity_entity->target_type = $entity_type_id;
    $storage_activity->field_activity_entity->target_id = $entity->id();
    $users = $this->entityTypeManager->getStorage('user')->loadMultiple($recipients);

    if ($activity_date !== NULL) {
      $storage_activity->set('field_activity_date', $activity_date);
    }
    else {
      $storage_activity->set('field_activity_date', time());
    }

    if (isset($users) && is_array($users) && !empty($users)) {
      foreach($users as $user) {
        $storage_activity->field_activity_recipient_user[] = $user->id(); 
      }
    }

    if(isset($destinations) && is_array($destinations) && !empty($destinations)) {
      foreach($destinations as $key => $destination) {
        if ($this->validateDestination($destination)) {
          $storage_activity->field_activity_destinations[] = $destination; 
        }
      }
    }

    $violations = $storage_activity->validate();
    if ($violations->count() > 0) {
      $this->getLogger('activity_stream')->error('Activity was not created due to validation errors. This usally happens when you miss out some required fields.');
    }
    else {
      $storage_activity->save();
    }     

  }

  /**
   * Validate destination
   *
   * @param [type] $destination
   * @return boolean
   */
  public function validateDestination($destination): bool {
    $activity_destination = $this->entityTypeManager->getStorage('activity_destination')->load($destination);
    if ($activity_destination instanceof ActivityDestinationInterface) {
      return TRUE;
    }
    return FALSE;
  }

  /**
   * Get supported content entities.
   *
   * @return array 
   *   Options of content entities.
   */
  public function getSupportedContentEntities() {
    $entity_type_manager = $this->entityTypeManager;
    $options = [];
    foreach ($entity_type_manager->getDefinitions() as $entity_id => $entity_type) {
      // Content entity.
      if ($entity_type instanceof ContentEntityTypeInterface
        && $entity_id !== 'activity'
        && $entity_id !== 'message'
        && $entity_id !== 'message_template') {
        $entity_type_bundle_info = \Drupal::service('entity_type.bundle.info');
        $config_entity_bundles = $entity_type_bundle_info->getBundleInfo($entity_type->id());
        foreach ($config_entity_bundles as $key => $value) {
          // Dot character in key names is not allowed in config, so we use "-".
          $options[$entity_id . '-' . $key] = $entity_type->getLabel() . ': ' . $value['label'];
        }
      }
    }
    asort($options);
    return $options;
  }

  /**
   * Get supported message templates
   *
   * @return array
   *   Message templates.
   */
  public function getSupportedMessageTemplates() {

    $message_templates = [
      '_none' => t('Do not use a message template')
    ];

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

    // Check all enabled messages.
    foreach ($message_storage->loadByProperties(['status' => '1']) as $key => $message_type) {
      if ($this->checkActivityStreamSupport($key)) {
        $message_templates[$key] = $key;
      }
    }

    return $message_templates;

  }

  /**
   * Get supported date fields
   *
   * @param $bundles
   *   The bundles of an entity.
   * @return array
   *   Supported date fields.
   */
  public function getSupportedDateFields($bundles) {

    $supported_fields = ['_none' => $this->t('Do not use Entity date field for activity date')];

    if (isset($bundles) && is_array($bundles) && !empty($bundles)) {
      foreach ($bundles as $key => $bundle) {          
        $bundle_string = $key; 
      }
      // Check if we have a group relationship
      if (str_contains($bundle_string, 'group_relationship')) {
        $entity = $this->getGroupRelationshipEntityFromString($bundle_string);
        if ($entity instanceof EntityInterface) {
          $entity_type_id = $entity->getEntityTypeId();
          $entity_bundle  = $entity->bundle();
        }
      }
      else {
        $entity_type_id = $this->getEntityTypeIdFromString($bundle_string);
        $entity_bundle  = $this->getEntityBundleFromString($bundle_string);
      }
      if (isset($entity_type_id) && isset($entity_bundle)) {
        // Check on that bundle
        $fields = $this->entityFieldManager
          ->getFieldDefinitions($entity_type_id, 
                              $entity_bundle);

        foreach ($fields as $key => $field) {
          if ($field->getType() === 'datetime' || $field->getType() === 'smartdate') {  
            $supported_fields[$key] = $field->getName();
          }
        }
      }
    }

    return $supported_fields;

  }

  /**
   * Get activity stream supported fields
   *
   * @return array
   *   Supported fields by activity stream.
   */
  protected function getActivityStreamSupportedFields() {

    $supported_fields = NULL;

    // Check on that bundle
    $fields = $this->entityFieldManager
      ->getFieldDefinitions('activity_stream_activity','activity_stream_activity');
      
    foreach ($fields as $key => $field) {
      $supported_fields[$key] = $key;
    }

    return $supported_fields;

  }

  /**
   * Get Group Relationship Entity From String.
   *
   * @param $string
   *   
   * @return object
   *   The entity object.
   */
  protected function getGroupRelationshipEntityFromString($string) {

    $entity = NULL; 

    $plugin_id = str_replace('group_relationship-', '', $string);
    $group_relationships = $this->entityTypeManager->getStorage('group_relationship')->loadByProperties(['type' => $plugin_id]);
    if ($group_relationship = reset($group_relationships)) {
      $entity = $group_relationship->getEntity();
    }

    return $entity;    

  }

  /**
   * Get entity type id from string.
   *
   * @param $string
   *   A string containing entity type id and bundle.
   * @return string
   *   The entity type id.
   */
  protected function getEntityTypeIdFromString($string) {
    $pos = strpos($string, '-');
    $entity_type_id = substr($string, 0, $pos);
    return $entity_type_id;
  }

  /**
   * Get entity bundle form string.
   *
   * @param $string
   *   A string containing entity type id and bundle.
   * @return string
   *   The entity bundle.
   */
  protected function getEntityBundleFromString($string) {
    $pos = strpos($string, '-') + 1;
    $entity_bundle = substr($string, $pos);
    return $entity_bundle;
  }  

  /**
   * Check activity stream support
   *
   * @param string $message_type
   *   The message type.
   * @return boolean
   *   TRUE | FALSE
   */
  protected function checkActivityStreamSupport(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;

  }

  /**
   * Check for a valid timestamp
   *
   * @param string $timestamp
   *   The timestamp string.
   * @return boolean
   *   TRUE | FALSE
   */
  public function isValidTimestamp(string $timestamp) {
    return (is_numeric($timestamp) && (int) $timestamp == $timestamp);
  } 

  /**
   * Validate entity type
   *
   * @param string $entity_type_id
   *   The entity type id as string.
   * @return boolean
   *   TRUE | FALSE
   */
  public function isValidEntityType(string $entity_type_id) {

    $storage = $this->entityTypeManager->getStorage($entity_type_id);
    if (!$storage) {
      return FALSE;
    }

    return TRUE;

  }

  /**
   * Validate entity bundle.
   *
   * @param string $entity_type_id
   *   The entity type id.
   * 
   * @param string $entity_bundle
   *   The entity bundle.
   * 
   * @return boolean
   *   TRUE | FALSE
   */
  public function isValidEntityBundle(string $entity_type_id, string $entity_bundle) {

    $storage = $this->entityTypeManager->getStorage($entity_type_id);
    if (!$storage) {
      return FALSE;
    }
    else {
      $bundle_entity_class = $storage->getEntityClass($entity_bundle);
      if (!$bundle_entity_class) {
        return FALSE;
      }
    }

    return TRUE;

  }  

  /**
   * Validate user UUID
   *
   * @param string $user_uuid
   *   The user uuid string.
   * @return boolean
   *   TRUE | FALSE
   */
  public function isValidUserUUID(string $user_uuid) {
    $users = $this->entityTypeManager->getStorage('user')->loadByProperties(['uuid' => $user_uuid]);
    if ($user = reset($users)) {
      if ($user instanceof UserInterface) {
        return TRUE;
      }
    }

    return FALSE;

  }

  /**
   * Check if activity has been set to direct
   *
   * @param $activity_config
   *   The activity config.
   * @return boolean
   *   TRUE | FALSE
   */
  public function isActivityDirect($activity_config) {

    $direct = FALSE;

    // Load Activity config from activity config id
    $activity_config = $this->entityTypeManager
      ->getStorage('activity_config')
      ->load($activity_config);

    if ($activity_config instanceof ActivityConfigInterface) {
      if ($activity_config->get('activity_direct')) {
        $direct = TRUE;
      }
    }

    return $direct;   

  }

  /**
   * Validate sort value
   *
   * @param string $sort_value
   *   The sort value.
   * @return boolean
   *   TRUE | FALSE
   */
  public function isValidSortValue(string $sort_value) {
    if ($sort_value === 'DESC' || $sort_value === 'ASC') {
      return TRUE;
    }    
    return FALSE;
  }

  /**
   * Validate sort field
   *
   * @param string $sort_field
   *   The sort field.
   * @return boolean
   *   TRUE | FALSE
   */
  public function isValidSortField(string $sort_field) {
    // Check the possible fields to sort
    $fields = $this->getActivityStreamSupportedFields();
    if (in_array($sort_field, $fields)) {
      return TRUE;
    }
    return FALSE;
  }

  /**
   * Get back multiple entities.
   *
   * @param $field
   *   The field instance.
   * @return array
   *   Data array of fields.
   */
  public function getMultipleEntities($field) {
    $data = [];
    $entities = $field->referencedEntities();

    foreach ($entities as $key => $entity) {
      if ($entity instanceof EntityInterface && !$entity instanceof ConfigEntityInterface) {
        foreach ($entity as $field_key => $field) {  
          if ($this->isReferenceType($field)) {
            $referenced_field = $field->entity;
            if ($referenced_field instanceof EntityInterface) {
              foreach ($referenced_field as $referenced_field_key => $referenced_field_value) {
                $data[$key][$field_key][$referenced_field_key] = $this->getFieldAtrributes($referenced_field_value);
              }
            }
          } 
          else {
            $data[$key][$field_key] = $this->getFieldAtrributes($field);
          }          
        }
      }
      else {
        $data[$key][$entity->id()] = $entity->id();
      }      
    }

    return $data;
  }

  /**
   * Validate reference type
   *
   * @param $field
   *   The field instance.
   * @return boolean
   *   TRUE | FALSE 
   */
  public function isReferenceType($field) {

    // Only works on object
    if (!is_object($field)) {
      return FALSE;
    }

    $field_defintion = $field->getFieldDefinition();
    $reference_types = ['entity_reference','dynamic_entity_reference', 'file', 'image'];
    if (in_array($field_defintion->getType(), $reference_types)) {
      return TRUE;
    }
    return FALSE;
  }

  /**
   * Get fields form referenced data.
   *
   * @param $field
   *   The field instance.
   * @return mixed
   *   FALSE | array   
   */
  public function isReferenceFieldType($field) {

    // Only works on object
    if (!is_object($field)) {
      return FALSE;
    }

    $field_defintion = $field->getFieldDefinition();
    $reference_types = ['entity_reference','dynamic_entity_reference', 'file', 'image'];
    if (in_array($field_defintion->getType(), $reference_types)) {
      if ($this->isUnlimited($field_defintion)) {
        return $this->getMultipleEntities($field);
      }
      else {
        return $field->entity;
      }
    }
    return FALSE;
  }

  /**
   * Check if field is set to unlimited
   *
   * @param $field_defintion
   *   The field defintion.
   * @return boolean
   *   TRUE | FALSE
   */
  public function isUnlimited($field_defintion) {
    $cardinality = FALSE;
    if ($field_defintion->getFieldStorageDefinition()->getCardinality() === -1) {
      $cardinality = TRUE;
    }
    return $cardinality; 
  }

  /**
   * Get flat attributes
   *
   * @param $field_defintion
   *   The field defintion.
   * @return boolean
   *   TRUE | FALSE
   */
  protected function getFlatAttributes($field_defintion) {

    $field_types = [
      'boolean',
      'string',
      'email',
      'integer',
      'language',
      'uuid'
    ];

    if (in_array($field_defintion->getType(), $field_types)) {
      return TRUE;
    } 

    return FALSE;

  }

  /**
   * Get the field atrributes
   *
   * @param $field
   *   The field as object or array.
   * @return array
   *   The field attribute.
   */
  protected function getFieldAtrributes($field) {
  
    if (is_object($field) && !$this->isUnlimited($field->getFieldDefinition())) {
      if ($this->getFlatAttributes($field->getFieldDefinition())) {
        return $field->value;
      }
      else {
        return $field[0];
      }        
    }

    return $field;

  }

  /**
   * Get an data array of fields for a given entity.
   *
   * @param $entity
   *   The entity
   * @return array
   *   The data array of fields.
   */
  public function loadTree($entity) {

    $tree = [];

    foreach($entity as $field_key => $field) {
      // Now check if we need to build a new tree
      if ($referenced_field = $this->isReferenceFieldType($entity->get($field_key))) {
        if ($referenced_field instanceof EntityInterface) {          
          $tree[$field_key] = $this->buildTree($referenced_field, 'reference');
        }
        else {
          $tree[$field_key] = $referenced_field;
        }
      }
      else {   
        $tree[$field_key] = $this->getFieldAtrributes($field);
      }
    }   

    return $tree;  
  }  

  /**
   * Get back data array of fields.
   *
   * @param $entity
   *   The entity object.
   * @return array
   *   Data array of fields.
   */
  protected function listFields($entity) {
    $tree = [];
    foreach($entity as $field_key => $field) {
      if ($referenced_field = $this->isReferenceFieldType($field)) {
        if ($referenced_field instanceof EntityInterface) {
          foreach ($referenced_field as $referenced_field_key => $referenced_field_value) {
            $tree[$field_key][$referenced_field_key] = $this->getFieldAtrributes($referenced_field_value);
          }
        }
      }
      else {
        $tree[$field_key] = $this->getFieldAtrributes($field);
      }
    }
    return $tree;
  }

  /**
   * Build a tree by given entity.
   *
   * @param $entity
   *   The entity object.
   * @return array
   *   The data array of fields.
   */
  protected function buildTree($entity) {

    $tree = [];
    
    foreach($entity as $field_key => $field) {  
      if ($referenced_field = $this->isReferenceFieldType($field)) {
        if ($referenced_field instanceof EntityInterface) {
          $tree[$field_key] = $this->listFields($referenced_field);
        }
        else {
          $tree[$field_key] = $referenced_field;
        }
      }
      else {
        $tree[$field_key] = $this->getFieldAtrributes($field); 
      }
    }
    
    return $tree;

  }  

}  


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

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