A PHP library to read and write feeds in JSONFeed, RSS or Atom format

Overview

feed-io

Latest Stable Version Build Status

feed-io is a PHP library built to consume and serve news feeds. It features:

  • JSONFeed / Atom / RSS read and write support
  • Feeds auto-discovery through HTML headers
  • a Command line interface to discover and read feeds
  • PSR-7 Response generation with accurate cache headers
  • HTTP Headers support when reading feeds in order to save network traffic
  • Detection of the format (RSS / Atom) when reading feeds
  • Enclosure support to handle external medias like audio content
  • Feed logo support (RSS + Atom)
  • PSR compliant logging
  • DateTime detection and conversion
  • A generic HTTP ClientInterface
  • Guzzle Client integration

This library is highly extensible and is designed to adapt to many situations, so if you don't find a solution through the documentation feel free to ask in the discussions.

Installation

Use Composer to add feed-io into your project's requirements :

    composer require debril/feed-io

Requirements

feed-io PHP
4.x 7.1+
5.0 8.0+

feed-io 4 requires PHP 7.1+, feed-io 5 requires PHP 8.0+. All versions relies on psr/log and guzzle. it suggests monolog for logging. Monolog is not the only library suitable to handle feed-io's logs, you can use any PSR/Log compliant library instead.

Usage

CLI

Let's suppose you installed feed-io using Composer, you can use its command line client to read feeds from your terminal :

./vendor/bin/feedio read http://php.net/feed.atom

You can specify the number of items you want to read using the --count option. The instruction below will display the latest item :

./vendor/bin/feedio read -c 1 http://php.net/feed.atom

reading

feed-io is designed to read feeds across the internet and to publish your own. Its main class is FeedIo :

// create a simple FeedIo instance
$feedIo = \FeedIo\Factory::create()->getFeedIo();

// read a feed
$result = $feedIo->read($url);

// get title
$feedTitle = $result->getFeed()->getTitle();

// iterate through items
foreach( $result->getFeed() as $item ) {
    echo $item->getTitle();
}

In order to save bandwidth, feed-io estimates the next time it will be relevant to read the feed and get new items from it.

$nextUpdate = $result->getNextUpdate();
echo "computed next update: {$nextUpdate->format(\DATE_ATOM)}";

// you may need to access the statistics
$updateStats = $result->getUpdateStats();
echo "average interval in seconds: {$updateStats->getAverageInterval()}";

feed-io calculates the next update time by first detecting if the feed was active in the last 7 days and if not we consider it as sleepy. The next update date for a sleepy feed is set to the next day at the same time. If the feed isn't sleepy we use the average interval and the median interval by adding those intervals to the feed's last modified date and compare the result to the current time. If the result is in the future, then it's returned as the next update time. If none of them are in the future, we considered the feed will be updated quite soon, so the next update time is one hour later from the moment of the calculation.

Please note: the fixed delays for sleepy and closed to be updated feeds can be set through Result::getNextUpdate() arguments, see Result for more details.

Feeds discovery

A web page can refer to one or more feeds in its headers, feed-io provides a way to discover them :

$feedIo = \FeedIo\Factory::create()->getFeedIo();

$feeds = $feedIo->discover($url);

foreach( $feeds as $feed ) {
    echo "discovered feed : {$feed}";
}

Or you can use feed-io's command line :

./vendor/bin/feedio discover https://a-website.org

You'll get all discovered feeds in the output.

formatting an object into a XML stream

// build the feed
$feed = new FeedIo\Feed;
$feed->setTitle('...');

// convert it into Atom
$atomString = $feedIo->toAtom($feed);

// or ...
$atomString = $feedIo->format($feed, 'atom');

Adding a StyleSheet

$feed = new FeedIo\Feed;
$feed->setTitle('...');
$styleSheet = new StyleSheet('http://url-of-the-xsl-stylesheet.xsl');
$feed->setStyleSheet($styleSheet);

building a feed including medias

// build the feed
$feed = new FeedIo\Feed;
$feed->setTitle('...');

$item = $feed->newItem();

