markocupic/rss-feed-generator-bundle

简单的RSS订阅生成器。在Symfony控制器内生成RSS订阅。

1.1.5 2023-05-30 05:43 UTC

This package is auto-updated.

Last update: 2024-08-30 01:11:57 UTC


README

RSS订阅生成器包

使用此包在您的Symfony应用程序内生成RSS订阅。

❤非常感谢@eko (Vincent Composieux)为我提供编写此包的灵感。https://github.com/eko/FeedBundle.

安装

composer require markocupic/rss-feed-generator-bundle

选项A: 将以下内容添加到config/bundles.php。

<?php

return [
    // ...
    Markocupic\RssFeedGeneratorBundle\MarkocupicRssFeedGeneratorBundle::class => ['all' => true],
];

选项B: 在一个Contao ❤环境中,在您的包的Contao Manager Plugin类中注册rss订阅生成器包。

<?php

declare(strict_types=1);

namespace Contao\CoreBundle\ContaoManager;
use Contao\CoreBundle\ContaoCoreBundle;
use Contao\ManagerPlugin\Bundle\BundlePluginInterface;
use Contao\ManagerPlugin\Bundle\Config\BundleConfig;
use Contao\ManagerPlugin\Bundle\Parser\ParserInterface;
use Contao\ManagerPlugin\Config\ConfigPluginInterface;
use Contao\ManagerPlugin\Routing\RoutingPluginInterface;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\Config\Loader\LoaderResolverInterface;
use Symfony\Component\HttpKernel\KernelInterface;
use Markocupic\RssFeedGeneratorBundle\MarkocupicRssFeedGeneratorBundle;
use Acme\MyBundle\AcmeMyBundleBundle;

class Plugin implements BundlePluginInterface, RoutingPluginInterface, ConfigPluginInterface
{
    /**
     * {@inheritdoc}
     */
    public function getBundles(ParserInterface $parser)
    {
        return [
            // Register RSS feed generator bundle
            BundleConfig::create(MarkocupicRssFeedGeneratorBundle::class),
            // register other bundles
            BundleConfig::create(AcmeMyBundle::class)
            ->setLoadAfter(MarkocupicRssFeedGeneratorBundle::class)
            ->setLoadAfter(ContaoCoreBundle::class)
        ];
    }

使用依赖注入在控制器中要求feed工厂。

# config/services.yml
services:

  Markocupic\DemoBundle\Controller\Feed\FeedController:
    arguments:
      - '@Markocupic\RssFeedGeneratorBundle\Feed\FeedFactory'
      - '@database_connection'
      - '%kernel.project_dir%'
    public: true

创建订阅

// Use the feed factory to generate the feed object
$rss = $this->feedFactory->createFeed(\Markocupic\RssFeedGeneratorBundle\Feed\Feed::ENCODING_UTF8);

 // Add one or more attributes to the root element
$rss->setRootAttributes([
    'xmlns:tourdb' => 'https://acme.com/schema/tourdbrss/1.0',
    'xmlns:atom'=>'http://www.w3.org/2005/Atom',
]);

// Add one or more attributes to the channel element
$rss->setChannelAttributes([
    'foo' => 'bar',
]);

添加订阅频道元素

在feed工厂方法FeedFactory::addChannelField()中使用Item类。

Item::__constructor($elementName, $strValue, $arrOptions, $arrAttributes)接受四个参数

  1. (string) 元素名称
  2. (string) 内容
  3. 可选: (array) 选项(目前有cdata和过滤器)
  4. 可选: (array) 属性
$rss->addChannelField(
    new Item('title', 'Demo feed')
);

$rss->addChannelField(
    new Item('link', 'https://foobar.ch')
);

创建cdata元素并插入属性

// Add CDATA element and an attribute
$rss->addChannelField(
    new Item('description', 'Check our news feed and have fun!', ['cdata' => true], ['attrName' => 'Here comes the attribute value'])
);

过滤或替换内容

// filter or replace values
$arrFilter = ['Ferrari' => 'Italia', 'car' => 'country'] ;
$rss->addChannelField(
    new Item('description', 'Ferrari is my favourite car!', ['filter' => $arrFilter])
);
// Will result in:
// <description>Italia is my favourite country!</description>

添加频道条目

使用FeedFactory::addChannelItemField(), ItemGroup()和Item()生成频道条目。

ItemGroup::__constructor($elementName, $arrItemObjects, $arrAttributes)接受三个参数

