225 lines
5.4 KiB
PHP
225 lines
5.4 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Collection - Mächtige Sammlung von Model-Objekten mit Filter-, Sortier- und Pagination-Methoden
|
|
*/
|
|
class Collection implements \IteratorAggregate, \Countable
|
|
{
|
|
/** @var array */
|
|
protected $items = [];
|
|
|
|
/**
|
|
* Konstruktor
|
|
* @param array $items
|
|
*/
|
|
public function __construct(array $items = [])
|
|
{
|
|
$this->items = $items;
|
|
}
|
|
|
|
/**
|
|
* WHERE-Bedingung (Vergleich)
|
|
*/
|
|
public function where($key, $operator, $value = null)
|
|
{
|
|
if (func_num_args() == 2) {
|
|
$value = $operator;
|
|
$operator = '=';
|
|
}
|
|
$filtered = array_filter($this->items, function ($item) use ($key, $operator, $value) {
|
|
$itemValue = is_array($item) ? $item[$key] : $item->$key;
|
|
switch ($operator) {
|
|
case '=': return $itemValue == $value;
|
|
case '!=': return $itemValue != $value;
|
|
case '>': return $itemValue > $value;
|
|
case '<': return $itemValue < $value;
|
|
case '>=': return $itemValue >= $value;
|
|
case '<=': return $itemValue <= $value;
|
|
case 'like': return stripos($itemValue, $value) !== false;
|
|
default: return false;
|
|
}
|
|
});
|
|
return new static(array_values($filtered));
|
|
}
|
|
|
|
/**
|
|
* WHERE IN
|
|
*/
|
|
public function whereIn($key, array $values)
|
|
{
|
|
$filtered = array_filter($this->items, function ($item) use ($key, $values) {
|
|
$itemValue = is_array($item) ? $item[$key] : $item->$key;
|
|
return in_array($itemValue, $values);
|
|
});
|
|
return new static(array_values($filtered));
|
|
}
|
|
|
|
/**
|
|
* WHERE BETWEEN
|
|
*/
|
|
public function whereBetween($key, array $range)
|
|
{
|
|
$filtered = array_filter($this->items, function ($item) use ($key, $range) {
|
|
$itemValue = is_array($item) ? $item[$key] : $item->$key;
|
|
return $itemValue >= $range[0] && $itemValue <= $range[1];
|
|
});
|
|
return new static(array_values($filtered));
|
|
}
|
|
|
|
/**
|
|
* WHERE NULL
|
|
*/
|
|
public function whereNull($key)
|
|
{
|
|
$filtered = array_filter($this->items, function ($item) use ($key) {
|
|
$itemValue = is_array($item) ? $item[$key] : $item->$key;
|
|
return is_null($itemValue);
|
|
});
|
|
return new static(array_values($filtered));
|
|
}
|
|
|
|
/**
|
|
* WHERE NOT NULL
|
|
*/
|
|
public function whereNotNull($key)
|
|
{
|
|
$filtered = array_filter($this->items, function ($item) use ($key) {
|
|
$itemValue = is_array($item) ? $item[$key] : $item->$key;
|
|
return !is_null($itemValue);
|
|
});
|
|
return new static(array_values($filtered));
|
|
}
|
|
|
|
/**
|
|
* ORDER BY
|
|
*/
|
|
public function orderBy($key)
|
|
{
|
|
$items = $this->items;
|
|
usort($items, function ($a, $b) use ($key) {
|
|
$aValue = is_array($a) ? $a[$key] : $a->$key;
|
|
$bValue = is_array($b) ? $b[$key] : $b->$key;
|
|
return $aValue <=> $bValue;
|
|
});
|
|
return new static($items);
|
|
}
|
|
|
|
/**
|
|
* ORDER BY DESC
|
|
*/
|
|
public function orderByDesc($key)
|
|
{
|
|
$items = $this->items;
|
|
usort($items, function ($a, $b) use ($key) {
|
|
$aValue = is_array($a) ? $a[$key] : $a->$key;
|
|
$bValue = is_array($b) ? $b[$key] : $b->$key;
|
|
return $bValue <=> $aValue;
|
|
});
|
|
return new static($items);
|
|
}
|
|
|
|
/**
|
|
* Neueste zuerst (nach Feld, default: date_add)
|
|
*/
|
|
public function latest($key = 'date_add')
|
|
{
|
|
return $this->orderByDesc($key);
|
|
}
|
|
|
|
/**
|
|
* Älteste zuerst (nach Feld, default: date_add)
|
|
*/
|
|
public function oldest($key = 'date_add')
|
|
{
|
|
return $this->orderBy($key);
|
|
}
|
|
|
|
/**
|
|
* Pagination
|
|
*/
|
|
public function paginate($perPage = 20, $page = 1)
|
|
{
|
|
$offset = ($page - 1) * $perPage;
|
|
$items = array_slice($this->items, $offset, $perPage);
|
|
return new static($items);
|
|
}
|
|
|
|
/**
|
|
* Einfache Pagination (liefert Array)
|
|
*/
|
|
public function simplePaginate($perPage = 20, $page = 1)
|
|
{
|
|
$offset = ($page - 1) * $perPage;
|
|
return array_slice($this->items, $offset, $perPage);
|
|
}
|
|
|
|
/**
|
|
* Chunk-Verarbeitung
|
|
*/
|
|
public function chunk($size, callable $callback)
|
|
{
|
|
$chunks = array_chunk($this->items, $size);
|
|
foreach ($chunks as $chunk) {
|
|
$callback(new static($chunk));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Iterator (each)
|
|
*/
|
|
public function each(callable $callback)
|
|
{
|
|
foreach ($this->items as $key => $item) {
|
|
$callback($item, $key);
|
|
}
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Zähle Elemente
|
|
*/
|
|
public function count()
|
|
{
|
|
return count($this->items);
|
|
}
|
|
|
|
/**
|
|
* IteratorAggregate
|
|
*/
|
|
public function getIterator()
|
|
{
|
|
return new \ArrayIterator($this->items);
|
|
}
|
|
|
|
/**
|
|
* Alle Elemente als Array
|
|
*/
|
|
public function all()
|
|
{
|
|
return $this->items;
|
|
}
|
|
|
|
/**
|
|
* Erstes Element
|
|
*/
|
|
public function first()
|
|
{
|
|
return reset($this->items);
|
|
}
|
|
|
|
/**
|
|
* Letztes Element
|
|
*/
|
|
public function last()
|
|
{
|
|
return end($this->items);
|
|
}
|
|
|
|
/**
|
|
* Leere Collection?
|
|
*/
|
|
public function isEmpty()
|
|
{
|
|
return empty($this->items);
|
|
}
|
|
}
|