// add namespaces
$feed->setNS(
    'itunes', //namespace
    'http://www.itunes.com/dtds/podcast-1.0.dtd' //dtd for the namespace
        );
$feed->set('itunes,title', 'Sample Title'); //OR any other element defined in the namespace.
$item->addElement('itunes:category', 'Education');

// build the media
$media = new \FeedIo\Feed\Item\Media
$media->setUrl('http://yourdomain.tld/medias/some-podcast.mp3');
$media->setType('audio/mpeg');

// add it to the item
$item->addMedia($media);

$feed->add($item);

Creating a valid PSR-7 Response with a feed

You can turn a \FeedIo\FeedInstance directly into a PSR-7 valid response using \FeedIo\FeedIo::getPsrResponse() :

$feed = new \FeedIo\Feed;

// feed the beast ...
$item = new \FeedIo\Feed\Item;
$item->set ...
$feed->add($item);

$atomResponse = $feedIo->getPsrResponse($feed, 'atom');

$jsonResponse = $feedIo->getPsrResponse($feed, 'json');

Configure feed-io using the Factory

We saw in the reading section that to get a simple FeedIo instance we can simply call the Factory statically and let it return a fresh FeedIo composed of the main dependencies it needs to work. The problem is that we may want to inject configuration to its underlying components, such as configuring Guzzle to ignore SSL errors.

For that, we will inject the configuration through Factory::create() parameters, first one being for the logging system, and the second one for the HTTP Client (well, Guzzle).

Configure Guzzle through the Factory

A few lines above, we talked about ignoring ssl errors, let's see how to configure Guzzle to do this:

$feedIo = \FeedIo\Factory::create(
        ['builder' => 'NullLogger'], // assuming you want feed-io to keep quiet
        ['builder' => 'GuzzleClient', 'config' => ['verify' => false]]
    )->getFeedIo();

It's important to specify the "builder", as it's the class that will be in charge of actually building the instance.

activate logging

feed-io natively supports PSR-3 logging, you can activate it by choosing a 'builder' in the factory :

$feedIo = \FeedIo\Factory::create(['builder' => 'monolog'])->getFeedIo();

feed-io only provides a builder to create Monolog\Logger instances. You can write your own, as long as the Builder implements BuilderInterface.

Building a FeedIo instance without the factory

To create a new FeedIo instance you only need to inject two dependencies :

  • an HTTP Client implementing FeedIo\Adapter\ClientInterface. It can be wrapper for an external library like FeedIo\Adapter\Guzzle\Client
  • a PSR-3 logger implementing Psr\Log\LoggerInterface
// first dependency : the HTTP client
// here we use Guzzle as a dependency for the client
$guzzle = new GuzzleHttp\Client();
// Guzzle is wrapped in this adapter which is a FeedIo\Adapter\ClientInterface  implementation
$client = new FeedIo\Adapter\Guzzle\Client($guzzle);

// second dependency : a PSR-3 logger
$logger = new Psr\Log\NullLogger();

// now create FeedIo's instance
$feedIo = new FeedIo\FeedIo($client, $logger);

Another example with Monolog configured to write on the standard output :

use FeedIo\FeedIo;
use FeedIo\Adapter\Guzzle\Client;
use GuzzleHttp\Client as GuzzleClient;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;

$client = new Client(new GuzzleClient());
$logger = new Logger('default', [new StreamHandler('php://stdout')]);

$feedIo = new FeedIo($client, $logger);

Guzzle Configuration

You can configure Guzzle before injecting it to FeedIo :

use FeedIo\FeedIo;
use FeedIo\Adapter\Guzzle\Client;
use GuzzleHttp\Client as GuzzleClient;
use \Psr\Log\NullLogger;

// We want to timeout after 3 seconds
$guzzle = new GuzzleClient(['timeout' => 3]);
$client = new Client($guzzle);

$logger = new NullLogger();

$feedIo = new \FeedIo\FeedIo($client, $logger);

Please read Guzzle's documentation to get more information about its configuration.

Caching Middleware usage

To prevent your application from hitting the same feeds multiple times, you can inject Kevin Rob's cache middleware into Guzzle's instance :

