Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
language: php
dist: trusty
install:
composer install
php:
- 5.5
- 5.6
- 7.1
- hhvm

script:
Expand Down
7 changes: 5 additions & 2 deletions src/Architect.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,14 @@ private function parseResource(array $modes, &$resource, &$root, $fullPropertyPa

$object = &$resource[$property];
} else {
if ($resource->{$property} === null) {
if (!is_object($resource)) {
continue;
}

$object = &$resource->{$property};
$object = $resource->{$property};
if (!is_object($object)) {
continue;
}
}

if (empty($steps)) {
Expand Down
6 changes: 3 additions & 3 deletions src/ModeResolver/IdsModeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ public function resolve($property, &$object, &$root, $fullPropertyPath)
// model, because the first item returned was a property
// We therefore just return the single ID
if (Utility::isPrimitive($firstElement)) {
return (int) Utility::getProperty($object, 'id');
return Utility::getProperty($object, 'id', true);
}

return array_map(function ($entry) {
return (int) Utility::getProperty($entry, 'id');
return Utility::getProperty($entry, 'id', true);
}, $object);
} elseif ($object instanceof Collection) {
return $object->map(function ($entry) {
return (int) Utility::getProperty($entry, 'id');
return Utility::getProperty($entry, 'id', true);
});
// The relation is not a collection, but rather
// a singular relation
Expand Down
4 changes: 2 additions & 2 deletions src/ModeResolver/SideloadModeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,13 @@ private function mergeRootCollection(&$collection, $object)
*/
private function addResourceToRootCollectionIfNonExistant(&$collection, $resource)
{
$identifier = Utility::getProperty($resource, 'id');
$identifier = Utility::getProperty($resource, 'id', true);
$exists = false;

$copy = $collection instanceof Collection ? $collection->toArray() : $collection;

foreach ($copy as $rootResource) {
if ((int) Utility::getProperty($rootResource, 'id') === (int) $identifier) {
if (Utility::getProperty($rootResource, 'id', true) === $identifier) {
$exists = true;
break;
}
Expand Down
28 changes: 25 additions & 3 deletions src/Utility.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,19 @@ class Utility
* @param string $property
* @return mixed
*/
public static function getProperty($objectOrArray, $property)
public static function getProperty($objectOrArray, $property, $format = false)
{
if (is_array($objectOrArray)) {
return $objectOrArray[$property];
$ret = $objectOrArray[$property];
} else {
return $objectOrArray->{$property};
$ret = $objectOrArray->{$property};
}

if (!$format) {
return $ret;
}

return static::formatProperty($ret);
}

/**
Expand Down Expand Up @@ -75,4 +81,20 @@ public static function isCollection($input)
{
return is_array($input) || $input instanceof Collection;
}

/**
* Format a given property.
* @param mixed $property
* @param bool $numericIntegers If true and property passes is_numeric test, cast as an integer
* @return mixed
*/
private static function formatProperty($property, $numericIntegers = true)
{
// handle default integer based properties
if ($numericIntegers && is_numeric($property)) {
return (int) $property;
}

return $property;
}
}
13 changes: 7 additions & 6 deletions tests/Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ public function getEloquentCollection(array $eagerLoad = array(), array $modes =
return $this->architect->parseData($collection, $modes, 'collection');
}

public function getCollection($rows, array $modes = [], $children = false, $childrensChildren = false, $array = false)
public function getCollection($rows, array $modes = [], $children = false, $childrensChildren = false, $array = false, $stringKeys = false)
{
$collection = $this->createCollection($rows, $children, $childrensChildren, $array);
$collection = $this->createCollection($rows, $children, $childrensChildren, $array, $stringKeys);

return $this->architect->parseData($collection, $modes, 'collection');
}

private function createCollection($rows = 2, $children = false, $childrensChildren = false, $array = false, $level = 1)
private function createCollection($rows = 2, $children = false, $childrensChildren = false, $array = false, $stringKeys = false, $level = 1)
{
if (!array_key_exists($level, $this->idCounts)) {
$this->idCounts[$level] = 0;
Expand All @@ -40,18 +40,19 @@ private function createCollection($rows = 2, $children = false, $childrensChildr
for ($i=1;$i<=$rows;$i++) {
$this->idCounts[$level]++;

$newId = (!$stringKeys ? $this->idCounts[$level] : 'aaa'.dechex($this->idCounts[$level]));
$tmp = [
'id' => $this->idCounts[$level],
'id' => $newId,
'title' => 'Resource ' . $i,
'singleChildren' => [
'id' => $this->idCounts[$level],
'id' => $newId,
'name' => 'Single child'
]
];

if (is_int($children)) {
$key = $level === 1 ? 'children' : 'nestedChildren';
$tmp[$key] = $this->createCollection($children, $childrensChildren, false, $array, ($level+1));
$tmp[$key] = $this->createCollection($children, $childrensChildren, false, $array, $stringKeys, ($level+1));
}

$data[] = $tmp;
Expand Down
20 changes: 20 additions & 0 deletions tests/ModeResolver/IdsModeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,26 @@ public function testIdsModeResolverOnNestedChildrenOnArrayCollections()
], $second);
}

public function testIdsModeResolverOnNestedChildrenOnArrayCollectionsAndStringKeys()
{
$controller = new Controller;

$modes = [
'children.nestedChildren' => 'ids'
];
$parsed = $controller->getCollection(2, $modes, 2, 2, true, true)['collection'];

$first = $parsed[0]['children'][0]['nestedChildren'];
$this->assertEquals([
'aaa1', 'aaa2'
], $first);

$second = $parsed[1]['children'][1]['nestedChildren'];
$this->assertEquals([
'aaa7', 'aaa8'
], $second);
}

public function testIdsModeResolverOnEloquentCollections()
{
$controller = new Controller;
Expand Down
40 changes: 40 additions & 0 deletions tests/ModeResolver/SideloadModeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,46 @@ public function testSideloadModeResolverOnNestedChildrenOnVanillaCollections()
]);
}

public function testSideloadModeResolverOnNestedChildrenOnVanillaCollectionsAndStringKeys()
{
$controller = new Controller;

$modes = [
'children.nestedChildren' => 'sideload'
];
$parsed = $controller->getCollection(2, $modes, 2, 2, false, true);
$collection = $parsed['collection'];
$nestedChildren = $parsed['children.nestedChildren'];

$first = $collection->get(0);
$this->assertEquals([
'aaa1', 'aaa2', 'aaa3', 'aaa4', 'aaa1', 'aaa2', 'aaa3', 'aaa4'
], [
$first['children']->get(0)['nestedChildren']->get(0),
$first['children']->get(0)['nestedChildren']->get(1),
$first['children']->get(1)['nestedChildren']->get(0),
$first['children']->get(1)['nestedChildren']->get(1),
$nestedChildren->get(0)['id'],
$nestedChildren->get(1)['id'],
$nestedChildren->get(2)['id'],
$nestedChildren->get(3)['id']
]);

$second = $collection->get(1);
$this->assertEquals([
'aaa5', 'aaa6', 'aaa7', 'aaa8', 'aaa5', 'aaa6', 'aaa7', 'aaa8'
], [
$second['children']->get(0)['nestedChildren']->get(0),
$second['children']->get(0)['nestedChildren']->get(1),
$second['children']->get(1)['nestedChildren']->get(0),
$second['children']->get(1)['nestedChildren']->get(1),
$nestedChildren->get(4)['id'],
$nestedChildren->get(5)['id'],
$nestedChildren->get(6)['id'],
$nestedChildren->get(7)['id']
]);
}

public function testSideloadModeResolverOnParentAndNestedChildrenOnVanillaCollections()
{
$controller = new Controller;
Expand Down