muspi/feedbundle

一个用于从实体构建 RSS 源的 Symfony 扩展包,克隆自 eko/feedbundle

1.2.9 2018-04-25 15:18 UTC

README

SensioLabsInsight

Build Status Latest Stable Version Total Downloads

功能

  • 生成 XML 源(RSS & Atom 格式)
  • 易于配置和使用
  • 基于实体的项目
  • 添加项目组
  • 添加媒体标签
  • 翻译源数据
  • 读取 XML 源并填充您的 Symfony 实体
  • 通过 Symfony 控制台命令将源导出到文件

安装

将包添加到您的 composer.json 文件

"eko/feedbundle": "dev-master",

添加到 app/AppKernel.php

<?php
    public function registerBundles()
    {
        $bundles = array(
            ...
            new Eko\FeedBundle\EkoFeedBundle(),
        );

        ...

        return $bundles;
    }

添加到 app/autoload.php

<?php
$loader->registerNamespaces(array(
   ...
    'Eko'             => __DIR__.'/../vendor/bundles'
));

配置(仅需 3 个快速步骤!)

1) 编辑 app/config.yml

需要以下配置行

eko_feed:
    hydrator: your_hydrator.custom.service # Optional, if you use entity hydrating with a custom hydrator
    translation_domain: test # Optional, if you want to use a custom translation domain
    feeds:
        article:
            title:       'My articles/posts'
            description: 'Latests articles'
            link:        'http://vincent.composieux.fr'
            encoding:    'utf-8'
            author:      'Vincent Composieux' # Only required for Atom feeds

您可以设置链接为路由

link:
    route_name: acme_blog_main_index
    route_params: {id: 2} # necessary if route cantains required parameters

2) 实现 ItemInterface

您将用于生成 RSS 源的每个实体都需要实现 Eko\FeedBundle\Item\Writer\ItemInterfaceEko\FeedBundle\Item\Writer\RoutedItemInterface,如下例所示,用于博客的 Article 实体

选项 A: Eko\FeedBundle\Item\Writer\ItemInterface

<?php

namespace Bundle\BlogBundle\Entity;

use Eko\FeedBundle\Item\Writer\ItemInterface;

/**
 * Bundle\BlogBundle\Entity\Article
 */
class Article implements ItemInterface
{

在此实体中,只需实现以下所需方法

  • public function getFeedItemTitle() { … } : 该方法返回实体项目标题
  • public function getFeedItemDescription() { … } : 该方法返回实体项目描述(或内容)
  • public function getFeedItemPubDate() { … } : 该方法返回实体项目发布日期
  • public function getFeedItemLink() { … } : 该方法返回实体项目链接(URL)

选项 B: Eko\FeedBundle\Item\Writer\RoutedItemInterface

如果您需要使用路由服务生成实体的链接,可以使用以下接口。您无需担心将路由器注入到实体中。

<?php

namespace Bundle\BlogBundle\Entity;

use Eko\FeedBundle\Item\Writer\RoutedItemInterface;

/**
 * Bundle\BlogBundle\Entity\Article
 */
class Article implements RoutedItemInterface
{

在此实体中,您需要实现以下方法

