diff --git a/src/Document.php b/src/Document.php index cafa441..ddb75d9 100644 --- a/src/Document.php +++ b/src/Document.php @@ -15,6 +15,7 @@ use alsvanzelf\jsonapi\interfaces\ExtensionInterface; use alsvanzelf\jsonapi\interfaces\ProfileInterface; use alsvanzelf\jsonapi\objects\JsonapiObject; +use alsvanzelf\jsonapi\objects\LinkObject; use alsvanzelf\jsonapi\objects\LinksObject; use alsvanzelf\jsonapi\objects\MetaObject; @@ -22,7 +23,9 @@ * @see ResourceDocument, CollectionDocument, ErrorsDocument or MetaDocument */ abstract class Document implements DocumentInterface, \JsonSerializable { - use AtMemberManager, ExtensionMemberManager, HttpStatusCodeManager, LinksManager; + use AtMemberManager, ExtensionMemberManager, HttpStatusCodeManager, LinksManager { + LinksManager::addLink as linkManagerAddLink; + } const JSONAPI_VERSION_1_0 = '1.0'; const JSONAPI_VERSION_1_1 = '1.1'; @@ -97,11 +100,7 @@ public function __construct() { */ public function addLink($key, $href, array $meta=[], $level=Document::LEVEL_ROOT) { if ($level === Document::LEVEL_ROOT) { - if ($this->links === null) { - $this->setLinksObject(new LinksObject()); - } - - $this->links->add($key, $href, $meta); + $this->linkManagerAddLink($key, $href, $meta); } elseif ($level === Document::LEVEL_JSONAPI) { throw new InputException('level "jsonapi" can not be used for links'); @@ -117,12 +116,24 @@ public function addLink($key, $href, array $meta=[], $level=Document::LEVEL_ROOT /** * set the self link on the document * + * @note a LinkObject is added when extensions or profiles are applied + * * @param string $href * @param array $meta optional, if given a LinkObject is added, otherwise a link string is added * @param string $level one of the Document::LEVEL_* constants, optional, defaults to Document::LEVEL_ROOT */ public function setSelfLink($href, array $meta=[], $level=Document::LEVEL_ROOT) { - $this->addLink('self', $href, $meta, $level); + if ($level === Document::LEVEL_ROOT && ($this->extensions !== [] || $this->profiles !== [])) { + $contentType = Converter::prepareContentType(Document::CONTENT_TYPE_OFFICIAL, $this->extensions, $this->profiles); + + $linkObject = new LinkObject($href, $meta); + $linkObject->setMediaType($contentType); + + $this->addLinkObject('self', $linkObject); + } + else { + $this->addLink('self', $href, $meta, $level); + } } /** diff --git a/tests/DocumentTest.php b/tests/DocumentTest.php index 30043cb..020a70a 100644 --- a/tests/DocumentTest.php +++ b/tests/DocumentTest.php @@ -237,23 +237,33 @@ public function testAddLinkObject_HappyPath() { public function testApplyExtension_HappyPath() { $extension = new TestExtension(); $extension->setNamespace('test'); - $extension->setOfficialLink('https://jsonapi.org'); + $extension->setOfficialLink('https://jsonapi.org/extension'); $document = new Document(); $document->applyExtension($extension); $document->addExtensionMember($extension, 'foo', 'bar'); + $document->setSelfLink('https://jsonapi.org/foo'); $array = $document->toArray(); + $this->assertCount(3, $array); $this->assertArrayHasKey('jsonapi', $array); $this->assertCount(2, $array['jsonapi']); $this->assertSame('1.1', $array['jsonapi']['version']); $this->assertArrayHasKey('ext', $array['jsonapi']); $this->assertCount(1, $array['jsonapi']['ext']); $this->assertArrayHasKey(0, $array['jsonapi']['ext']); - $this->assertSame('https://jsonapi.org', $array['jsonapi']['ext'][0]); + $this->assertSame('https://jsonapi.org/extension', $array['jsonapi']['ext'][0]); $this->assertArrayHasKey('test:foo', $array); $this->assertSame('bar', $array['test:foo']); + $this->assertArrayHasKey('links', $array); + $this->assertCount(1, $array['links']); + $this->assertArrayHasKey('self', $array['links']); + $this->assertCount(2, $array['links']['self']); + $this->assertArrayHasKey('href', $array['links']['self']); + $this->assertArrayHasKey('type', $array['links']['self']); + $this->assertSame('https://jsonapi.org/foo', $array['links']['self']['href']); + $this->assertSame('application/vnd.api+json; ext="https://jsonapi.org/extension"', $array['links']['self']['type']); } /** @@ -298,20 +308,30 @@ public function testApplyExtension_ConflictingNamespace() { */ public function testApplyProfile_HappyPath() { $profile = new TestProfile(); - $profile->setOfficialLink('https://jsonapi.org'); + $profile->setOfficialLink('https://jsonapi.org/profile'); $document = new Document(); $document->applyProfile($profile); + $document->setSelfLink('https://jsonapi.org/foo'); $array = $document->toArray(); + $this->assertCount(2, $array); $this->assertArrayHasKey('jsonapi', $array); $this->assertCount(2, $array['jsonapi']); $this->assertSame('1.1', $array['jsonapi']['version']); $this->assertArrayHasKey('profile', $array['jsonapi']); $this->assertCount(1, $array['jsonapi']['profile']); $this->assertArrayHasKey(0, $array['jsonapi']['profile']); - $this->assertSame('https://jsonapi.org', $array['jsonapi']['profile'][0]); + $this->assertSame('https://jsonapi.org/profile', $array['jsonapi']['profile'][0]); + $this->assertArrayHasKey('links', $array); + $this->assertCount(1, $array['links']); + $this->assertArrayHasKey('self', $array['links']); + $this->assertCount(2, $array['links']['self']); + $this->assertArrayHasKey('href', $array['links']['self']); + $this->assertArrayHasKey('type', $array['links']['self']); + $this->assertSame('https://jsonapi.org/foo', $array['links']['self']['href']); + $this->assertSame('application/vnd.api+json; profile="https://jsonapi.org/profile"', $array['links']['self']['type']); } public function testToJson_HappyPath() {