  1. (string) 元素名称
  2. (array) Item对象
  3. 可选: (array) 属性
// Retrieve data from database and add items
$results = $this->getEvents($section);

if (null !== $results) {
    while (false !== ($arrEvent = $results->fetch())) {
        // Use a new instance of ItemGroup to add a collection of items all of the same level.
        $rss->addChannelItemField(
            new ItemGroup('item', [
                new Item('title', $arrEvent['title']),
                new Item('link', $arrEvent['link']),
                new Item('description', $arrEvent['description'], ['cdata' => true]),
                new Item('pubDate', date('r',(int) $arrEvent['tstamp'])),
                new Item('author', $arrEvent['author']),
                new Item('guid', $arrEvent['uuid']),
                new Item('tourdb:startdate', date('Y-m-d', (int) $arrEvent['startDate'])),
                new Item('tourdb:enddate', date('Y-m-d', (int) $arrEvent['endDate'])),
            ])
        );
    }
}

嵌套条目

// Append nested items with ItemGroup.
$rss->addChannelItemField(
    new ItemGroup('item', [
        new Item('title', 'Title'),
        new Item('link', 'https://foo.bar'),
        new ItemGroup('nestedItems', [
            new Item('subitem', 'Some content'),
            new Item('subitem', 'Some content'),
        ], ['foo'=> 'bar']),
    ])
);

结果

<item>
    <title>Title</title>
    <link>https://foo.bar</link>
    <nestedItem foo="bar">
        <subitem>Some content</subitem>
        <subitem>Some content</subitem>
    </nestedItem>
</item>

渲染并发送内容到浏览器。

return $rss->render();

渲染并将内容保存到文件系统。

return $rss->render('public/share/myfeed.xml);

在Symfony包的控制器中生成RSS 2.0订阅

<?php

declare(strict_types=1);

namespace Acme\DemoBundle\Controller\Feed;

use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Query\QueryBuilder;
use Markocupic\RssFeedGeneratorBundle\Feed\FeedFactory;
use Markocupic\RssFeedGeneratorBundle\Item\Item;
use Markocupic\RssFeedGeneratorBundle\Feed\ItemGroup;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class FeedController extends AbstractController
{
    /**
     * @var FeedFactory
     */
    private $feedFactory;

    /**
     * @var Connection
     */
    private $connection;

    /**
     * @var string
     */
    private $projectDir;

    /**
     * @Route("/_rssfeed", name="rss_feed")
     */
    public function printLatestEvents(): Response
    {

        $rss = $this->feedFactory->createFeed('utf-8');

        $rss->addChannelField(
            new Item('title', 'Acme news')
        );

        $rss->addChannelField(
            new Item('description', 'Enjoj our news.')
        );

        $rss->addChannelField(
            new Item('link', 'https://acme.com')
        );

        $rss->addChannelField(
            new Item('language', 'de')
        );

        $rss->addChannelField(
            new Item('pubDate', date('r', (time() - 3600)))
        );

        // Retrieve data from db
        $results = $this->getEvents($section);

        // Add some channel items
        if (null !== $results) {
            while (false !== ($arrEvent = $results->fetch())) {
                $eventsModel = $calendarEventsModelAdapter->findByPk($arrEvent['id']);

                $rss->addChannelItemField(
                    new ItemGroup('item', [
                        new Item('title', $arrEvent['title']),
                        new Item('link', $arrEvent['link']),
                        new Item('description', $arrEvent['description'], ['cdata' => true]),
                        new Item('pubDate', date('r', (int) $eventsModel->tstamp)),
                    ])
                );
            }
        }

        return $rss->render($this->projectDir.'/public/share/rss.xml');
    }
}

过滤和搜索替换字符串

默认情况下,此扩展会过滤一些字符。换行符将被替换为空格等。请参阅插件配置

覆盖这些默认值相对简单,可以在config/parameters.yml中完成。请使用正则表达式作为搜索模式。

# config/parameters.yml
markocupic_rss_feed_generator:
  filter:
    '/</': '&lt;'
    '/[\n\r]+/': ' '
    '/&#40;/': '('
    '/&#41;/': ')'
    '/\[-\]/': ''
    '/\&shy;/': ''
    '/\[nbsp\]/': ' '
    '/&nbsp;/': ' '
    '/&/': '&amp;'