diff --git a/CHANGELOG.md b/CHANGELOG.md index d262fec..4fe6b04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to this project will be documented in this file. +## Unreleased + +### Added + +- Getters on `Atom\Link`, `Media\Content`, and `Media\Thumbnail`, matching their setters. `Content::isDefault()` is the setter, so its getter is `getIsDefault()`. + ## 8.2.0 - 2026-10-06 The PHP 8.2 line of the package, with the same API and features as 8.1.0. See [UPGRADE.md](UPGRADE.md) for migrating from 1.x. diff --git a/docs/sections/11-elements-api.md b/docs/sections/11-elements-api.md index 36d6b29..e40312a 100644 --- a/docs/sections/11-elements-api.md +++ b/docs/sections/11-elements-api.md @@ -26,11 +26,11 @@ Structured elements are small `final` value objects. Each has a static `make()` | Class | Create with | Setters | | --- | --- | --- | -| `Atom\Link` | `make(string $href)`, `self(string $href)` | `rel()`, `type()`, `hreflang()`, `title()`, `length(?int)` | +| `Atom\Link` | `make(string $href)`, `self(string $href)` | `rel()`, `type()`, `hreflang()`, `title()`, `length(?int)`; getters `getHref()`, `getRel()`, `getType()`, `getHreflang()`, `getTitle()`, `getLength()` | | `Content\Encoded` | `make(string $content)` | Getter: `getContent()` | | `DublinCore\Creator` | `make(string $name)` | Getter: `getName()` | -| `Media\Content` | `make(string $url)` | `fileSize()`, `type()`, `medium()`, `isDefault()`, `expression()`, `bitrate()`, `duration()`, `width()`, `height()`, `lang()`, `title(?Title)`, `description(?Description)`, `thumbnail(Thumbnail)` | -| `Media\Thumbnail` | `make(string $url)` | `width()`, `height()`, `time(?string)` | +| `Media\Content` | `make(string $url)` | `fileSize()`, `type()`, `medium()`, `isDefault()`, `expression()`, `bitrate()`, `duration()`, `width()`, `height()`, `lang()`, `title(?Title)`, `description(?Description)`, `thumbnail(Thumbnail)`; getters `getUrl()`, `getFileSize()`, `getType()`, `getMedium()`, `getIsDefault()`, `getExpression()`, `getBitrate()`, `getDuration()`, `getWidth()`, `getHeight()`, `getLang()`, `getTitle()`, `getDescription()`, `getThumbnails()` | +| `Media\Thumbnail` | `make(string $url)` | `width()`, `height()`, `time(?string)`; getters `getUrl()`, `getWidth()`, `getHeight()`, `getTime()` | | `Media\Title` | `make(string $text)` | `type(?string)`; getters `getText()`, `getType()` | | `Media\Description` | `make(string $text)` | `type(?string)`; getters `getText()`, `getType()` | diff --git a/src/Extensions/Atom/Link.php b/src/Extensions/Atom/Link.php index c0dbf11..f252947 100644 --- a/src/Extensions/Atom/Link.php +++ b/src/Extensions/Atom/Link.php @@ -108,6 +108,36 @@ public function length(?int $length): self return $this; } + public function getHref(): string + { + return $this->href; + } + + public function getRel(): ?string + { + return $this->rel; + } + + public function getType(): ?string + { + return $this->type; + } + + public function getHreflang(): ?string + { + return $this->hreflang; + } + + public function getTitle(): ?string + { + return $this->title; + } + + public function getLength(): ?int + { + return $this->length; + } + public function write(XMLWriter $writer): void { $writer->startElement($this->prefix() . ':link'); diff --git a/src/Extensions/Media/Content.php b/src/Extensions/Media/Content.php index 35b88c0..a800e52 100644 --- a/src/Extensions/Media/Content.php +++ b/src/Extensions/Media/Content.php @@ -236,6 +236,79 @@ public function thumbnail(Thumbnail $thumbnail): self return $this; } + public function getUrl(): string + { + return $this->url; + } + + public function getFileSize(): ?int + { + return $this->fileSize; + } + + public function getType(): ?string + { + return $this->type; + } + + public function getMedium(): ?string + { + return $this->medium; + } + + public function getIsDefault(): ?bool + { + return $this->isDefault; + } + + public function getExpression(): ?string + { + return $this->expression; + } + + public function getBitrate(): ?int + { + return $this->bitrate; + } + + public function getDuration(): ?int + { + return $this->duration; + } + + public function getWidth(): ?int + { + return $this->width; + } + + public function getHeight(): ?int + { + return $this->height; + } + + public function getLang(): ?string + { + return $this->lang; + } + + public function getTitle(): ?Title + { + return $this->title; + } + + public function getDescription(): ?Description + { + return $this->description; + } + + /** + * @return list + */ + public function getThumbnails(): array + { + return $this->thumbnails; + } + public function write(XMLWriter $writer): void { $writer->startElement($this->prefix() . ':content'); diff --git a/src/Extensions/Media/Thumbnail.php b/src/Extensions/Media/Thumbnail.php index 5c4b795..1d8f108 100644 --- a/src/Extensions/Media/Thumbnail.php +++ b/src/Extensions/Media/Thumbnail.php @@ -73,6 +73,26 @@ public function time(?string $time): self return $this; } + public function getUrl(): string + { + return $this->url; + } + + public function getWidth(): ?int + { + return $this->width; + } + + public function getHeight(): ?int + { + return $this->height; + } + + public function getTime(): ?string + { + return $this->time; + } + public function write(XMLWriter $writer): void { $writer->startElement($this->prefix() . ':thumbnail'); diff --git a/tests/Unit/Extensions/AtomLinkTest.php b/tests/Unit/Extensions/AtomLinkTest.php index 09d9355..811f9d0 100644 --- a/tests/Unit/Extensions/AtomLinkTest.php +++ b/tests/Unit/Extensions/AtomLinkTest.php @@ -63,6 +63,50 @@ public function testOptionalAttributesCanBeRemoved(): void $this->assertXPathCount(1, $xpath, '/root/atom:link/@*'); } + public function testGettersReturnNullByDefault(): void + { + $link = Link::make('https://example.com/rss.xml'); + + $this->assertSame('https://example.com/rss.xml', $link->getHref()); + $this->assertNull($link->getRel()); + $this->assertNull($link->getType()); + $this->assertNull($link->getHreflang()); + $this->assertNull($link->getTitle()); + $this->assertNull($link->getLength()); + } + + public function testGettersReturnTheConfiguredValues(): void + { + $link = Link::make('https://example.com/feed') + ->rel('alternate') + ->type('text/html') + ->hreflang('ar') + ->title('النسخة العربية') + ->length(1024); + + $this->assertSame('alternate', $link->getRel()); + $this->assertSame('text/html', $link->getType()); + $this->assertSame('ar', $link->getHreflang()); + $this->assertSame('النسخة العربية', $link->getTitle()); + $this->assertSame(1024, $link->getLength()); + } + + public function testSelfLinkGetters(): void + { + $link = Link::self('https://example.com/rss.xml'); + + $this->assertSame('self', $link->getRel()); + $this->assertSame('application/rss+xml', $link->getType()); + } + + public function testRemovedAttributesAreReturnedAsNull(): void + { + $link = Link::self('https://example.com/rss.xml')->rel(null)->type(''); + + $this->assertNull($link->getRel()); + $this->assertNull($link->getType()); + } + public function testRejectsEmptyHref(): void { $this->expectException(InvalidElementException::class); diff --git a/tests/Unit/Extensions/MediaContentTest.php b/tests/Unit/Extensions/MediaContentTest.php index c140ecf..b043394 100644 --- a/tests/Unit/Extensions/MediaContentTest.php +++ b/tests/Unit/Extensions/MediaContentTest.php @@ -82,6 +82,64 @@ public function testWritesNestedElements(): void ); } + public function testGettersReturnNullByDefault(): void + { + $content = Content::make('https://example.com/video.mp4'); + + $this->assertSame('https://example.com/video.mp4', $content->getUrl()); + $this->assertNull($content->getFileSize()); + $this->assertNull($content->getType()); + $this->assertNull($content->getMedium()); + $this->assertNull($content->getIsDefault()); + $this->assertNull($content->getExpression()); + $this->assertNull($content->getBitrate()); + $this->assertNull($content->getDuration()); + $this->assertNull($content->getWidth()); + $this->assertNull($content->getHeight()); + $this->assertNull($content->getLang()); + $this->assertNull($content->getTitle()); + $this->assertNull($content->getDescription()); + $this->assertSame([], $content->getThumbnails()); + } + + public function testGettersReturnTheConfiguredValues(): void + { + $title = Title::make('Launch video'); + $description = Description::make('Behind the scenes'); + $first = Thumbnail::make('https://example.com/1.jpg'); + $second = Thumbnail::make('https://example.com/2.jpg'); + + $content = Content::make('https://example.com/video.mp4') + ->fileSize(12216320) + ->type('video/mp4') + ->medium(Content::MEDIUM_VIDEO) + ->isDefault(false) + ->expression(Content::EXPRESSION_FULL) + ->bitrate(128) + ->duration(185) + ->width(1920) + ->height(1080) + ->lang('en') + ->title($title) + ->description($description) + ->thumbnail($first) + ->thumbnail($second); + + $this->assertSame(12216320, $content->getFileSize()); + $this->assertSame('video/mp4', $content->getType()); + $this->assertSame('video', $content->getMedium()); + $this->assertFalse($content->getIsDefault()); + $this->assertSame('full', $content->getExpression()); + $this->assertSame(128, $content->getBitrate()); + $this->assertSame(185, $content->getDuration()); + $this->assertSame(1920, $content->getWidth()); + $this->assertSame(1080, $content->getHeight()); + $this->assertSame('en', $content->getLang()); + $this->assertSame($title, $content->getTitle()); + $this->assertSame($description, $content->getDescription()); + $this->assertSame([$first, $second], $content->getThumbnails()); + } + public function testRejectsEmptyUrl(): void { $this->expectException(InvalidElementException::class); diff --git a/tests/Unit/Extensions/MediaThumbnailTest.php b/tests/Unit/Extensions/MediaThumbnailTest.php index 27c9c07..f2c5e24 100644 --- a/tests/Unit/Extensions/MediaThumbnailTest.php +++ b/tests/Unit/Extensions/MediaThumbnailTest.php @@ -36,6 +36,33 @@ public function testWritesAllAttributes(): void ); } + public function testGettersReturnNullByDefault(): void + { + $thumbnail = Thumbnail::make('https://example.com/image.jpg'); + + $this->assertSame('https://example.com/image.jpg', $thumbnail->getUrl()); + $this->assertNull($thumbnail->getWidth()); + $this->assertNull($thumbnail->getHeight()); + $this->assertNull($thumbnail->getTime()); + } + + public function testGettersReturnTheConfiguredValues(): void + { + $thumbnail = Thumbnail::make('https://example.com/image.jpg') + ->width(1200) + ->height(630) + ->time('12:05:01.123'); + + $this->assertSame(1200, $thumbnail->getWidth()); + $this->assertSame(630, $thumbnail->getHeight()); + $this->assertSame('12:05:01.123', $thumbnail->getTime()); + } + + public function testEmptyTimeIsReturnedAsNull(): void + { + $this->assertNull(Thumbnail::make('https://example.com/image.jpg')->time('')->getTime()); + } + public function testRejectsEmptyUrl(): void { $this->expectException(InvalidElementException::class);