Commit
… handled as a list.
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
<?php | ||
/** | ||
* A list object that wraps around an array of objects or arrays. | ||
* | ||
* @package sapphire | ||
* @subpackage model | ||
*/ | ||
class ArrayList extends ViewableData implements SS_List { | ||
|
||
/** | ||
* @var array | ||
*/ | ||
protected $array; | ||
|
||
public function __construct(array $array = array()) { | ||
$this->array = $array; | ||
parent::__construct(); | ||
} | ||
|
||
public function count() { | ||
return count($this->array); | ||
} | ||
|
||
public function getIterator() { | ||
return new ArrayIterator($this->array); | ||
} | ||
|
||
public function toArray() { | ||
return $this->array; | ||
} | ||
|
||
public function toNestedArray() { | ||
$result = array(); | ||
|
||
foreach ($this->array as $item) { | ||
if (is_object($item)) { | ||
if (method_exists($item, 'toMap')) { | ||
$result[] = $item->toMap(); | ||
} else { | ||
$result[] = (array) $item; | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
ajshort
Author
Contributor
|
||
} | ||
} else { | ||
$result[] = $item; | ||
} | ||
} | ||
|
||
return $result; | ||
} | ||
|
||
public function getRange($offset, $length) { | ||
return array_slice($this->array, $offset, $length); | ||
} | ||
|
||
public function add($item) { | ||
$this->array[] = $item; | ||
} | ||
|
||
public function remove($item) { | ||
foreach ($this->array as $key => $value) { | ||
if ($item === $value) unset($this->array[$key]); | ||
} | ||
} | ||
|
||
public function first() { | ||
return reset($this->array); | ||
} | ||
|
||
public function last() { | ||
return end($this->array); | ||
} | ||
|
||
public function map($keyfield, $titlefield) { | ||
$map = array(); | ||
foreach ($this->array as $item) { | ||
$map[$this->extract($item, $keyfield)] = $this->extract($item, $titlefield); | ||
} | ||
return $map; | ||
} | ||
|
||
public function find($key, $value) { | ||
foreach ($this->array as $item) { | ||
if ($this->extract($item, $key) == $value) return $item; | ||
} | ||
} | ||
|
||
public function column($field) { | ||
$result = array(); | ||
foreach ($this->array as $item) { | ||
$result[] = $this->extract($item, $field); | ||
} | ||
return $result; | ||
} | ||
|
||
public function canSortBy($by) { | ||
return true; | ||
} | ||
|
||
public function sort($by, $dir = 'ASC') { | ||
$sorts = array(); | ||
$dir = strtoupper($dir) == 'DESC' ? SORT_DESC : SORT_ASC; | ||
|
||
foreach ($this->array as $item) { | ||
$sorts[] = $this->extract($item, $by); | ||
} | ||
|
||
array_multisort($sorts, $dir, $this->array); | ||
} | ||
|
||
public function offsetExists($offset) { | ||
return array_key_exists($offset, $this->array); | ||
} | ||
|
||
public function offsetGet($offset) { | ||
if ($this->offsetExists($offset)) return $this->array[$offset]; | ||
} | ||
|
||
public function offsetSet($offset, $value) { | ||
$this->array[$offset] = $value; | ||
} | ||
|
||
public function offsetUnset($offset) { | ||
unset($this->array[$offset]); | ||
} | ||
|
||
/** | ||
* Extracts a value from an item in the list, where the item is either an | ||
* object or array. | ||
* | ||
* @param array|object $item | ||
* @param string $key | ||
* @return mixed | ||
*/ | ||
protected function extract($item, $key) { | ||
if (is_object($item)) { | ||
return $item->$key; | ||
} else { | ||
if (array_key_exists($key, $item)) return $item[$key]; | ||
} | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
<?php | ||
/** | ||
* @package sapphire | ||
* @subpackage tests | ||
*/ | ||
class ArrayListTest extends SapphireTest { | ||
|
||
public function testCount() { | ||
$list = new ArrayList(); | ||
$this->assertEquals(0, $list->count()); | ||
$list = new ArrayList(array(1, 2, 3)); | ||
$this->assertEquals(3, $list->count()); | ||
} | ||
|
||
public function testToNestedArray() { | ||
$list = new ArrayList(array( | ||
array('First' => 'FirstFirst', 'Second' => 'FirstSecond'), | ||
(object) array('First' => 'SecondFirst', 'Second' => 'SecondSecond'), | ||
new ArrayListTest_Object('ThirdFirst', 'ThirdSecond') | ||
)); | ||
|
||
$this->assertEquals($list->toNestedArray(), array( | ||
array('First' => 'FirstFirst', 'Second' => 'FirstSecond'), | ||
array('First' => 'SecondFirst', 'Second' => 'SecondSecond'), | ||
array('First' => 'ThirdFirst', 'Second' => 'ThirdSecond') | ||
)); | ||
} | ||
|
||
public function testGetRange() { | ||
$list = new ArrayList(array( | ||
array('Key' => 1), array('Key' => 2), array('Key' => 3) | ||
)); | ||
$this->assertEquals($list->getRange(1, 2), array( | ||
array('Key' => 2), array('Key' => 3) | ||
)); | ||
} | ||
|
||
public function testAddRemove() { | ||
$list = new ArrayList(array( | ||
array('Key' => 1), array('Key' => 2) | ||
)); | ||
|
||
$list->add(array('Key' => 3)); | ||
$this->assertEquals($list->toArray(), array( | ||
array('Key' => 1), array('Key' => 2), array('Key' => 3) | ||
)); | ||
|
||
$list->remove(array('Key' => 2)); | ||
$this->assertEquals(array_values($list->toArray()), array( | ||
array('Key' => 1), array('Key' => 3) | ||
)); | ||
} | ||
|
||
public function testFirstLast() { | ||
$list = new ArrayList(array( | ||
array('Key' => 1), array('Key' => 2), array('Key' => 3) | ||
)); | ||
$this->assertEquals($list->first(), array('Key' => 1)); | ||
$this->assertEquals($list->last(), array('Key' => 3)); | ||
} | ||
|
||
public function testMap() { | ||
$list = new ArrayList(array( | ||
array('ID' => 1, 'Name' => 'Steve',), | ||
(object) array('ID' => 3, 'Name' => 'Bob'), | ||
array('ID' => 5, 'Name' => 'John') | ||
)); | ||
$this->assertEquals($list->map('ID', 'Name'), array( | ||
1 => 'Steve', | ||
3 => 'Bob', | ||
5 => 'John' | ||
)); | ||
} | ||
|
||
public function testFind() { | ||
$list = new ArrayList(array( | ||
array('Name' => 'Steve'), | ||
(object) array('Name' => 'Bob'), | ||
array('Name' => 'John') | ||
)); | ||
$this->assertEquals($list->find('Name', 'Bob'), (object) array( | ||
'Name' => 'Bob' | ||
)); | ||
} | ||
|
||
public function testColumn() { | ||
$list = new ArrayList(array( | ||
array('Name' => 'Steve'), | ||
(object) array('Name' => 'Bob'), | ||
array('Name' => 'John') | ||
)); | ||
$this->assertEquals($list->column('Name'), array( | ||
'Steve', 'Bob', 'John' | ||
)); | ||
} | ||
|
||
public function testSort() { | ||
$list = new ArrayList(array( | ||
array('Name' => 'Steve'), | ||
(object) array('Name' => 'Bob'), | ||
array('Name' => 'John') | ||
)); | ||
|
||
$list->sort('Name'); | ||
$this->assertEquals($list->toArray(), array( | ||
(object) array('Name' => 'Bob'), | ||
array('Name' => 'John'), | ||
array('Name' => 'Steve') | ||
)); | ||
|
||
$list->sort('Name', 'DESC'); | ||
$this->assertEquals($list->toArray(), array( | ||
array('Name' => 'Steve'), | ||
array('Name' => 'John'), | ||
(object) array('Name' => 'Bob') | ||
)); | ||
} | ||
|
||
} | ||
|
||
/** | ||
* @ignore | ||
*/ | ||
class ArrayListTest_Object { | ||
|
||
public $First; | ||
public $Second; | ||
|
||
public function __construct($first, $second) { | ||
$this->First = $first; | ||
$this->Second = $second; | ||
} | ||
|
||
public function toMap() { | ||
return array('First' => $this->First, 'Second' => $this->Second); | ||
} | ||
|
||
} |
Hey, what was the reason to cast as an array at this point? I'm currently doing
Debug::show(FieldList)
and which results in toNestedArray being called, but an (array) cast on aFormField
results in an infinite loop... Removing this line fixes the infinite loop..Perhaps fixing the infinite loop caused by casting as an array is a better approach.. but not sure what's causing that