use FeedIo\FeedIo;
use FeedIo\Adapter\Guzzle\Client;
use GuzzleHttp\Client As GuzzleClient;
use GuzzleHttp\HandlerStack;
use Kevinrob\GuzzleCache\CacheMiddleware;
use Psr\Log\NullLogger;

// Create default HandlerStack
$stack = HandlerStack::create();

// Add this middleware to the top with `push`
$stack->push(new CacheMiddleware(), 'cache');

// Initialize the client with the handler option
$guzzle = new GuzzleClient(['handler' => $stack]);
$client = new Client($guzzle);
$logger = new NullLogger();

$feedIo = new \FeedIo\FeedIo($client, $logger);

As feeds' content may vary often, caching may result in unwanted behaviors.

Inject a custom Logger

You can inject any Logger you want as long as it implements Psr\Log\LoggerInterface. Monolog does, but it's the only library : https://packagist.org/providers/psr/log-implementation

use FeedIo\FeedIo;
use FeedIo\Adapter\Guzzle\Client;
use GuzzleHttp\Client as GuzzleClient;
use Custom\Logger;

$client = new Client(new GuzzleClient());
$logger = new Logger();

$feedIo = new FeedIo($client, $logger);

Inject a custom HTTP Client

Warning : it is highly recommended to use the default Guzzle Client integration.

If you really want to use another library to read feeds, you need to create your own FeedIo\Adapter\ClientInterface class to embed interactions with the library :

use FeedIo\FeedIo;
use Custom\Adapter\Client;
use Library\Client as LibraryClient;
use Psr\Log\NullLogger;

$client = new Client(new LibraryClient());
$logger = new NullLogger();

$feedIo = new FeedIo($client, $logger);

Factory or Dependency Injection ?

Choosing between using the Factory or build FeedIo without it is a question you must ask yourself at some point of your project. The Factory is mainly designed to let you use feed-io with the lesser efforts and get your first results in a small amount of time. However, it doesn't let you benefit of all Monolog's and Guzzle's features, which could be annoying. Dependency injection will also let you choose another library to handle logs if you need to.

Dealing with missing timezones

Sometimes you have to consume feeds in which the timezone is missing from the dates. In some use-cases, you may need to specify the feed's timezone to get an accurate value, so feed-io offers a workaround for that :

$feedIo->getDateTimeBuilder()->setFeedTimezone(new \DateTimeZone($feedTimezone));
$result = $feedIo->read($feedUrl);
$feedIo->getDateTimeBuilder()->resetFeedTimezone();

Don't forget to reset feedTimezone after fetching the result, or you'll end up with all feeds located in the same timezone.

Built with PHP Storm

Most of feed-io's code was written using PHP Storm courtesy of Jetbrains.

