butils-8.x-1.x-dev/src/EntityTrait.php

src/EntityTrait.php
<?php

namespace Drupal\butils;

use Drupal\Core\Entity\EntityInterface;
use Drupal\file\Entity\File;

/**
 * Trait Entity.
 *
 * Provides general entity related utils.
 */
trait EntityTrait {

  /**
   * Either gets the entity by values or creates a new one.
   *
   * @param string $type
   *   Entity type.
   * @param array $values
   *   Entity values.
   *
   * @return \Drupal\Core\Entity\EntityInterface
   *   Resulting entity.
   */
  public function toEntity($type, array $values) {
    $query = $this->entityTypeManager->getStorage($type)->getQuery();
    foreach ($values as $key => $value) {
      $query->condition($key, $value);
    }
    $ids = $query->accessCheck(FALSE)->execute();
    if (!empty($ids)) {
      $id = reset($ids);
      $entity = $this->entityTypeManager->getStorage($type)->load($id);
    }
    else {
      $entity = $this->entityTypeManager->getStorage($type)->create($values);
      $entity->save();
    }

    return $entity;
  }

  /**
   * Dereference: get value by path.
   *
   * Path should be in the form of field_1.fild2.fid.
   *
   * @param string $path
   *   Mapped path.
   * @param object $entity
   *   Source data.
   *
   * @return mixed
   *   Field result.
   */
  public function deref($path, $entity) {
    $path_parts = explode('.', $path);
    $entity_type = $entity->getEntityTypeId();

    // Drill through the entity mapping values.
    $item = $entity;
    foreach ($path_parts as $part) {
      array_shift($path_parts);

      // Item is object.
      if ($item instanceof EntityInterface) {

        // Not a webform submission. Handle as a usual entity.
        if ($item->hasField($part)) {
          $field = $item->get($part);
          $def = $field->getFieldDefinition();
          $field_type = $def->getType();

          // Numeric? Sub-item.
          $key = is_numeric(reset($path_parts)) ? array_shift($path_parts) : 0;

          // Get value depending on type.
          switch ($field_type) {

            // Address.
            case 'address':
              $item = $field->getValue($key);
              if (!empty($item)) {
                $item = reset($item);
              }
              break;

            // File or Image.
            case 'image':
            case 'file':
              $item = $field->getValue($key);
              if (!empty($item)) {
                $item = File::load(reset($item)['target_id']);
                if (!empty($item)) {
                  $item = $this->deref(implode('.', $path_parts), $item);
                }
                else {
                  $item = '';
                }
                break;
              }
              break;

            // Entity reference.
            case 'entity_reference':
            case 'entity_reference_revisions':
              $ref_settings = $def->getSettings();
              $target_type = $ref_settings['target_type'];
              $item = $field->get($key);
              if (!empty($item)) {
                $item = $item->target_id;
              }
              if (!empty($target_type) && is_numeric($item)) {
                $item = $this->entityTypeManager->getStorage($target_type)->load($item);
                $item = $this->deref(implode('.', $path_parts), $item);
              }
              else {
                $item = '';
              }
              break;

            default:
              $values = $field->getValue();
              if (count($values) > 1) {
                $item = [];
                foreach ($values as $value) {
                  $item[] = reset($value);
                }
              }
              else {
                $item = $field->getString();
              }
          }
        }

        // Some more options. Log error if fail.
        else {

          // Allow mapping webform submission value.
          if ($entity_type == 'webform_submission') {
            $data = $item->getData();
            $item = $data[$part] ?? '';
          }

          // No matches, return empty result.
          else {
            return '';
          }
        }
      }

      // Item is array.
      elseif (is_array($item)) {
        if (!empty($item[$part])) {
          $item = $item[$part];
        }
        else {

          // Array key empty. Return NULL.
          return '';
        }
      }
    }

    // Result is an entity. Get it's title or name.
    if ($item instanceof EntityInterface) {
      if ($item->hasField('title')) {
        $item = $item->title->getString();
      }
      elseif ($item->hasField('name')) {
        $item = $item->name->getString();
      }
    }

    return $item;
  }

