Skip to content

Commit

Permalink
Issue Nekland#22 - Add group item field
Browse files Browse the repository at this point in the history
  • Loading branch information
Vincent Composieux committed Sep 5, 2013
1 parent bdeacca commit 6b8a501
Show file tree
Hide file tree
Showing 9 changed files with 216 additions and 28 deletions.
7 changes: 4 additions & 3 deletions Feed/Feed.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@
use Eko\FeedBundle\Item\Writer\RoutedItemInterface;
use Eko\FeedBundle\Formatter\RssFormatter;
use Eko\FeedBundle\Field\ChannelField;
use Eko\FeedBundle\Field\ItemField;
use Eko\FeedBundle\Field\ItemFieldInterface;
use Eko\FeedBundle\Item\Writer\ItemInterface;

use Symfony\Component\Routing\RouterInterface;

/**
Expand Down Expand Up @@ -190,11 +191,11 @@ public function getChannelFields()
/**
* Add a new item field to render
*
* @param ItemField $field A custom Field instance
* @param ItemFieldInterface $field A custom Field instance
*
* @return \Eko\FeedBundle\Feed\Feed
*/
public function addItemField(ItemField $field)
public function addItemField(ItemFieldInterface $field)
{
$this->itemFields[] = $field;

Expand Down
66 changes: 66 additions & 0 deletions Field/GroupItemField.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php
/*
* This file is part of the Eko\FeedBundle Symfony bundle.
*
* (c) Vincent Composieux <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Eko\FeedBundle\Field;

use Eko\FeedBundle\Field\ItemField;
use Eko\FeedBundle\Field\ItemFieldInterface;

/**
* GroupField
*
* This is items group field class
*
* @author Vincent Composieux <[email protected]>
*/
class GroupItemField implements ItemFieldInterface
{
/**
* @var string $name Field name
*/
protected $name;

/**
* @var ItemField ItemField instance
*/
protected $itemField;

/**
* Constructor
*
* @param string $name A group field name
* @param ItemField $itemField A ItemField instance
*/
public function __construct($name, ItemField $itemField)
{
$this->name = $name;
$this->itemField = $itemField;
}

/**
* Returns group field name
*
* @return string
*/
public function getName()
{
return $this->name;
}

/**
* Returns item field
*
* @return ItemField
*/
public function getItemField()
{
return $this->itemField;
}
}
6 changes: 4 additions & 2 deletions Field/ItemField.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@

namespace Eko\FeedBundle\Field;

use Eko\FeedBundle\Field\ItemFieldInterface;

/**
* Field
* ItemField
*
* This is the items field class
*
* @author Vincent Composieux <[email protected]>
*/
class ItemField
class ItemField implements ItemFieldInterface
{
/**
* @var string $name Field name
Expand Down
28 changes: 28 additions & 0 deletions Field/ItemFieldInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php
/*
* This file is part of the Eko\FeedBundle Symfony bundle.
*
* (c) Vincent Composieux <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Eko\FeedBundle\Field;

/**
* FieldInterface
*
* This is the item field interface
*
* @author Vincent Composieux <[email protected]>
*/
interface ItemFieldInterface
{
/**
* Returns field name
*
* @return string
*/
public function getName();
}
69 changes: 46 additions & 23 deletions Formatter/Formatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
namespace Eko\FeedBundle\Formatter;

use Eko\FeedBundle\Feed\Feed;
use Eko\FeedBundle\Field\ItemField;
use Eko\FeedBundle\Field\GroupItemField;
use Eko\FeedBundle\Field\ItemFieldInterface;
use Eko\FeedBundle\Item\Writer\ItemInterface;

/**
Expand Down Expand Up @@ -53,44 +54,66 @@ public function __construct(Feed $feed)
/**
* Format items field
*
* @param ItemField $field A item field instance
* @param ItemInterface $item An entity instance
* @param ItemFieldInterface $field A item field instance
* @param ItemInterface $item An entity instance
*
* @return string
*/
protected function format(ItemField $field, ItemInterface $item)
protected function format(ItemFieldInterface $field, ItemInterface $item)
{
$name = $field->getName();

if ($field instanceof GroupItemField) {
$element = $this->dom->createElement($name);
$itemElements = $this->format($field->getItemField(), $item);

foreach ($itemElements as $itemElement) {
$element->appendChild($itemElement);
}

return $element;
}

$elements = array();

$method = $field->getMethod();
$value = $item->{$method}();
$values = $item->{$method}();

if (!is_array($values)) {
$values = array($values);
}

if ($field->get('cdata')) {
$value = $this->dom->createCDATASection($value);
foreach ($values as $value) {
if ($field->get('cdata')) {
$value = $this->dom->createCDATASection($value);

$element = $this->dom->createElement($name);
$element->appendChild($value);
} else if ($field->get('attribute')) {
if (!$field->get('attribute_name')) {
throw new \InvalidArgumentException("'attribute' parameter required an 'attribute_name' parameter.");
}
$element = $this->dom->createElement($name);
$element->appendChild($value);

$element = $this->dom->createElement($name);
$element->setAttribute($field->get('attribute_name'), $item->getFeedItemLink());
$elements[] = $element;
} else if ($field->get('attribute')) {
if (!$field->get('attribute_name')) {
throw new \InvalidArgumentException("'attribute' parameter required an 'attribute_name' parameter.");
}

$element = $this->dom->createElement($name);
$element->setAttribute($field->get('attribute_name'), $item->getFeedItemLink());

} else {
if ($format = $field->get('date_format')) {
if (!$value instanceof \DateTime) {
throw new \InvalidArgumentException(sprintf('Field "%s" should be a DateTime instance.', $name));
$elements[] = $element;
} else {
if ($format = $field->get('date_format')) {
if (!$value instanceof \DateTime) {
throw new \InvalidArgumentException(sprintf('Field "%s" should be a DateTime instance.', $name));
}

$value = $value->format($format);
}

$value = $value->format($format);
$elements[] = $this->dom->createElement($name, $value);
}

$element = $this->dom->createElement($name, $value);
}

return $element;
return 1 == count($elements) ? current($elements) : $elements;
}

/**
Expand Down
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,17 @@ $feed->add(new FakeEntity());
$feed->addItemField(new ItemField('fake_custom', 'getFeedItemCustom'));
```

You can also add group item fields using this way, if your method returns an array:

```php
<?php
$feed = $this->get('eko_feed.feed.manager')->get('article');
$feed->add(new FakeEntity());
$feed->addItemField(
new GroupItemField('categories', new ItemField('category', 'getFeedCategoriesCustom'))
);
```

Of course, `getFeedItemCustom()` method needs to be declared in your entity.

Moreover, entities objects can be added separatly with add method:
Expand Down
14 changes: 14 additions & 0 deletions Tests/Entity/Writer/FakeItemInterfaceEntity.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,18 @@ public function getFeedItemCustom()
{
return 'My custom field';
}

/**
* Returns a fake custom categories array
*
* @return array
*/
public function getFeedCategoriesCustom()
{
return array(
'category 1',
'category 2',
'category 3'
);
}
}
22 changes: 22 additions & 0 deletions Tests/Format/AtomFormatterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

use Eko\FeedBundle\Feed\FeedManager;
use Eko\FeedBundle\Field\ChannelField;
use Eko\FeedBundle\Field\GroupItemField;
use Eko\FeedBundle\Field\ItemField;
use Eko\FeedBundle\Tests\Entity\Writer\FakeItemInterfaceEntity;
use Eko\FeedBundle\Tests\Entity\Writer\FakeRoutedItemInterfaceEntity;
Expand Down Expand Up @@ -140,6 +141,27 @@ public function testAddCustomItemFieldWithItemInterface()
$this->assertContains('<fake_custom>My custom field</fake_custom>', $output);
}

/**
* Check if a custom group item field is properly rendered with ItemInterface
*/
public function testAddCustomGroupItemFieldWithItemInterface()
{
$feed = $this->manager->get('article');
$feed->add(new FakeItemInterfaceEntity());
$feed->addItemField(new GroupItemField(
'categories',
new ItemField('category', 'getFeedCategoriesCustom'))
);

$output = $feed->render('atom');

$this->assertContains('<categories>', $output);
$this->assertContains('<category>category 1</category>', $output);
$this->assertContains('<category>category 2</category>', $output);
$this->assertContains('<category>category 3</category>', $output);
$this->assertContains('</categories>', $output);
}

/**
* Check if a custom item field is properly rendered with RoutedItemInterface
*/
Expand Down
21 changes: 21 additions & 0 deletions Tests/Format/RSSFormatterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

use Eko\FeedBundle\Feed\FeedManager;
use Eko\FeedBundle\Field\ChannelField;
use Eko\FeedBundle\Field\GroupItemField;
use Eko\FeedBundle\Field\ItemField;
use Eko\FeedBundle\Tests\Entity\Writer\FakeItemInterfaceEntity;
use Eko\FeedBundle\Tests\Entity\Writer\FakeRoutedItemInterfaceEntity;
Expand Down Expand Up @@ -115,6 +116,26 @@ public function testAddCustomItemFieldWithItemInterface()
$this->assertContains('<fake_custom>My custom field</fake_custom>', $output);
}

/**
* Check if a custom group item field is properly rendered with ItemInterface
*/
public function testAddCustomGroupItemFieldWithItemInterface()
{
$feed = $this->manager->get('article');
$feed->add(new FakeItemInterfaceEntity());
$feed->addItemField(
new GroupItemField('categories', new ItemField('category', 'getFeedCategoriesCustom'))
);

$output = $feed->render('rss');

$this->assertContains('<categories>', $output);
$this->assertContains('<category>category 1</category>', $output);
$this->assertContains('<category>category 2</category>', $output);
$this->assertContains('<category>category 3</category>', $output);
$this->assertContains('</categories>', $output);
}

/**
* Check if a custom item field is properly rendered with RoutedItemInterface
*/
Expand Down

0 comments on commit 6b8a501

Please sign in to comment.