Comments
  • Date and timezone is not handled properly if feed timezone is different than script one

    Date and timezone is not handled properly if feed timezone is different than script one

    Background

    I want to consume a feed I know is produced in a different time zone. For example purposes, let's say it's America/Chicago. The format of dates in the feed is M d, Y g:i:s a - not a standard one. Note, the date string doesn't have any timezone info.

    Preparing the client:

    $feedIo->getDateTimeBuilder()->addDateFormat('M d, Y g:i:s a');
    

    Problem

    I need to instruct FeedIO not to parse date strings as in a current script timezone but rather to treat them all as coming from the different one. I see DateTimeBuilder has a public setter for timezone, so I assume that's the thing to use.

    If I don't set the timezone myself and rely on DateTimeBuilder to read it from PHP settings, the date string is interpreted as coming from my script's timezone.

    On the other hand, if I register a different timezone:

    $feedIo->getDateTimeBuilder()->setTimezone(new \DateTimeZone('America/Chicago'));
    

    and then read the RSS, this is what happens:

    1. Date string is used to create a DateTime object. As DateTimeZone setting is not used when constructing DateTime object, the script timezone is used.
    2. A custom timezone I set is applied on DateTime object. If you didn't override timezone in builder, it's the same timezone so you don't see a time shift. Nonetheless, if you do, DateTime object state is going to be changed.

    For example, if I get Aug 02, 2017 2:21:29 AM string from RSS and set America/Chicago timezone for builder, I should get a DateTime object that corresponds to Unix timestamp 1501658489:

    $dateString = 'Aug 02, 2017 2:21:29 AM';
    $timezoneOfFeed = 'America/Chicago';
    
    $dt = DateTime::createFromFormat('M d, Y g:i:s a', $dateString, new DateTimeZone($timezoneOfFeed));
    
    echo $dt->format('U') . PHP_EOL; // 1501658489
    

    It comes down to what setTimestamp does to DateTime object. Instead of "Take the original date string and reinterpret it using provided timezone", it's "Take the DateTime object (in timezone you've provided during construction) and tell me what date time that would be in provided timezone".

    Solution

    I'm not 100% sure if it's a bug or a feature ~~but I don't see any value in it~~. It's good thing a resulting parsed feed keeps a DateTime object instead of a string but it's critical to interpret this flawlessly at parse time.

    There are two ways to fix this:

    1. As in my example, use third param of DateTime::createFromFormat and use timezone set in builder. Don't use setTimezone on already created DateTime as it's probably not what you want.
    2. Don't allow setting custom timezone for builder to remove ambiguity. Make \FeedIo\Rule\DateTimeBuilder::setTimezone private. State in docs that date strings coming from feed will be interpreted in script timezone unless a string contains a timezone identifier.

    Note, I don't say what happens when \FeedIo\Rule\DateTimeBuilder::convertToDateTime fails to guess a format and falls back to \FeedIo\Rule\DateTimeBuilder::stringToDateTime. It seems something similar is done there.

    opened by mirfilip 14
  • FeedIO client does not cache by default

    FeedIO client does not cache by default

    Hi!

    In readme you state:

    HTTP Headers support when reading feeds in order to save network traffic does this imply caching requests/responses?

    As it stands, Guzzle6 isn't configured with caching middleware and thus doing any kind of polling actually ignores HTTP caching headers.

    Am I missing sth?

    opened by mirfilip 12
  • Full MediaRSS support

    Full MediaRSS support

    This PR attempts to fix #240 Let me know if there are things I need to change!

    Éloi

    Commits review

    MRSS-1

    This commit is just some test refactoring. It is mostly harmless

    MRSS-2

    This commit follows #252 and remove the deprecated method

    MRSS-3

    This commit implements the priority mechanism explained in the specification:

    The following elements are optional and may appear as sub-elements of <channel>, <item>, <media:content> and/or <media:group>.

    When an element appears at a shallow level, such as or , it means that the element should be applied to every media object within its scope.

    Duplicated elements appearing at deeper levels of the document tree have higher priority over other levels. For example, <media:content> level elements are favored over <item> level elements. The priority level is listed from strongest to weakest: <media:content>, <media:group>, <item>, <channel>.

    You might want to have a look at the findTags method in Rule/Media.php that implements this mechanism with XPath. I tried to minimize their use at the maximum but there should be at least ~20 XPath use by feed.

    MRSS-4

    This one is the big one. It adds all the tags and attributes the specification details.

    For each tag I copy/pasted matching piece of specification in the test comments, and tried to implement what I understood. I made some design choices you may have an advice on:

    • in item/Media.php I created some enum classes (like abstract class MediaContentMedium) for attributes that can only have certain values (for instance, <media:content medium> attribute can only has those values image, audio, video, document or executable);
    • I also implemented some shallow classes (like MediaCredit) in some cases, where maybe arrays should have sufficed.

    MRSS-5

    A readme update

    opened by azmeuk 11
  • Media-RSS support

    Media-RSS support

    opened by azmeuk 10
  • Impossible to convert date

    Impossible to convert date

    We got an error report, https://github.com/nextcloud/news/issues/461 for the following feed: https://sourceforge.net/projects/cheeseburgerdumplings/rss?path=/15.1/dumpling

    w3c-validator: https://validator.w3.org/feed/check.cgi?url=https%3A%2F%2Fsourceforge.net%2Fprojects%2Fcheeseburgerdumplings%2Frss%3Fpath%3D%2F15.1%2Fdumpling

    As you may know, we are currently using 3.0 but I also tested 4.1. The full error:

    PHP Fatal error:  Uncaught InvalidArgumentException: Impossible to convert date : Fri, 22 Mar 2019 08:24:31 UT in /home/grotax/git/feed-io/src/FeedIo/Rule/DateTimeBuilder.php:150
    Stack trace:
    #0 /home/grotax/git/feed-io/src/FeedIo/Rule/DateTimeBuilder.php(136): FeedIo\Rule\DateTimeBuilder->stringToDateTime('Fri, 22 Mar 201...')
    #1 /home/grotax/git/feed-io/src/FeedIo/Rule/ModifiedSince.php(26): FeedIo\Rule\DateTimeBuilder->convertToDateTime('Fri, 22 Mar 201...')
    #2 /home/grotax/git/feed-io/src/FeedIo/Parser/XmlParser.php(114): FeedIo\Rule\ModifiedSince->setProperty(Object(FeedIo\Feed), Object(DOMElement))
    #3 /home/grotax/git/feed-io/src/FeedIo/Parser/XmlParser.php(95): FeedIo\Parser\XmlParser->handleNode(Object(FeedIo\Feed), Object(DOMElement), Object(FeedIo\RuleSet))
    #4 /home/grotax/git/feed-io/src/FeedIo/Parser/XmlParser.php(53): FeedIo\Parser\XmlParser->parseNode(Object(FeedIo\Feed), Object(DOMElement), Object(FeedIo\RuleSet))
    #5 /home/grotax/git/feed-io/src/FeedIo/ParserAbstract.php(70): FeedIo\Parser\XmlParser->parseConten in /home/grotax/git/feed-io/src/FeedIo/Reader.php on line 122
    
    enhancement 
    opened by Grotax 10
  • feed-io produces invalid RSS feeds

    feed-io produces invalid RSS feeds

    following https://github.com/alexdebril/rss-atom-bundle/issues/170

    feed-io produces invalid feeds as we can see through https://validator.w3.org/feed/check.cgi?url=https%3A%2F%2Frss-atom-demo.herokuapp.com%2Frss%2Fmock

    main errors are :

    • <guid> should not be declared in the channel, neither <lastPubDate>
    • Missing atom:link with rel="self"

    Other validation problems may be added in the following issue.

    bug 
    opened by alexdebril 10
  • Optional elements can not be parsed further

    Optional elements can not be parsed further

    This issue is similar to issue #72 , but more generic.

    RSS 2.0 feeds can be extended with other elements than specified in the specification. See http://www.rssboard.org/rss-specification#extendingRss .

    When this namespace contains tags with subtags, feed-io is not capable of reading those subtags separately.

    For example:

    XML:

    <itunes:owner>
        <itunes:name>Example</itunes:name>
        <itunes:email>[email protected]</itunes:email>
    </itunes:owner>
    

    PHP:

    $ownerValue = $feed->getValue('itunes:owner');
    var_dump($ownerValue);
    

    Output:

    string(58) "
                Example
                [email protected]
            "
    

    I'm pretty sure (but I can be wrong) feed-io is not capable of fetching the content of itunes:name.

    I have two suggestions to handle this problem:

    1. Allow developers to create their own Feed Rulesets and Objects to add to the feed-io parser as an extension

    2. Modify the FeedIo\Feed\Node\Element to store and parse subtags of that element

    What's your vision on this problem? Is this something feed-io should be able to do in the future?

    enhancement 
    opened by ruudvdd 9
  • Error_log flooding in version 4.9.8 on getDescription() vs getContent()

    Error_log flooding in version 4.9.8 on getDescription() vs getContent()

    There's a lot of error_log() flooding due to the depricated method getDescription() when using version 4.9.8. This method will be removed from future versions and instead we're required to install PHP8.0 or higher and use getContent().

    Could you please remove the error_log() call in a hotfix for version 4.9.81?

    opened by geoffsmiths 8
  • Use Httplug and remove dependency on Guzzle

    Use Httplug and remove dependency on Guzzle

    Hi Alex,

    as @aschempp is busy I picked up his issue #398. I removed the dependency on Guzzle and required Httplug instead. This PR is not finished yet, but I want to let you in early on what I am doing here ;-)

    • I figured this would end in a new major release anyways so I removed the factory all together as you already planned to deprecate it anyways (see #388). Must still be deprecated in 5.x though.
    • I removed every usage of Guzzle ~and introduced a NullClient (equivalent to NullLogger). However, this renders the binary useless at the moment, as there is no default HTTP client anymore. I don't know yet how to solve this.~ and use php-http/discovery to automatically find a suitable PSR-18 compliant HTTP client
    • When upgrading to the release this PR will be merged into, you need to manually require a specific HTTP client implementation, e.h. composer require php-http/guzzle7-adapter which will install Guzzle 7. To install the library in the future, you would need to run composer require debril/feed-io php-http/guzzle7-adapter, otherwise the packages cannot be resolved to an installable set. You can now chose your HTTP client from this list ;-)
    • The TimingStats is a Guzzle Feature, that is not available anymore, now that we rely on PSR-18 only. I mimicked a basic performance measurement, but I wonder, if we should remove this all together?
    • ~As of now, reading from the file system is not supported anymore.~

    Anyways, what are your thoughts on this? Happy to hear your comments.

    Cheerio

    opened by bezin 7
  • Read last modified value from response

    Read last modified value from response

    Found while looking into: https://github.com/nextcloud/news/issues/607 Here is a minimal working example: https://github.com/kesselb/fefe-feed-io

    This patch will read the last modified value from the response and pass it to the feed. The last modified fixer will usually workaround this issue for feeds with pub date for the items.

    opened by kesselb 7
  • Property tagName

    Property tagName

    Hello, I get this error with https://feeds.feedblitz.com/scotch_io. There is no exception ?

    PHP Notice:  Trying to get property 'tagName' of non-object in /srv/http/vhosts/piso.local/vendor/debril/feed-io/src/FeedIo/Standard/Atom.php on line 55
    PHP Notice:  Trying to get property 'tagName' of non-object in /srv/http/vhosts/piso.local/vendor/debril/feed-io/src/FeedIo/Standard/Rss.php on line 72
    PHP Notice:  Trying to get property 'tagName' of non-object in /srv/http/vhosts/piso.local/vendor/debril/feed-io/src/FeedIo/Standard/Rdf.php on line 43
    PHP Fatal error:  Uncaught TypeError: strpos() expects parameter 1 to be string, null given in /srv/http/vhosts/piso.local/vendor/debril/feed-io/src/FeedIo/Standard/Rdf.php:43
    Stack trace:
    #0 /srv/http/vhosts/piso.local/vendor/debril/feed-io/src/FeedIo/Standard/Rdf.php(43): strpos(NULL, 'rdf')
    #1 /srv/http/vhosts/piso.local/vendor/debril/feed-io/src/FeedIo/Reader.php(175): FeedIo\Standard\Rdf->canHandle(Object(FeedIo\Reader\Document))
    #2 /srv/http/vhosts/piso.local/vendor/debril/feed-io/src/FeedIo/Reader.php(161): FeedIo\Reader->getAccurateParser(Object(FeedIo\Reader\Document))
    #3 /srv/http/vhosts/piso.local/vendor/debril/feed-io/src/FeedIo/Reader.php(146): FeedIo\Reader->parseDocument(Object(FeedIo\Reader\Document), Object(FeedIo\Feed))
    #4 /srv/http/vhosts/piso.local/vendor/debril/feed-io/src/FeedIo/Reader.php(125): FeedIo\Reader->handleResponse(Object(FeedIo\Adapter\Guzzle\Response), Object(FeedIo\Feed))
    #5 /srv/http/vhosts/piso.local/vendor/debril/feed-io/src/FeedIo/FeedIo.php(302): FeedIo\Reader->read('https://feeds.f...', in /srv/http/vhosts/piso.local/vendor/debril/feed-io/src/FeedIo/Standard/Rdf.php on line 43
    
    help wanted 
    opened by miradozk 7
  • How to parse feed from existing string

    How to parse feed from existing string

    I have an existing feed in a string and I wanted to parse it. So I don't need feed-io to fetch it via network. So I am answering my own question with an example:

    <?php
    
    namespace kek;
    
    use FeedIo\Adapter\NullClient;
    use FeedIo\Feed;
    use FeedIo\Parser\XmlParser;
    use FeedIo\Reader;
    use FeedIo\Reader\Document;
    use FeedIo\Rule\DateTimeBuilder;
    use FeedIo\Standard\Rss;
    use Psr\Log\NullLogger;
    
    require 'vendor/autoload.php';
    
    $client = new NullClient();
    $logger = new NullLogger();
    $reader = new Reader($client, $logger);
    $reader->addParser(new XmlParser(new Rss(new DateTimeBuilder()), $logger));
    $document = new Document(file_get_contents('https://news.ycombinator.com/rss'));
    
    $feed = $reader->parseDocument($document, new Feed());
    
    echo "feed title : {$feed->getTitle()} \n";
    
    foreach ($feed as $item) {
        print "  {$item->getTitle()}\n";
    }
    

    As far as I understand this is the way to go when wanting to parse a feed when you already have it as a string. Has a readString() method in FeedIo been considered? Would be nice to have all the parser already loaded etc.

    opened by dvikan 0
  • Additional namespaces are omitted from rss tag

    Additional namespaces are omitted from rss tag

    When reading a feed with additional NSs in the RSS tag definition, these are omitted from the feed.

    For example, the RSS tag <rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0" version="2.0> results in <rss version="2.0"> being generated so that the original additional namespaces have to be added manually via addNS() afterwards.

    opened by monochromec 0
  • <itunes:owner> tag causes repeated emails in field

    tag causes repeated emails in field

    Per https://support.google.com/podcast-publishers/answer/9889544?hl=en the

    <itunes:owner>
    <itunes:email>[email protected]</itunes:email>
    </itunes:owner>
    

    channel metadata is highly encouraged. Unfortunately, this causes the email [email protected] to be inserted between the <itunes:owner and <itunes:email> tags.

    BTW: How do I specify a version of a DTD when invoking addNS on a Feed object?

    opened by monochromec 0
  • Exception on url with redirects.

    Exception on url with redirects.

    When I'm running Guzzle standalone requests, get status 200

    $url = 'https://iphones.ru/';
    $guzzle = new \GuzzleHttp\Client();
    $result = $guzzle->get($url);
    var_dump($result->getStatusCode()); // status 200
    

    When running with FeedIo, it's throws an exception

    $url = 'https://iphones.ru/';
    $guzzle = new \GuzzleHttp\Client();
    $client = new \FeedIo\Adapter\Http\Client($guzzle);
    $feedIo = new \FeedIo\FeedIo($client);
    $feeds = $feedIo->discover($url);
    /*
    FeedIo\Adapter\ServerErrorException 
    
    internal server error
    */
    

    composer.json

    "guzzlehttp/guzzle": "7.4.5",
    "debril/feed-io": "6.0"
    
    opened by Stajor 1