  /**
   * Get all available view modes as key => value.
   *
   * @param string $entity_type
   *   Type of entity which view modes to get.
   * @param string $bundle
   *   Entity bundle if any. Required to get display settings.
   * @param bool $labels_only
   *   Whether to return only the labels, or actual view modes as well.
   *
   * @return array
   *   View modes.
   */
  public function getViewModes($entity_type, $bundle = '', $labels_only = TRUE) {
    if ($labels_only) {
      return !empty($bundle)
        ? $this->entityDisplayRepository->getViewModeOptionsByBundle($entity_type, $bundle)
        : $this->entityDisplayRepository->getViewModeOptions($entity_type);
    }
    $view_modes = [];
    $all_modes = $this->entityDisplayRepository->getViewModes($entity_type);
    $bundle_modes = !empty($bundle)
      ? $this->entityDisplayRepository->getViewModeOptionsByBundle($entity_type, $bundle)
      : [];
    $all_modes['default'] = [
      'label' => 'Default',
      'emulated' => TRUE,
    ];
    foreach ($all_modes as $name => $mode) {
      if (!empty($bundle_modes)) {
        if (!empty($bundle_modes[$name]) || $name == 'default') {
          $view_modes[$name] = $labels_only ? $mode['label'] : $mode;
          $view_modes[$name]['display'] = $this->entityDisplayRepository->getViewDisplay($entity_type, $bundle, $name);
        }
      }
      else {
        $view_modes[$name] = $labels_only ? $mode['label'] : $mode;
      }
    }

    return $view_modes;
  }

  /**
   * Counts words in an entity.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   Entity to render and count words.
   * @param string $view_mode
   *   View mode to render in.
   *
   * @return int
   *   Number of words.
   */
  public function entityCountWords(EntityInterface $entity, $view_mode = 'default') {
    $build = $this->entityTypeManager
      ->getViewBuilder($entity->getEntityTypeId())
      ->view($entity, $view_mode);
    $html = $this->renderer->renderRoot($build);
    return $this->countWords($html);
  }

  /**
   * Builds a build array for an entity.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   Entity to render and count words.
   * @param string $view_mode
   *   View mode to render in.
   *
   * @return array
   *   Build array.
   */
  public function entityBuild(EntityInterface $entity, $view_mode = 'default') {
    $view_builder = $this->entityTypeManager->getViewBuilder($entity->getEntityTypeId());
    $viewed = $view_builder->view($entity, $view_mode);
    return $view_builder->build($viewed);
  }

  /**
   * Renders an entity.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   Entity to render and count words.
   * @param string $view_mode
   *   View mode to render in.
   *
   * @return string
   *   Html output.
   */
  public function entityRender(EntityInterface $entity, $view_mode = 'default') {
    $build = $this->entityTypeManager
      ->getViewBuilder($entity->getEntityTypeId())
      ->view($entity, $view_mode);
    return $this->renderer->renderRoot($build);
  }

  /**
   * Loads entity of type by id.
   *
   * @param string $type
   *   Entity type.
   * @param string|array $id
   *   Entity id.
   *
   * @return \Drupal\Core\Entity\EntityInterface|array|null
   *   The loaded entity.
   */
  public function entityLoad($type, $id) {
    if (is_array($id)) {
      return $this->entityTypeManager->getStorage($type)->loadMultiple($id);
    }
    else {
      return $this->entityTypeManager->getStorage($type)->load($id);
    }
  }

  /**
   * Get entity query by type.
   *
   * @param string $type
   *   Entity type.
   *
   * @return \Drupal\Core\Entity\Query\QueryInterface|null
   *   The entity query.
   */
  public function entityQuery($type) {
    return $this->entityTypeManager->getStorage($type)->getQuery();
  }

  /**
   * Check existance of entity type.
   *
   * @param string $type
   *   Entity type.
   *
   * @return bool
   *   Operation result.
   */
  public function entityTypeExists($type) {
    return $this->entityTypeManager->hasDefinition($type);
  }

  /**
   * Check existance of entity of type by id.
   *
   * @param string $type
   *   Entity type.
   * @param string $id
   *   Entity id.
   *
   * @return bool
   *   Operation result.
   */
  public function entityExists($type, $id) {
    if (!$this->entityTypeExists($type)) {
      return FALSE;
    }
    $query = $this->entityQuery($type);
    $key = $this->entityTypeManager->getDefinition($type)->getKey('id');
    $query->accessCheck(FALSE);
    return (!empty($query->condition($key, $id)->execute()));
  }

