Skip to content

Commit 366f468

Browse files
committed
Introduce Resource\ItemLink object
refs #23
1 parent c9e1f6b commit 366f468

File tree

9 files changed

+238
-16
lines changed

9 files changed

+238
-16
lines changed

src/Resource/Item.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public function __construct($object, FactoryManagerInterface $manager)
9090
if ( property_exists($object, 'links') )
9191
{
9292
$this->container->set('links', $this->manager->getFactory()->make(
93-
'Link',
93+
'Resource\ItemLink',
9494
[$object->links, $this->manager, $this]
9595
));
9696
}

src/Resource/ItemLink.php

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<?php
2+
3+
namespace Art4\JsonApiClient\Resource;
4+
5+
use Art4\JsonApiClient\AccessInterface;
6+
use Art4\JsonApiClient\Resource\ItemLinkInterface;
7+
use Art4\JsonApiClient\Utils\AccessTrait;
8+
use Art4\JsonApiClient\Utils\DataContainer;
9+
use Art4\JsonApiClient\Utils\FactoryManagerInterface;
10+
use Art4\JsonApiClient\Exception\AccessException;
11+
use Art4\JsonApiClient\Exception\ValidationException;
12+
13+
/**
14+
* ItemLink Object
15+
*
16+
* @see http://jsonapi.org/format/#document-links
17+
*/
18+
final class ItemLink implements ItemLinkInterface
19+
{
20+
use AccessTrait;
21+
22+
/**
23+
* @var AccessInterface
24+
*/
25+
protected $parent;
26+
27+
/**
28+
* @var DataContainerInterface
29+
*/
30+
protected $container;
31+
32+
/**
33+
* @var FactoryManagerInterface
34+
*/
35+
protected $manager;
36+
37+
/**
38+
* @param object $object The error object
39+
*
40+
* @return self
41+
*
42+
* @throws ValidationException
43+
*/
44+
public function __construct($object, FactoryManagerInterface $manager, AccessInterface $parent)
45+
{
46+
if ( ! is_object($object) )
47+
{
48+
throw new ValidationException('ItemLink has to be an object, "' . gettype($object) . '" given.');
49+
}
50+
51+
$this->parent = $parent;
52+
53+
$this->manager = $manager;
54+
55+
$this->container = new DataContainer();
56+
57+
$object_vars = get_object_vars($object);
58+
59+
if ( count($object_vars) === 0 )
60+
{
61+
return $this;
62+
}
63+
64+
foreach ($object_vars as $name => $value)
65+
{
66+
$this->set($name, $value);
67+
}
68+
69+
return $this;
70+
}
71+
72+
/**
73+
* Get a value by the key of this object
74+
*
75+
* @param string $key The key of the value
76+
* @return mixed The value
77+
*/
78+
public function get($key)
79+
{
80+
try
81+
{
82+
return $this->container->get($key);
83+
}
84+
catch (AccessException $e)
85+
{
86+
throw new AccessException('"' . $key . '" doesn\'t exist in this object.');
87+
}
88+
}
89+
90+
/**
91+
* Set a link
92+
*
93+
* @param string $name The Name
94+
* @param string|object $link The Link
95+
*
96+
* @return self
97+
*/
98+
protected function set($name, $link)
99+
{
100+
// from spec: aA link MUST be represented as either:
101+
// - a string containing the link's URL.
102+
// - an object ("link object") which can contain the following members:
103+
if ( ! is_object($link) and ! is_string($link) )
104+
{
105+
throw new ValidationException('Link has to be an object or string, "' . gettype($link) . '" given.');
106+
}
107+
108+
if ( is_string($link) )
109+
{
110+
$this->container->set($name, strval($link));
111+
112+
return $this;
113+
}
114+
115+
// Now $link can only be an object
116+
$this->container->set($name, $this->manager->getFactory()->make(
117+
'Link',
118+
[$link, $this->manager, $this]
119+
));
120+
121+
return $this;
122+
}
123+
}

src/Resource/ItemLinkInterface.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Art4\JsonApiClient\Resource;
4+
5+
use Art4\JsonApiClient\AccessInterface;
6+
7+
/**
8+
* Resource\ItemLink Interface
9+
*/
10+
interface ItemLinkInterface extends AccessInterface { }

src/Utils/Factory.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ final class Factory implements FactoryInterface
2727
'Resource\Identifier' => 'Art4\JsonApiClient\Resource\Identifier',
2828
'Resource\IdentifierCollection' => 'Art4\JsonApiClient\Resource\IdentifierCollection',
2929
'Resource\Item' => 'Art4\JsonApiClient\Resource\Item',
30+
'Resource\ItemLink' => 'Art4\JsonApiClient\Resource\ItemLink',
3031
'Resource\NullResource' => 'Art4\JsonApiClient\Resource\NullResource',
3132
];
3233

tests/integration/DotNotationTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public function testCompleteResourceObjectWithMultipleRelationships()
3939
$this->assertSame($document->get('data.0.attributes.title'), 'JSON API paints my bikeshed!');
4040

