muspi / feedbundle
一个用于从实体构建 RSS 源的 Symfony 扩展包,克隆自 eko/feedbundle
Requires
- php: ^5.4|^7.0
- symfony/framework-bundle: ^2.5|^3.0|^4.0
- zendframework/zend-feed: >=2.0
- zendframework/zend-http: >=2.0
- zendframework/zend-servicemanager: >=2.0
Requires (Dev)
- doctrine/orm: ~2.2,>=2.2.3|~2.5
- phpunit/phpunit: ~4
Suggests
- doctrine/orm: ~2.2,>=2.2.3|~2.5
README
功能
- 生成 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\ItemInterface 或 Eko\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') 来使用它。
贡献者
-
Vincent Composieux vincent.composieux@gmail.com (Twitter: @vcomposieux)
-
Rob Masters mastahuk@gmail.com
-
Thomas P thomas@scullwm.com (Twitter: @scullwm)
-
有人想贡献吗?请不要犹豫,你将被列入其中!