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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed
- Add isPermaLink=false support to setPublicId() - (#103)
- Keep every author of a node, available through getAuthors() - (#141)

### Fixed
- fix: rewrite relative links in `content:encoded` and other optional elements, not only in `content`/`description` properties
Expand Down
20 changes: 20 additions & 0 deletions src/FeedIo/Feed/Node.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class Node implements NodeInterface, ElementsAwareInterface, ArrayableInterface

protected ?AuthorInterface $author = null;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should keep this, it makes for a very confusing situation. Let's just store the author information only in the array. If that changes the behaviour of getAuthor I think that's okay.


protected array $authors = [];

protected ?DateTime $lastModified = null;

protected ?string $title = null;
Expand Down Expand Up @@ -64,6 +66,23 @@ public function setAuthor(?AuthorInterface $author = null): NodeInterface
return $this;
}

public function getAuthors(): iterable
{
if (!empty($this->authors)) {
return $this->authors;
}

return $this->author !== null ? [$this->author] : [];
}

public function addAuthor(AuthorInterface $author): NodeInterface
{
$this->authors[] = $author;
$this->author = $author;

return $this;
}

public function newAuthor(): AuthorInterface
{
return new Author();
Expand Down Expand Up @@ -371,6 +390,7 @@ public function toArray(): array
$properties = get_object_vars($this);
$properties['elements'] = iterator_to_array($this->getElementsGenerator());
$properties['categories'] = iterator_to_array($this->getCategoriesGenerator());
$properties['authors'] = new \ArrayIterator($this->authors);

foreach ($properties as $name => $property) {
if ($property instanceof \DateTime) {
Expand Down
15 changes: 15 additions & 0 deletions src/FeedIo/Feed/NodeInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,21 @@ public function getAuthor(): ?AuthorInterface;
*/
public function setAuthor(?AuthorInterface $author = null): NodeInterface;

/**
* returns all the authors of the node, in document order
*
* @return iterable
*/
public function getAuthors(): iterable;
Comment on lines +32 to +37

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just array?


/**
* adds an author to the node, getAuthor() returns the last one added
*
* @param AuthorInterface $author
* @return NodeInterface
*/
public function addAuthor(AuthorInterface $author): NodeInterface;

/**
* returns a new AuthorInterface
*
Expand Down
20 changes: 14 additions & 6 deletions src/FeedIo/Parser/JsonParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,21 @@ protected function readMedias(ItemInterface $item, array $data): void

protected function readAuthor(NodeInterface $node, array $data): void
{
if (array_key_exists('author', $data)) {
$author = $this->extractAuthor($data['author']);
$node->setAuthor($author);
}
if (array_key_exists('authors', $data) && is_array($data['authors'])) {
$author = $this->extractAuthor(reset($data['authors']));
$node->setAuthor($author);
$first = null;
foreach ($data['authors'] as $authorData) {
if (!is_array($authorData)) {
continue;
}
$author = $this->extractAuthor($authorData);
$first ??= $author;
$node->addAuthor($author);
}
if ($first !== null) {
$node->setAuthor($first);
}
} elseif (array_key_exists('author', $data)) {
$node->addAuthor($this->extractAuthor($data['author']));
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/FeedIo/Rule/Atom/Author.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public function setProperty(NodeInterface $node, DOMElement $element): void
$author->setName($this->getChildValue($element, 'name'));
$author->setUri($this->getChildValue($element, 'uri'));
$author->setEmail($this->getChildValue($element, 'email'));
$node->setAuthor($author);
$node->addAuthor($author);
}

protected function hasValue(NodeInterface $node): bool
Expand Down
2 changes: 1 addition & 1 deletion src/FeedIo/Rule/Author.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public function setProperty(NodeInterface $node, \DOMElement $element): void
if ($node instanceof ItemInterface) {
$author = $node->newAuthor();
$author->setName($element->nodeValue);
$node->setAuthor($author);
$node->addAuthor($author);
}
}

Expand Down
19 changes: 19 additions & 0 deletions tests/FeedIo/Feed/NodeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,25 @@ public function testLastModified()
$this->assertEquals($lastModified, $this->object->getLastModified());
}

public function testGetAuthorsFallsBackToSetAuthor()
{
$this->assertEquals([], $this->object->getAuthors());

$author = $this->object->newAuthor();
$this->object->setAuthor($author);

$this->assertSame([$author], $this->object->getAuthors());
}

public function testToArrayIncludesEveryAuthor()
{
$this->object->addAuthor($this->object->newAuthor()->setName('John Doe'));
$this->object->addAuthor($this->object->newAuthor()->setName('Jane Roe'));

$authors = $this->object->toArray()['authors'];
$this->assertEquals(['John Doe', 'Jane Roe'], array_column($authors, 'name'));
}

public function testNewCategory()
{
$this->assertInstanceOf('\FeedIo\Feed\Node\CategoryInterface', $this->object->newCategory());
Expand Down
21 changes: 21 additions & 0 deletions tests/FeedIo/Parser/JsonParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,25 @@ public function testParseContent()
$this->assertEquals('http://manton.org', $items[3]['author']['uri']);
$this->assertEquals('manton@micro.blog', $items[3]['author']['email']);
}

public function testParseContentKeepsEveryAuthor()
{
$json = json_encode([
'version' => 'https://jsonfeed.org/version/1.1',
'title' => 'JSON Feed',
'authors' => [
['name' => 'John Doe'],
['name' => 'Jane Roe'],
],
'items' => [],
]);
$parser = new JsonParser(new Json(new DateTimeBuilder()), new NullLogger());
$feed = new Feed();

$parser->parse(new Document($json), $feed);

$this->assertEquals('John Doe', $feed->getAuthor()->getName());
$names = array_map(fn ($author) => $author->getName(), [...$feed->getAuthors()]);
$this->assertEquals(['John Doe', 'Jane Roe'], $names);
}
}
20 changes: 20 additions & 0 deletions tests/FeedIo/Rule/Atom/AuthorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,26 @@ public function testNamespacedSet()
$this->assertEquals('john@localhost', $item->getAuthor()->getEmail());
}

public function testSetKeepsEveryAuthorAndGetAuthorReturnsTheLast()
{
$item = new Item();

$document = new \DOMDocument();

$first = $document->createElement('author');
$first->appendChild($document->createElement('name', 'John Doe'));

$second = $document->createElement('author');
$second->appendChild($document->createElement('name', 'Jane Roe'));

$this->object->setProperty($item, $first);
$this->object->setProperty($item, $second);

$this->assertEquals('Jane Roe', $item->getAuthor()->getName());
$names = array_map(fn ($author) => $author->getName(), [...$item->getAuthors()]);
$this->assertEquals(['John Doe', 'Jane Roe'], $names);
}

public function testGetChildValue()
{
$document = new \DOMDocument();
Expand Down
12 changes: 12 additions & 0 deletions tests/FeedIo/Rule/AuthorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,18 @@ public function testSet()
$this->assertEquals(self::AUTHOR, $item->getAuthor()->getName());
}

public function testSetKeepsEveryAuthorAndGetAuthorReturnsTheLast()
{
$item = new Item();

$this->object->setProperty($item, new \DOMElement('author', self::AUTHOR));
$this->object->setProperty($item, new \DOMElement('author', 'Jane Roe'));

$this->assertEquals('Jane Roe', $item->getAuthor()->getName());
$names = array_map(fn ($author) => $author->getName(), [...$item->getAuthors()]);
$this->assertEquals([self::AUTHOR, 'Jane Roe'], $names);
}

public function testCreateElement()
{
$item = new Item();
Expand Down