  • public function getFeedItemTitle() { … } : 该方法返回实体项目标题
  • public function getFeedItemDescription() { … } : 该方法返回实体项目描述(或内容)
  • public function getFeedItemPubDate() { … } : 该方法返回实体项目发布日期
  • public function getFeedItemRouteName() { … } : 该方法返回路由名称
  • public function getFeedItemRouteParameters() { … } : 该方法必须返回一个包含所需路由参数的数组
  • public function getFeedItemUrlAnchor() { … } : 该方法返回将附加到由路由器生成的 URL 的锚点。 注意:可以是空字符串。

3) 生成源!

现在操作发生在您的控制器中。只需声明一个新操作并使用以下示例行

<?php

namespace Bundle\BlogBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class BlogController extends Controller
{
    /**
     * Generate the article feed
     *
     * @return Response XML Feed
     */
    public function feedAction()
    {
        $articles = $this->getDoctrine()->getRepository('BundleBlogBundle:Article')->findAll();

        $feed = $this->get('eko_feed.feed.manager')->get('article');
        $feed->addFromArray($articles);

        return new Response($feed->render('rss')); // or 'atom'
    }
}

请注意,为了更好的性能,您可以使用缓存控制。

此外,实体对象可以单独通过 add 方法添加

<?php
$feed = $this->get('eko_feed.feed.manager')->get('article');
$feed->add($article);

进一步使用您的源

添加一些自定义通道字段

您可以通过这种方式添加到主通道的自定义字段

<?php
$feed = $this->get('eko_feed.feed.manager')->get('article');
$feed->add(new FakeEntity());
$feed->addChannelField(new ChannelField('custom_name', 'custom_value'));

添加一些自定义项目字段

添加自定义项目字段

您可以通过这种方式为您的实体节点添加自定义项目字段

<?php
$feed = $this->get('eko_feed.feed.manager')->get('article');
$feed->add(new FakeEntity());
$feed->addItemField(new ItemField('fake_custom', 'getFeedItemCustom'));

当然,需要在您的实体中声明 getFeedItemCustom() 方法。

添加一组自定义项目字段(可选,带有属性)

您也可以使用这种方式添加组项目字段,如果您的返回值为数组

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

甚至,在一个组中添加多个项目字段,如下所示

$feed->addItemField(
    new GroupItemField('author', array(
        new ItemField('name', 'getFeedItemAuthorName', array('cdata' => true)),
        new ItemField('email', 'getFeedItemAuthorEmail')
    )
);
添加一组自定义通道字段

就像您可以为项目字段做的那样,您也可以使用这种方式添加自定义通道组字段

$feed->addChannelField(
    new GroupChannelField('author', array(
        new ChannelField('name', 'My author name'),
        new ChannelField('email', 'myauthor@email.org')
    )
);
添加自定义媒体项目字段

可以使用以下 MediaItemField 字段类型添加媒体封装

<?php
$feed = $this->get('eko_feed.feed.manager')->get('article');
$feed->add(new FakeEntity());
$feed->addItemField(new MediaItemField('getFeedMediaItem'));

getFeedMediaItem() 方法必须返回一个包含以下键的数组:type、length 和 value。

/**
 * Returns a custom media field
 *
 * @return string
 */
public function getFeedMediaItem()
{
    return array(
        'type'   => 'image/jpeg',
        'length' => 500,
        'value'  => 'http://website.com/image.jpg'
    );
}

这些媒体项目也可以通过 GroupItemField 进行分组。

使用 Symfony 控制台命令来导出你的内容。

如果你想将内容导出到 .xml 文件而不是动态生成,可以使用 php app/console eko:feed:dump Symfony 命令。

以下是一些选项:

以下是一个包含所有选项的示例

php app/console eko:feed:dump --name=article --entity=AcmeDemoBundle:Fake --filename=test.xml --format=atom --orderBy=id --direction=DESC www.myhost.com

这将得到以下结果

Start dumping "article" feed from "AcmeDemoBundle:Fake" entity...
done!
Feed has been dumped and located in "/Users/vincent/dev/perso/symfony/web/test.xml"

使用 eko_feed.feed.dump 来导出你的内容

你可以通过简单地使用 "eko_feed.feed.dump" 服务来导出你的内容。dump 命令使用相同的值。如果你已经有你的项目内容,你可以使用 setItems() 来导出。

<?php

$feedDumpService = $this->get('eko_feed.feed.dump');
$feedDumpService
        ->setName($name)
        //You can set an entity
        //->setEntity($entity)
        // Or set you Items
        ->setItems($MyOwnItemList)
        ->setFilename($filename)
        ->setFormat($format)
        ->setLimit($limit)
        ->setDirection($direction)
        ->setOrderBy($orderBy)
    ;

$feedDumpService->dump();

如有任何疑问,请随时联系我并/或参与。

读取 XML 内容并填充实体

如果你想只读取 XML 内容,这里是如何操作的

<?php
$reader = $this->get('eko_feed.feed.reader');
$reader->setHydrator(new DefaultHydrator());
$feed = $reader->load('https://php.ac.cn/feed.atom')->get();

$feed 将是一个 \Zend\Feed\Reader\Feed\FeedInterface,你可以对其进行操作。

你还可以从一个 XML 内容中填充实体。这很简单。

只需加载内容并调用 populate 方法,传入需要填充的实体名称,该实体需要实现 Eko\FeedBundle\Item\Reader\ItemInterface,请参考以下示例

<?php
$reader = $this->get('eko_feed.feed.reader');
$reader->setHydrator(new DefaultHydrator());
$items = $reader->load('https://php.ac.cn/feed.atom')->populate('MyNamespace\Entity\Name');

在这个例子中,$items 将是一个数组,包含使用给定内容填充的实体。

使用自定义填充器来填充你的实体

你也可以编写自己的填充器并这样使用

$reader = $this->get('eko_feed.feed.reader');
$reader->setHydrator(new MyCustomHydrator());

$items = $reader->load('https://php.ac.cn/feed.atom')->populate('MyNamespace\Entity\Name');

这样,你的自定义填充器将代替 Eko\FeedBundle\Hydrator\DefaultHydrator 使用。

定义一个自定义内容格式化器

你可以通过以下标签定义自己的内容格式化器

<service id="acme.my_bundle.formatter.custom" class="Acme\MyBundle\Feed\Formatter\CustomFormatter">
    <tag name="eko_feed.formatter" format="custom"></tag>

    <argument type="service" id="translator" />
</service>

然后,通过调用 $feed->render('custom') 来使用它。

贡献者