Releases(v5.3.1)
A feed parser to normalise typical feed data into Atom-like constructs.

PHP5 Feed parser and normaliser A feed parser to normalise typical feed data into Atom-like constructs. This parser supports / will support: RSS 2.0 p

Chr1s HuntΞr 4 Sep 2, 2022
Quick and dirty PHP script to turn a Twitter feed into an RSS feed using Twitter's v2 API

Twitter to RSS Quick and dirty PHP script that turns a given Twitter feed into a RSS feed using Twitter's API v2 (the free version!) Does some basic l

Jon W 0 Aug 11, 2022
Simple-podcast-generator - 👉 A very simple way to host your podcast files and generate the RSS Podcast feed 🎙

Podcast RSS Feed Generator A very simple way to host your podcast files and generate the RSS Podcast feed ?? ?? Contents Summary Requirements Installa

♚ PH⑦ de Soria™♛ 11 Dec 2, 2022
A simple RSS feed reader for Laravel 5

Laravel 5 - Feed Reader A simple RSS feed reader for Laravel 5 Features One command to read any RSS feed Different RSS feed profiles enabled Quick Sta

Andrew Judd 45 Oct 10, 2022
An RSS reader application built with Laravel

About Laravel Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experie

Ryan Chandler 4 Mar 24, 2022
The objective of this project is to manage The Website Manga, this site permits to Client to show, read and download Manga with the possibility to react, vote, and save his data.

