vendor/shopware/core/Framework/Struct/Collection.php line 120

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Framework\Struct;
  3. use Shopware\Core\Framework\Log\Package;
  4. /**
  5.  * @template TElement
  6.  * @implements \IteratorAggregate<array-key, TElement>
  7.  */
  8. #[Package('core')]
  9. abstract class Collection extends Struct implements \IteratorAggregate\Countable
  10. {
  11.     /**
  12.      * @var array<array-key, TElement>
  13.      */
  14.     protected $elements = [];
  15.     /**
  16.      * @param array<TElement> $elements
  17.      */
  18.     public function __construct(iterable $elements = [])
  19.     {
  20.         foreach ($elements as $key => $element) {
  21.             $this->set($key$element);
  22.         }
  23.     }
  24.     /**
  25.      * @param TElement $element
  26.      */
  27.     public function add($element): void
  28.     {
  29.         $this->validateType($element);
  30.         $this->elements[] = $element;
  31.     }
  32.     /**
  33.      * @param array-key|null $key
  34.      * @param TElement $element
  35.      */
  36.     public function set($key$element): void
  37.     {
  38.         $this->validateType($element);
  39.         if ($key === null) {
  40.             $this->elements[] = $element;
  41.         } else {
  42.             $this->elements[$key] = $element;
  43.         }
  44.     }
  45.     /**
  46.      * @param array-key $key
  47.      *
  48.      * @return TElement|null
  49.      */
  50.     public function get($key)
  51.     {
  52.         if ($this->has($key)) {
  53.             return $this->elements[$key];
  54.         }
  55.         return null;
  56.     }
  57.     public function clear(): void
  58.     {
  59.         $this->elements = [];
  60.     }
  61.     public function count(): int
  62.     {
  63.         return \count($this->elements);
  64.     }
  65.     /**
  66.      * @return list<array-key>
  67.      */
  68.     public function getKeys(): array
  69.     {
  70.         return array_keys($this->elements);
  71.     }
  72.     /**
  73.      * @param array-key $key
  74.      */
  75.     public function has($key): bool
  76.     {
  77.         return \array_key_exists($key$this->elements);
  78.     }
  79.     /**
  80.      * @return list<mixed>
  81.      */
  82.     public function map(\Closure $closure): array
  83.     {
  84.         return array_map($closure$this->elements);
  85.     }
  86.     /**
  87.      * @param  mixed|null        $initial
  88.      *
  89.      * @return mixed|null
  90.      */
  91.     public function reduce(\Closure $closure$initial null)
  92.     {
  93.         return array_reduce($this->elements$closure$initial);
  94.     }
  95.     /**
  96.      * @return array<array-key, mixed>
  97.      */
  98.     public function fmap(\Closure $closure): array
  99.     {
  100.         return array_filter($this->map($closure));
  101.     }
  102.     public function sort(\Closure $closure): void
  103.     {
  104.         uasort($this->elements$closure);
  105.     }
  106.     /**
  107.      * @param class-string $class
  108.      *
  109.      * @return static
  110.      */
  111.     public function filterInstance(string $class)
  112.     {
  113.         return $this->filter(static function ($item) use ($class) {
  114.             return $item instanceof $class;
  115.         });
  116.     }
  117.     /**
  118.      * @return static
  119.      */
  120.     public function filter(\Closure $closure)
  121.     {
  122.         return $this->createNew(array_filter($this->elements$closure));
  123.     }
  124.     /**
  125.      * @return static
  126.      */
  127.     public function slice(int $offset, ?int $length null)
  128.     {
  129.         return $this->createNew(\array_slice($this->elements$offset$lengthtrue));
  130.     }
  131.     /**
  132.      * @return array<TElement>
  133.      */
  134.     public function getElements(): array
  135.     {
  136.         return $this->elements;
  137.     }
  138.     /**
  139.      * @return list<TElement>
  140.      */
  141.     public function jsonSerialize(): array
  142.     {
  143.         return array_values($this->elements);
  144.     }
  145.     /**
  146.      * return ($this->elements is non-empty-array ? TElement : null) does not work as return type for now.
  147.      * Possible with PHPStan 1.9.0 see https://github.com/phpstan/phpstan/issues/7110
  148.      */
  149.     public function first()
  150.     {
  151.         return array_values($this->elements)[0] ?? null;
  152.     }
  153.     /**
  154.      * @return TElement|null
  155.      */
  156.     public function getAt(int $position)
  157.     {
  158.         return array_values($this->elements)[$position] ?? null;
  159.     }
  160.     /**
  161.      * return ($this->elements is non-empty-array ? TElement : null) does not work as return type for now.
  162.      * Possible with PHPStan 1.9.0 see https://github.com/phpstan/phpstan/issues/7110
  163.      */
  164.     public function last()
  165.     {
  166.         return array_values($this->elements)[\count($this->elements) - 1] ?? null;
  167.     }
  168.     /**
  169.      * @param array-key $key
  170.      */
  171.     public function remove($key): void
  172.     {
  173.         unset($this->elements[$key]);
  174.     }
  175.     /**
  176.      * @deprecated tag:v6.5.0 - reason:return-type-change - Return type will be changed to \Traversable
  177.      *
  178.      * @return \Generator<TElement>
  179.      */
  180.     #[\ReturnTypeWillChange]
  181.     public function getIterator(): \Generator/* :\Traversable */
  182.     {
  183.         yield from $this->elements;
  184.     }
  185.     /**
  186.      * @return class-string<TElement>|null
  187.      */
  188.     protected function getExpectedClass(): ?string
  189.     {
  190.         return null;
  191.     }
  192.     /**
  193.      * @param iterable<TElement> $elements
  194.      *
  195.      * @return static
  196.      */
  197.     protected function createNew(iterable $elements = [])
  198.     {
  199.         return new static($elements);
  200.     }
  201.     /**
  202.      * @param TElement $element
  203.      */
  204.     protected function validateType($element): void
  205.     {
  206.         $expectedClass $this->getExpectedClass();
  207.         if ($expectedClass === null) {
  208.             return;
  209.         }
  210.         if (!$element instanceof $expectedClass) {
  211.             $elementClass \get_class($element);
  212.             throw new \InvalidArgumentException(
  213.                 sprintf('Expected collection element of type %s got %s'$expectedClass$elementClass)
  214.             );
  215.         }
  216.     }
  217. }