Merge pull request #4964 from tractorcow/pulls/4.0/tomap-standardise

API Standardise SS_List::map() implementation
This commit is contained in:
Daniel Hensby 2016-01-25 13:31:05 +00:00
commit e74665b639
6 changed files with 46 additions and 34 deletions

View File

@ -275,21 +275,13 @@ class ArrayList extends ViewableData implements SS_List, SS_Filterable, SS_Sorta
/** /**
* Returns a map of this list * Returns a map of this list
* *
* @param string $keyfield - the 'key' field of the result array * @param string $keyfield The 'key' field of the result array
* @param string $titlefield - the value field of the result array * @param string $titlefield The value field of the result array
* @return array * @return SS_Map
*/ */
public function map($keyfield = 'ID', $titlefield = 'Title') { public function map($keyfield = 'ID', $titlefield = 'Title') {
$map = array(); $list = clone $this;
return new SS_Map($list, $keyfield, $titlefield);
foreach ($this->items as $item) {
$map[$this->extractValue($item, $keyfield)] = $this->extractValue(
$item,
$titlefield
);
}
return $map;
} }
/** /**
@ -674,9 +666,14 @@ class ArrayList extends ViewableData implements SS_List, SS_Filterable, SS_Sorta
*/ */
protected function extractValue($item, $key) { protected function extractValue($item, $key) {
if (is_object($item)) { if (is_object($item)) {
return $item->$key; if(method_exists($item, 'hasMethod') && $item->hasMethod($key)) {
return $item->{$key}();
}
return $item->{$key};
} else { } else {
if (array_key_exists($key, $item)) return $item[$key]; if (array_key_exists($key, $item)) {
return $item[$key];
}
} }
} }

View File

@ -56,7 +56,7 @@ interface SS_List extends ArrayAccess, Countable, IteratorAggregate {
* *
* @param string $keyfield * @param string $keyfield
* @param string $titlefield * @param string $titlefield
* @return array * @return SS_Map
*/ */
public function map($keyfield = 'ID', $titlefield = 'Title'); public function map($keyfield = 'ID', $titlefield = 'Title');

View File

@ -286,7 +286,7 @@ class SS_Map_Iterator implements Iterator {
* @param Iterator $items The iterator to build this map from * @param Iterator $items The iterator to build this map from
* @param string $keyField The field to use for the keys * @param string $keyField The field to use for the keys
* @param string $titleField The field to use for the values * @param string $titleField The field to use for the values
* @param array $fristItems An optional map of items to show first * @param array $firstItems An optional map of items to show first
* @param array $lastItems An optional map of items to show last * @param array $lastItems An optional map of items to show last
*/ */
public function __construct(Iterator $items, $keyField, $titleField, $firstItems = null, $lastItems = null) { public function __construct(Iterator $items, $keyField, $titleField, $firstItems = null, $lastItems = null) {
@ -326,11 +326,7 @@ class SS_Map_Iterator implements Iterator {
return $this->firstItems[$this->firstItemIdx][1]; return $this->firstItems[$this->firstItemIdx][1];
} else { } else {
if($rewoundItem) { if($rewoundItem) {
if($rewoundItem->hasMethod($this->titleField)) { return $this->extractValue($rewoundItem, $this->titleField);
return $rewoundItem->{$this->titleField}();
}
return $rewoundItem->{$this->titleField};
} else if(!$this->items->valid() && $this->lastItems) { } else if(!$this->items->valid() && $this->lastItems) {
$this->endItemIdx = 0; $this->endItemIdx = 0;
@ -349,12 +345,28 @@ class SS_Map_Iterator implements Iterator {
return $this->lastItems[$this->endItemIdx][1]; return $this->lastItems[$this->endItemIdx][1];
} else if(isset($this->firstItems[$this->firstItemIdx])) { } else if(isset($this->firstItems[$this->firstItemIdx])) {
return $this->firstItems[$this->firstItemIdx][1]; return $this->firstItems[$this->firstItemIdx][1];
} else { }
if($this->items->current()->hasMethod($this->titleField)) { return $this->extractValue($this->items->current(), $this->titleField);
return $this->items->current()->{$this->titleField}();
} }
return $this->items->current()->{$this->titleField}; /**
* 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 extractValue($item, $key) {
if (is_object($item)) {
if(method_exists($item, 'hasMethod') && $item->hasMethod($key)) {
return $item->{$key}();
}
return $item->{$key};
} else {
if (array_key_exists($key, $item)) {
return $item[$key];
}
} }
} }
@ -369,7 +381,7 @@ class SS_Map_Iterator implements Iterator {
} else if(isset($this->firstItems[$this->firstItemIdx])) { } else if(isset($this->firstItems[$this->firstItemIdx])) {
return $this->firstItems[$this->firstItemIdx][0]; return $this->firstItems[$this->firstItemIdx][0];
} else { } else {
return $this->items->current()->{$this->keyField}; return $this->extractValue($this->items->current(), $this->keyField);
} }
} }

View File

@ -1176,8 +1176,7 @@ class Member extends DataObject implements TemplateGlobalProvider {
* If no $groups is passed, all members will be returned * If no $groups is passed, all members will be returned
* *
* @param mixed $groups - takes a SS_List, an array or a single Group.ID * @param mixed $groups - takes a SS_List, an array or a single Group.ID
* @return SQLMap Returns an SQLMap that returns all Member data. * @return SS_Map Returns an SS_Map that returns all Member data.
* @see map()
*/ */
public static function map_in_groups($groups = null) { public static function map_in_groups($groups = null) {
$groupIDList = array(); $groupIDList = array();

View File

@ -214,11 +214,15 @@ class ArrayListTest extends SapphireTest {
(object) array('ID' => 3, 'Name' => 'Bob'), (object) array('ID' => 3, 'Name' => 'Bob'),
array('ID' => 5, 'Name' => 'John') array('ID' => 5, 'Name' => 'John')
)); ));
$this->assertEquals($list->map('ID', 'Name'), array( $map = $list->map('ID', 'Name');
// Items added after calling map should not be included retroactively
$list->add(array('ID' => 7, 'Name' => 'Andrew'));
$this->assertInstanceOf('SS_Map', $map);
$this->assertEquals(array(
1 => 'Steve', 1 => 'Steve',
3 => 'Bob', 3 => 'Bob',
5 => 'John' 5 => 'John'
)); ), $map->toArray());
} }
public function testFind() { public function testFind() {

View File

@ -709,7 +709,7 @@ class MemberTest extends FunctionalTest {
*/ */
public function testMap_in_groupsReturnsAll() { public function testMap_in_groupsReturnsAll() {
$members = Member::map_in_groups(); $members = Member::map_in_groups();
$this->assertEquals(13, count($members), 'There are 12 members in the mock plus a fake admin'); $this->assertEquals(13, $members->count(), 'There are 12 members in the mock plus a fake admin');
} }
/** /**
@ -717,7 +717,7 @@ class MemberTest extends FunctionalTest {
*/ */
public function testMap_in_groupsReturnsAdmins() { public function testMap_in_groupsReturnsAdmins() {
$adminID = $this->objFromFixture('Group', 'admingroup')->ID; $adminID = $this->objFromFixture('Group', 'admingroup')->ID;
$members = Member::map_in_groups($adminID); $members = Member::map_in_groups($adminID)->toArray();
$admin = $this->objFromFixture('Member', 'admin'); $admin = $this->objFromFixture('Member', 'admin');
$otherAdmin = $this->objFromFixture('Member', 'other-admin'); $otherAdmin = $this->objFromFixture('Member', 'other-admin');