Skip to content

Commit

Permalink
Add support for forcing plural link relations.
Browse files Browse the repository at this point in the history
When there is a one-to-many relationship between a resource and a
particular link relation, a specific representation may return a link
relation that is a json object and other times that same link relation
as a json array. This can be confusing to clients. The setLink method
now allows the user to force a link relation to always be plural if they
so desire.
  • Loading branch information
hjr3 committed Dec 28, 2012
1 parent cad3cda commit 4ea2b93
Show file tree
Hide file tree
Showing 2 changed files with 150 additions and 7 deletions.
15 changes: 9 additions & 6 deletions library/Hal/Resource.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,19 +77,22 @@ public function getLinks()
* Per the JSON-HAL specification, a link relation can reference a
* single link or an array of links. By default, two or more links with
* the same relation will be treated as an array of links. The $singular
* flag will force links with the same relation to be overwritten.
* flag will force links with the same relation to be overwritten. The
* $plural flag will force links with only one relation to be treated
* as an array of links. The $plural flag has no effect if $singular
* is set to true.
*
* @param Link $link
* @return Resource
*/
public function setLink(Link $link, $singular=false)
public function setLink(Link $link, $singular=false, $plural=false)
{
$rel = $link->getRel();

if (!isset($this->_links[$rel]) || $singular) {
if ($singular || (!isset($this->_links[$rel]) && !$plural)) {
$this->_links[$rel] = $link;
} else {
if (!is_array($this->_links[$rel])) {
if (isset($this->_links[$rel]) && !is_array($this->_links[$rel])) {
$orig_link = $this->_links[$rel];
$this->_links[$rel] = array($orig_link);
}
Expand All @@ -106,10 +109,10 @@ public function setLink(Link $link, $singular=false)
* @param array $links Array of Link objects
* @param boolean $singular
*/
public function setLinks(array $links, $singular = false)
public function setLinks(array $links, $singular = false, $plural = false)
{
foreach ($links as $link) {
$this->setLink($link, $singular);
$this->setLink($link, $singular, $plural);
}

return $this;
Expand Down
142 changes: 141 additions & 1 deletion tests/library/Hal/ResourceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,32 @@ public function testSetSingleLink()
$this->assertEquals($expected, $actual);
}

public function testSetSingleLinkPlural()
{
$parent = new Resource('/dogs');
$parent->setLink(new Link('/dogs?q={text}', 'search'), false, true);

$actual = json_decode($parent);

$JSON = <<<EOF
{
"_links":{
"self":{
"href":"\/dogs"
},
"search": [
{
"href":"\/dogs?q={text}"
}
]
}
}
EOF;

$expected = json_decode($JSON);
$this->assertEquals($expected, $actual);
}

public function testSetLinkMultiple()
{
$parent = new Resource('/dogs');
Expand Down Expand Up @@ -103,6 +129,58 @@ public function testSetLinkMultipleSingular()
$this->assertEquals($expected, $actual);
}

public function testSetLinkMultipleSingularPlural()
{
$parent = new Resource('/dogs');
$parent->setLink(new Link('/dogs?q={text}', 'search'));
$parent->setLink(new Link('/dogs?q={text}&limit={limit}', 'search'), true, true);

$actual = json_decode($parent);

$JSON = <<<EOF
{
"_links":{
"self":{
"href":"\/dogs"
},
"search":{
"href":"\/dogs?q={text}&limit={limit}"
}
}
}
EOF;

$expected = json_decode($JSON);
$this->assertEquals($expected, $actual);
}

public function testSetLinkMultiplePlural()
{
$parent = new Resource('/dogs');
$parent->setLink(new Link('/dogs?q={text}', 'search'), false, true);
$parent->setLink(new Link('/dogs?q={text}&limit={limit}', 'search'), false, true);

$actual = json_decode($parent);

$JSON = <<<EOF
{
"_links":{
"self":{
"href":"\/dogs"
},
"search":[{
"href":"\/dogs?q={text}"
},{
"href":"\/dogs?q={text}&limit={limit}"
}]
}
}
EOF;

$expected = json_decode($JSON);
$this->assertEquals($expected, $actual);
}

public function testSetLinksMultiple()
{
$parent = new Resource('/dogs');
Expand Down Expand Up @@ -133,7 +211,7 @@ public function testSetLinksMultiple()
$this->assertEquals($expected, $actual);
}

public function testSetLinksMultipleSingluar()
public function testSetLinksMultipleSingluar()
{
$parent = new Resource('/dogs');
$links = array(
Expand Down Expand Up @@ -161,6 +239,68 @@ public function testSetLinksMultipleSingluar()
$this->assertEquals($expected, $actual);
}

public function testSetLinksMultipleSingluarPlural()
{
$parent = new Resource('/dogs');
$links = array(
new Link('/dogs?q={text}', 'search'),
new Link('/dogs?q={text}&limit={limit}', 'search')
);
$parent->setLinks($links, true, true);

$actual = json_decode($parent);

$JSON = <<<EOF
{
"_links":{
"self":{
"href":"\/dogs"
},
"search":{
"href":"\/dogs?q={text}&limit={limit}"
}
}
}
EOF;

$expected = json_decode($JSON);
$this->assertEquals($expected, $actual);
}

public function testSetLinksMultiplePlural()
{
$parent = new Resource('/dogs');
$links = array(
new Link('/dogs?q={text}', 'search'),
new Link('/dogs?q={text}&limit={limit}', 'search'),
new Link('/dogs?page=2', 'next')
);
$parent->setLinks($links, false, true);

$actual = json_decode($parent);

$JSON = <<<EOF
{
"_links":{
"self":{
"href":"\/dogs"
},
"search":[{
"href":"\/dogs?q={text}"
},{
"href":"\/dogs?q={text}&limit={limit}"
}],
"next":[{
"href":"\/dogs?page=2"
}]
}
}
EOF;

$expected = json_decode($JSON);
$this->assertEquals($expected, $actual);
}

/**
* This tests adding an empty resource
*/
Expand Down

0 comments on commit 4ea2b93

Please sign in to comment.