entity_hierarchy-8.x-2.24/src/Storage/RecordCollection.php

src/Storage/RecordCollection.php
<?php

declare(strict_types=1);

namespace Drupal\entity_hierarchy\Storage;

/**
 * A collection of record objects with useful functions.
 */
class RecordCollection implements \IteratorAggregate, \Countable {

  /**
   * Constructor for a record collection.
   *
   * @param \Drupal\entity_hierarchy\Storage\Record[] $records
   *   The records to put in a collection.
   */
  public function __construct(
    protected array $records,
  ) {}

  /**
   * The raw underlying records in the collection.
   *
   * @return \Drupal\entity_hierarchy\Storage\Record[]
   *   The records.
   */
  public function getRecords() {
    return $this->records;
  }

  /**
   * An iterator that knows how to handle the collection tree structure.
   *
   * @return \Traversable<\Drupal\entity_hierarchy\Storage\Record>
   *   The iterator so that a collection can be passed directly into foreach.
   */
  public function getIterator(): \Traversable {
    return new \RecursiveIteratorIterator(
      new RecordRecursiveIterator($this->records),
      \RecursiveIteratorIterator::SELF_FIRST
    );
  }

  /**
   * Count the number of records in the collection.
   *
   * @return int
   *   The count of the records, traversing hierarchy.
   */
  public function count(): int {
    $counts = $this->map(fn($record) => !empty($record->getChildren()) ? count($record->getChildren()) : 0);
    $counts[] = count($this->records);
    return array_sum(array_filter($counts));
  }

  /**
   * Synonymous with array_map but can traverse the hierarchy tree.
   *
   * @param callable $callable
   *   Function to call on records.
   *
   * @return array
   *   The resulting output. Will be flattened.
   */
  public function map(callable $callable): array {
    $result = [];
    foreach ($this as $record) {
      $result[] = $callable($record);
    }
    return $result;
  }

  /**
   * Synonymous with array_filter but can traverse the hierarchy tree.
   *
   * When filtering a tree structure, the entire limb will be removed if one
   * of the parents matches the filter.
   *
   * @param callable $callable
   *   Callable to filter out records.
   *
   * @return $this
   *   Make this chainable.
   */
  public function filter(callable $callable): RecordCollection {
    $this->records = array_filter($this->records, $callable);
    foreach ($this->records as $record) {
      $this->doFilter($callable, $record);
    }
    return $this;
  }

  /**
   * Underlying worker function to filter the tree.
   *
   * @param callable $callable
   *   Callable to filter out records.
   * @param \Drupal\entity_hierarchy\Storage\Record $record
   *   The current record being filtered.
   */
  protected function doFilter(callable $callable, Record &$record) {
    $children = $record->getChildren();
    if (!empty($children)) {
      $filtered = array_filter($children, $callable);
      $record->setChildren($filtered);
      foreach ($filtered as $childRecord) {
        $this->doFilter($callable, $childRecord);
      }
    }
  }

  /**
   * Synonymous with usort but can traverse the hierarchy tree.
   *
   * @param callable|null $callable
   *   Callable to sort records. If null,
   *   RecordCollectionCallable::weightSort(...).
   *
   * @return $this
   *   Make this chainable.
   */
  public function sort(?callable $callable = NULL): RecordCollection {
    if (!isset($callable)) {
      $callable = RecordCollectionCallable::weightSort(...);
    }
    usort($this->records, $callable);
    foreach ($this->records as $record) {
      $this->doSort($callable, $record);
    }
    return $this;
  }

  /**
   * Underlying worker function to sort records..
   *
   * @param callable $callable
   *   Callable to sort records.
   * @param \Drupal\entity_hierarchy\Storage\Record $record
   *   The current record being sorted.
   */
  protected function doSort(callable $callable, Record &$record) {
    $children = $record->getChildren();
    if (!empty($children)) {
      usort($children, $callable);
      foreach ($children as $childRecord) {
        $this->doSort($callable, $childRecord);
      }
    }
  }

  /**
   * Iterate the records and turn them into a tree.
   *
   * @return $this
   *   Make this chainable.
   */
  public function buildTree(): RecordCollection {
    $indexed_records = [];
    foreach ($this->records as $record) {
      $indexed_records[$record->getId()] = $record;
    }

    $new_records = [];
    foreach ($this->records as $record) {
      $target_id = $record->getTargetId();
      if (!empty($indexed_records[$target_id])) {
        $children = $indexed_records[$target_id]->getChildren() ?: [];
        $children[] = $record;
        $indexed_records[$target_id]->setChildren($children);
      }
      else {
        $new_records[] = $record;
      }
    }

    $this->records = $new_records;
    return $this;
  }

  /**
   * Flatten out records that are in a tree.
   *
   * @return $this
   *   Make this chainable.
   */
  public function flatten(): RecordCollection {
    $this->records = $this->map(fn($record) => $record);
    foreach ($this->records as $record) {
      $record->setChildren([]);
    }
    return $this;
  }

}

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

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