4141
$this->assertTrue($document->has('data.0.links'));
42-
$this->assertInstanceOf('Art4\JsonApiClient\Link', $document->get('data.0.links'));
42+
$this->assertInstanceOf('Art4\JsonApiClient\Resource\ItemLink', $document->get('data.0.links'));
4343

4444
$this->assertTrue($document->has('data.0.links.self'));
4545
$this->assertSame($document->get('data.0.links.self'), 'http://example.com/articles/1');
@@ -126,7 +126,7 @@ public function testCompleteResourceObjectWithMultipleRelationships()
126126
$this->assertSame($document->get('included.0.attributes.twitter'), 'dgeb');
127127

128128
$this->assertTrue($document->has('included.0.links'));
129-
$this->assertInstanceOf('Art4\JsonApiClient\Link', $document->get('included.0.links'));
129+
$this->assertInstanceOf('Art4\JsonApiClient\Resource\ItemLink', $document->get('included.0.links'));
130130

131131
$this->assertTrue($document->has('included.0.links.self'));
132132
$this->assertSame($document->get('included.0.links.self'), 'http://example.com/people/9');
@@ -147,7 +147,7 @@ public function testCompleteResourceObjectWithMultipleRelationships()
147147
$this->assertSame($document->get('included.1.attributes.body'), 'First!');
148148

149149
$this->assertTrue($document->has('included.1.links'));
150-
$this->assertInstanceOf('Art4\JsonApiClient\Link', $document->get('included.1.links'));
150+
$this->assertInstanceOf('Art4\JsonApiClient\Resource\ItemLink', $document->get('included.1.links'));
151151

152152
$this->assertTrue($document->has('included.1.links.self'));
153153
$this->assertSame($document->get('included.1.links.self'), 'http://example.com/comments/5');
@@ -168,7 +168,7 @@ public function testCompleteResourceObjectWithMultipleRelationships()
168168
$this->assertSame($document->get('included.2.attributes.body'), 'I like XML better');
169169

170170
$this->assertTrue($document->has('included.2.links'));
171-
$this->assertInstanceOf('Art4\JsonApiClient\Link', $document->get('included.2.links'));
171+
$this->assertInstanceOf('Art4\JsonApiClient\Resource\ItemLink', $document->get('included.2.links'));
172172

173173
$this->assertTrue($document->has('included.2.links.self'));
174174
$this->assertSame($document->get('included.2.links.self'), 'http://example.com/comments/12');

tests/integration/ParsingTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ public function testParseCompleteResourceObjectWithMultipleRelationships()
226226

227227
$links = $resource->get('links');
228228

229-
$this->assertInstanceOf('Art4\JsonApiClient\Link', $links);
229+
$this->assertInstanceOf('Art4\JsonApiClient\Resource\ItemLink', $links);
230230
$this->assertTrue($links->has('self'));
231231
$this->assertSame($links->get('self'), 'http://example.com/articles/1');
232232

@@ -256,7 +256,7 @@ public function testParseCompleteResourceObjectWithMultipleRelationships()
256256

257257
$links = $include->get('links');
258258

259-
$this->assertInstanceOf('Art4\JsonApiClient\Link', $links);
259+
$this->assertInstanceOf('Art4\JsonApiClient\Resource\ItemLink', $links);
260260
$this->assertTrue($links->has('self'));
261261
$this->assertSame($links->get('self'), 'http://example.com/people/9');
262262

@@ -277,7 +277,7 @@ public function testParseCompleteResourceObjectWithMultipleRelationships()
277277

278278
$links = $include->get('links');
279279

280-
$this->assertInstanceOf('Art4\JsonApiClient\Link', $links);
280+
$this->assertInstanceOf('Art4\JsonApiClient\Resource\ItemLink', $links);
281281
$this->assertTrue($links->has('self'));
282282
$this->assertSame($links->get('self'), 'http://example.com/comments/5');
283283

@@ -298,7 +298,7 @@ public function testParseCompleteResourceObjectWithMultipleRelationships()
298298

299299
$links = $include->get('links');
300300

301-
$this->assertInstanceOf('Art4\JsonApiClient\Link', $links);
301+
$this->assertInstanceOf('Art4\JsonApiClient\Resource\ItemLink', $links);
302302
$this->assertTrue($links->has('self'));
303303
$this->assertSame($links->get('self'), 'http://example.com/comments/12');
304304

tests/unit/LinkTest.php

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,36 +29,30 @@ public function testCreateWithObject()
2929
$object = new \stdClass();
3030
$object->meta = new \stdClass();
3131
$object->href = 'http://example.org/href';
32-
$object->linkobj = new \stdClass();
3332
$object->link = 'http://example.org/link';
3433

3534
$link = new Link($object, $this->manager, $this->parent_link);
3635

3736
$this->assertInstanceOf('Art4\JsonApiClient\Link', $link);
3837
$this->assertInstanceOf('Art4\JsonApiClient\AccessInterface', $link);
39-
$this->assertSame($link->getKeys(), array('meta', 'href', 'linkobj', 'link'));
4038

