/home/techb158/public_html/wp-content/plugins/kirki/libraries/framework/Collections
Edit: /home/techb158/public_html/wp-content/plugins/kirki/libraries/framework/Collections/Collection.php (30511B)
items = $this->get_arrayable_items($items);
}
/**
* Create a new collection instance from a range of numbers.
*
* @param int $start The start of the range
* @param int $end The end of the range
* @param int $step The step of the range
*
* @return static A new collection instance
*
* @since 1.0.0
*/
public static function range($start, $end, $step = 1)
{
return new static(\range($start, $end, $step));
}
/**
* Retrieve all items as a plain array.
*
* Return the underlying array without modification. Useful when consumers
* need direct array semantics or to interoperate with functions expecting
* native arrays instead of collection instances.
*
* @return array The raw array of items stored in the collection
*
* @since 1.0.0
*/
public function all()
{
return $this->items;
}
/**
* Get the unique items from the collection.
*
* @param callable|string|null $key The key to use for uniqueness.
* @param bool $strict Whether to use strict comparison.
*
* @return static A new collection containing the unique items.
*
* @since 1.0.0
*/
public function unique($key = null, $strict = \false)
{
if (\is_null($key) && $strict === \false) {
return $this->new_instance(\array_unique($this->items, \SORT_REGULAR));
}
$callback = $this->value_retriever($key);
$exists = [];
return $this->reject(function ($item, $key) use($callback, $strict, &$exists) {
if (\in_array($id = $callback($item, $key), $exists, $strict)) {
return \true;
}
$exists[] = $id;
});
}
/**
* Get the values of the collection.
*
* @return static A new collection containing the values
*
* @since 1.0.0
*/
public function values()
{
return new static(\array_values($this->items));
}
/**
* Determine if the collection contains a given item.
*
* @param mixed $value The item to check for
* @param bool $strict The strict.
*
* @return bool True if the collection contains the item, false otherwise
*
* @since 1.0.0
*/
public function contains($value, bool $strict = \false)
{
if ($value instanceof Closure) {
foreach ($this->items as $index => $item) {
if ($value($item, $index)) {
return \true;
}
}
return \false;
}
return \in_array($value, $this->items, $strict);
}
/**
* Determine if the collection contains a given item using strict comparison.
*
* @param mixed $value The item to check for
*
* @return bool True if the collection contains the item, false otherwise
*
* @since 1.0.0
*/
public function contains_strict($value)
{
return $this->contains($value, \true);
}
/**
* Determine if the collection does not contain a given item.
*
* @param mixed $value The item to check for
*
* @return bool True if the collection does not contain the item, false otherwise
*
* @since 1.0.0
*/
public function not_contains($value)
{
return !$this->contains($value);
}
/**
* Determine if the collection does not contain a given item using strict comparison.
*
* @param mixed $value The item to check for
*
* @return bool True if the collection does not contain the item, false otherwise
*
* @since 1.0.0
*/
public function not_contains_strict($value)
{
return !$this->contains_strict($value);
}
/**
* Diff the collection with the given items.
*
* @param mixed $items The items to diff with the collection
*
* @return static A new collection containing the diff
*
* @since 1.0.0
*/
public function diff($items)
{
return new static(\array_diff($this->items, $this->get_arrayable_items($items)));
}
/**
* Get the arrayable items from the given items.
*
* @param mixed $items The items to get the arrayable items from
*
* @return array The arrayable items
*
* @since 1.0.0
*/
public function get_arrayable_items($items)
{
return \is_null($items) || \is_scalar($items) ? Arr::wrap($items) : Arr::from($items);
}
/**
* Get the first item in the collection.
*
* @template TFirstDefault
*
* Returns null when the collection is empty. This is typically used to
* access a single model or value from a previously constrained result set
* without performing additional checks.
*
* @param (callable(TValue, TKey): bool)|null $callback The to use to determine the first item
* @param TFirstDefault|(\Closure(): TFirstDefault) $default The default value to return if no items exist
*
* @return TValue|TFirstDefault The first item or null when no items exist
*
* @since 1.0.0
*/
public function first(?callable $callback = null, $default = null)
{
return Arr::first($this->items, $callback, $default);
}
/**
* Get the last item in the collection.
*
* Uses PHP's end pointer to retrieve the last element when available and
* returns null when the collection is empty. Helpful for ordered results
* where the terminal element is meaningful.
*
* @return mixed The last item or null when no items exist
*
* @since 1.0.0
*/
public function last()
{
return !empty($this->items) ? array_last($this->items) : null;
}
/**
* Count the number of items in the collection.
*
* Implements Countable and returns the total item count. This mirrors
* PHP's count behavior and is frequently used in pagination and guards.
*
* @return int The number of items contained in the collection
*
* @since 1.0.0
*/
public function count() : int
{
return \count($this->items);
}
/**
* Determine if the collection is empty.
*
* @return bool True when empty; false otherwise
*
* @since 1.0.0
*/
public function empty()
{
return empty($this->items);
}
/**
* Determine if the collection is empty.
*
* @return bool True when empty; false otherwise
*
* @since 1.0.0
*/
public function is_empty()
{
return $this->empty();
}
/**
* Determine if the collection is not empty.
*
* @return bool True when not empty; false otherwise
*
* @since 1.0.0
*/
public function not_empty()
{
return !$this->empty();
}
/**
* Determine if the collection is not empty.
*
* @return bool True when not empty; false otherwise
*
* @since 1.0.0
*/
public function is_not_empty()
{
return $this->not_empty();
}
/**
* Add one or more items to the end of the collection.
*
* @param mixed $values The values to add to the collection
*
* @return $this The collection instance for method chaining
*
* @since 1.0.0
*/
public function push(...$values)
{
foreach ($values as $value) {
$this->items[] = $value;
}
return $this;
}
/**
* Add one or more items to the beginning of the collection.
*
* @param mixed $values The values to add to the collection
*
* @return $this The collection instance for method chaining
*
* @since 1.0.0
*/
public function unshift(...$values)
{
\array_unshift($this->items, ...$values);
return $this;
}
/**
* Remove and return the last item from the collection.
*
* @return mixed The removed item or null if the collection is empty
*
* @since 1.0.0
*/
public function pop()
{
return \array_pop($this->items);
}
/**
* Reverse the order of the collection items.
*
* @return static A new collection with the items in reverse order
*
* @since 1.0.0
*/
public function reverse()
{
return new static(\array_reverse($this->items, \true));
}
/**
* Transform each item in the collection using a callback.
*
* The callback receives the item and its key, and the return values are
* collected into a new collection. This does not mutate the original and
* supports fluent method chaining by returning a collection instance.
*
* @param callable $callback The transformer to apply to each item
*
* @return static A new collection containing transformed items
*
* @since 1.0.0
*/
public function map(callable $callback)
{
return $this->new_instance(Arr::map($this->items, $callback));
}
/**
* Collapse a collection of arrays into a single array.
*
* @return static A new collection containing collapsed items
*
* @since 1.0.0
*/
public function collapse()
{
return $this->new_instance(Arr::collapse($this->items));
}
/**
* Transform each item in the collection using a callback.
*
* The callback receives the item and its key, and the return values are
* collected into a new collection. This does not mutate the original and
* supports fluent method chaining by returning a collection instance.
*
* @param callable $callback The transformer to apply to each item
*
* @return static A new collection containing transformed items
*
* @since 1.0.0
*/
public function flat_map(callable $callback)
{
return $this->map($callback)->collapse();
}
/**
* Filter items in the collection using a callback predicate.
*
* The callback should return truthy for items to keep. A new collection is
* returned leaving the original intact, enabling immutable-style chaining
* and reuse of the source collection.
*
* @param callable $callback The predicate determining which items remain
*
* @return static A new collection containing only matching items
*
* @since 1.0.0
*/
public function filter(?callable $callback = null)
{
if ($callback) {
return new static(Arr::where($this->items, $callback));
}
return new static(\array_filter($this->items));
}
/**
* Reject items in the collection using a callback predicate.
*
* The callback should return false for items to reject. A new collection is
* returned leaving the original intact, enabling immutable-style chaining
* and reuse of the source collection.
*
* @param callable $callback The predicate determining which items remain
*
* @return static A new collection containing only matching items
*
* @since 1.0.0
*/
public function reject(callable $callback)
{
return $this->new_instance(Arr::reject($this->items, $callback));
}
/**
* Accept items in the collection using a callback predicate.
*
* The callback should return true for items to accept. A new collection is
* returned leaving the original intact, enabling immutable-style chaining
* and reuse of the source collection.
*
* @param callable $callback The predicate determining which items remain
*
* @return static A new collection containing only matching items
*
* @since 1.0.0
*/
public function accept(callable $callback)
{
return $this->new_instance(Arr::accept($this->items, $callback));
}
/**
* Find the first item in the collection that matches the key.
*
* @param Closure|null $key The key to find the item by.
* @param mixed $default The default value to return if the key is not found.
*
* @return mixed The first item that matches the key.
*
* @throws \InvalidArgumentException
*
* @since 1.0.0
*/
public function find($key, $default = null)
{
if (\is_null($key)) {
return value($default);
}
if (!$key instanceof Closure) {
throw new InvalidArgumentException('The key must be a Closure.');
}
return Arr::first($this->items, $key, $default);
}
/**
* Iterate over each item and invoke the given callback.
*
* The callback receives the item and key. If the callback returns false,
* iteration stops early. This method returns the collection instance for
* method chaining with subsequent operations.
*
* @param callable $callback The function to invoke for each item
*
* @return $this The collection instance for method chaining
*
* @since 1.0.0
*/
public function each(callable $callback)
{
foreach ($this->items as $key => $item) {
if ($callback($item, $key) === \false) {
break;
}
}
return $this;
}
/**
* Determine if the collection satisfies a given condition.
*
* @param callable $callback The callback to check the items
*
* @return bool True if the collection satisfies the condition, false otherwise
*
* @since 1.0.0
*/
public function some(callable $callback)
{
return Arr::some($this->items, $callback);
}
/**
* Determine if the collection satisfies a given condition.
*
* @param callable $callback The callback to check the items
*
* @return bool True if the collection satisfies the condition, false otherwise
*
* @since 1.0.0
*/
public function every(callable $callback)
{
return Arr::every($this->items, $callback);
}
/**
* Group the collection items by the given key.
*
* @param callable|array $group_by The key or callback to group by
* @param bool $preserve_keys Whether to preserve the keys
*
* @return static A new collection containing the grouped items
*
* @since 1.0.0
*/
public function group_by($group_by, $preserve_keys = \false)
{
if (!$this->is_callable($group_by) && \is_array($group_by)) {
$next_groups = $group_by;
$group_by = \array_shift($next_groups);
}
$group_by = $this->value_retriever($group_by);
$results = [];
foreach ($this->items as $key => $value) {
$group_keys = $group_by($value, $key);
if (!\is_array($group_keys)) {
$group_keys = [$group_keys];
}
foreach ($group_keys as $group_key) {
if (\is_bool($group_key)) {
$group_key = (int) $group_key;
} elseif (\is_null($group_key)) {
$group_key = (string) $group_key;
}
if (!\array_key_exists($group_key, $results)) {
$results[$group_key] = $this->new_instance();
}
$results[$group_key]->offsetSet($preserve_keys ? $key : null, $value);
}
}
$result = $this->new_instance($results);
if (!empty($next_groups)) {
return $result->map(function ($inner) use($next_groups, $preserve_keys) {
return $inner->group_by($next_groups, $preserve_keys);
});
}
return $result;
}
/**
* Key the collection by the given key.
*
* @param callable|string $key_by The key or callback to key by
*
* @return static A new collection containing the keyed items
*
* @since 1.0.0
*/
public function key_by($key_by)
{
$key_by = $this->value_retriever($key_by);
$results = [];
foreach ($this->items as $key => $value) {
$resolved_key = $key_by($value, $key);
if (\is_object($resolved_key)) {
$resolved_key = (string) $resolved_key;
}
$results[$resolved_key] = $value;
}
return $this->new_instance($results);
}
/**
* Extract a single column or property from each item.
*
* For objects, attempts to read the property; for arrays, reads the array
* key. Missing properties or keys are represented as null. A new collection
* of the extracted values is returned for additional transformations.
*
* @param string|array|int|Closure|null $value The value to pluck
* @param string|Closure|null $key The key to pluck by
*
* @return static A new collection of extracted values
*
* @since 1.0.0
*/
public function pluck($value, $key = null)
{
return $this->new_instance(Arr::pluck($this->items, $value, $key));
}
/**
* Create a new collection instance.
*
* @param array $items The items to seed the collection
*
* @return static A new collection instance
*
* @since 1.0.0
*/
protected function new_instance($items = [])
{
return new static($items);
}
/**
* Merge the collection with the given items.
*
* @param mixed $items The items to merge with the collection
*
* @return static A new collection containing the merged items
*
* @since 1.0.0
*/
public function merge($items)
{
return $this->new_instance(\array_merge($this->items, $this->get_arrayable_items($items)));
}
/**
* Merge the collection with the given items recursively.
*
* @param mixed $items The items to merge with the collection
*
* @return static A new collection containing the merged items
*
* @since 1.0.0
*/
public function merge_recursive($items)
{
return $this->new_instance(\array_merge_recursive($this->items, $this->get_arrayable_items($items)));
}
/**
* Union the collection with the given items.
*
* @param mixed $items The items to union with the collection
*
* @return static A new collection containing the union of items
*
* @since 1.0.0
*/
public function union($items)
{
return new static($this->items + $this->get_arrayable_items($items));
}
/**
* Return a new collection containing only the specified keys.
*
* @param mixed $keys The keys to keep
*
* @return static A new collection containing only the specified keys
*
* @throws \InvalidArgumentException
*
* @since 1.0.0
*/
public function only($keys)
{
if (empty($keys)) {
throw new InvalidArgumentException('You must pass at least one key to the only method.');
}
$keys = \is_array($keys) ? $keys : \func_get_args();
return new static(Arr::only($this->items, $keys));
}
/**
* Sort the collection items.
*
* @param callable $callback The callback to sort the items
*
* @return static A new collection containing the sorted items
*
* @since 1.0.0
*/
public function sort($callback = null)
{
$items = $this->items;
$callback && \is_callable($callback) ? \uasort($items, $callback) : \asort($items, $callback ?? \SORT_REGULAR);
return new static($items);
}
/**
* Sum the collection items.
*
* @param callable $callback The callback to sum the items
*
* @return int The sum of the items
*
* @since 1.0.0
*/
public function sum($callback = null)
{
if (empty($callback)) {
return \array_sum($this->get_arrayable_items($this->items));
}
return \array_reduce($this->items, function ($sum, $item) use($callback) {
return $sum + $callback($item);
}, 0);
}
/**
* Calculate the average of the collection items.
*
* @param callable $callback The callback to calculate the average
*
* @return float The average of the items
*
* @since 1.0.0
*/
public function average($callback = null)
{
return $this->sum($callback) / $this->count();
}
/**
* Calculate the average of the collection items.
*
* @param callable $callback The callback to calculate the average
*
* @return float The average of the items
*
* @since 1.0.0
*/
public function avg($callback = null)
{
return $this->average($callback);
}
/**
* Find the minimum value in the collection.
*
* @param callable $callback The callback to find the minimum value
*
* @return mixed The minimum value
*
* @since 1.0.0
*/
public function min($callback = null)
{
return $callback ? \min(\array_map($callback, $this->items)) : \min($this->get_arrayable_items($this->items));
}
/**
* Find the maximum value in the collection.
*
* @param callable $callback The callback to find the maximum value
*
* @return mixed The maximum value
*
* @since 1.0.0
*/
public function max($callback = null)
{
return $callback ? \max(\array_map($callback, $this->items)) : \max($this->get_arrayable_items($this->items));
}
/**
* Calculate the percentage of items that satisfy a given condition.
*
* @param callable $callback The callback to calculate the percentage
* @param int $precision The number of decimal places to round to
*
* @return float|null The percentage of items that satisfy the condition
*
* @since 1.0.0
*/
public function percentage(callable $callback, int $precision = 2)
{
if ($this->empty()) {
return null;
}
return \round($this->filter($callback)->count() / $this->count() * 100, $precision);
}
/**
* Join the collection items into a string using a glue.
*
* @param string $glue The glue to join the items with
*
* @return string The joined string
*
* @since 1.0.0
*/
public function join(string $glue = ',')
{
return \implode($glue, $this->items);
}
/**
* Get the keys of the collection.
*
* @return static A new collection containing the keys
*
* @since 1.0.0
*/
public function keys()
{
return $this->new_instance(\array_keys($this->items));
}
/**
* Convert the collection to an array.
*
* @return array The array representation of the collection
*
* @since 1.0.0
*/
public function to_array()
{
return $this->map(function ($item) {
return $item instanceof Arrayable ? $item->to_array() : $item;
})->all();
}
/**
* Convert the collection to a base collection.
*
* @return Collection The base collection
*
* @since 1.0.0
*/
public function to_base()
{
return new self($this);
}
/**
* Convert the collection into a JSON string.
* This is an alias of the toJson method for following wordpress convention.
*
* @param mixed $options The options array.
*
* @return string The JSON-encoded representation of the items
*
* @since 1.0.0
*/
public function to_json($options = 0)
{
return Arr::json_encode($this->jsonSerialize(), $options);
}
/**
* Determine if an offset exists in the collection.
*
* Part of the ArrayAccess contract. This checks whether an index is set in
* the internal array and returns a boolean accordingly.
*
* @param mixed $offset The array index to check for existence
*
* @return bool True when the offset exists; false otherwise
*
* @since 1.0.0
*/
public function offsetExists($offset) : bool
{
return isset($this->items[$offset]);
}
/**
* Retrieve the value at the given offset.
*
* Returns null when the offset is not present. This enables array-like
* access to collection items while keeping behavior predictable.
*
* @param mixed $offset The array index to retrieve
*
* @return mixed The value at the offset or null if not set
*
* @since 1.0.0
*/
#[\ReturnTypeWillChange]
public function offsetGet($offset)
{
return $this->items[$offset] ?? null;
}
/**
* Set the value at the given offset.
*
* When the offset is null, the value is appended to the end of the list.
* This fulfills the ArrayAccess interface for write operations.
*
* @param mixed $offset The index to set, or null to append
* @param mixed $value The value to assign at the offset
*
* @return void
*
* @since 1.0.0
*/
public function offsetSet($offset, $value) : void
{
if ($offset === null) {
$this->items[] = $value;
} else {
$this->items[$offset] = $value;
}
}
/**
* Unset the value at the given offset.
*
* Removes the key from the internal array if present. This supports the
* ArrayAccess interface for deletion semantics.
*
* @param mixed $offset The index to remove from the collection
*
* @return void
*
* @since 1.0.0
*/
public function offsetUnset($offset) : void
{
unset($this->items[$offset]);
}
/**
* Get the current item during iteration.
*
* Implements Iterator by returning the item at the internal pointer's
* current position. This is used by foreach and manual iteration.
*
* @return mixed The current item at the iterator position
* @since 1.0.0
*/
#[\ReturnTypeWillChange]
public function current()
{
return $this->items[$this->position];
}
/**
* Convert the collection to a JSON serializable array.
*
* @return mixed The JSON serializable array
* @since 1.0.0
*/
#[\ReturnTypeWillChange]
public function jsonSerialize()
{
return \array_map(function ($value) {
switch (\true) {
case $value instanceof JsonSerializable:
return $value->jsonSerialize();
case $value instanceof Jsonable:
return \json_decode($value->to_json(), \true);
case $value instanceof Arrayable:
return $value->to_array();
default:
return $value;
}
}, $this->all());
}
/**
* Get the key of the current iterator position.
*
* Returns the numerical position index used internally by the iterator
* implementation. Useful when keys are significant during traversal.
*
* @return mixed The current iterator key
* @since 1.0.0
*/
#[\ReturnTypeWillChange]
public function key()
{
return $this->position;
}
/**
* Advance the iterator to the next position.
*
* Increments the internal position counter by one. Part of the Iterator
* interface contract to enable standard iteration semantics.
*
* @return void
*
* @since 1.0.0
*/
public function next() : void
{
++$this->position;
}
/**
* Rewind the iterator back to the first position.
*
* Resets the internal pointer to the beginning so that iteration can be
* restarted or reused by consumers expecting fresh traversal.
*
* @return void
*
* @since 1.0.0
*/
public function rewind() : void
{
$this->position = 0;
}
/**
* Determine if the current iterator position is valid.
*
* Checks whether the position maps to an existing item within the array.
* This informs iteration whether to continue or terminate.
*
* @return bool True when a current item exists; false otherwise
*
* @since 1.0.0
*/
public function valid() : bool
{
return isset($this->items[$this->position]);
}
}