  /**
   * Map string value to entity field.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   Destination entity.
   * @param string $field_name
   *   Name of the field.
   * @param string $value
   *   Value to map.
   * @param string $input_format
   *   Input format if any. Used for textareas.
   *
   * @return bool
   *   Operation result.
   */
  public function mapString(EntityInterface $entity, $field_name, $value, $input_format = NULL) {
    if (!$entity->hasField($field_name)) {
      return FALSE;
    }
    if (!empty($value)) {
      if ($input_format) {
        $entity->set($field_name, [
          'value' => $value,
          'format' => $input_format,
        ]);
      }
      else {
        $entity->set($field_name, $value);
      }
    }
    else {
      $this->emptyField($entity, $field_name, FALSE);
    }

    return TRUE;
  }

  /**
   * Map some value to entity field.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   Destination entity.
   * @param string $field_name
   *   Name of the field.
   * @param string|array $value
   *   Value to map.
   *
   * @return bool
   *   Operation result.
   */
  public function mapValue(EntityInterface $entity, $field_name, $value) {
    if (!$entity->hasField($field_name)) {
      return FALSE;
    }
    if (!empty($value)) {
      $entity->set($field_name, $value);
    }
    else {
      $this->emptyField($entity, $field_name, FALSE);
    }

    return TRUE;
  }

  /**
   * Map boolean value to an entity.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   Node object.
   * @param string $field_name
   *   Name of the field.
   * @param string $value
   *   Value to map.
   *
   * @return bool
   *   Operation result.
   */
  public function mapBool(EntityInterface $entity, $field_name, $value) {
    if (!$entity->hasField($field_name)) {
      return FALSE;
    }
    $value = (bool) $this->cleanString($value);
    if ($value) {
      $entity->set($field_name, $value);
    }
    else {
      $this->emptyField($entity, $field_name, FALSE);
    }

    return TRUE;
  }

  /**
   * Map term value to an entity field.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   Node object.
   * @param string $field_name
   *   Name of the field.
   * @param string $vid
   *   Vocabulary id.
   * @param string|array|null $value
   *   Value to map.
   * @param string $langcode
   *   Langcode to use for new terms. Defaults to zxx.
   *
   * @return bool
   *   Operation result.
   */
  public function mapTerm(EntityInterface $entity, $field_name, $vid, $value = NULL, $langcode = NULL) {
    if (!$entity->hasField($field_name)) {
      return FALSE;
    }
    $langcode = $langcode ?? 'zxx';
    $value = (array) $value;
    $tids = [];

    if (!empty($value)) {
      foreach ($value as $sub_value) {
        if (is_array($sub_value)) {
          $tids[] = $this->toHierarchicalTerms($sub_value, $vid, $langcode);
        }
        else {
          $tids[] = $this->toTerm($sub_value, $vid, $langcode);
        }
      }
      if (!empty($tids)) {
        $field_value = [];
        foreach ($tids as $tid) {
          if (!empty($tid)) {
            $field_value[] = [
              'target_id' => $tid,
            ];
          }
        }
        if (!empty($field_value)) {
          $entity->set($field_name, $field_value);
        }
      }
    }
    else {
      $this->emptyField($entity, $field_name, FALSE);
    }

    return TRUE;
  }

  /**
   * Map number value to an entity field.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   Node object.
   * @param string $field_name
   *   Name of the field.
   * @param string $value
   *   Value to map.
   *
   * @return bool
   *   Operation result.
   */
  public function mapNum(EntityInterface $entity, $field_name, $value) {
    if (!$entity->hasField($field_name)) {
      return FALSE;
    }
    $value = (float) $this->cleanString($value);
    if ($value) {
      $entity->set($field_name, $value);
    }
    else {
      $this->emptyField($entity, $field_name, FALSE);
    }

    return TRUE;
  }

  /**
   * Maps key-value field data.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   Entity to map to.
   * @param string $field_name
   *   Field id.
   * @param array $keys
   *   Keys.
   * @param array $values
   *   Values.
   *
   * @return bool
   *   Operation result.
   */
  public function mapKeyValues(EntityInterface $entity, $field_name, $keys, $values) {
    if (!empty($keys) && !empty($values)) {
      $field_value = [];
      foreach ($keys as $i => $key) {
        if (!empty($key)) {
          $field_value[$i] = [
            'key' => $key,
            'value' => $values[$i] ?? NULL,
          ];
        }
      }
      $entity->set($field_name, $field_value);
    }
    else {
      $this->emptyField($entity, $field_name, FALSE);
    }

    return TRUE;
  }

}

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

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