<?php
/**
* _Type_IndexedList object contains a list of objects (_Type_Object) that can be accessed through predefined indexes.
* @copyright Copyright (c) 2012, PWF
* @license http://phpwebframework.com/License
* @version PWF_0.3.0
*/
class _Type_IndexedList
{
private $list;
private $map = array();
private $indexForObject = 1;
private $indexForSublist = 0;
private $mapTypes = array(1,0);
private $indexes = array();
/**
* Adds an objec to the list
* @param _Type_Object $object
*/
public function add(_Type_Object $object)
{
$this->list[] = $object;
$this->mapObjectIndexes(count($this->list)-1, $object);
}
/**
* If sets an object of the list depending to its consequence position
* @param integer $i The consequence position of the object to the list
* @param _Type_Object $object
*/
public function set($i,_Type_Object $object)
{
$this->list[$i] = $object;
$this->mapObjectIndexes($i, $object);
}
/**
* It returns an object of the list depending to its consequence position
* @param integer $i The consequence position of the object to the list
*/
public function get($i)
{
return $this->list[$i];
}
/**
* It appends a second _Type_ObjectsList to the current
* @param _Type_ObjectsList $list The list to be appended
*/
public function appendList(_Type_ObjectsList $list)
{
if($list->size()>0)
{
foreach($list->objects() as $object)
{
$this->list[] = $object;
$this->mapObjectIndexes(count($this->list)-1, $object);
}
}
}
/**
* It returns the number of objects in the list
* @return number
*/
public function size()
{
return count($this->list);
}
/**
* It returns the objects of the list (array)
* @return array of _Type_Object
*/
public function objects()
{
return $this->list;
}
/**
* Sets an index (property name) for retrieving object from the list based to given value
* This means that the index has a relationship one to one to list objects
* (For example a unique id property)
* @param string $index The property
*/
public function setIndexForObjects($index)
{
$this->indexes[$index] = $this->indexForObject;
if(isset($this->list))
{
$this->appendIndexToList($key, $keyType);
}
}
/**
* Sets an index (property name) for retrieving a sub list from the list based to given value
* This means that the index may have a relationship one to many to list objects
* @param string $index The property name
*/
public function setIndexForSublists($index)
{
$this->indexes[$index] = $this->indexForSublist;
if(isset($this->list))
{
$this->appendIndexToList($key, $keyType);
}
}
/**
* Gets a sub list from the list based to the value of a predefined index by setIndexForSublists
* Even if there is only one object that correspond that value of the index a _Type_ObjectsList will
* be returned
* @param string $index The index predefined by setIndexForSublists
* @param string $value The value of the property to generate the sub list
* @return _Type_ObjectsList
*/
public function getIndexedSublist($index,$value,$preserveIndexes = false)
{
$list = new _Type_ObjectsList();
if(isset($this->map[$index][$value]))
{
if($preserveIndexes)
{
foreach($this->indexes as $index => $indexType)
{
if($indexType == $this->indexForObject)
{
$this->setIndexForObject($index);
}
else
{
$this->setIndexForSublist($index);
}
}
}
foreach($this->map[$index][$value] as $o)
{
$list->add($o);
}
}
return $list;
}
/**
* Gets an object from the list based to the value of a prefefiend index by setIndexForObjects
* @param string $index The index predefined by setIndexForObjects
* @param string $value The value of the property to get the object
*/
public function getIndexedObject($index,$value)
{
if(isset($this->map[$index][$value]))
{
return $this->list[$this->map[$index][$value]];
}
else
{
return null;
}
}
// TODO αν είναι ανÏικείμενο και αν είναι λίÏÏα;
/**
* Removes all objects from the list that fetch a specific index and a value
* no matter what type of index is it (unique or sub list)
* @param $index
* @param $value
*/
public function removeByIndex($index,$value)
{
if(isset($this->map[$index][$value]))
{
unset($this->list[$this->map[$index][$value]]);
unset($this->map[$index][$value]);
}
}
/**
* Check if the list contains a indexed sublist based to the index property name and the value of it
* The index should has been first seted with setIndexForSublists
* @param string $index
* @param string $value
* @return boolean
*/
public function containsIndexedSublist($index,$value)
{
return isset($this->map[$index][$value]) && is_array($this->map[$index][$value]);
}
/**
* Check if the list contains a indexed object based to the index property name and the value of it
* @param string $index
* @param string $value
* @return boolean
*/
public function containsIndexedObject($index,$value)
{
return isset($this->map[$index][$value]) && !is_array($this->map[$index][$value]);
}
/**
* Maps the indexes properties based on their name to an object of the list
* @param unknown_type $i
* @param _Type_Object $object
*/
private function mapObjectIndexes($i,_Type_Object $object)
{
$a = $object->toArray();
foreach ($this->indexes as $index=>$indexType)
{
if(isset($a[$index]))
{
if($indexType==$this->indexForObject)
{
$this->map[$index][$a[$index]] = $i;
}
else
{
$this->map[$index][$a[$index]][] = $i;
}
}
}
}
/**
* Adds an index to the list when the list in not empty
* @param unknown_type $index
* @param unknown_type $indexType
*/
private function appendIndexToList($index,$indexType)
{
for($i=0; $i<_Array::size($this->list); $i++)
{
$o = $this->get($i);
$a = $o->toArray();
if(_Array::containsKey($a, $index))
{
if($indexType==$this->indexForObject)
{
$this->map[$index][$a[$index]] = $i;
}
else
{
$this->map[$index][$a[$index]][] = $i;
}
}
}
}
}
?>