freenet-router |
Subversion Repositories: |
Compare with Previous - Blame - Download
<?php
namespace Phem\Core;
use Countable;
use Iterator;
use JsonSerializable;
use Phem\ToolSuite;
/**
* @author Jakub PetrĹžĂlka <petrzilka@czweb.net>
*
*/
class Collection implements Iterator, Countable, JsonSerializable
{
protected $items = array();
public function __construct($items = null)
{
if (is_array($items))
{
$this->items = $items;
}
}
public function current()
{
return current($this->items);
}
public function key()
{
return key($this->items);
}
public function next()
{
return next($this->items);
}
public function rewind()
{
reset($this->items);
}
public function valid()
{
$key = key($this->items);
return ($key !== null && $key !== false);
}
public function getFirst()
{
$this->rewind();
return $this->current();
}
public function getFirstKey()
{
$this->rewind();
return $this->key();
}
public function getLastKey()
{
end($this->items);
return $this->key();
}
public function contains($value)
{
return ($this->getKey($value) != null);
}
public function containsKey($key)
{
return array_key_exists($key, $this->items);
}
public function containsAnyKeyOf(array $keys)
{
foreach ($keys as $key)
{
if (array_key_exists($key, $this->items))
return true;
}
return false;
}
public function put($key, $value)
{
if (!($this->containsKey($key)))
{
$this->items[$key] = $value;
}
}
public function add($value)
{
$this->items[] = $value;
}
public function set($key, $value)
{
$this->items[$key] = $value;
}
public function get($key)
{
if (array_key_exists($key, $this->items))
return $this->items[$key];
else
return null;
}
public function getKey($value)
{
foreach ($this->items as $key => $currentValue)
{
if ($currentValue == $value)
return $key;
}
return null;
}
public function count()
{
return count($this->items);
}
public function uniqueValues()
{
return array_unique($this->items);
}
public function getKeys()
{
return array_keys($this->items);
}
public function toArray()
{
return $this->items;
}
public function isEmpty()
{
return (count($this->items) == 0);
}
public function removeKey($key)
{
if (array_key_exists($key, $this->items))
{
$this->items[$key] = null;
unset($this->items[$key]);
}
}
public function getSubCollection($path)
{
return ToolSuite::getSubCollection($this->items, $path);
}
public function join(Collection $collection)
{
$this->items = array_merge($this->items,$collection->toArray());
}
public function findNearestGreaterThanOrEqual($needleKey)
{
$min = null;
$result = null;
foreach ($this->items as $key => $value)
{
if ($key >= $needleKey)
{
if (($min === null)||($key <= $min))
{
$min = $key;
$result = $value;
}
}
}
return $result;
}
/**
* Sorts the collection according to strategy given in $sortBy argument.
* Available strategies can be found in CollectionSortType.
*
* Sort on nested object attributes can be done using $sortOnAttribute,
* Provide an optional path string to identifiy the field to sort on.
* Eg. 'prop1/attr2' will be translated to $collectionEntry->getProp1()->getAttr2();
*
* @param int $sortBy CollectionSortType strategy
* @param string $sortOnAttribute Path to field to sort on
*/
public function sort($sortType, $sortOnAttribute = null)
{
if (($sortType & CollectionSortType::VALUE) == 0)
{
if ($sortOnAttribute != null)
{
$cmpFunction = function($a, $b) use ($sortOnAttribute, $sortType)
{
$comparedA = $a;
$comparedB = $a;
if ($sortOnAttribute != null)
{
$comparedA = ToolSuite::getObjectValueFromPath($a, $sortOnAttribute);
$comparedB = ToolSuite::getObjectValueFromPath($b, $sortOnAttribute);
}
if ($sortType & CollectionSortType::CASE_STRING)
{
if (($sortType & CollectionSortType::DESC) == 0)
{
strcasecmp($comparedA, $comparedB);
}
else
{
-strcasecmp($comparedA, $comparedB);
}
}
else if (($sortType & CollectionSortType::STRING) == 0)
{
if (($sortType & CollectionSortType::DESC) == 0)
{
return (int) $comparedA - (int) $comparedB;
}
else
{
return -($comparedA - $comparedB);
}
}
else if ($sortType & CollectionSortType::STRING)
{
if (($sortType & CollectionSortType::DESC) == 0)
{
return strcmp($comparedA, $comparedB);
}
else
{
return -strcmp($comparedA, $comparedB);
}
}
};
uasort($this->items, $cmpFunction);
}
else
{
if ($sortType & CollectionSortType::NUMERIC)
{
if ($sortType & CollectionSortType::ASC)
{
asort($this->items, SORT_NUMERIC);
}
else
{
arsort($this->items, SORT_NUMERIC);
}
}
else if ($sortType & CollectionSortType::STRING)
{
if ($sortType & CollectionSortType::ASC)
{
asort($this->items, SORT_STRING);
}
else
{
arsort($this->items, SORT_STRING);
}
}
else if ($sortType & CollectionSortType::CASE_STRING)
{
if ($sortType & CollectionSortType::ASC)
{
asort($this->items, SORT_STRING | SORT_FLAG_CASE);
}
else
{
arsort($this->items, SORT_STRING | SORT_FLAG_CASE);
}
}
}
}
else
{
if ($sortType & CollectionSortType::NUMERIC)
{
if ($sortType & CollectionSortType::ASC)
{
ksort($this->items, SORT_NUMERIC);
}
else
{
krsort($this->items, SORT_NUMERIC);
}
}
else if ($sortType & CollectionSortType::STRING)
{
if ($sortType & CollectionSortType::ASC)
{
ksort($this->items, SORT_STRING);
}
else
{
krsort($this->items, SORT_STRING);
}
}
else if ($sortType & CollectionSortType::CASE_STRING)
{
if ($sortType & CollectionSortType::ASC)
{
ksort($this->items, SORT_STRING | SORT_FLAG_CASE);
}
else
{
krsort($this->items, SORT_STRING | SORT_FLAG_CASE);
}
}
}
}
public function reverse($preserveKeys = false)
{
$this->items = array_reverse($this->items, $preserveKeys);
}
public function jsonSerialize()
{
return json_encode($this->toArray());
}
}