235 lines
4.7 KiB
PHP
235 lines
4.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Intervention\Image;
|
|
|
|
use Intervention\Image\Interfaces\CollectionInterface;
|
|
use ArrayIterator;
|
|
use Countable;
|
|
use Traversable;
|
|
use IteratorAggregate;
|
|
|
|
/**
|
|
* @implements IteratorAggregate<int|string, mixed>
|
|
*/
|
|
class Collection implements CollectionInterface, IteratorAggregate, Countable
|
|
{
|
|
/**
|
|
* Create new collection object.
|
|
*
|
|
* @param array<int|string, mixed> $items
|
|
*/
|
|
public function __construct(protected array $items = [])
|
|
{
|
|
//
|
|
}
|
|
|
|
/**
|
|
* Static constructor.
|
|
*
|
|
* @param array<int|string, mixed> $items
|
|
* @return self<int|string, mixed>
|
|
*/
|
|
public static function create(array $items = []): self
|
|
{
|
|
return new self($items);
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see CollectionInterface::has()
|
|
*/
|
|
public function has(int|string $key): bool
|
|
{
|
|
return array_key_exists($key, $this->items);
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see CollectionInterface::set()
|
|
*/
|
|
public function set(int|string $key, mixed $item): self
|
|
{
|
|
$this->items[$key] = $item;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Returns Iterator.
|
|
*
|
|
* @return Traversable<int|string, mixed>
|
|
*/
|
|
public function getIterator(): Traversable
|
|
{
|
|
return new ArrayIterator($this->items);
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see CollectionInterface::toArray()
|
|
*/
|
|
public function toArray(): array
|
|
{
|
|
return $this->items;
|
|
}
|
|
|
|
/**
|
|
* Count items in collection.
|
|
*
|
|
* @return int<0, max>
|
|
*/
|
|
public function count(): int
|
|
{
|
|
return count($this->items);
|
|
}
|
|
|
|
/**
|
|
* Append new item to collection.
|
|
*
|
|
* @return CollectionInterface<int|string, mixed>
|
|
*/
|
|
public function push(mixed $item): CollectionInterface
|
|
{
|
|
$this->items[] = $item;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Return first item in collection.
|
|
*/
|
|
public function first(): mixed
|
|
{
|
|
if (count($this->items) === 0) {
|
|
return null;
|
|
}
|
|
|
|
return reset($this->items);
|
|
}
|
|
|
|
/**
|
|
* Returns last item in collection.
|
|
*/
|
|
public function last(): mixed
|
|
{
|
|
if (count($this->items) === 0) {
|
|
return null;
|
|
}
|
|
|
|
return end($this->items);
|
|
}
|
|
|
|
/**
|
|
* Return item at given position starting at 0.
|
|
*/
|
|
public function at(int $key = 0, mixed $default = null): mixed
|
|
{
|
|
if ($this->count() === 0) {
|
|
return $default;
|
|
}
|
|
|
|
$positions = array_values($this->items);
|
|
if (!array_key_exists($key, $positions)) {
|
|
return $default;
|
|
}
|
|
|
|
return $positions[$key];
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see CollectionInterface::get()
|
|
*/
|
|
public function get(int|string $query, mixed $default = null): mixed
|
|
{
|
|
if ($this->count() === 0) {
|
|
return $default;
|
|
}
|
|
|
|
if (is_int($query) && array_key_exists($query, $this->items)) {
|
|
return $this->items[$query];
|
|
}
|
|
|
|
if (is_string($query) && !str_contains($query, '.')) {
|
|
return array_key_exists($query, $this->items) ? $this->items[$query] : $default;
|
|
}
|
|
|
|
$query = explode('.', (string) $query);
|
|
|
|
$result = $default;
|
|
$items = $this->items;
|
|
foreach ($query as $key) {
|
|
if (!is_array($items) || !array_key_exists($key, $items)) {
|
|
$result = $default;
|
|
break;
|
|
}
|
|
|
|
$result = $items[$key];
|
|
$items = $result;
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see CollectionInterface::map()
|
|
*/
|
|
public function map(callable $callback): self
|
|
{
|
|
|
|
return new self(
|
|
array_map(
|
|
fn(mixed $item) => $callback($item),
|
|
$this->items,
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see CollectionInterface::map()
|
|
*/
|
|
public function filter(callable $callback): self
|
|
{
|
|
return new self(
|
|
array_filter(
|
|
$this->items,
|
|
fn(mixed $item) => $callback($item),
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see CollectionInterface::clear()
|
|
*/
|
|
public function clear(): CollectionInterface
|
|
{
|
|
$this->items = [];
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see CollectionInterface::slice()
|
|
*/
|
|
public function slice(int $offset, ?int $length = null): CollectionInterface
|
|
{
|
|
$this->items = array_slice($this->items, $offset, $length);
|
|
|
|
return $this;
|
|
}
|
|
}
|