4139
$this->assertTrue($link->has('href'));
4240
$this->assertSame($link->get('href'), 'http://example.org/href');
4341
$this->assertTrue($link->has('meta'));
4442
$this->assertInstanceOf('Art4\JsonApiClient\MetaInterface', $link->get('meta'));
4543
$this->assertTrue($link->has('link'));
4644
$this->assertSame($link->get('link'), 'http://example.org/link');
47-
$this->assertTrue($link->has('linkobj'));
48-
$this->assertInstanceOf('Art4\JsonApiClient\LinkInterface', $link->get('linkobj'));
4945

5046
$this->assertSame($link->asArray(), array(
5147
'meta' => $link->get('meta'),
5248
'href' => $link->get('href'),
53-
'linkobj' => $link->get('linkobj'),
5449
'link' => $link->get('link'),
5550
));
5651

5752
// Test full array
5853
$this->assertSame($link->asArray(true), array(
5954
'meta' => $link->get('meta')->asArray(true),
6055
'href' => $link->get('href'),
61-
'linkobj' => $link->get('linkobj')->asArray(true),
6256
'link' => $link->get('link'),
6357
));
6458

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<?php
2+
3+
namespace Art4\JsonApiClient\Resource\Tests;
4+
5+
use Art4\JsonApiClient\Resource\ItemLink;
6+
use Art4\JsonApiClient\Tests\Fixtures\HelperTrait;
7+
8+
class ItemLinkTest extends \PHPUnit_Framework_TestCase
9+
{
10+
use HelperTrait;
11+
12+
/**
13+
* @setup
14+
*/
15+
public function setUp()
16+
{
17+
$this->manager = $this->buildManagerMock();
18+
19+
// Mock parent
20+
$this->parent = $this->getMockBuilder('Art4\JsonApiClient\AccessInterface')
21+
->getMock();
22+
}
23+
24+
/**
25+
* @test parsing of all properties
26+
*/
27+
public function testParsingPropertiesExists()
28+
{
29+
$object = new \stdClass();
30+
$object->self = 'http://example.org/self';
31+
$object->custom = 'http://example.org/custom';
32+
$object->related = new \stdClass();
33+
34+
$link = new ItemLink($object, $this->manager, $this->parent);
35+
36+
$this->assertInstanceOf('Art4\JsonApiClient\Resource\ItemLink', $link);
37+
$this->assertInstanceOf('Art4\JsonApiClient\AccessInterface', $link);
38+
$this->assertSame($link->getKeys(), array('self', 'custom', 'related'));
39+
40+
$this->assertTrue($link->has('self'));
41+
$this->assertSame($link->get('self'), 'http://example.org/self');
42+
$this->assertTrue($link->has('custom'));
43+
$this->assertSame($link->get('custom'), 'http://example.org/custom');
44+
$this->assertTrue($link->has('related'));
45+
$this->assertInstanceOf('Art4\JsonApiClient\LinkInterface', $link->get('related'));
46+
47+
$this->assertSame($link->asArray(), array(
48+
'self' => $link->get('self'),
49+
'custom' => $link->get('custom'),
50+
'related' => $link->get('related'),
51+
));
52+
}
53+
54+
/**
55+
* @dataProvider jsonValuesProvider
56+
*
57+
* links: a links object related to the primary data.
58+
*/
59+
public function testCreateWithoutObjectThrowsException($input)
60+
{
61+
// Input must be an object
62+
if ( gettype($input) === 'object' )
63+
{
64+
return;
65+
}
66+
67+
$this->setExpectedException(
68+
'Art4\JsonApiClient\Exception\ValidationException',
69+
'ItemLink has to be an object, "' . gettype($input) . '" given.'
70+
);
71+
72+
$link = new ItemLink($input, $this->manager, $this->parent);
73+
}
74+
75+
/**
76+
* @test
77+
*/
78+
public function testGetOnANonExistingKeyThrowsException()
79+
{
80+
$object = new \stdClass();
81+
$object->self = 'http://example.org/self';
82+
83+
$link = new ItemLink($object, $this->manager, $this->parent);
84+
85+
$this->assertFalse($link->has('something'));
86+
87+
$this->setExpectedException(
88+
'Art4\JsonApiClient\Exception\AccessException',
89+
'"something" doesn\'t exist in this object.'
90+
);
91+
92+
$link->get('something');
93+
}
94+
}

tests/unit/Resource/ItemTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public function testCreateWithFullObject()
8282
$this->assertTrue($resource->has('relationships'));
8383
$this->assertInstanceOf('Art4\JsonApiClient\RelationshipCollectionInterface', $resource->get('relationships'));
8484
$this->assertTrue($resource->has('links'));
85-
$this->assertInstanceOf('Art4\JsonApiClient\LinkInterface', $resource->get('links'));
85+
$this->assertInstanceOf('Art4\JsonApiClient\Resource\ItemLinkInterface', $resource->get('links'));
8686
$this->assertSame($resource->getKeys(), array('type', 'id', 'meta', 'attributes', 'relationships', 'links'));
8787

8888
$this->assertSame($resource->asArray(), array(

0 commit comments

Comments
 (0)