this->get_item_value( $item, $key );
}
return new static( $result );
}
/**
* Group the collection items by specific key in each collection item.
*
* @param $group_by
*
* @return $this
*/
public function group_by( $group_by ) {
$result = [];
foreach ( $this->items as $item ) {
$group_key = $this->get_item_value( $item, $group_by, 0 );
$result[ $group_key ][] = $item;
}
return new static( $result );
}
/**
* Sort keys
*
* @param false $descending
*
* @return $this
*/
public function sort_keys( $descending = false ) {
$items = $this->items;
if ( $descending ) {
krsort( $items );
} else {
ksort( $items );
}
return new static( $items );
}
/**
* Get specific item from the collection.
*
* @param $key
* @param null $default
*
* @return mixed|null
*/
public function get( $key, $default = null ) {
if ( ! array_key_exists( $key, $this->items ) ) {
return $default;
}
return $this->items[ $key ];
}
/**
* Get the first item.
*
* @param null $default
*
* @return mixed|null
*/
public function first( $default = null ) {
if ( $this->is_empty() ) {
return $default;
}
foreach ( $this->items as $item ) {
return $item;
}
}
/**
* Find an element from the items.
*
* @param callable $callback
* @param null $default
*
* @return mixed|null
*/
public function find( callable $callback, $default = null ) {
foreach ( $this->all() as $key => $item ) {
if ( $callback( $item, $key ) ) {
return $item;
}
}
return $default;
}
/**
* Make sure all the values inside the array are uniques.
*
* @param null|string|string[] $keys
*
* @return $this
*/
public function unique( $keys = null ) {
if ( ! $keys ) {
return new static(
array_unique( $this->items )
);
}
if ( ! is_array( $keys ) ) {
$keys = [ $keys ];
}
$exists = [];
return $this->filter( function ( $item ) use ( $keys, &$exists ) {
$value = null;
foreach ( $keys as $key ) {
$current_value = $this->get_item_value( $item, $key );
$value .= "{$key}:{$current_value};";
}
// If no value for the specific key return the item.
if ( null === $value ) {
return true;
}
// If value is not exists, add to the exists array and return the item.
if ( ! in_array( $value, $exists, true ) ) {
$exists[] = $value;
return true;
}
return false;
} );
}
/**
* @return array
*/
public function keys() {
return array_keys( $this->items );
}
/**
* @return bool
*/
public function is_empty() {
return empty( $this->items );
}
/**
* @return array
*/
public function all() {
return $this->items;
}
/**
* @return array
*/
public function values() {
return array_values( $this->all() );
}
/**
* Support only one level depth.
*
* @return $this
*/
public function flatten() {
$result = [];
foreach ( $this->all() as $item ) {
$item = $item instanceof Collection ? $item->all() : $item;
if ( ! is_array( $item ) ) {
$result[] = $item;
} else {
$values = array_values( $item );
foreach ( $values as $value ) {
$result[] = $value;
}
}
}
return new static( $result );
}
/**
* @param ...$values
*
* @return $this
*/
public function push( ...$values ) {
foreach ( $values as $value ) {
$this->items[] = $value;
}
return $this;
}
/**
* @param mixed $offset
*
* @return bool
*/
#[\ReturnTypeWillChange]
public function offsetExists( $offset ) {
return isset( $this->items[ $offset ] );
}
/**
* @param mixed $offset
*
* @return mixed
*/
#[\ReturnTypeWillChange]
public function offsetGet( $offset ) {
return $this->items[ $offset ];
}
/**
* @param mixed $offset
* @param mixed $value
*/
#[\ReturnTypeWillChange]
public function offsetSet( $offset, $value ) {
if ( is_null( $offset ) ) {
$this->items[] = $value;
} else {
$this->items[ $offset ] = $value;
}
}
/**
* @param mixed $offset
*/
#[\ReturnTypeWillChange]
public function offsetUnset( $offset ) {
unset( $this->items[ $offset ] );
}
/**
* @return \ArrayIterator|\Traversable
*/
#[\ReturnTypeWillChange]
public function getIterator() {
return new \ArrayIterator( $this->items );
}
/**
* @return int|void
*/
#[\ReturnTypeWillChange]
public function count() {
return count( $this->items );
}
/**
* @param $item
* @param $key
* @param null $default
*
* @return mixed|null
*/
private function get_item_value( $item, $key, $default = null ) {
$value = $default;
if ( is_object( $item ) && isset( $item->{$key} ) ) {
$value = $item->{$key};
} elseif ( is_array( $item ) && isset( $item[ $key ] ) ) {
$value = $item[ $key ];
}
return $value;
}
}