The objective of this project is to manage The Website Manga, this site permits to Client to show, read and download Manga with the possibility to react, vote, and save his data.

Reda Ennakouri 5 Nov 23, 2022
A powerful open source Laravel Blog with WYSWYG and CRUD (Create Read Update Delete) built on Laravel 5.8 and Bootstrap 4

Larablog A powerful open source Laravel Blog with WYSWYG and CRUD (Create Read Update Delete) built on Laravel 5.8 and Bootstrap 4 Table of contents F

Jeremy Kenedy 144 Oct 11, 2022
Simple searching for postcodes to retrieve geographic information. Support for various API providers and a unified address/output format.

Postcode Search Simple searching for postcodes to retrieve geographic information. Support for various API providers and a unified address/output form

Gary Green 10 Nov 29, 2022
Desarrollo de una aplicación muy sencilla, desarrollada con HTML - Bootstrap - PHP - (PDO)- Mysql. (Login - Registro - Create Read Update Delete)

php-mysql-aplicacion-web Desarrollo de una aplicación muy sencilla, desarrollada con HTML - Bootstrap - PHP - (PDO)- Mysql. (Login - Registro - Create

Ángel Daniel Fuentes Segura 4 Sep 18, 2022
Create a PHP 8 CRUD (Create, Read, Update, Delete) RESTful API with an MySQL database.

Créer une API RESTful PHP 8 CRUD (Create, Read, Update , Delete) simple avec MySQL et PDO (PHP Data Objects) Détails du référentiel : Lire, insérer, m

HOUESSOU Béryl 5 Oct 10, 2022
Das AddOn stellt den Lottie-Player für das Abspielen von Lottie-Animationen im .json-Format zur Verfügung.

REDAXO-AddOn: Lottie Das AddOn stellt den Lottie-Player für das Abspielen von Lottie-Animationen im .json-Format zur Verfügung. Das AddOn ermöglicht i

Friends Of REDAXO 17 Sep 9, 2022
Library JGU is a website created for a university library system information. Made with PHP & TailwindCSS.

Library JGU Library JGU is a website created for a university library system information. Made with PHP & TailwindCSS. Key Features • How To Use • Rel

Azkazikna Ageung Laksana 23 Oct 7, 2022
Laravel-Library-Management-system is nice to management library system...

About Laravel Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experie

Eng Hasan Hajjar 2 Sep 30, 2022
A simple wrapper for PHP Intervention Library to provide a more simple interface and convenient way to convert images to webp

This package is a simple wrapper for PHP Intervention Library to provide a more simple interface and convenient way to convert images to webp - next generation format - extension, and resize them to render only needed sizes.

eyad hamza 18 Jun 28, 2022
A simple PHP library for complex monetary prices management

PHP Prices ?? Version 2.x This new major version is shifting the package towards more flexibility and configuration possibilities in general. One of t

Whitecube 134 Dec 16, 2022
An automated library management system developed in Laravel 4.2 PHP MVC Framework

An automated system to manage a public library. Admin panel for librarians to control and manage the system easily through an interactive interface.

Prabhakar Gupta 244 Dec 27, 2022
Eden PHP library

Eden PHP Library ##Designed for rapid prototyping, with less code. Eden is purely a library packed with core concepts and web services. You can use Ed

Sterling Openovate Corporation 402 Dec 27, 2022
The classic email sending library for PHP - this is my personal fork, please post issues on the upstream project

PHPMailer - A full-featured email creation and transfer class for PHP Build status: Class Features Probably the world's most popular code for sending

Marcus Bointon 1.5k Dec 5, 2022
QuidPHP/Core is a PHP library that provides an extendable platform to create dynamic applications

QuidPHP/Core About QuidPHP/Core is a PHP library that provides an extendable platform to create dynamic applications. It is part of the QuidPHP packag

QuidPHP 4 Jul 2, 2022