Newwebshop/classes/Collection.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);
}
}