.gitignore 0000666 00000000023 13112056273 0006533 0 ustar 00 artifacts/
vendor/
.scrutinizer.yml 0000666 00000000073 13112056273 0007732 0 ustar 00 imports:
- php
tools:
external_code_coverage: true
.travis.yml 0000666 00000001451 13112056273 0006662 0 ustar 00 language: php
php:
- 5.6
- 7.0
- 7.1
- nightly
env:
global:
- PHPUNIT_BIN='vendor/bin/phpunit'
- PHPUNIT_CONFIG='phpunit.xml.dist'
- PHPUNIT_FLAGS='--stop-on-failure --verbose'
matrix:
include:
- php: '5.6'
env:
- PHPUNIT_FLAGS="--stop-on-failure --verbose --coverage-text --coverage-clover=coverage.xml"
allow_failures:
- php: nightly
before_script:
- composer config --global repo.packagist composer https://packagist.org
- composer install
script : $PHPUNIT_BIN -c $PHPUNIT_CONFIG $PHPUNIT_FLAGS
after_script:
- |
if [ -f "coverage.xml" ]; then
echo 'sending clover to Scrutinizer'
wget https://scrutinizer-ci.com/ocular.phar
php ocular.phar code-coverage:upload --format=php-clover coverage.xml
echo 'done'
fi
CHANGELOG.md 0000666 00000003206 13112056273 0006362 0 ustar 00 CHANGELOG
=========
0.8.0 (2015-04-25)
-------------------
* RuleSet's default rule can be set
* Atom and RSS enclosures support
0.7.0 (2015-04-21)
-------------------
* RSS/RDF Format support
0.6.0 (2015-04-15)
-------------------
* OptionalField is replaced by Element
* item supports multiple elements of same names
* Element supports multiple attributes
* Fixer system to repair feeds after parsing -(like missing date)
0.5.2 (2015-04-01)
-------------------
* alias system to fetch same data from different nodes (like lastBuildDate and lastPubDate in RSS)
* lastBuildDate is now an alias of lastPubDate in RSS standard
0.5.1 (2015-03-23)
-------------------
* atom specifications : "content" node instead of "description"
0.5.0 (2015-02-23)
------------------
* FeedIo main class
0.4.0 (2015-01-25)
------------------
* Guzzle Client
0.3.1 (2015-01-18)
------------------
* updated the Changelog
0.3.0 (2014-12-13)
------------------
* Removed ParserAbstract, Parser/Rss Parser/Atom
* Added Parser class. This class parses a Feed using a Standard
* Added StandardAbstract
* Added Standard/Atom
* Added Standard/Rss
* Added Formatter class. This class formats a Feed using a Standard
0.2.0 (2014-11-23)
------------------
* added ClientInterface to handle HTTP queries
* added ParserAbstract
* added Parser/Rss
* added Parser/atom
* Feed now extends Item
0.1.0 (2014-09-06)
------------------
* added FeedInterface to represent a Feed which is the whole RSS/Atom document
* added NodeInterface to represent a Node which contains basic attributes of the whole document or an item
* added ItemInterface to represent an Item
* project structure
LICENSE 0000666 00000002065 13112056273 0005560 0 ustar 00 The MIT License (MIT)
Copyright (c) 2014 alexdebril
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Makefile 0000666 00000000377 13112056273 0006217 0 ustar 00 all: clean coverage
test:
vendor/bin/phpunit
test-live-feeds:
vendor/bin/phpunit -c phpunit-feeds.xml
coverage:
vendor/bin/phpunit --coverage-html=artifacts/coverage
view-coverage:
open artifacts/coverage/index.html
clean:
rm -rf artifacts/*
README.md 0000666 00000012122 13112056273 0006025 0 ustar 00 # feed-io
[![SensioLabsInsight](https://insight.sensiolabs.com/projects/9cabcb4b-695e-43fa-8b83-a1f9ecefea88/big.png)](https://insight.sensiolabs.com/projects/9cabcb4b-695e-43fa-8b83-a1f9ecefea88)
[![Latest Stable Version](https://poser.pugx.org/debril/feed-io/v/stable.png)](https://packagist.org/packages/debril/feed-io)
[![Build Status](https://secure.travis-ci.org/alexdebril/feed-io.png?branch=master)](http://travis-ci.org/alexdebril/feed-io)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/alexdebril/feed-io/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/alexdebril/feed-io/?branch=master)
[![Code Coverage](https://scrutinizer-ci.com/g/alexdebril/feed-io/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/alexdebril/feed-io/?branch=master)
[![PHP Tested versions](https://php-eye.com/badge/debril/feed-io/tested.svg)](https://php-eye.com/package/debril/feed-io)
[![Dependency Status](https://www.versioneye.com/php/debril:feed-io/2.3.1/badge?style=flat-square)](https://www.versioneye.com/php/debril:feed-io/2.3.1)
[feed-io](https://github.com/alexdebril/feed-io) is a PHP library built to consume and serve RSS / Atom feeds. It features:
- Atom / RSS read and write support
- a Command line interface to read feeds
- 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
- PSR compliant logging
- Content filtering to fetch only the newest items
- Malformed feeds auto correction
- DateTime detection and conversion
- A generic HTTP ClientInterface
- Guzzle Client integration
Keep informed about new releases and incoming features : http://debril.org/category/feed-io
# Installation
Use Composer to add feed-io into your project's requirements :
```sh
composer require debril/feed-io
```
# Requirements
feed-io requires :
- php 5.6+
- psr/log 1.0
- guzzlehttp/guzzle 6.2+
it suggests :
- monolog/monolog 1.10+
Monolog is not the only library suitable to handle feed-io's logs, you can use any PSR/Log compliant library instead.
# Fetching the repository
Do this if you want to contribute (and you're welcome to do so):
```sh
git clone https://github.com/alexdebril/feed-io.git
cd feed-io/
composer install
```
# Unit Testing
You can run the unit test suites using the following command in the library's source directory:
```sh
make test
```
Usage
=====
## CLI
Let's suppose you installed feed-io using Composer, you can use its command line client to read feeds from your terminal :
```shell
./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 :
```shell
./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](https://github.com/alexdebril/feed-io/blob/master/src/FeedIo/FeedIo.php) :
```php
// create a simple FeedIo instance
$feedIo = \FeedIo\Factory::create()->getFeedIo();
// read a feed
$result = $feedIo->read($url);
// or read a feed since a certain date
$result = $feedIo->readSince($url, new \DateTime('-7 days'));
// get title
$feedTitle = $result->getFeed()->getTitle();
// iterate through items
foreach( $result->getFeed() as $item ) {
echo $item->getTitle();
}
```
## formatting an object into a XML stream
```php
// build the feed
$feed = new FeedIo\Feed;
$feed->setTitle('...');
// convert it into Atom
$dom = $feedIo->toAtom($feed);
// or ...
$dom = $feedIo->format($feed, 'atom');
```
## building a feed including medias
```php
// build the feed
$feed = new FeedIo\Feed;
$feed->setTitle('...');
$item = $feed->newItem();
// 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);
```
## activate logging
feed-io natively supports PSR-3 logging, you can activate it by choosing a 'builder' in the factory :
```php
$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
```php
// 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);
```
bin/feedio 0000666 00000002204 13112056273 0006474 0 ustar 00 #!/usr/bin/env php
setName('feed-io : the CLI feed reader');
$application->add(new \FeedIo\Command\ReadCommand());
$application->run();
} else {
main($argc, $argv);
exit;
}
/**
* This function is invoked if symfony/console is not installed
*/
function main($argc, $argv) {
if ( $argc < 2 ) {
echo 'feed-io version 2.4' . PHP_EOL;
echo 'Usage : ' . PHP_EOL;
echo "\t feed-io [url]" . PHP_EOL;
exit;
}
$feedIo = \FeedIo\Factory::create()->getFeedIo();
$feed = array_reverse(iterator_to_array($feedIo->read($argv[$argc-1])->getFeed()));
foreach( $feed as $i => $item ) {
echo "\033[32m{$item->getLastModified()->format(\DateTime::ATOM)} : \033[34m{$item->getTitle()}\033[0m";
echo strip_tags(nl2br($item->getDescription())) . PHP_EOL;
}
} composer.json 0000666 00000001714 13112056273 0007275 0 ustar 00 {
"name": "debril/feed-io",
"description": "PHP library built to consume and serve RSS / Atom feeds",
"keywords": ["rss", "atom", "feed", "news", "CLI", "client"],
"homepage": "http://debril.org/category/feed-io/",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "Alexandre Debril",
"email": "alex.debril@gmail.com"
}
],
"bin" : [
"bin/feedio"
],
"require": {
"php": ">=5.6.0",
"guzzlehttp/guzzle": "~6.2",
"psr/log": "~1.0"
},
"require-dev": {
"phpunit/phpunit": ">=5.5.0",
"monolog/monolog": "1.*"
},
"suggest": {
"monolog/monolog": "Allows to handle logs",
"symfony/console": "Allows to use the command line interface"
},
"autoload": {
"psr-4": {"FeedIo\\": "src/FeedIo"}
},
"config": {
"preferred-install": {
"*": "dist"
}
}
}
composer.lock 0000666 00000163750 13112056273 0007265 0 ustar 00 {
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "bb7b6c2e8f3b427fe533cfec4185460b",
"packages": [
{
"name": "guzzlehttp/guzzle",
"version": "6.2.3",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
"reference": "8d6c6cc55186db87b7dc5009827429ba4e9dc006"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/8d6c6cc55186db87b7dc5009827429ba4e9dc006",
"reference": "8d6c6cc55186db87b7dc5009827429ba4e9dc006",
"shasum": ""
},
"require": {
"guzzlehttp/promises": "^1.0",
"guzzlehttp/psr7": "^1.4",
"php": ">=5.5"
},
"require-dev": {
"ext-curl": "*",
"phpunit/phpunit": "^4.0",
"psr/log": "^1.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "6.2-dev"
}
},
"autoload": {
"files": [
"src/functions_include.php"
],
"psr-4": {
"GuzzleHttp\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
}
],
"description": "Guzzle is a PHP HTTP client library",
"homepage": "http://guzzlephp.org/",
"keywords": [
"client",
"curl",
"framework",
"http",
"http client",
"rest",
"web service"
],
"time": "2017-02-28T22:50:30+00:00"
},
{
"name": "guzzlehttp/promises",
"version": "v1.3.1",
"source": {
"type": "git",
"url": "https://github.com/guzzle/promises.git",
"reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646",
"reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646",
"shasum": ""
},
"require": {
"php": ">=5.5.0"
},
"require-dev": {
"phpunit/phpunit": "^4.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.4-dev"
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Promise\\": "src/"
},
"files": [
"src/functions_include.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
}
],
"description": "Guzzle promises library",
"keywords": [
"promise"
],
"time": "2016-12-20T10:07:11+00:00"
},
{
"name": "guzzlehttp/psr7",
"version": "1.4.1",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
"reference": "0d6c7ca039329247e4f0f8f8f6506810e8248855"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/0d6c7ca039329247e4f0f8f8f6506810e8248855",
"reference": "0d6c7ca039329247e4f0f8f8f6506810e8248855",
"shasum": ""
},
"require": {
"php": ">=5.4.0",
"psr/http-message": "~1.0"
},
"provide": {
"psr/http-message-implementation": "1.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.4-dev"
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Psr7\\": "src/"
},
"files": [
"src/functions_include.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
},
{
"name": "Tobias Schultze",
"homepage": "https://github.com/Tobion"
}
],
"description": "PSR-7 message implementation that also provides common utility methods",
"keywords": [
"http",
"message",
"request",
"response",
"stream",
"uri",
"url"
],
"time": "2017-02-27T10:51:17+00:00"
},
{
"name": "psr/http-message",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-message.git",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for HTTP messages",
"homepage": "https://github.com/php-fig/http-message",
"keywords": [
"http",
"http-message",
"psr",
"psr-7",
"request",
"response"
],
"time": "2016-08-06T14:39:51+00:00"
},
{
"name": "psr/log",
"version": "1.0.2",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
"reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Log\\": "Psr/Log/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for logging libraries",
"homepage": "https://github.com/php-fig/log",
"keywords": [
"log",
"psr",
"psr-3"
],
"time": "2016-10-10T12:19:37+00:00"
}
],
"packages-dev": [
{
"name": "doctrine/instantiator",
"version": "1.0.5",
"source": {
"type": "git",
"url": "https://github.com/doctrine/instantiator.git",
"reference": "8e884e78f9f0eb1329e445619e04456e64d8051d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d",
"reference": "8e884e78f9f0eb1329e445619e04456e64d8051d",
"shasum": ""
},
"require": {
"php": ">=5.3,<8.0-DEV"
},
"require-dev": {
"athletic/athletic": "~0.1.8",
"ext-pdo": "*",
"ext-phar": "*",
"phpunit/phpunit": "~4.0",
"squizlabs/php_codesniffer": "~2.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Marco Pivetta",
"email": "ocramius@gmail.com",
"homepage": "http://ocramius.github.com/"
}
],
"description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
"homepage": "https://github.com/doctrine/instantiator",
"keywords": [
"constructor",
"instantiate"
],
"time": "2015-06-14T21:17:01+00:00"
},
{
"name": "monolog/monolog",
"version": "1.22.0",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
"reference": "bad29cb8d18ab0315e6c477751418a82c850d558"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/bad29cb8d18ab0315e6c477751418a82c850d558",
"reference": "bad29cb8d18ab0315e6c477751418a82c850d558",
"shasum": ""
},
"require": {
"php": ">=5.3.0",
"psr/log": "~1.0"
},
"provide": {
"psr/log-implementation": "1.0.0"
},
"require-dev": {
"aws/aws-sdk-php": "^2.4.9 || ^3.0",
"doctrine/couchdb": "~1.0@dev",
"graylog2/gelf-php": "~1.0",
"jakub-onderka/php-parallel-lint": "0.9",
"php-amqplib/php-amqplib": "~2.4",
"php-console/php-console": "^3.1.3",
"phpunit/phpunit": "~4.5",
"phpunit/phpunit-mock-objects": "2.3.0",
"ruflin/elastica": ">=0.90 <3.0",
"sentry/sentry": "^0.13",
"swiftmailer/swiftmailer": "~5.3"
},
"suggest": {
"aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
"doctrine/couchdb": "Allow sending log messages to a CouchDB server",
"ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
"ext-mongo": "Allow sending log messages to a MongoDB server",
"graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
"mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver",
"php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
"php-console/php-console": "Allow sending log messages to Google Chrome",
"rollbar/rollbar": "Allow sending log messages to Rollbar",
"ruflin/elastica": "Allow sending log messages to an Elastic Search server",
"sentry/sentry": "Allow sending log messages to a Sentry server"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Monolog\\": "src/Monolog"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jordi Boggiano",
"email": "j.boggiano@seld.be",
"homepage": "http://seld.be"
}
],
"description": "Sends your logs to files, sockets, inboxes, databases and various web services",
"homepage": "http://github.com/Seldaek/monolog",
"keywords": [
"log",
"logging",
"psr-3"
],
"time": "2016-11-26T00:15:39+00:00"
},
{
"name": "myclabs/deep-copy",
"version": "1.6.0",
"source": {
"type": "git",
"url": "https://github.com/myclabs/DeepCopy.git",
"reference": "5a5a9fc8025a08d8919be87d6884d5a92520cefe"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/5a5a9fc8025a08d8919be87d6884d5a92520cefe",
"reference": "5a5a9fc8025a08d8919be87d6884d5a92520cefe",
"shasum": ""
},
"require": {
"php": ">=5.4.0"
},
"require-dev": {
"doctrine/collections": "1.*",
"phpunit/phpunit": "~4.1"
},
"type": "library",
"autoload": {
"psr-4": {
"DeepCopy\\": "src/DeepCopy/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Create deep copies (clones) of your objects",
"homepage": "https://github.com/myclabs/DeepCopy",
"keywords": [
"clone",
"copy",
"duplicate",
"object",
"object graph"
],
"time": "2017-01-26T22:05:40+00:00"
},
{
"name": "phpdocumentor/reflection-common",
"version": "1.0",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionCommon.git",
"reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
"reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
"shasum": ""
},
"require": {
"php": ">=5.5"
},
"require-dev": {
"phpunit/phpunit": "^4.6"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"phpDocumentor\\Reflection\\": [
"src"
]
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jaap van Otterdijk",
"email": "opensource@ijaap.nl"
}
],
"description": "Common reflection classes used by phpdocumentor to reflect the code structure",
"homepage": "http://www.phpdoc.org",
"keywords": [
"FQSEN",
"phpDocumentor",
"phpdoc",
"reflection",
"static analysis"
],
"time": "2015-12-27T11:43:31+00:00"
},
{
"name": "phpdocumentor/reflection-docblock",
"version": "3.1.1",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
"reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/8331b5efe816ae05461b7ca1e721c01b46bafb3e",
"reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e",
"shasum": ""
},
"require": {
"php": ">=5.5",
"phpdocumentor/reflection-common": "^1.0@dev",
"phpdocumentor/type-resolver": "^0.2.0",
"webmozart/assert": "^1.0"
},
"require-dev": {
"mockery/mockery": "^0.9.4",
"phpunit/phpunit": "^4.4"
},
"type": "library",
"autoload": {
"psr-4": {
"phpDocumentor\\Reflection\\": [
"src/"
]
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mike van Riel",
"email": "me@mikevanriel.com"
}
],
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
"time": "2016-09-30T07:12:33+00:00"
},
{
"name": "phpdocumentor/type-resolver",
"version": "0.2.1",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/TypeResolver.git",
"reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb",
"reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb",
"shasum": ""
},
"require": {
"php": ">=5.5",
"phpdocumentor/reflection-common": "^1.0"
},
"require-dev": {
"mockery/mockery": "^0.9.4",
"phpunit/phpunit": "^5.2||^4.8.24"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"phpDocumentor\\Reflection\\": [
"src/"
]
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mike van Riel",
"email": "me@mikevanriel.com"
}
],
"time": "2016-11-25T06:54:22+00:00"
},
{
"name": "phpspec/prophecy",
"version": "v1.6.2",
"source": {
"type": "git",
"url": "https://github.com/phpspec/prophecy.git",
"reference": "6c52c2722f8460122f96f86346600e1077ce22cb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/6c52c2722f8460122f96f86346600e1077ce22cb",
"reference": "6c52c2722f8460122f96f86346600e1077ce22cb",
"shasum": ""
},
"require": {
"doctrine/instantiator": "^1.0.2",
"php": "^5.3|^7.0",
"phpdocumentor/reflection-docblock": "^2.0|^3.0.2",
"sebastian/comparator": "^1.1",
"sebastian/recursion-context": "^1.0|^2.0"
},
"require-dev": {
"phpspec/phpspec": "^2.0",
"phpunit/phpunit": "^4.8 || ^5.6.5"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.6.x-dev"
}
},
"autoload": {
"psr-0": {
"Prophecy\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Konstantin Kudryashov",
"email": "ever.zet@gmail.com",
"homepage": "http://everzet.com"
},
{
"name": "Marcello Duarte",
"email": "marcello.duarte@gmail.com"
}
],
"description": "Highly opinionated mocking framework for PHP 5.3+",
"homepage": "https://github.com/phpspec/prophecy",
"keywords": [
"Double",
"Dummy",
"fake",
"mock",
"spy",
"stub"
],
"time": "2016-11-21T14:58:47+00:00"
},
{
"name": "phpunit/php-code-coverage",
"version": "4.0.7",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "09e2277d14ea467e5a984010f501343ef29ffc69"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/09e2277d14ea467e5a984010f501343ef29ffc69",
"reference": "09e2277d14ea467e5a984010f501343ef29ffc69",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-xmlwriter": "*",
"php": "^5.6 || ^7.0",
"phpunit/php-file-iterator": "^1.3",
"phpunit/php-text-template": "^1.2",
"phpunit/php-token-stream": "^1.4.2 || ^2.0",
"sebastian/code-unit-reverse-lookup": "^1.0",
"sebastian/environment": "^1.3.2 || ^2.0",
"sebastian/version": "^1.0 || ^2.0"
},
"require-dev": {
"ext-xdebug": "^2.1.4",
"phpunit/phpunit": "^5.7"
},
"suggest": {
"ext-xdebug": "^2.5.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.0.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"role": "lead"
}
],
"description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
"homepage": "https://github.com/sebastianbergmann/php-code-coverage",
"keywords": [
"coverage",
"testing",
"xunit"
],
"time": "2017-03-01T09:12:17+00:00"
},
{
"name": "phpunit/php-file-iterator",
"version": "1.4.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
"reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
"reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.4.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"role": "lead"
}
],
"description": "FilterIterator implementation that filters files based on a list of suffixes.",
"homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
"keywords": [
"filesystem",
"iterator"
],
"time": "2016-10-03T07:40:28+00:00"
},
{
"name": "phpunit/php-text-template",
"version": "1.2.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-text-template.git",
"reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
"reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de",
"role": "lead"
}
],
"description": "Simple template engine.",
"homepage": "https://github.com/sebastianbergmann/php-text-template/",
"keywords": [
"template"
],
"time": "2015-06-21T13:50:34+00:00"
},
{
"name": "phpunit/php-timer",
"version": "1.0.9",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-timer.git",
"reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
"reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
"shasum": ""
},
"require": {
"php": "^5.3.3 || ^7.0"
},
"require-dev": {
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"role": "lead"
}
],
"description": "Utility class for timing",
"homepage": "https://github.com/sebastianbergmann/php-timer/",
"keywords": [
"timer"
],
"time": "2017-02-26T11:10:40+00:00"
},
{
"name": "phpunit/php-token-stream",
"version": "1.4.11",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
"reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e03f8f67534427a787e21a385a67ec3ca6978ea7",
"reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7",
"shasum": ""
},
"require": {
"ext-tokenizer": "*",
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~4.2"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.4-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
}
],
"description": "Wrapper around PHP's tokenizer extension.",
"homepage": "https://github.com/sebastianbergmann/php-token-stream/",
"keywords": [
"tokenizer"
],
"time": "2017-02-27T10:12:30+00:00"
},
{
"name": "phpunit/phpunit",
"version": "5.7.14",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "4906b8faf23e42612182fd212eb6f4c0f2954b57"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/4906b8faf23e42612182fd212eb6f4c0f2954b57",
"reference": "4906b8faf23e42612182fd212eb6f4c0f2954b57",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-json": "*",
"ext-libxml": "*",
"ext-mbstring": "*",
"ext-xml": "*",
"myclabs/deep-copy": "~1.3",
"php": "^5.6 || ^7.0",
"phpspec/prophecy": "^1.6.2",
"phpunit/php-code-coverage": "^4.0.4",
"phpunit/php-file-iterator": "~1.4",
"phpunit/php-text-template": "~1.2",
"phpunit/php-timer": "^1.0.6",
"phpunit/phpunit-mock-objects": "^3.2",
"sebastian/comparator": "^1.2.4",
"sebastian/diff": "~1.2",
"sebastian/environment": "^1.3.4 || ^2.0",
"sebastian/exporter": "~2.0",
"sebastian/global-state": "^1.1",
"sebastian/object-enumerator": "~2.0",
"sebastian/resource-operations": "~1.0",
"sebastian/version": "~1.0.3|~2.0",
"symfony/yaml": "~2.1|~3.0"
},
"conflict": {
"phpdocumentor/reflection-docblock": "3.0.2"
},
"require-dev": {
"ext-pdo": "*"
},
"suggest": {
"ext-xdebug": "*",
"phpunit/php-invoker": "~1.1"
},
"bin": [
"phpunit"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.7.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de",
"role": "lead"
}
],
"description": "The PHP Unit Testing framework.",
"homepage": "https://phpunit.de/",
"keywords": [
"phpunit",
"testing",
"xunit"
],
"time": "2017-02-19T07:22:16+00:00"
},
{
"name": "phpunit/phpunit-mock-objects",
"version": "3.4.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
"reference": "3ab72b65b39b491e0c011e2e09bb2206c2aa8e24"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/3ab72b65b39b491e0c011e2e09bb2206c2aa8e24",
"reference": "3ab72b65b39b491e0c011e2e09bb2206c2aa8e24",
"shasum": ""
},
"require": {
"doctrine/instantiator": "^1.0.2",
"php": "^5.6 || ^7.0",
"phpunit/php-text-template": "^1.2",
"sebastian/exporter": "^1.2 || ^2.0"
},
"conflict": {
"phpunit/phpunit": "<5.4.0"
},
"require-dev": {
"phpunit/phpunit": "^5.4"
},
"suggest": {
"ext-soap": "*"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.2.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"role": "lead"
}
],
"description": "Mock Object library for PHPUnit",
"homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
"keywords": [
"mock",
"xunit"
],
"time": "2016-12-08T20:27:08+00:00"
},
{
"name": "sebastian/code-unit-reverse-lookup",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
"reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/c36f5e7cfce482fde5bf8d10d41a53591e0198fe",
"reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe",
"shasum": ""
},
"require": {
"php": ">=5.6"
},
"require-dev": {
"phpunit/phpunit": "~5"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
}
],
"description": "Looks up which function or method a line of code belongs to",
"homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
"time": "2016-02-13T06:45:14+00:00"
},
{
"name": "sebastian/comparator",
"version": "1.2.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git",
"reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
"reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"sebastian/diff": "~1.2",
"sebastian/exporter": "~1.2 || ~2.0"
},
"require-dev": {
"phpunit/phpunit": "~4.4"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.2.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Jeff Welch",
"email": "whatthejeff@gmail.com"
},
{
"name": "Volker Dusch",
"email": "github@wallbash.com"
},
{
"name": "Bernhard Schussek",
"email": "bschussek@2bepublished.at"
},
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
}
],
"description": "Provides the functionality to compare PHP values for equality",
"homepage": "http://www.github.com/sebastianbergmann/comparator",
"keywords": [
"comparator",
"compare",
"equality"
],
"time": "2017-01-29T09:50:25+00:00"
},
{
"name": "sebastian/diff",
"version": "1.4.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/diff.git",
"reference": "13edfd8706462032c2f52b4b862974dd46b71c9e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e",
"reference": "13edfd8706462032c2f52b4b862974dd46b71c9e",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~4.8"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.4-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Kore Nordmann",
"email": "mail@kore-nordmann.de"
},
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
}
],
"description": "Diff implementation",
"homepage": "https://github.com/sebastianbergmann/diff",
"keywords": [
"diff"
],
"time": "2015-12-08T07:14:41+00:00"
},
{
"name": "sebastian/environment",
"version": "2.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/environment.git",
"reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac",
"reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac",
"shasum": ""
},
"require": {
"php": "^5.6 || ^7.0"
},
"require-dev": {
"phpunit/phpunit": "^5.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
}
],
"description": "Provides functionality to handle HHVM/PHP environments",
"homepage": "http://www.github.com/sebastianbergmann/environment",
"keywords": [
"Xdebug",
"environment",
"hhvm"
],
"time": "2016-11-26T07:53:53+00:00"
},
{
"name": "sebastian/exporter",
"version": "2.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/exporter.git",
"reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4",
"reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"sebastian/recursion-context": "~2.0"
},
"require-dev": {
"ext-mbstring": "*",
"phpunit/phpunit": "~4.4"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Jeff Welch",
"email": "whatthejeff@gmail.com"
},
{
"name": "Volker Dusch",
"email": "github@wallbash.com"
},
{
"name": "Bernhard Schussek",
"email": "bschussek@2bepublished.at"
},
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
},
{
"name": "Adam Harvey",
"email": "aharvey@php.net"
}
],
"description": "Provides the functionality to export PHP variables for visualization",
"homepage": "http://www.github.com/sebastianbergmann/exporter",
"keywords": [
"export",
"exporter"
],
"time": "2016-11-19T08:54:04+00:00"
},
{
"name": "sebastian/global-state",
"version": "1.1.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/global-state.git",
"reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4",
"reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~4.2"
},
"suggest": {
"ext-uopz": "*"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
}
],
"description": "Snapshotting of global state",
"homepage": "http://www.github.com/sebastianbergmann/global-state",
"keywords": [
"global state"
],
"time": "2015-10-12T03:26:01+00:00"
},
{
"name": "sebastian/object-enumerator",
"version": "2.0.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/object-enumerator.git",
"reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1311872ac850040a79c3c058bea3e22d0f09cbb7",
"reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7",
"shasum": ""
},
"require": {
"php": ">=5.6",
"sebastian/recursion-context": "~2.0"
},
"require-dev": {
"phpunit/phpunit": "~5"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
}
],
"description": "Traverses array structures and object graphs to enumerate all referenced objects",
"homepage": "https://github.com/sebastianbergmann/object-enumerator/",
"time": "2017-02-18T15:18:39+00:00"
},
{
"name": "sebastian/recursion-context",
"version": "2.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/recursion-context.git",
"reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a",
"reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~4.4"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Jeff Welch",
"email": "whatthejeff@gmail.com"
},
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
},
{
"name": "Adam Harvey",
"email": "aharvey@php.net"
}
],
"description": "Provides functionality to recursively process PHP variables",
"homepage": "http://www.github.com/sebastianbergmann/recursion-context",
"time": "2016-11-19T07:33:16+00:00"
},
{
"name": "sebastian/resource-operations",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/resource-operations.git",
"reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
"reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
"shasum": ""
},
"require": {
"php": ">=5.6.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
}
],
"description": "Provides a list of PHP built-in functions that operate on resources",
"homepage": "https://www.github.com/sebastianbergmann/resource-operations",
"time": "2015-07-28T20:34:47+00:00"
},
{
"name": "sebastian/version",
"version": "2.0.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/version.git",
"reference": "99732be0ddb3361e16ad77b68ba41efc8e979019"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019",
"reference": "99732be0ddb3361e16ad77b68ba41efc8e979019",
"shasum": ""
},
"require": {
"php": ">=5.6"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de",
"role": "lead"
}
],
"description": "Library that helps with managing the version number of Git-hosted PHP projects",
"homepage": "https://github.com/sebastianbergmann/version",
"time": "2016-10-03T07:35:21+00:00"
},
{
"name": "symfony/yaml",
"version": "v3.2.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "9724c684646fcb5387d579b4bfaa63ee0b0c64c8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/9724c684646fcb5387d579b4bfaa63ee0b0c64c8",
"reference": "9724c684646fcb5387d579b4bfaa63ee0b0c64c8",
"shasum": ""
},
"require": {
"php": ">=5.5.9"
},
"require-dev": {
"symfony/console": "~2.8|~3.0"
},
"suggest": {
"symfony/console": "For validating YAML files using the lint command"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.2-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\Yaml\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
"time": "2017-02-16T22:46:52+00:00"
},
{
"name": "webmozart/assert",
"version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/webmozart/assert.git",
"reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f",
"reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f",
"shasum": ""
},
"require": {
"php": "^5.3.3 || ^7.0"
},
"require-dev": {
"phpunit/phpunit": "^4.6",
"sebastian/version": "^1.0.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.3-dev"
}
},
"autoload": {
"psr-4": {
"Webmozart\\Assert\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Bernhard Schussek",
"email": "bschussek@gmail.com"
}
],
"description": "Assertions to validate method input/output with nice error messages.",
"keywords": [
"assert",
"check",
"validate"
],
"time": "2016-11-23T20:04:58+00:00"
}
],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": ">=5.6.0"
},
"platform-dev": []
}
doc/specifications-support.md 0000666 00000004032 13112056273 0012353 0 ustar 00 # synopsis
This document explains which attributes are supported by feed-io and how to access them
## top level document : feed (atom) / channel (rss)
interface : FeedInterface
| atom | rss | getter | setter
| title | title | getTitle | setTitle
| link | link | getLink | setLink
| updated | pubDate / lastBuildDate | getLastModified | setLastModified
| id | N/A | getPublicId | setPublicId
| N/A | description | getDescription | setDescription
| category | category | not supported | not supported
| author | N/A | not supported | not supported
| contributor | N/A | not supported | not supported
| icon / logo | image | not supported | not supported
| rights | copyright | not supported | not supported
| subtitle | N/A | not supported | not supported
| lang | language | not supported | not supported
| base | N/A | not supported | not supported
| generator | generator | not supported | not supported
| N/A | managingEditor | not supported | not supported
| N/A | webMaster | not supported | not supported
| N/A | docs | not supported | not supported
| N/A | cloud | not supported | not supported
| N/A | ttl | not supported | not supported
| N/A | rating | not supported | not supported
| N/A | textInput | not supported | not supported
| N/A | skipdays | not supported | not supported
| N/A | skipHours | not supported | not supported
## entry (atom) / item (rss)
Interface : ItemInterface
| atom | rss | getter | setter
| title | title | getTitle | setTitle
| link | link | getLink | setLink
| link | enclosure | getMedias | addMedia
| updated / published | pubDate | getLastModified | setLastModified
| id | guid | getPublicId | setPublicId
| content | description | getDescription | setDescription
| summary | N/A | not supported | not supported
| source | source | not supported | not supported
| category | category | not supported | not supported
| author | N/A | not supported | not supported
| contributor | N/A | not supported | not supported
| N/A | comments | not supported | not supported
| rights | N/A | not supported | not supported
examples/bootstrap.php 0000666 00000000511 13112056273 0011111 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
$loader = require __DIR__."/../vendor/autoload.php";
date_default_timezone_set('UTC');
examples/factory.php 0000666 00000001556 13112056273 0010555 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
require __DIR__.DIRECTORY_SEPARATOR.'bootstrap.php';
$feedIo = \FeedIo\Factory::create()->getFeedIo();
$result = $feedIo->read('http://php.net/feed.atom');
echo "feed title : {$result->getFeed()->getTitle()} \n ";
foreach ($result->getFeed() as $item) {
echo "item title : {$item->getTitle()} \n ";
// let's turn php.net into a PodCast
$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);
}
$domDocument = $feedIo->toAtom($result->getFeed());
echo $domDocument->saveXML();
examples/feedio.php 0000666 00000001731 13112056273 0010334 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
require __DIR__.DIRECTORY_SEPARATOR.'bootstrap.php';
$client = new \FeedIo\Adapter\Guzzle\Client(new GuzzleHttp\Client());
$logger = new \Psr\Log\NullLogger();
$feedIo = new \FeedIo\FeedIo($client, $logger);
$result = $feedIo->read('http://php.net/feed.atom');
echo "feed title : {$result->getFeed()->getTitle()} \n ";
foreach ($result->getFeed() as $item) {
echo "item title : {$item->getTitle()} \n ";
// let's turn php.net into a PodCast
$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);
}
$domDocument = $feedIo->toAtom($result->getFeed());
echo $domDocument->saveXML();
examples/guzzle-client.php 0000666 00000000731 13112056273 0011674 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
require __DIR__.DIRECTORY_SEPARATOR.'bootstrap.php';
$client = new \FeedIo\Adapter\Guzzle\Client(new GuzzleHttp\Client());
$response = $client->getResponse('http://php.net/feed.atom', new \DateTime());
echo $response->getBody();
examples/media.php 0000666 00000001505 13112056273 0010157 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
require __DIR__.DIRECTORY_SEPARATOR.'bootstrap.php';
$feed = new \FeedIo\Feed();
// ask for a new Item
$item = $feed->newItem();
// 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);
// add the item to the feed
$feed->add($item);
$client = new \FeedIo\Adapter\NullClient();
$logger = new \Psr\Log\NullLogger();
$feedIo = new \FeedIo\FeedIo($client, $logger);
$domDocument = $feedIo->toAtom($result->getFeed());
echo $domDocument->saveXML();
examples/modifiedSince.php 0000666 00000001374 13112056273 0011646 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
require __DIR__.DIRECTORY_SEPARATOR.'bootstrap.php';
$client = new \FeedIo\Adapter\Guzzle\Client(new GuzzleHttp\Client());
$logger = new \Psr\Log\NullLogger();
$feedIo = new \FeedIo\FeedIo($client, $logger);
$result = $feedIo->readSince('http://php.net/feed.atom', new \DateTime('-1 month'));
echo "feed title : {$result->getFeed()->getTitle()} \n ";
$newItems = $result->getFeed();
foreach($newItems as $value) {
echo $value->getTitle() . ' : ' . $value->getLastModified()->format(\DateTime::ATOM) . PHP_EOL;
}
examples/parse-rss.php 0000666 00000002552 13112056273 0011022 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
require __DIR__.DIRECTORY_SEPARATOR.'bootstrap.php';
// new DateTimeBuilder : it will be used by the parser to convert formatted dates into DateTime instances
$dateTimeBuilder = new \FeedIo\Rule\DateTimeBuilder();
// new Standard\\Rss : it will provide all standard specific rules to the parser
$standard = new \FeedIo\Standard\Rss($dateTimeBuilder);
// new Parser: it will turn a RSS stream into a Feed instance, using the rules provided by the Standard
// the Logger must implement the PSR3 logging standard
$parser = new \FeedIo\Parser($standard, new \Psr\Log\NullLogger());
// the file is sample-rss.xml
$file = dirname(__FILE__)."/../tests/samples/rss/sample-rss.xml";
// we load it using the Dom library
$document = new DOMDocument();
$document->load($file, LIBXML_NOBLANKS | LIBXML_COMPACT);
// Now let's parse it
// The second argument must implement FeedInterface
$feed = $parser->parse($document, new \FeedIo\Feed());
// $feed is now ready
echo "feed's title : {$feed->getTitle()} \n";
// FeedInterface extends \Iterator, we can iterate through it
foreach ($feed as $item) {
echo "item's title : {$item->getTitle()} \n";
}
examples/rich-feed.php 0000666 00000001612 13112056273 0010725 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
require __DIR__.DIRECTORY_SEPARATOR.'bootstrap.php';
$feedIo = \FeedIo\Factory::create()->getFeedIo();
$result = $feedIo->read('https://debril.org/feed/');
echo "feed title : {$result->getFeed()->getTitle()} \n ";
foreach ($result->getFeed() as $item) {
echo "item title : {$item->getTitle()} \n ";
foreach ($item->getAllElements() as $element) {
echo "element name : " . $element->getName() . PHP_EOL;
foreach( $element->getAllElements() as $subElement) {
echo "sub element name : " . $subElement->getName() . PHP_EOL;
echo "sub element value : " . $subElement->getValue() . PHP_EOL;
}
}
}
phpunit-feeds.xml 0000666 00000000615 13112056273 0010047 0 ustar 00
tests/live-feeds/src/FeedIo/
phpunit.xml.dist 0000666 00000000604 13112056273 0007723 0 ustar 00
tests/FeedIo/src/FeedIo/
src/FeedIo/Adapter/ClientInterface.php 0000666 00000001461 13112056273 0013624 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Adapter;
/**
* Describes a HTTP Client used by \FeedIo\Reader
*
* getResponse() MUST return an instance of \FeedIo\Adapter\ResponseInterface or throw an exception
*
*/
interface ClientInterface
{
/**
* @param string $url
* @param \DateTime $modifiedSince
* @throws \FeedIo\Adapter\NotFoundException
* @throws \FeedIo\Adapter\ServerErrorException
* @return \FeedIo\Adapter\ResponseInterface
*/
public function getResponse($url, \DateTime $modifiedSince);
}
src/FeedIo/Adapter/FileSystem/Client.php 0000666 00000001714 13112056273 0014070 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Adapter\FileSystem;
use FeedIo\Adapter\ClientInterface;
use FeedIo\Adapter\NotFoundException;
/**
* Filesystem client
*/
class Client implements ClientInterface
{
/**
* @param string $path
* @param \DateTime $modifiedSince
* @throws \FeedIo\Adapter\NotFoundException
* @return \FeedIo\Adapter\ResponseInterface
*/
public function getResponse($path, \DateTime $modifiedSince)
{
if (file_exists($path)) {
return new Response(
file_get_contents($path),
new \DateTime('@'.filemtime($path))
);
}
throw new NotFoundException($path);
}
}
src/FeedIo/Adapter/FileSystem/Response.php 0000666 00000002352 13112056273 0014447 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Adapter\FileSystem;
use FeedIo\Adapter\ResponseInterface;
/**
*
*/
class Response implements ResponseInterface
{
/**
* @var string
*/
protected $fileContent;
/**
* @var \DateTime
*/
protected $lastModified;
/**
* @param string $fileContent
* @param \DateTime $lastModified
*/
public function __construct($fileContent, \DateTime $lastModified)
{
$this->fileContent = $fileContent;
$this->lastModified = $lastModified;
}
/**
* @return string
*/
public function getBody()
{
return $this->fileContent;
}
/**
* @return array
*/
public function getHeaders()
{
return array();
}
/**
* @param string $name
* @return string
*/
public function getHeader($name)
{
return '';
}
/**
* @return \DateTime
*/
public function getLastModified()
{
return $this->lastModified;
}
}
src/FeedIo/Adapter/Guzzle/Client.php 0000666 00000003064 13112056273 0013264 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Adapter\Guzzle;
use FeedIo\Adapter\ClientInterface;
use FeedIo\Adapter\NotFoundException;
use FeedIo\Adapter\ServerErrorException;
use GuzzleHttp\Exception\BadResponseException;
/**
* Guzzle dependent HTTP client
*/
class Client implements ClientInterface
{
/**
* @var \GuzzleHttp\ClientInterface
*/
protected $guzzleClient;
/**
* @param \GuzzleHttp\ClientInterface $guzzleClient
*/
public function __construct(\GuzzleHttp\ClientInterface $guzzleClient)
{
$this->guzzleClient = $guzzleClient;
}
/**
* @param string $url
* @param \DateTime $modifiedSince
* @throws \FeedIo\Adapter\NotFoundException
* @throws \FeedIo\Adapter\ServerErrorException
* @return \FeedIo\Adapter\ResponseInterface
*/
public function getResponse($url, \DateTime $modifiedSince)
{
try {
return new Response($this->guzzleClient->request('get', $url));
} catch (BadResponseException $e) {
switch ((int) $e->getResponse()->getStatusCode()) {
case 404:
throw new NotFoundException($e->getMessage());
default:
throw new ServerErrorException($e->getMessage());
}
}
}
}
src/FeedIo/Adapter/Guzzle/Response.php 0000666 00000003161 13112056273 0013642 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Adapter\Guzzle;
use FeedIo\Adapter\ResponseInterface;
use Psr\Http\Message\ResponseInterface as PsrResponseInterface;
/**
* Guzzle dependent HTTP Response
*/
class Response implements ResponseInterface
{
const HTTP_LAST_MODIFIED = 'Last-Modified';
/**
* @var \Psr\Http\Message\ResponseInterface
*/
protected $psrResponse;
/**
* @param \Psr\Http\Message\ResponseInterface
*/
public function __construct(PsrResponseInterface $psrResponse)
{
$this->psrResponse = $psrResponse;
}
/**
* @return \Psr\Http\Message\StreamInterface
*/
public function getBody()
{
return $this->psrResponse->getBody();
}
/**
* @return \DateTime|null
*/
public function getLastModified()
{
if ($this->psrResponse->hasHeader(static::HTTP_LAST_MODIFIED)) {
$lastModified = \DateTime::createFromFormat(\DateTime::RFC2822, $this->getHeader(static::HTTP_LAST_MODIFIED));
return false === $lastModified ? null : $lastModified;
}
return;
}
/**
* @return array
*/
public function getHeaders()
{
return $this->psrResponse->getHeaders();
}
/**
* @param string $name
* @return string[]
*/
public function getHeader($name)
{
return $this->psrResponse->getHeader($name);
}
}
src/FeedIo/Adapter/NotFoundException.php 0000666 00000000534 13112056273 0014200 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Adapter;
use FeedIo\FeedIoException;
class NotFoundException extends FeedIoException
{
}
src/FeedIo/Adapter/NullClient.php 0000666 00000001176 13112056273 0012641 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Adapter;
/**
* Fake HTTP client
*/
class NullClient implements ClientInterface
{
/**
* @param string $url
* @param \DateTime $modifiedSince
* @return \FeedIo\Adapter\ResponseInterface
*/
public function getResponse($url, \DateTime $modifiedSince)
{
return new NullResponse();
}
}
src/FeedIo/Adapter/NullResponse.php 0000666 00000001477 13112056273 0013225 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Adapter;
/**
* Null HTTP Response
*/
class NullResponse implements ResponseInterface
{
/**
* @return string
*/
public function getBody()
{
return;
}
/**
* @return \DateTime
*/
public function getLastModified()
{
return new \DateTime('@0');
}
/**
* @return array
*/
public function getHeaders()
{
return array();
}
/**
* @param string $name
* @return array|string
*/
public function getHeader($name)
{
return $name;
}
}
src/FeedIo/Adapter/ResponseInterface.php 0000666 00000001311 13112056273 0014176 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Adapter;
/**
* Describes a HTTP Response as returned by an instance of ClientInterface
*
*/
interface ResponseInterface
{
/**
* @return string
*/
public function getBody();
/**
* @return \DateTime
*/
public function getLastModified();
/**
* @return array
*/
public function getHeaders();
/**
* @param string $name
* @return string
*/
public function getHeader($name);
}
src/FeedIo/Adapter/ServerErrorException.php 0000666 00000000537 13112056273 0014727 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Adapter;
use FeedIo\FeedIoException;
class ServerErrorException extends FeedIoException
{
}
src/FeedIo/Command/ReadCommand.php 0000666 00000003746 13112056273 0012745 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Command;
use FeedIo\Factory;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class ReadCommand extends Command
{
protected function configure()
{
$this->setName('read')
->setDescription('reads a feed')
->addArgument(
'url',
InputArgument::REQUIRED,
'Please provide the feed\' URL'
)
->addOption('count', 'c', InputOption::VALUE_OPTIONAL)
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$url = $input->getArgument('url');
$feed = $this->readFeed($url);
$output->writeln("{$feed->getTitle()}");
$limit = $this->getLimit($input);
foreach( $feed as $i => $item ) {
$output->writeln("{$item->getLastModified()->format(\DateTime::ATOM)} : {$item->getTitle()}");
$output->writeln("{$item->getDescription()}");
if ( ! is_null($limit) && $limit === $i+1 )
break;
}
}
/**
* @param string $url
* @return \FeedIo\FeedInterface
*/
public function readFeed($url)
{
$feedIo = Factory::create()->getFeedIo();
return $feedIo->read($url)->getFeed();
}
/**
* @param InputInterface $input
* @return int|null
*/
public function getLimit(InputInterface $input)
{
if ( $input->hasOption('count') ) {
return intval($input->getOption('count'));
}
return null;
}
}
src/FeedIo/DateRuleAbstract.php 0000666 00000002526 13112056273 0012401 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo;
use FeedIo\Rule\DateTimeBuilder;
abstract class DateRuleAbstract extends RuleAbstract
{
/**
* @var \FeedIo\Rule\DateTimeBuilder
*/
protected $dateTimeBuilder = null;
/**
* @var string
*/
protected $defaultFormat = \DateTime::RSS;
/**
* @param \FeedIo\Rule\DateTimeBuilder $dateTimeBuilder
* @return $this
*/
public function setDateTimeBuilder(DateTimeBuilder $dateTimeBuilder)
{
$this->dateTimeBuilder = $dateTimeBuilder;
return $this;
}
/**
* @return DateTimeBuilder
*/
public function getDateTimeBuilder()
{
if (is_null($this->dateTimeBuilder)) {
throw new \UnexpectedValueException('date time builder should not be null');
}
return $this->dateTimeBuilder;
}
/**
* @return string
*/
public function getDefaultFormat()
{
return $this->defaultFormat;
}
/**
* @param string $defaultFormat
*/
public function setDefaultFormat($defaultFormat)
{
$this->defaultFormat = $defaultFormat;
}
}
src/FeedIo/Factory.php 0000666 00000006131 13112056273 0010613 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo;
use FeedIo\Factory\MissingDependencyException;
use FeedIo\Factory\LoggerBuilderInterface;
use FeedIo\Factory\ClientBuilderInterface;
use FeedIo\Factory\BuilderInterface;
class Factory
{
/**
* @var \Psr\Log\LoggerInterface
*/
protected $logger;
/**
* @var \FeedIo\Adapter\ClientInterface
*/
protected $client;
/**
* @var \FeedIo\Factory\ClientBuilderInterface
*/
protected $clientBuilder;
/**
* @var \FeedIo\Factory\LoggerBuilderInterface
*/
protected $loggerBuilder;
static public function create(
array $loggerConfig = [
'builder' => 'NullLogger',
'config' => [],
],
array $clientConfig = [
'builder' => 'GuzzleClient',
'config' => [],
]
)
{
$factory = new static();
$factory->setClientBuilder(
$factory->getBuilder($clientConfig['builder'], $factory->extractConfig($clientConfig)))
->setLoggerBuilder(
$factory->getBuilder($loggerConfig['builder'],$factory->extractConfig($loggerConfig)));
return $factory;
}
/**
* @param $builderConfig
* @return array
*/
public function extractConfig(array $builderConfig)
{
return isset($builderConfig['config']) ? $builderConfig['config']:[];
}
/**
* @return \FeedIo\FeedIo
*/
public function getFeedIo()
{
return new FeedIo(
$this->clientBuilder->getClient(),
$this->loggerBuilder->getLogger()
);
}
public function getBuilder($builder, array $args = [])
{
$class = "\\FeedIo\\Factory\\Builder\\{$builder}Builder";
if ( ! class_exists($class) ) {
$class = $builder;
}
$reflection = new \ReflectionClass($class);
return $reflection->newInstanceArgs($args);
}
public function setLoggerBuilder(LoggerBuilderInterface $loggerBuilder)
{
$this->loggerBuilder = $loggerBuilder;
return $this;
}
public function setClientBuilder(ClientBuilderInterface $clientBuilder)
{
$this->clientBuilder = $clientBuilder;
return $this;
}
/**
* @param BuilderInterface $builder
* @return boolean true if the dependency is met
*/
public function checkDependency(BuilderInterface $builder)
{
if ( ! class_exists($builder->getMainClassName()) ) {
$message = "missing {$builder->getPackageName()}, please install it using composer : composer require {$builder->getPackageName()}";
throw new MissingDependencyException($message);
}
return true;
}
}
src/FeedIo/Factory/Builder/GuzzleClientBuilder.php 0000666 00000002103 13112056273 0016122 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Factory\Builder;
use FeedIo\Factory\ClientBuilderInterface;
use \FeedIo\Adapter\Guzzle\Client;
use \GuzzleHttp\Client as GuzzleClient;
/**
* @package FeedIo
*/
class GuzzleClientBuilder implements ClientBuilderInterface
{
/**
* This method MUST return a \FeedIo\Adapter\ClientInterface instance
* @return \FeedIo\Adapter\ClientInterface
*/
public function getClient()
{
return new Client(new GuzzleClient);
}
/**
* This method MUST return the name of the main class
* @return string
*/
public function getMainClassName()
{
return '\GuzzleHttp\Client';
}
/**
* This method MUST return the name of the package name
* @return string
*/
public function getPackageName()
{
return 'guzzlehttp/guzzle';
}
}
src/FeedIo/Factory/Builder/MonologBuilder.php 0000666 00000004246 13112056273 0015127 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Factory\Builder;
use FeedIo\Factory\LoggerBuilderInterface;
use Monolog\Logger;
/**
* @package FeedIo
*/
class MonologBuilder implements LoggerBuilderInterface
{
protected $loggerName = 'feed-io';
protected $handlersConfig = [
[
'class' => 'Monolog\Handler\StreamHandler',
'params' => ['php://stdout', Logger::DEBUG],
],
];
/**
* @param array $config
*/
public function __construct(array $config = [])
{
$this->loggerName = isset($config['name']) ? $config['name']:$this->loggerName;
$this->handlersConfig = isset($config['handlers']) ? $config['handlers']:$this->handlersConfig;
}
/**
* This method MUST return a valid PSR3 logger
* @return \Monolog\Logger
*/
public function getLogger()
{
$logger = new Logger($this->loggerName);
foreach ( $this->handlersConfig as $config ) {
$handler = $this->newHandler($config['class'], $config['params']);
$logger->pushHandler($handler);
}
return $logger;
}
/**
* @param string $class
* @param array $params
* @return Monolog\Handler\HandlerInterface
*/
public function newHandler($class, array $params = [])
{
$reflection = new \ReflectionClass($class);
if ( ! $reflection->implementsInterface('Monolog\Handler\HandlerInterface') ) {
throw new \InvalidArgumentException();
}
return $reflection->newInstanceArgs($params);
}
/**
* This method MUST return the name of the main class
* @return string
*/
public function getMainClassName()
{
return 'Monolog\Logger';
}
/**
* This method MUST return the name of the package name
* @return string
*/
public function getPackageName()
{
return 'monolog/monolog';
}
}
src/FeedIo/Factory/Builder/NullLoggerBuilder.php 0000666 00000001736 13112056273 0015570 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Factory\Builder;
use FeedIo\Factory\LoggerBuilderInterface;
use \Psr\Log\NullLogger;
/**
* @package FeedIo
*/
class NullLoggerBuilder implements LoggerBuilderInterface
{
/**
* This method MUST return a valid PSR3 logger
* @return \Psr\Log\NullLogger
*/
public function getLogger()
{
return new \Psr\Log\NullLogger;
}
/**
* This method MUST return the name of the main class
* @return string
*/
public function getMainClassName()
{
return '\Psr\Log\NullLogger';
}
/**
* This method MUST return the name of the package name
* @return string
*/
public function getPackageName()
{
return 'psr/log';
}
}
src/FeedIo/Factory/BuilderInterface.php 0000666 00000001134 13112056273 0014020 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Factory;
/**
* @package FeedIo
*/
interface BuilderInterface
{
/**
* This method MUST return the name of the main class
* @return string
*/
public function getMainClassName();
/**
* This method MUST return the name of the package name
* @return string
*/
public function getPackageName();
}
src/FeedIo/Factory/ClientBuilderInterface.php 0000666 00000001020 13112056273 0015151 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Factory;
/**
* @package FeedIo
*/
interface ClientBuilderInterface extends BuilderInterface
{
/**
* This method MUST return a \FeedIo\Adapter\ClientInterface instance
* @return \FeedIo\Adapter\ClientInterface
*/
public function getClient();
}
src/FeedIo/Factory/LoggerBuilderInterface.php 0000666 00000000762 13112056273 0015166 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Factory;
/**
* @package FeedIo
*/
interface LoggerBuilderInterface extends BuilderInterface
{
/**
* This method MUST return a valid PSR3 logger
* @return \Psr\Log\LoggerInterface
*/
public function getLogger();
}
src/FeedIo/Factory/MissingDependencyException.php 0000666 00000000545 13112056273 0016105 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Factory;
use FeedIo\FeedIoException;
class MissingDependencyException extends FeedIoException
{
}
src/FeedIo/Feed.php 0000666 00000006126 13112056273 0010053 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo;
use FeedIo\Feed\Node;
use FeedIo\Feed\Item;
use FeedIo\Feed\ItemInterface;
class Feed extends Node implements FeedInterface, \JsonSerializable
{
/**
* @var \ArrayIterator
*/
protected $items;
/**
* @var string $url
*/
protected $url;
public function __construct()
{
$this->items = new \ArrayIterator();
parent::__construct();
}
/**
* @return string $url
*/
public function getUrl()
{
return $this->url;
}
/**
* @param string $url
* @return FeedInterface
*/
public function setUrl($url)
{
$this->url = $url;
return $this;
}
/**
* (PHP 5 >= 5.0.0)
* Return the current element
* @link http://php.net/manual/en/iterator.current.php
* @return mixed Can return any type.
*/
public function current()
{
return $this->items->current();
}
/**
* (PHP 5 >= 5.0.0)
* Move forward to next element
* @link http://php.net/manual/en/iterator.next.php
* @return void Any returned value is ignored.
*/
public function next()
{
return $this->items->next();
}
/**
* (PHP 5 >= 5.0.0)
* Return the key of the current element
* @link http://php.net/manual/en/iterator.key.php
* @return mixed scalar on success, or null on failure.
*/
public function key()
{
return $this->items->key();
}
/**
* (PHP 5 >= 5.0.0)
* Checks if current position is valid
* @link http://php.net/manual/en/iterator.valid.php
* @return boolean The return value will be casted to boolean and then evaluated.
* Returns true on success or false on failure.
*/
public function valid()
{
return $this->items->valid();
}
/**
* (PHP 5 >= 5.0.0)
* Rewind the Iterator to the first element
* @link http://php.net/manual/en/iterator.rewind.php
* @return void Any returned value is ignored.
*/
public function rewind()
{
return $this->items->rewind();
}
/**
* @param ItemInterface $item
* @return $this
*/
public function add(ItemInterface $item)
{
$this->items->append($item);
return $this;
}
/**
* @return ItemInterface
*/
public function newItem()
{
return new Item();
}
/**
* @return array
*/
public function jsonSerialize()
{
return $this->toArray();
}
/**
* @return array
*/
public function toArray()
{
$items = [];
foreach( $this->items as $item ) {
$items[] = $item->toArray();
}
$properties = parent::toArray();
$properties['items'] = $items;
return $properties;
}
}
src/FeedIo/Feed/ElementsAwareTrait.php 0000666 00000004473 13112056273 0013616 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Feed;
use FeedIo\Feed\Node\Element;
use FeedIo\Feed\Node\ElementInterface;
use FeedIo\Feed\Node\ElementIterator;
trait ElementsAwareTrait
{
/**
* @var \ArrayIterator
*/
protected $elements;
/**
* initialize the elements property before use
*/
protected function initElements()
{
$this->elements = new \ArrayIterator();
}
/**
* @return ElementInterface
*/
public function newElement()
{
return new Element();
}
/**
* @param string $name element name
* @return mixed
*/
public function getValue($name)
{
foreach ($this->getElementIterator($name) as $element) {
return $element->getValue();
}
return;
}
/**
* @param string $name element name
* @return ElementIterator
*/
public function getElementIterator($name)
{
return new ElementIterator($this->elements, $name);
}
/**
* @param string $name element name
* @return boolean true if the element exists
*/
public function hasElement($name)
{
$filter = $this->getElementIterator($name);
return $filter->count() > 0;
}
/**
* @param ElementInterface $element
* @return $this
*/
public function addElement(ElementInterface $element)
{
$this->elements->append($element);
return $this;
}
/**
* Returns all the item's optional elements
* @return \ArrayIterator
*/
public function getAllElements()
{
return $this->elements;
}
/**
* Returns the item's optional elements tag names
* @return array
*/
public function listElements()
{
foreach ($this->elements as $element) {
yield ($element->getName());
}
}
/**
* @return \Generator
*/
public function getElementsGenerator()
{
$elements = $this->getAllElements();
foreach ($elements as $element) {
yield $element->getName() => $element->getValue();
}
}
}
src/FeedIo/Feed/Item.php 0000666 00000003267 13112056273 0010754 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Feed;
use FeedIo\Feed\Item\Media;
use FeedIo\Feed\Item\MediaInterface;
use FeedIo\Feed\Item\Author;
use FeedIo\Feed\Item\AuthorInterface;
class Item extends Node implements ItemInterface
{
/**
* @var \ArrayIterator
*/
protected $medias;
/**
* @var AuthorInterface
*/
protected $author;
public function __construct()
{
$this->medias = new \ArrayIterator();
parent::__construct();
}
/**
* @param MediaInterface $media
* @return $this
*/
public function addMedia(MediaInterface $media)
{
$this->medias->append($media);
return $this;
}
/**
* @return \ArrayIterator
*/
public function getMedias()
{
return $this->medias;
}
/**
* @return boolean
*/
public function hasMedia()
{
return $this->medias->count() > 0;
}
/**
* @return MediaInterface
*/
public function newMedia()
{
return new Media();
}
/**
* @return AuthorInterface
*/
public function getAuthor()
{
return $this->author;
}
/**
* @param AuthorInterface $author
* @return $this
*/
public function setAuthor(AuthorInterface $author)
{
$this->author = $author;
return $this;
}
/**
* @return AuthorInterface
*/
public function newAuthor()
{
return new Author();
}
}
src/FeedIo/Feed/Item/Author.php 0000666 00000002430 13112056273 0012205 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Feed\Item;
class Author implements AuthorInterface
{
/**
* @var string
*/
protected $name;
/**
* @var string
*/
protected $uri;
/**
* @var int
*/
protected $email;
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @param string $name
* @return $this
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* @return string
*/
public function getUri()
{
return $this->uri;
}
/**
* @param string $uri
* @return $this
*/
public function setUri($uri)
{
$this->uri = $uri;
return $this;
}
/**
* @return string
*/
public function getEmail()
{
return $this->email;
}
/**
* @param string $email
* @return $this
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
}
src/FeedIo/Feed/Item/AuthorInterface.php 0000666 00000001531 13112056273 0014027 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Feed\Item;
/**
* Describe a Author instance
*
*/
interface AuthorInterface
{
/**
* @return string
*/
public function getName();
/**
* @param string $name
* @return $this
*/
public function setName($name);
/**
* @return string
*/
public function getUri();
/**
* @param string $uri
* @return $this
*/
public function setUri($uri);
/**
* @return string
*/
public function getEmail();
/**
* @param string $email
* @return $this
*/
public function setEmail($email);
}
src/FeedIo/Feed/Item/Media.php 0000666 00000002445 13112056273 0011770 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Feed\Item;
class Media implements MediaInterface
{
/**
* @var string
*/
protected $type;
/**
* @var string
*/
protected $url;
/**
* @var int
*/
protected $length;
/**
* @return string
*/
public function getType()
{
return $this->type;
}
/**
* @param string $type
* @return $this
*/
public function setType($type)
{
$this->type = $type;
return $this;
}
/**
* @return string
*/
public function getUrl()
{
return $this->url;
}
/**
* @param string $url
* @return $this
*/
public function setUrl($url)
{
$this->url = $url;
return $this;
}
/**
* @return string
*/
public function getLength()
{
return $this->length;
}
/**
* @param string $length
* @return $this
*/
public function setLength($length)
{
$this->length = intval($length);
return $this;
}
}
src/FeedIo/Feed/Item/MediaInterface.php 0000666 00000002332 13112056273 0013604 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Feed\Item;
/**
* Describe a Media instance
*
* most of the time medias are defined as enclosure in the XML document
*
* Atom :
*
*
* RSS :
*
*
*
* // will display http://example.org/video.mpeg
* echo $media->getUrl();
*
*/
interface MediaInterface
{
/**
* @return string
*/
public function getType();
/**
* @param string $type
* @return $this
*/
public function setType($type);
/**
* @return string
*/
public function getUrl();
/**
* @param string $url
* @return $this
*/
public function setUrl($url);
/**
* @return string
*/
public function getLength();
/**
* @param string $length
* @return $this
*/
public function setLength($length);
}
src/FeedIo/Feed/ItemInterface.php 0000666 00000004000 13112056273 0012557 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Feed;
use FeedIo\Feed\Item\MediaInterface;
use FeedIo\Feed\Item\AuthorInterface;
/**
* Describes an Item instance
*
* an item holds three types of properties :
* - basic values inherited from the NodeInterface like title, description, URL
* - MediaInterface instances for medias like videos, images and podcasts
* - ElementInterface instances for nodes not related to a known property of the ItemInterface instance
*
* ElementInterface instances are accessed using two methods :
*
* - ItemInterface::getElementIterator($name). Use it to read an array of elements or if you need to get an ElementInterface instance
* - ItemInterface::getValue($name). use it to get the element's v lue
*
*/
interface ItemInterface extends NodeInterface
{
/**
* adds $media to the object's attributes
*
* @param MediaInterface $media
* @return $this
*/
public function addMedia(MediaInterface $media);
/**
* returns the current object's medias
*
* @return \ArrayIterator
*/
public function getMedias();
/**
* returns true if at least one MediaInterface exists in the object's attributes
*
* @return boolean
*/
public function hasMedia();
/**
* returns a new MediaInterface
*
* @return MediaInterface
*/
public function newMedia();
/**
* returns the author attribute
*
* @return AuthorInterface
*/
public function getAuthor();
/**
* sets $author to the object's attributes
*
* @param AuthorInterface $author
* @return $this
*/
public function setAuthor(AuthorInterface $author);
/**
* returns a new AuthorInterface
*
* @return AuthorInterface
*/
public function newAuthor();
}
src/FeedIo/Feed/Node.php 0000666 00000010122 13112056273 0010727 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Feed;
use FeedIo\Feed\Node\Category;
use FeedIo\Feed\Node\CategoryInterface;
class Node implements NodeInterface
{
use ElementsAwareTrait;
/**
* @var \ArrayIterator
*/
protected $categories;
/**
* @var string
*/
protected $title;
/**
* @var string
*/
protected $publicId;
/**
* @var string
*/
protected $description;
/**
* @var \DateTime
*/
protected $lastModified;
/**
* @var string
*/
protected $link;
public function __construct()
{
$this->initElements();
$this->categories = new \ArrayIterator();
}
/**
* @param string $name element name
* @param string $value element value
* @return $this
*/
public function set($name, $value)
{
$element = $this->newElement();
$element->setName($name);
$element->setValue($value);
$this->addElement($element);
return $this;
}
/**
* returns node's categories
*
* @return \ArrayIterator
*/
public function getCategories()
{
return $this->categories;
}
/**
* @return \Generator
*/
public function getCategoriesGenerator()
{
foreach( $this->categories as $category ) {
yield $category->getlabel();
}
}
/**
* adds a category to the node
*
* @param \FeedIo\Feed\Node\CategoryInterface $category
* @return $this
*/
public function addCategory(CategoryInterface $category)
{
$this->categories->append($category);
return $this;
}
/**
* returns a new CategoryInterface
*
* @return \FeedIo\Feed\Node\CategoryInterface
*/
public function newCategory()
{
return new Category();
}
/**
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* @param string $title
* @return $this
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* @return string
*/
public function getPublicId()
{
return $this->publicId;
}
/**
* @param string $publicId
* @return $this
*/
public function setPublicId($publicId)
{
$this->publicId = $publicId;
return $this;
}
/**
* @return string
*/
public function getDescription()
{
return $this->description;
}
/**
* @param string $description
* @return $this
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* @return \DateTime
*/
public function getLastModified()
{
return $this->lastModified;
}
/**
* @param \DateTime $lastModified
* @return $this
*/
public function setLastModified(\DateTime $lastModified)
{
$this->lastModified = $lastModified;
return $this;
}
/**
* @return string
*/
public function getLink()
{
return $this->link;
}
/**
* @param string $link
* @return $this
*/
public function setLink($link)
{
$this->link = $link;
return $this;
}
/**
* @return array
*/
public function toArray()
{
$properties = get_object_vars($this);
foreach( $properties as $name => $property ) {
if ( $property instanceof \DateTime ) {
$properties[$name] = $property->format(\DateTime::ATOM);
}
}
$properties['elements'] = iterator_to_array($this->getElementsGenerator());
$properties['categories'] = iterator_to_array($this->getCategoriesGenerator());
return $properties;
}
}
src/FeedIo/Feed/Node/Category.php 0000666 00000002573 13112056273 0012517 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Feed\Node;
class Category implements CategoryInterface
{
/**
* @var string
*/
protected $term;
/**
* @var string
*/
protected $scheme;
/**
* @var string
*/
protected $label;
/**
* @return string
*/
public function getTerm()
{
return $this->term;
}
/**
* @param string $term
* @return $this
*/
public function setTerm($term)
{
$this->term = $term;
return $this;
}
/**
* @return string
*/
public function getScheme()
{
return $this->scheme;
}
/**
* @param string $scheme
* @return $this
*/
public function setScheme($scheme)
{
$this->scheme = $scheme;
return $this;
}
/**
* @return string
*/
public function getLabel()
{
return $this->label;
}
/**
* @param string $label
* @return $this
*/
public function setLabel($label)
{
$this->label = $label;
return $this;
}
}
src/FeedIo/Feed/Node/CategoryInterface.php 0000666 00000001601 13112056273 0014327 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Feed\Node;
/**
* Describe a Category instance
*
*/
interface CategoryInterface
{
/**
* @return string
*/
public function getTerm();
/**
* @param string $term
* @return $this
*/
public function setTerm($term);
/**
* @return string
*/
public function getScheme();
/**
* @param string $scheme
* @return $this
*/
public function setScheme($scheme);
/**
* @return string
*/
public function getLabel();
/**
* @param string $label
* @return $this
*/
public function setLabel($label);
}
src/FeedIo/Feed/Node/Element.php 0000666 00000003376 13112056273 0012335 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Feed\Node;
use FeedIo\Feed\ElementsAwareTrait;
class Element implements ElementInterface
{
use ElementsAwareTrait;
/**
* @var string
*/
protected $name;
/**
* @var string
*/
protected $value;
/**
* @var array
*/
protected $attributes = array();
public function __construct()
{
$this->initElements();
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @param string $name
* @return $this
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* @return string
*/
public function getValue()
{
return $this->value;
}
/**
* @param string $value
* @return $this
*/
public function setValue($value)
{
$this->value = $value;
return $this;
}
/**
* @param string $name
* @return string
*/
public function getAttribute($name)
{
if (array_key_exists($name, $this->attributes)) {
return $this->attributes[$name];
}
return;
}
/**
* @return array
*/
public function getAttributes()
{
return $this->attributes;
}
/**
* @param string $name
* @param string $value
* @return $this
*/
public function setAttribute($name, $value)
{
$this->attributes[$name] = $value;
return $this;
}
}
src/FeedIo/Feed/Node/ElementInterface.php 0000666 00000004641 13112056273 0014152 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Feed\Node;
/**
* Describe an Element instance
*
* $name matches the node's tag name
* $value matches the node's content
* each attribute matches an attribute of the node
*
* for example, to represent this XML node
*
* http://example.org/some-sound.mp3
*
* you must set the ElementInstance's properties this way
*
*
* $item->setName('media');
* $item->setValue('http://example.org/some-sound.mp3');
* $item->setAttribute('lenght', 45668);
* $item->setAttribute('type', 'audio/mpeg');
*
*
*/
interface ElementInterface
{
/**
* @return string
*/
public function getName();
/**
* @param string $name
* @return $this
*/
public function setName($name);
/**
* @return string
*/
public function getValue();
/**
* @param string $value
* @return $this
*/
public function setValue($value);
/**
* @param string $name
* @return string
*/
public function getAttribute($name);
/**
* @return array
*/
public function getAttributes();
/**
* @param string $name
* @param string $value
* @return $this
*/
public function setAttribute($name, $value);
/**
* returns the ElementIterator to iterate over ElementInterface instances called $name
*
* @param string $name element name
* @return \FeedIo\Feed\Node\ElementIterator
*/
public function getElementIterator($name);
/**
* returns true if an ElementInterface instance called $name exists
*
* @param string $name element name
* @return boolean true if the element exists
*/
public function hasElement($name);
/**
* adds $element to the object's attributes
*
* @param ElementInterface $element
* @return $this
*/
public function addElement(ElementInterface $element);
/**
* Returns all the item's elements
*
* @return \ArrayIterator
*/
public function getAllElements();
/**
* Returns the item's elements tag names
*
* @return array
*/
public function listElements();
}
src/FeedIo/Feed/Node/ElementIterator.php 0000666 00000002340 13112056273 0014035 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Feed\Node;
/**
* Iterator to filter elements by name
* @see \FilterIterator
*/
class ElementIterator extends \FilterIterator
{
/**
* @var string $name Element name to accept
*/
protected $name;
/**
* @param \Iterator $iterator Set of elements to filter
* @param string $name Element name to accept
*/
public function __construct(\Iterator $iterator, $name)
{
parent::__construct($iterator);
$this->name = $name;
}
/**
* override PHP's count implementation.
* @return int
*/
public function count()
{
$count = 0;
foreach ($this as $node) {
$count++;
}
return $count;
}
/**
* @return boolean True if the current element's name matches the expected one
*/
public function accept()
{
$element = $this->getInnerIterator()->current();
return (0 == strcasecmp($this->name, $element->getName()));
}
}
src/FeedIo/Feed/NodeInterface.php 0000666 00000007331 13112056273 0012560 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Feed;
use FeedIo\Feed\Node\ElementInterface;
use FeedIo\Feed\Node\CategoryInterface;
/**
* Describes a node instance
*
* A node exposes attributes which are common to feeds and items
*/
interface NodeInterface
{
/**
* Returns node's title
*
* @return string
*/
public function getTitle();
/**
* Sets nodes's title
*
* @param string $title
* @return $this
*/
public function setTitle($title);
/**
* Returns node's public id
*
* @return string
*/
public function getPublicId();
/**
* sets node's public id
*
* @param string $id
* @return $this
*/
public function setPublicId($id);
/**
* Returns node's description
*
* @return string
*/
public function getDescription();
/**
* Sets node's description
*
* @param string $description
* @return $this
*/
public function setDescription($description);
/**
* Returns the node's last modified date
*
* @return \DateTime
*/
public function getLastModified();
/**
* Sets the node's last modified date
*
* @param \DateTime $lastModified
* @return $this
*/
public function setLastModified(\DateTime $lastModified);
/**
* Returns the node's link
*
* @return string
*/
public function getLink();
/**
* Sets the nodes's link
*
* @param string $link
* @return $this
*/
public function setLink($link);
/**
* returns node's categories
*
* @return \ArrayIterator
*/
public function getCategories();
/**
* adds a category to the node
*
* @param \FeedIo\Feed\Node\CategoryInterface $category
* @return $this
*/
public function addCategory(CategoryInterface $category);
/**
* returns a new CategoryInterface
*
* @return \FeedIo\Feed\Node\CategoryInterface
*/
public function newCategory();
/**
* returns a new ElementInterface
*
* @return \FeedIo\Feed\Node\ElementInterface
*/
public function newElement();
/**
* returns an element's value
*
* @param string $name element name
* @return mixed
*/
public function getValue($name);
/**
* creates a new ElementInterface called $name and sets its value to $value
*
* @param string $name element name
* @param string $value element value
* @return $this
*/
public function set($name, $value);
/**
* returns the ElementIterator to iterate over ElementInterface instances called $name
*
* @param string $name element name
* @return \FeedIo\Feed\Node\ElementIterator
*/
public function getElementIterator($name);
/**
* returns true if an ElementInterface instance called $name exists
*
* @param string $name element name
* @return boolean true if the element exists
*/
public function hasElement($name);
/**
* adds $element to the object's attributes
*
* @param ElementInterface $element
* @return $this
*/
public function addElement(ElementInterface $element);
/**
* Returns all the item's elements
*
* @return \ArrayIterator
*/
public function getAllElements();
/**
* Returns the item's elements tag names
*
* @return array
*/
public function listElements();
}
src/FeedIo/FeedInterface.php 0000666 00000001760 13112056273 0011673 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo;
use FeedIo\Feed\NodeInterface;
use FeedIo\Feed\ItemInterface;
/**
* Interface FeedInterface
* Represents the top node of a news feed
* @package FeedIo
*/
interface FeedInterface extends \Iterator, NodeInterface
{
/**
* This method MUST return the feed's full URL
* @return string
*/
public function getUrl();
/**
* @param string $url
* @return FeedInterface
*/
public function setUrl($url);
/**
* Atom : feed.entry
* Rss : rss.channel.item
* @param ItemInterface $item
* @return FeedInterface
*/
public function add(ItemInterface $item);
/**
* @return ItemInterface
*/
public function newItem();
}
src/FeedIo/FeedIo.php 0000666 00000017423 13112056273 0010345 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo;
use FeedIo\Filter\ModifiedSince;
use FeedIo\Reader;
use FeedIo\Reader\FixerSet;
use FeedIo\Reader\FixerAbstract;
use FeedIo\Rule\DateTimeBuilder;
use FeedIo\Adapter\ClientInterface;
use FeedIo\Standard\Atom;
use FeedIo\Standard\Rss;
use FeedIo\Standard\Rdf;
use Psr\Log\LoggerInterface;
/**
* This class acts as a facade. It provides methods to access feed-io main features
*
*
* // $client is a \FeedIo\Adapter\ClientInterface instance, $logger a \Psr\Log\LoggerInterface
* $feedIo = new FeedIo($client, $logger);
*
* // read a feed. Output is a Result instance
* $result = $feedIo->read('http://somefeed.org/feed.rss');
*
* // use the feed
* $feed = $result->getFeed();
* echo $feed->getTitle();
*
* // and its items
* foreach ( $feed as $item ) {
* echo $item->getTitle();
* echo $item->getDescription();
* }
*
*
*
*
* // build the feed to publish
* $feed = new \FeedIo\Feed;
* $feed->setTitle('title');
* // ...
*
* // add items to it
* $item = new \FeedIo\Feed\Item
* $item->setTitle('my great post');
*
* // want to publish a media ? no problem
* $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);
*
* // add the item to the feed (almost there)
* $feed->add($item);
*
* // format it in atom
* $feedIo->toAtom($feed);
*
*
*/
class FeedIo
{
/**
* @var \FeedIo\Reader
*/
protected $reader;
/**
* @var \FeedIo\Rule\DateTimeBuilder
*/
protected $dateTimeBuilder;
/**
* @var \Psr\Log\LoggerInterface
*/
protected $logger;
/**
* @var array
*/
protected $standards;
/**
* @var \FeedIo\Reader\FixerSet
*/
protected $fixerSet;
/**
* @param \FeedIo\Adapter\ClientInterface $client
* @param \Psr\Log\LoggerInterface $logger
*/
public function __construct(ClientInterface $client, LoggerInterface $logger)
{
$this->logger = $logger;
$this->dateTimeBuilder = new DateTimeBuilder();
$this->setReader(new Reader($client, $logger));
$this->loadCommonStandards();
$this->loadFixerSet();
}
/**
* Loads main standards (RSS, RDF, Atom) in current object's attributes
*
* @return $this
*/
protected function loadCommonStandards()
{
$standards = $this->getCommonStandards();
foreach ($standards as $name => $standard) {
$this->addStandard($name, $standard);
}
return $this;
}
/**
* adds a filter to the reader
*
* @param \FeedIo\FilterInterface $filter
* @return $this
*/
public function addFilter(FilterInterface $filter)
{
$this->getReader()->addFilter($filter);
return $this;
}
/**
* Returns main standards
*
* @return array
*/
public function getCommonStandards()
{
return array(
'atom' => new Atom($this->dateTimeBuilder),
'rss' => new Rss($this->dateTimeBuilder),
'rdf' => new Rdf($this->dateTimeBuilder),
);
}
/**
* @param string $name
* @param \FeedIo\StandardAbstract $standard
* @return $this
*/
public function addStandard($name, StandardAbstract $standard)
{
$name = strtolower($name);
$this->standards[$name] = $standard;
$this->reader->addParser(
new Parser($standard, $this->logger)
);
return $this;
}
/**
* @return \FeedIo\Reader\FixerSet
*/
public function getFixerSet()
{
return $this->fixerSet;
}
/**
* @return $this
*/
protected function loadFixerSet()
{
$this->fixerSet = new FixerSet();
$fixers = $this->getBaseFixers();
foreach ($fixers as $fixer) {
$this->addFixer($fixer);
}
return $this;
}
/**
* @param FixerAbstract $fixer
* @return $this
*/
public function addFixer(FixerAbstract $fixer)
{
$fixer->setLogger($this->logger);
$this->fixerSet->add($fixer);
return $this;
}
/**
* @return array
*/
public function getBaseFixers()
{
return array(
new Reader\Fixer\LastModified(),
new Reader\Fixer\PublicId(),
);
}
/**
* @return \FeedIo\Rule\DateTimeBuilder
*/
public function getDateTimeBuilder()
{
return $this->dateTimeBuilder;
}
/**
* @return \FeedIo\Reader
*/
public function getReader()
{
return $this->reader;
}
/**
* @param \FeedIo\Reader
* @return $this
*/
public function setReader(Reader $reader)
{
$this->reader = $reader;
return $this;
}
/**
* @param $url
* @param FeedInterface $feed
* @param \DateTime $modifiedSince
* @return \FeedIo\Reader\Result
*/
public function read($url, FeedInterface $feed = null, \DateTime $modifiedSince = null)
{
if (is_null($feed)) {
$feed = new Feed();
}
if ($modifiedSince instanceof \DateTime) {
$this->addFilter(new ModifiedSince($modifiedSince));
}
$this->logAction($feed, "read access : $url into a feed instance");
$result = $this->reader->read($url, $feed, $modifiedSince);
$this->fixerSet->correct($result->getFeed());
return $result;
}
/**
* @param $url
* @param \DateTime $modifiedSince
* @return \FeedIo\Reader\Result
*/
public function readSince($url, \DateTime $modifiedSince)
{
return $this->read($url, new Feed(), $modifiedSince);
}
/**
* @return $this
*/
public function resetFilters()
{
$this->getReader()->resetFilters();
return $this;
}
/**
* @param FeedInterface $feed
* @param string $standard Standard's name
* @return \DomDocument
*/
public function format(FeedInterface $feed, $standard)
{
$this->logAction($feed, "formatting a feed in $standard format");
$formatter = new Formatter($this->getStandard($standard), $this->logger);
return $formatter->toDom($feed);
}
/**
* @param \FeedIo\FeedInterface $feed
* @return \DomDocument
*/
public function toRss(FeedInterface $feed)
{
return $this->format($feed, 'rss');
}
/**
* @param \FeedIo\FeedInterface $feed
* @return \DomDocument
*/
public function toAtom(FeedInterface $feed)
{
return $this->format($feed, 'atom');
}
/**
* @param string $name
* @return \FeedIo\StandardAbstract
* @throws \OutOfBoundsException
*/
public function getStandard($name)
{
$name = strtolower($name);
if (array_key_exists($name, $this->standards)) {
return $this->standards[$name];
}
throw new \OutOfBoundsException("no standard found for $name");
}
/**
* @param \FeedIo\FeedInterface $feed
* @param string $message
* @return $this
*/
protected function logAction(FeedInterface $feed, $message)
{
$class = get_class($feed);
$this->logger->debug("$message (feed class : $class)");
return $this;
}
}
src/FeedIo/FeedIoException.php 0000666 00000000467 13112056273 0012224 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo;
class FeedIoException extends \RuntimeException
{
}
src/FeedIo/Filter/ModifiedSince.php 0000666 00000001576 13112056273 0013143 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Filter;
use FeedIo\Feed\ItemInterface;
use FeedIo\FilterInterface;
class ModifiedSince implements FilterInterface
{
/**
* @var \DateTime
*/
protected $date;
/**
* ModifiedSince constructor.
* @param \DateTime $date
*/
public function __construct(\DateTime $date)
{
$this->date = $date;
}
/**
* @param ItemInterface $item
* @return bool
*/
public function isValid(ItemInterface $item)
{
if ($item->getLastModified() instanceof \DateTime) {
return $item->getLastModified() > $this->date;
}
return false;
}
}
src/FeedIo/FilterInterface.php 0000666 00000000673 13112056273 0012257 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo;
use FeedIo\Feed\ItemInterface;
interface FilterInterface
{
/**
* @param ItemInterface $item
* @return bool
*/
public function isValid(ItemInterface $item);
}
src/FeedIo/Formatter.php 0000666 00000010003 13112056273 0011140 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo;
use FeedIo\Feed\NodeInterface;
use FeedIo\Rule\OptionalField;
use Psr\Log\LoggerInterface;
/**
* Turns a FeedInterface instance into a XML document.
*
* Depends on :
* - FeedIo\StandardAbstract
* - Psr\Log\LoggerInterface
*
*/
class Formatter
{
/**
* @var StandardAbstract
*/
protected $standard;
/**
* @var LoggerInterface
*/
protected $logger;
/**
* @param StandardAbstract $standard
* @param LoggerInterface $logger
*/
public function __construct(StandardAbstract $standard, LoggerInterface $logger)
{
$this->standard = $standard;
$this->logger = $logger;
}
/**
* @param \DOMDocument $document
* @param FeedInterface $feed
* @return $this
*/
public function setHeaders(\DOMDocument $document, FeedInterface $feed)
{
$rules = $this->standard->getFeedRuleSet();
$elements = $this->buildElements($rules, $document, $feed);
foreach ($elements as $element) {
$this->standard->getMainElement($document)->appendChild($element);
}
return $this;
}
/**
* @param \DOMDocument $document
* @param NodeInterface $node
* @return $this
*/
public function addItem(\DOMDocument $document, NodeInterface $node)
{
$domItem = $document->createElement($this->standard->getItemNodeName());
$rules = $this->standard->getItemRuleSet();
$elements = $this->buildElements($rules, $document, $node);
foreach ($elements as $element) {
$domItem->appendChild($element);
}
$this->standard->getMainElement($document)->appendChild($domItem);
return $this;
}
/**
* @param RuleSet $ruleSet
* @param \DOMDocument $document
* @param NodeInterface $node
* @return array
*/
public function buildElements(RuleSet $ruleSet, \DOMDocument $document, NodeInterface $node)
{
$rules = $this->getAllRules($ruleSet, $node);
$elements = array();
foreach ($rules as $rule) {
$elements[] = $rule->createElement($document, $node);
}
return array_filter($elements);
}
/**
* @param RuleSet $ruleSet
* @param NodeInterface $node
* @return array|\ArrayIterator
*/
public function getAllRules(RuleSet $ruleSet, NodeInterface $node)
{
$rules = $ruleSet->getRules();
$optionalFields = $node->listElements();
foreach ($optionalFields as $optionalField) {
$rules[] = new OptionalField($optionalField);
}
return $rules;
}
/**
* @return \DOMDocument
*/
public function getEmptyDocument()
{
return new \DOMDocument('1.0', 'utf-8');
}
/**
* @return \DOMDocument
*/
public function getDocument()
{
$document = $this->getEmptyDocument();
return $this->standard->format($document);
}
/**
* @param FeedInterface $feed
* @return string
*/
public function toString(FeedInterface $feed)
{
$document = $this->toDom($feed);
return $document->saveXML();
}
/**
* @param FeedInterface $feed
* @return \DomDocument
*/
public function toDom(FeedInterface $feed)
{
$document = $this->getDocument();
$this->setHeaders($document, $feed);
$this->setItems($document, $feed);
return $document;
}
/**
* @param \DOMDocument $document
* @param FeedInterface $feed
* @return $this
*/
public function setItems(\DOMDocument $document, FeedInterface $feed)
{
foreach ($feed as $item) {
$this->addItem($document, $item);
}
return $this;
}
}
src/FeedIo/Parser.php 0000666 00000011720 13112056273 0010440 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo;
use DOMDocument;
use FeedIo\Feed\ItemInterface;
use FeedIo\Feed\NodeInterface;
use FeedIo\Parser\MissingFieldsException;
use FeedIo\Parser\UnsupportedFormatException;
use Psr\Log\LoggerInterface;
/**
* Parses a DOM document if its format matches the parser's standard
*
* Depends on :
* - FeedIo\StandardAbstract
* - Psr\Log\LoggerInterface
*
*/
class Parser
{
/**
* @var \Psr\Log\LoggerInterface
*/
protected $logger;
/**
* @var array[FilterInterface]
*/
protected $filters = array();
/**
* @var StandardAbstract
*/
protected $standard;
/**
* @param StandardAbstract $standard
* @param LoggerInterface $logger
*/
public function __construct(StandardAbstract $standard, LoggerInterface $logger)
{
$this->standard = $standard;
$this->logger = $logger;
}
/**
* @return StandardAbstract
*/
public function getStandard()
{
return $this->standard;
}
/**
* @param $tagName
* @return bool
*/
public function isItem($tagName)
{
return (strtolower($this->standard->getItemNodeName()) === strtolower($tagName));
}
/**
* @param FilterInterface $filter
* @return $this
*/
public function addFilter(FilterInterface $filter)
{
$this->filters[] = $filter;
return $this;
}
/**
* Reset filters
* @return $this
*/
public function resetFilters()
{
$this->filters = [];
return $this;
}
/**
* @param DOMDocument $document
* @param FeedInterface $feed
* @return \FeedIo\FeedInterface
* @throws Parser\MissingFieldsException
* @throws Parser\UnsupportedFormatException
*/
public function parse(DOMDocument $document, FeedInterface $feed)
{
if (!$this->standard->canHandle($document)) {
throw new UnsupportedFormatException('this is not a supported format');
}
$this->checkBodyStructure($document, $this->standard->getMandatoryFields());
$element = $this->standard->getMainElement($document);
$this->parseNode($feed, $element, $this->standard->getFeedRuleSet());
return $feed;
}
/**
* @param DOMDocument $document
* @param array $mandatoryFields
* @return $this
* @throws MissingFieldsException
*/
public function checkBodyStructure(DOMDocument $document, array $mandatoryFields)
{
$errors = array();
$element = $document->documentElement;
foreach ($mandatoryFields as $field) {
$list = $element->getElementsByTagName($field);
if (0 === $list->length) {
$errors[] = $field;
}
}
if (!empty($errors)) {
$message = "missing mandatory field(s) : ".implode(',', $errors);
$this->logger->warning($message);
throw new MissingFieldsException($message);
}
return $this;
}
/**
* @param NodeInterface $item
* @param \DOMElement $element
* @param RuleSet $ruleSet
* @return NodeInterface
*/
public function parseNode(NodeInterface $item, \DOMElement $element, RuleSet $ruleSet)
{
foreach ($element->childNodes as $node) {
if ($node instanceof \DOMElement) {
$this->handleNode($item, $node, $ruleSet);
}
}
return $item;
}
/**
* @param NodeInterface $item
* @param \DOMElement $node
* @param RuleSet $ruleSet
* @return $this
*/
protected function handleNode(NodeInterface $item, \DOMElement $node, RuleSet $ruleSet)
{
if ($this->isItem($node->tagName) && $item instanceof FeedInterface) {
$newItem = $this->parseNode($item->newItem(), $node, $this->standard->getItemRuleSet());
$this->addValidItem($item, $newItem);
} else {
$rule = $ruleSet->get($node->tagName);
$rule->setProperty($item, $node);
}
return $this;
}
/**
* @param FeedInterface $feed
* @param NodeInterface $item
* @return $this
*/
public function addValidItem(FeedInterface $feed, NodeInterface $item)
{
if ($item instanceof ItemInterface && $this->isValid($item)) {
$feed->add($item);
}
return $this;
}
/**
* @param ItemInterface $item
* @return bool
*/
public function isValid(ItemInterface $item)
{
foreach ($this->filters as $filter) {
if (!$filter->isValid($item)) {
return false;
}
}
return true;
}
}
src/FeedIo/Parser/MissingFieldsException.php 0000666 00000000540 13112056273 0015055 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Parser;
use FeedIo\FeedIoException;
class MissingFieldsException extends FeedIoException
{
}
src/FeedIo/Parser/UnsupportedFormatException.php 0000666 00000000544 13112056273 0016022 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Parser;
use FeedIo\FeedIoException;
class UnsupportedFormatException extends FeedIoException
{
}
src/FeedIo/Reader.php 0000666 00000011436 13112056273 0010412 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo;
use FeedIo\Adapter\ClientInterface;
use FeedIo\Reader\ReadErrorException;
use FeedIo\Reader\Result;
use FeedIo\Reader\NoAccurateParserException;
use Psr\Log\LoggerInterface;
/**
* Consumes feeds and return corresponding Result instances
*
* Depends on :
* - FeedIo\Adapter\ClientInterface
* - Psr\Log\LoggerInterface
*
* A Reader instance MUST have at least one parser added with the addParser() method to read feeds
* It will throw a NoAccurateParserException if it cannot find a suitable parser for the feed.
*/
class Reader
{
/**
* @var \FeedIo\Adapter\ClientInterface;
*/
protected $client;
/**
* @var \Psr\Log\LoggerInterface
*/
protected $logger;
/**
* @var array
*/
protected $parsers = array();
/**
* @param ClientInterface $client
* @param LoggerInterface $logger
*/
public function __construct(ClientInterface $client, LoggerInterface $logger)
{
$this->client = $client;
$this->logger = $logger;
}
/**
* @param Parser $parser
* @return $this
*/
public function addParser(Parser $parser)
{
$this->logger->debug("new parser added : ".get_class($parser->getStandard()));
$this->parsers[] = $parser;
return $this;
}
/**
* adds a filter to every parsers
*
* @param \FeedIo\FilterInterface $filter
* @return $this
*/
public function addFilter(FilterInterface $filter)
{
foreach ($this->parsers as $parser) {
$parser->addFilter($filter);
}
return $this;
}
/**
* Reset filters on every parsers
* @return $this
*/
public function resetFilters()
{
foreach ($this->parsers as $parser) {
$parser->resetFilters();
}
return $this;
}
/**
* @param string $body
* @return \DOMDocument
*/
public function loadDocument($body)
{
set_error_handler(
/**
* @param string $errno
*/
function ($errno, $errstr) {
throw new \InvalidArgumentException("malformed xml string. parsing error : $errstr ($errno)");
}
);
$domDocument = new \DOMDocument();
$domDocument->loadXML($body);
restore_error_handler();
return $domDocument;
}
/**
* @param $url
* @param FeedInterface $feed
* @param \DateTime $modifiedSince
* @return \FeedIo\Reader\Result
* @throws ReadErrorException
*/
public function read($url, FeedInterface $feed, \DateTime $modifiedSince = null)
{
$this->logger->debug("start reading {$url}");
if (is_null($modifiedSince)) {
$this->logger->notice("no 'modifiedSince' parameter given, setting it to 01/01/1970");
$modifiedSince = new \DateTime('@0');
}
try {
$response = $this->client->getResponse($url, $modifiedSince);
$this->logger->debug("response ok, now turning it into a DomDocument");
$document = $this->loadDocument(trim($response->getBody()));
$this->parseDocument($document, $feed);
$this->logger->info("{$url} successfully parsed");
return new Result($document, $feed, $modifiedSince, $response, $url);
} catch (\Exception $e) {
$this->logger->warning("{$url} read error : {$e->getMessage()}");
throw new ReadErrorException($e);
}
}
/**
* @param \DOMDocument $document
* @param FeedInterface $feed
* @return FeedInterface
* @throws Parser\UnsupportedFormatException
* @throws Reader\NoAccurateParserException
*/
public function parseDocument(\DOMDocument $document, FeedInterface $feed)
{
$parser = $this->getAccurateParser($document);
$this->logger->debug("accurate parser : ".get_class($parser));
return $parser->parse($document, $feed);
}
/**
* @param \DOMDocument $document
* @return ParserAbstract
* @throws Reader\NoAccurateParserException
*/
public function getAccurateParser(\DOMDocument $document)
{
foreach ($this->parsers as $parser) {
if ($parser->getStandard()->canHandle($document)) {
return $parser;
}
}
$message = 'No parser can handle this stream';
$this->logger->error($message);
throw new NoAccurateParserException($message);
}
}
src/FeedIo/Reader/Fixer/LastModified.php 0000666 00000002226 13112056273 0014030 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Reader\Fixer;
use FeedIo\FeedInterface;
use FeedIo\Reader\FixerAbstract;
class LastModified extends FixerAbstract
{
/**
* @param FeedInterface $feed
* @return $this
*/
public function correct(FeedInterface $feed)
{
if (is_null($feed->getLastModified())) {
$this->logger->notice("correct last modified date for feed {$feed->getTitle()}");
$feed->setLastModified(
$this->searchLastModified($feed)
);
}
return $this;
}
/**
* @param FeedInterface $feed
* @return \DateTime
*/
public function searchLastModified(FeedInterface $feed)
{
$latest = new \DateTime('@0');
foreach ($feed as $item) {
if ($item->getLastModified() > $latest) {
$latest = $item->getLastModified();
}
}
return $latest;
}
}
src/FeedIo/Reader/Fixer/PublicId.php 0000666 00000002252 13112056273 0013156 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Reader\Fixer;
use FeedIo\FeedInterface;
use FeedIo\Feed\NodeInterface;
use FeedIo\Reader\FixerAbstract;
class PublicId extends FixerAbstract
{
/**
* @param FeedInterface $feed
* @return $this
*/
public function correct(FeedInterface $feed)
{
$this->fixNode($feed);
$this->fixItems($feed);
return $this;
}
/**
* @param NodeInterface $node
* @return $this
*/
protected function fixNode(NodeInterface $node)
{
if (is_null($node->getPublicId())) {
$this->logger->notice("correct public id for node {$node->getTitle()}");
$node->setPublicId($node->getLink());
}
}
/**
* @param FeedInterface $feed
* @return $this
*/
protected function fixItems(FeedInterface $feed)
{
foreach ($feed as $item) {
$this->fixNode($item);
}
return $this;
}
}
src/FeedIo/Reader/FixerAbstract.php 0000666 00000001264 13112056273 0013151 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Reader;
use FeedIo\FeedInterface;
use Psr\Log\LoggerInterface;
abstract class FixerAbstract
{
/**
* @var \Psr\Log\LoggerInterface
*/
protected $logger;
/**
* @param \Psr\Log\LoggerInterface
* @return $this
*/
public function setLogger(LoggerInterface $logger)
{
$this->logger = $logger;
return $this;
}
abstract public function correct(FeedInterface $feed);
}
src/FeedIo/Reader/FixerSet.php 0000666 00000001425 13112056273 0012140 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Reader;
use FeedIo\FeedInterface;
class FixerSet
{
protected $fixers = array();
/**
* @param \FeedIo\Reader\FixerAbstract
* @return $this
*/
public function add(FixerAbstract $fixer)
{
$this->fixers[] = $fixer;
return $this;
}
/**
* @param FeedInterface $feed
* @return $this
*/
public function correct(FeedInterface $feed)
{
foreach ($this->fixers as $fixer) {
$fixer->correct($feed);
}
return $this;
}
}
src/FeedIo/Reader/NoAccurateParserException.php 0000666 00000000543 13112056273 0015467 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Reader;
use FeedIo\FeedIoException;
class NoAccurateParserException extends FeedIoException
{
}
src/FeedIo/Reader/ReadErrorException.php 0000666 00000000534 13112056273 0014153 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Reader;
use FeedIo\FeedIoException;
class ReadErrorException extends FeedIoException
{
}
src/FeedIo/Reader/Result.php 0000666 00000004501 13112056273 0011663 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Reader;
use FeedIo\Adapter\ResponseInterface;
use FeedIo\FeedInterface;
/**
* Result of the read() operation
*
* a Result instance holds the following :
*
* - the Feed instance
* - Date and time of the request
* - value of the 'modifiedSince' header sent throught the request
* - the raw response
* - the DOM document
* - URL of the feed
*/
class Result
{
/**
* @var \DateTime
*/
protected $modifiedSince;
/**
* @var \DateTime
*/
protected $date;
/**
* @var \FeedIo\FeedInterface
*/
protected $feed;
/**
* @var \FeedIo\Adapter\ResponseInterface
*/
protected $response;
/**
* @var \DomDocument
*/
protected $document;
/**
* @var string
*/
protected $url;
/**
* @param \DOMDocument $document
* @param FeedInterface $feed
* @param \DateTime $modifiedSince
* @param ResponseInterface $response
* @param $url
*/
public function __construct(
\DOMDocument $document,
FeedInterface $feed,
\DateTime $modifiedSince,
ResponseInterface $response,
$url
) {
$this->date = new \DateTime();
$this->document = $document;
$this->feed = $feed;
$this->modifiedSince = $modifiedSince;
$this->response = $response;
$this->url = $url;
}
/**
* @return \DateTime
*/
public function getDate()
{
return $this->date;
}
/**
* @return \DomDocument
*/
public function getDocument()
{
return $this->document;
}
/**
* @return FeedInterface
*/
public function getFeed()
{
return $this->feed;
}
/**
* @return \DateTime
*/
public function getModifiedSince()
{
return $this->modifiedSince;
}
/**
* @return ResponseInterface
*/
public function getResponse()
{
return $this->response;
}
/**
* @return string
*/
public function getUrl()
{
return $this->url;
}
}
src/FeedIo/Rule/Atom/Author.php 0000666 00000003374 13112056273 0012263 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Rule\Atom;
use FeedIo\Feed\ItemInterface;
use FeedIo\Feed\NodeInterface;
use FeedIo\RuleAbstract;
class Author extends RuleAbstract
{
const NODE_NAME = 'author';
/**
* @param NodeInterface $node
* @param \DOMElement $element
* @return mixed
*/
public function setProperty(NodeInterface $node, \DOMElement $element)
{
if ($node instanceof ItemInterface) {
$author = $node->newAuthor();
$author->setName($this->getChildValue($element, 'name'));
$author->setUri($this->getChildValue($element, 'uri'));
$author->setEmail($this->getChildValue($element, 'email'));
$node->setAuthor($author);
}
return $this;
}
/**
* creates the accurate DomElement content according to the $item's property
*
* @param \DomDocument $document
* @param NodeInterface $node
* @return \DomElement
*/
public function createElement(\DomDocument $document, NodeInterface $node)
{
if ($node instanceof ItemInterface && !is_null($node->getAuthor())) {
$element = $document->createElement(static::NODE_NAME);
$element->appendChild($document->createElement('name', $node->getAuthor()->getName()));
$element->appendChild($document->createElement('uri', $node->getAuthor()->getUri()));
$element->appendChild($document->createElement('email', $node->getAuthor()->getEmail()));
return $element;
}
return;
}
}
src/FeedIo/Rule/Atom/Category.php 0000666 00000002652 13112056273 0012574 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Rule\Atom;
use FeedIo\Feed\Node\CategoryInterface;
use FeedIo\Feed\NodeInterface;
class Category extends \FeedIo\Rule\Category
{
/**
* @param NodeInterface $node
* @param \DOMElement $element
* @return mixed
*/
public function setProperty(NodeInterface $node, \DOMElement $element)
{
$category = $node->newCategory();
$category->setScheme($this->getAttributeValue($element, 'scheme'))
->setLabel($this->getAttributeValue($element, 'label'))
->setTerm($this->getAttributeValue($element, 'term'));
$node->addCategory($category);
return $this;
}
/**
* @param \DomDocument $document
* @param CategoryInterface $category
* @return \DomElement
*/
public function createCategoryElement(\DomDocument $document, CategoryInterface $category)
{
$element = $document->createElement($this->getNodeName());
$element->setAttribute('scheme', $category->getScheme());
$element->setAttribute('term', $category->getTerm());
$element->setAttribute('label', $category->getLabel());
return $element;
}
}
src/FeedIo/Rule/Atom/Link.php 0000666 00000002227 13112056273 0011712 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Rule\Atom;
use FeedIo\Feed\NodeInterface;
use FeedIo\RuleAbstract;
class Link extends RuleAbstract
{
const NODE_NAME = 'link';
/**
* @param NodeInterface $node
* @param \DOMElement $element
* @return mixed
*/
public function setProperty(NodeInterface $node, \DOMElement $element)
{
if ($element->hasAttribute('href')) {
$node->setLink($element->getAttribute('href'));
}
return $this;
}
/**
* creates the accurate DomElement content according to the $item's property
*
* @param \DomDocument $document
* @param NodeInterface $node
* @return \DomElement
*/
public function createElement(\DomDocument $document, NodeInterface $node)
{
$element = $document->createElement(static::NODE_NAME);
$element->setAttribute('href', $node->getLink());
return $element;
}
}
src/FeedIo/Rule/Atom/LinkNode.php 0000666 00000003214 13112056273 0012515 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Rule\Atom;
use FeedIo\Feed\NodeInterface;
use FeedIo\RuleAbstract;
use FeedIo\RuleSet;
use FeedIo\Rule\Media;
class LinkNode extends RuleAbstract
{
const NODE_NAME = 'link';
/**
* @var \FeedIo\RuleSet
*/
protected $ruleSet;
/**
* @param string $nodeName
*/
public function __construct($nodeName = null)
{
parent::__construct($nodeName);
$mediaRule = new Media();
$mediaRule->setUrlAttributeName('href');
$this->ruleSet = new RuleSet(new Link('related'));
$this->ruleSet->add($mediaRule);
}
/**
* @param NodeInterface $node
* @param \DOMElement $element
* @return mixed
*/
public function setProperty(NodeInterface $node, \DOMElement $element)
{
if ($element->hasAttribute('rel')) {
$this->ruleSet->get($element->getAttribute('rel'))->setProperty($node, $element);
} else {
$this->ruleSet->getDefault()->setProperty($node, $element);
}
return $this;
}
/**
* creates the accurate DomElement content according to the $item's property
*
* @param \DomDocument $document
* @param NodeInterface $node
* @return \DomElement
*/
public function createElement(\DomDocument $document, NodeInterface $node)
{
return $this->ruleSet->getDefault()->createElement($document, $node);
}
}
src/FeedIo/Rule/Author.php 0000666 00000002464 13112056273 0011362 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Rule;
use FeedIo\Feed\ItemInterface;
use FeedIo\Feed\NodeInterface;
use FeedIo\RuleAbstract;
class Author extends RuleAbstract
{
const NODE_NAME = 'author';
/**
* @param NodeInterface $node
* @param \DOMElement $element
* @return mixed
*/
public function setProperty(NodeInterface $node, \DOMElement $element)
{
if ($node instanceof ItemInterface) {
$author = $node->newAuthor();
$author->setName($element->nodeValue);
$node->setAuthor($author);
}
return $this;
}
/**
* creates the accurate DomElement content according to the $item's property
*
* @param \DomDocument $document
* @param NodeInterface $node
* @return \DomElement|null
*/
public function createElement(\DomDocument $document, NodeInterface $node)
{
if ($node instanceof ItemInterface && !is_null($node->getAuthor())) {
return $document->createElement($this->getNodeName(), $node->getAuthor()->getName());
}
return;
}
}
src/FeedIo/Rule/Category.php 0000666 00000003646 13112056273 0011700 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Rule;
use FeedIo\Feed\Node\CategoryInterface;
use FeedIo\Feed\NodeInterface;
use FeedIo\RuleAbstract;
class Category extends RuleAbstract
{
const NODE_NAME = 'category';
/**
* @param NodeInterface $node
* @param \DOMElement $element
* @return mixed
*/
public function setProperty(NodeInterface $node, \DOMElement $element)
{
$category = $node->newCategory();
$category->setScheme($this->getAttributeValue($element, 'domain'))
->setLabel($element->nodeValue)
->setTerm($element->nodeValue);
$node->addCategory($category);
return $this;
}
/**
* creates the accurate DomElement content according to the $item's property
*
* @param \DomDocument $document
* @param NodeInterface $node
* @return \DomElement|null
*/
public function createElement(\DomDocument $document, NodeInterface $node)
{
if ( ! is_null($node->getCategories()) ) {
foreach( $node->getCategories() as $category ) {
return $this->createCategoryElement($document, $category);
}
}
return;
}
/**
* @param \DomDocument $document
* @param CategoryInterface $category
* @return \DomElement
*/
public function createCategoryElement(\DomDocument $document, CategoryInterface $category)
{
$element = $document->createElement(
$this->getNodeName(),
is_null($category->getTerm()) ? $category->getLabel():$category->getTerm()
);
$element->setAttribute('domain', $category->getScheme());
return $element;
}
}
src/FeedIo/Rule/DateTimeBuilder.php 0000666 00000005733 13112056273 0013125 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Rule;
class DateTimeBuilder
{
/**
* Supported date formats
* @var array
*/
protected $dateFormats = [
\DateTime::RFC2822,
\DateTime::ATOM,
\DateTime::RFC3339,
\DateTime::RSS,
\DateTime::W3C,
'Y-m-d\TH:i:s.uP',
'Y-m-d\TH:i:s',
'Y-m-d',
'd/m/Y',
'D, d M Y H:i O',
'D, d M Y H:i:s O',
'D M d Y H:i:s e',
'*, m#d#Y - H:i',
];
/**
* @var \DateTimeZone
*/
protected $timezone;
/**
* @var string
*/
protected $lastGuessedFormat = \DateTime::RFC2822;
public function __construct()
{
$this->setTimezone(new \DateTimeZone(date_default_timezone_get()));
}
/**
* @param $dateFormat
* @return $this
*/
public function addDateFormat($dateFormat)
{
$this->dateFormats[] = $dateFormat;
return $this;
}
/**
* @param array $dateFormats
* @return $this
*/
public function setDateFormats(array $dateFormats)
{
$this->dateFormats = $dateFormats;
return $this;
}
/**
* @return string
*/
public function getLastGuessedFormat()
{
return $this->lastGuessedFormat;
}
/**
*
* @param string $date
* @return string|false date Format
* @throws InvalidArgumentException
*/
public function guessDateFormat($date)
{
foreach ($this->dateFormats as $format) {
$test = \DateTime::createFromFormat($format, $date);
if ($test instanceof \DateTime) {
$this->lastGuessedFormat = $format;
return $format;
}
}
return false;
}
/**
* Creates a DateTime instance for the given string. Default format is RFC2822
* @param string $string
* @return \DateTime
* @throws InvalidArgumentException
*/
public function convertToDateTime($string)
{
$string = trim($string);
foreach ([$this->getLastGuessedFormat(), $this->guessDateFormat($string) ] as $format) {
$date = \DateTime::createFromFormat($format, $string);
if ($date instanceof \DateTime) {
$date->setTimezone($this->getTimezone());
return $date;
}
}
throw new \InvalidArgumentException('Impossible to convert date : '.$string);
}
/**
* @return \DateTimeZone
*/
public function getTimezone()
{
return $this->timezone;
}
/**
* @param \DateTimeZone $timezone
*/
public function setTimezone(\DateTimeZone $timezone)
{
$this->timezone = $timezone;
}
}
src/FeedIo/Rule/Description.php 0000666 00000002423 13112056273 0012376 0 ustar 00 firstChild && $element->firstChild->nodeType == XML_CDATA_SECTION_NODE ) {
$string = $element->firstChild->textContent;
} else {
foreach($element->childNodes as $childNode) {
$string .= $element->ownerDocument->saveXML($childNode);
}
}
$node->setDescription($string);
return $this;
}
/**
* creates the accurate DomElement content according to the $item's property
*
* @param \DOMDocument $document
* @param NodeInterface $node
* @return \DOMElement
*/
public function createElement(\DOMDocument $document, NodeInterface $node)
{
$description = htmlspecialchars($node->getDescription());
return $document->createElement($this->getNodeName(), $description);
}
}
src/FeedIo/Rule/Link.php 0000666 00000002007 13112056273 0011006 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Rule;
use FeedIo\Feed\NodeInterface;
use FeedIo\RuleAbstract;
class Link extends RuleAbstract
{
const NODE_NAME = 'link';
/**
* @param NodeInterface $node
* @param \DOMElement $element
* @return mixed
*/
public function setProperty(NodeInterface $node, \DOMElement $element)
{
$node->setLink($element->nodeValue);
return $this;
}
/**
* creates the accurate DomElement content according to the $item's property
*
* @param \DomDocument $document
* @param NodeInterface $node
* @return \DomElement
*/
public function createElement(\DomDocument $document, NodeInterface $node)
{
return $document->createElement($this->getNodeName(), $node->getLink());
}
}
src/FeedIo/Rule/Media.php 0000666 00000004635 13112056273 0011141 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Rule;
use FeedIo\Feed\Item;
use FeedIo\Feed\Item\MediaInterface;
use FeedIo\Feed\ItemInterface;
use FeedIo\Feed\NodeInterface;
use FeedIo\RuleAbstract;
class Media extends RuleAbstract
{
const NODE_NAME = 'enclosure';
protected $urlAttributeName = 'url';
/**
* @return string
*/
public function getUrlAttributeName()
{
return $this->urlAttributeName;
}
/**
* @param string $name
* @return $this
*/
public function setUrlAttributeName($name)
{
$this->urlAttributeName = $name;
return $this;
}
/**
* @param NodeInterface $node
* @param \DOMElement $element
* @return $this
*/
public function setProperty(NodeInterface $node, \DOMElement $element)
{
if ($node instanceof ItemInterface) {
$media = $node->newMedia();
$media->setType($this->getAttributeValue($element, 'type'))
->setUrl($this->getAttributeValue($element, $this->getUrlAttributeName()))
->setLength($this->getAttributeValue($element, 'length'));
$node->addMedia($media);
}
return $this;
}
/**
* creates the accurate DomElement content according to the $item's property
*
* @param \DomDocument $document
* @param NodeInterface $node
* @return \DomElement
*/
public function createElement(\DomDocument $document, NodeInterface $node)
{
if ($node instanceof ItemInterface) {
foreach ($node->getMedias() as $media) {
return $this->createMediaElement($document, $media);
}
}
return;
}
/**
* @param \DomDocument $document
* @param MediaInterface $media
* @return \DomElement
*/
public function createMediaElement(\DomDocument $document, MediaInterface $media)
{
$element = $document->createElement($this->getNodeName());
$element->setAttribute($this->getUrlAttributeName(), $media->getUrl());
$element->setAttribute('type', $media->getType());
$element->setAttribute('length', $media->getLength());
return $element;
}
}
src/FeedIo/Rule/ModifiedSince.php 0000666 00000002240 13112056273 0012612 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Rule;
use FeedIo\Feed\NodeInterface;
use FeedIo\DateRuleAbstract;
class ModifiedSince extends DateRuleAbstract
{
const NODE_NAME = 'pubDate';
/**
* @param NodeInterface $node
* @param \DOMElement $element
* @return $this
*/
public function setProperty(NodeInterface $node, \DOMElement $element)
{
$node->setLastModified($this->getDateTimeBuilder()->convertToDateTime($element->nodeValue));
return $this;
}
/**
* creates the accurate DomElement content according to the $item's property
*
* @param \DomDocument $document
* @param NodeInterface $node
* @return \DomElement
*/
public function createElement(\DomDocument $document, NodeInterface $node)
{
return $document->createElement(
$this->getNodeName(),
$node->getLastModified()->format($this->getDefaultFormat())
);
}
}
src/FeedIo/Rule/OptionalField.php 0000666 00000007370 13112056273 0012652 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Rule;
use FeedIo\Feed\NodeInterface;
use FeedIo\Feed\Node\ElementInterface;
use FeedIo\RuleAbstract;
class OptionalField extends RuleAbstract
{
const NODE_NAME = 'default';
/**
* @param NodeInterface $node
* @param \DOMElement $domElement
* @return $this
*/
public function setProperty(NodeInterface $node, \DOMElement $domElement)
{
$element = $this->createElementFromDomNode($node, $domElement);
$node->addElement($element);
return $this;
}
/**
* @param NodeInterface $node
* @param ElementInterface $element
* @param \DOMNode $domNode
*/
private function addSubElements(NodeInterface $node, ElementInterface $element, \DOMNode $domNode)
{
if (!$domNode->hasChildNodes() || !$this->hasSubElements($domNode)) {
// no elements to add
return;
}
$this->addElementsFromNodeList($node, $element, $domNode->childNodes);
}
/**
* @param NodeInterface $node
* @param ElementInterface $element
* @param \DOMNodeList $childNodeList
*/
private function addElementsFromNodeList(NodeInterface $node, ElementInterface $element, \DOMNodeList $childNodeList)
{
foreach ($childNodeList as $childNode) {
if ($childNode instanceof \DOMText) {
continue;
}
$element->addElement($this->createElementFromDomNode($node, $childNode));
}
}
/**
* @param \DOMNode $domNode
* @return bool
*/
private function hasSubElements(\DOMNode $domNode)
{
foreach ($domNode->childNodes as $childDomNode) {
if (!$childDomNode instanceof \DOMText) {
return true;
}
}
return false;
}
/**
* @param NodeInterface $node
* @param \DOMNode $domNode
* @return ElementInterface
*/
private function createElementFromDomNode(NodeInterface $node, \DOMNode $domNode)
{
$element = $node->newElement();
$element->setName($domNode->nodeName);
$element->setValue($domNode->nodeValue);
foreach ($domNode->attributes as $attribute) {
$element->setAttribute($attribute->name, $attribute->value);
}
$this->addSubElements($node, $element, $domNode);
return $element;
}
/**
* creates the accurate DomElement content according to the $item's property
*
* @param \DomDocument $document
* @param NodeInterface $node
* @return \DomElement
*/
public function createElement(\DomDocument $document, NodeInterface $node)
{
$domElement = $document->createElement($this->getNodeName());
foreach ($node->getElementIterator($this->getNodeName()) as $element) {
$this->buildDomElement($domElement, $element);
}
return $domElement;
}
public function buildDomElement(\DomElement $domElement, ElementInterface $element)
{
$domElement->nodeValue = $element->getValue();
foreach ($element->getAttributes() as $name => $value) {
$domElement->setAttribute($name, $value);
}
/** @var ElementInterface $subElement */
foreach ($element->getAllElements() as $subElement) {
$subDomElement = $domElement->ownerDocument->createElement($subElement->getName());
$this->buildDomElement($subDomElement, $subElement);
$domElement->appendChild($subDomElement);
}
return $domElement;
}
}
src/FeedIo/Rule/PublicId.php 0000666 00000001570 13112056273 0011610 0 ustar 00 setPublicId($element->nodeValue);
return $node;
}
/**
* creates the accurate DomElement content according to the $item's property
*
* @param \DomDocument $document
* @param NodeInterface $node
* @return \DomElement
*/
public function createElement(\DomDocument $document, NodeInterface $node)
{
return $document->createElement($this->getNodeName(), $node->getPublicId());
}
}
src/FeedIo/Rule/Structure.php 0000666 00000003333 13112056273 0012114 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Rule;
use FeedIo\Feed\NodeInterface;
use FeedIo\RuleAbstract;
use FeedIo\RuleSet;
class Structure extends RuleAbstract
{
const NODE_NAME = 'structure';
/**
* @var \FeedIo\RuleSet
*/
protected $ruleSet;
/**
* @param string $nodeName
* @param RuleSet $ruleSet
*/
public function __construct($nodeName = null, $ruleSet = null)
{
parent::__construct($nodeName);
$this->ruleSet = is_null($ruleSet) ? new RuleSet() : $ruleSet;
}
/**
* @param NodeInterface $node
* @param \DOMElement $element
* @return mixed
*/
public function setProperty(NodeInterface $node, \DOMElement $element)
{
foreach ($element->childNodes as $domNode) {
if ($domNode instanceof \DomElement) {
$rule = $this->ruleSet->get($domNode->tagName);
$rule->setProperty($node, $domNode);
}
}
return $this;
}
/**
* creates the accurate DomElement content according to the $item's property
*
* @param \DomDocument $document
* @param NodeInterface $node
* @return \DomElement
*/
public function createElement(\DomDocument $document, NodeInterface $node)
{
$element = $document->createElement($this->getNodeName());
foreach ($this->ruleSet->getRules() as $rule) {
$element->appendChild($rule->createElement($document, $node));
}
return $element;
}
}
src/FeedIo/Rule/Title.php 0000666 00000002064 13112056273 0011175 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Rule;
use FeedIo\Feed\NodeInterface;
use FeedIo\RuleAbstract;
class Title extends RuleAbstract
{
const NODE_NAME = 'title';
/**
* @param NodeInterface $node
* @param \DOMElement $element
* @return $this
*/
public function setProperty(NodeInterface $node, \DOMElement $element)
{
$node->setTitle($element->nodeValue);
return $this;
}
/**
* creates the accurate DomElement content according to the $item's property
*
* @param \DomDocument $document
* @param NodeInterface $node
* @return \DomElement
*/
public function createElement(\DomDocument $document, NodeInterface $node)
{
$title = htmlspecialchars($node->getTitle());
return $document->createElement(static::NODE_NAME, $title);
}
}
src/FeedIo/RuleAbstract.php 0000666 00000003646 13112056273 0011607 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo;
use FeedIo\Feed\NodeInterface;
abstract class RuleAbstract
{
const NODE_NAME = 'node';
/**
* @var string
*/
protected $nodeName;
/**
* @param string $nodeName
*/
public function __construct($nodeName = null)
{
$this->nodeName = is_null($nodeName) ? static::NODE_NAME : $nodeName;
}
/**
* @return string
*/
public function getNodeName()
{
return $this->nodeName;
}
/**
* @param \DOMElement $element
* @param string $name
* @return string|null
*/
public function getAttributeValue(\DOMElement $element, $name)
{
if ($element->hasAttribute($name)) {
return $element->getAttribute($name);
}
return;
}
/**
* @param \DOMElement $element
* @param string $name
* @return string|null
*/
public function getChildValue(\DOMElement $element, $name)
{
$list = $element->getElementsByTagName($name);
if ( $list->length > 0 ) {
return $list->item(0)->nodeValue;
}
return;
}
/**
* Sets the accurate $item property according to the DomElement content
*
* @param NodeInterface $node
* @param \DOMElement $element
* @return mixed
*/
abstract public function setProperty(NodeInterface $node, \DOMElement $element);
/**
* creates the accurate DomElement content according to the $item's property
*
* @param \DomDocument $document
* @param NodeInterface $node
* @return \DomElement
*/
abstract public function createElement(\DomDocument $document, NodeInterface $node);
}
src/FeedIo/RuleSet.php 0000666 00000004271 13112056273 0010572 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo;
use FeedIo\Rule\OptionalField;
class RuleSet
{
/**
* @var \ArrayIterator
*/
protected $rules;
/**
* @var array
*/
protected $aliases = array();
/**
* @var RuleAbstract
*/
protected $default;
/**
* @param RuleAbstract $default default rule
*/
public function __construct(RuleAbstract $default = null)
{
$this->rules = new \ArrayIterator(array());
$this->default = is_null($default) ? new OptionalField() : $default;
}
/**
* @return RuleAbstract
*/
public function getDefault()
{
return $this->default;
}
/**
* @return array
*/
public function getRules()
{
return $this->rules->getArrayCopy();
}
/**
* @param RuleAbstract $rule
* @return $this
*/
public function add(RuleAbstract $rule, array $aliases = array())
{
$this->rules->offsetSet(strtolower($rule->getNodeName()), $rule);
$this->addAliases($rule->getNodeName(), $aliases);
return $this;
}
/**
* @param string $name
* @param array $aliases
* @return $this
*/
public function addAliases($name, array $aliases)
{
foreach ($aliases as $alias) {
$this->aliases[strtolower($alias)] = strtolower($name);
}
return $this;
}
/**
* @param string $name
* @return RuleAbstract
* @throws NotFoundException
*/
public function get($name)
{
$name = $this->getNameForAlias(strtolower($name));
if ($this->rules->offsetExists($name)) {
return $this->rules->offsetGet($name);
}
return $this->default;
}
/**
* @param string $alias
*/
public function getNameForAlias($alias)
{
if (array_key_exists($alias, $this->aliases)) {
return $this->aliases[$alias];
}
return $alias;
}
}
src/FeedIo/Standard/Atom.php 0000666 00000004616 13112056273 0011652 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Standard;
use DOMDocument;
use FeedIo\Rule\Atom\Author;
use FeedIo\Rule\Atom\LinkNode;
use FeedIo\Rule\Description;
use FeedIo\Rule\PublicId;
use FeedIo\Rule\Atom\Category;
use FeedIo\StandardAbstract;
class Atom extends StandardAbstract
{
/**
* Atom document must have a root node
*/
const ROOT_NODE_TAGNAME = 'feed';
const ITEM_NODE = 'entry';
/**
* Formats the document according to the standard's specification
* @param \DOMDocument $document
* @return \DOMDocument
*/
public function format(\DOMDocument $document)
{
$element = $document->createElement('feed');
$element->setAttribute('xmlns', 'http://www.w3.org/2005/Atom');
$document->appendChild($element);
return $document;
}
/**
* Tells if the parser can handle the feed or not
* @param \DOMDocument $document
* @return mixed
*/
public function canHandle(\DOMDocument $document)
{
return self::ROOT_NODE_TAGNAME === $document->documentElement->tagName;
}
/**
* @param DOMDocument $document
* @return \DomElement
*/
public function getMainElement(\DOMDocument $document)
{
return $document->documentElement;
}
/**
* Builds and returns a rule set to parse the root node
* @return \FeedIo\RuleSet
*/
public function buildFeedRuleSet()
{
$ruleSet = $this->buildBaseRuleSet();
$ruleSet
->add(new LinkNode())
->add(new PublicId('id'))
->add($this->getModifiedSinceRule('updated'))
;
return $ruleSet;
}
/**
* Builds and returns a rule set to parse an item
* @return \FeedIo\RuleSet
*/
public function buildItemRuleSet()
{
$ruleSet = $this->buildFeedRuleSet();
$ruleSet
->add(new Author())
->add(new Description('content'), ['summary']);
return $ruleSet;
}
/**
* @return RuleSet
*/
protected function buildBaseRuleSet()
{
$ruleSet = parent::buildBaseRuleSet();
$ruleSet->add(new Category());
return $ruleSet;
}
}
src/FeedIo/Standard/Rdf.php 0000666 00000002501 13112056273 0011454 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Standard;
use DOMDocument;
use FeedIo\RuleSet;
use FeedIo\Rule\Structure;
class Rdf extends Rss
{
/**
* Format version
*/
const VERSION = '1.0';
/**
* RDF document must have a root node
*/
const ROOT_NODE_TAGNAME = 'rdf';
/**
* publication date
*/
const DATE_NODE_TAGNAME = 'dc:date';
/**
* Tells if the parser can handle the feed or not
* @param \DOMDocument $document
* @return boolean
*/
public function canHandle(\DOMDocument $document)
{
return false !== strpos($document->documentElement->tagName, static::ROOT_NODE_TAGNAME);
}
/**
* @param DOMDocument $document
* @return \DomElement
*/
public function getMainElement(\DOMDocument $document)
{
return $document->documentElement;
}
/**
* @return RuleSet
*/
public function buildFeedRuleSet()
{
$ruleSet = new RuleSet();
$ruleSet->add(new Structure(static::CHANNEL_NODE_TAGNAME, $this->buildItemRuleSet()));
return $ruleSet;
}
}
src/FeedIo/Standard/Rss.php 0000666 00000005442 13112056273 0011517 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Standard;
use DOMDocument;
use FeedIo\Rule\Author;
use FeedIo\Rule\Description;
use FeedIo\Rule\Link;
use FeedIo\Rule\PublicId;
use FeedIo\Rule\Media;
use FeedIo\Rule\Category;
use FeedIo\StandardAbstract;
class Rss extends StandardAbstract
{
/**
* Format version
*/
const VERSION = '2.0';
/**
* RSS document must have a root node
*/
const ROOT_NODE_TAGNAME = 'rss';
/**
* node contains feed's metadata
*/
const CHANNEL_NODE_TAGNAME = 'channel';
/**
* publication date
*/
const DATE_NODE_TAGNAME = 'pubDate';
/**
* Formats the document according to the standard's specification
* @param \DOMDocument $document
* @return mixed
*/
public function format(\DOMDocument $document)
{
$rss = $document->createElement(static::ROOT_NODE_TAGNAME);
$rss->setAttribute('version', static::VERSION);
$channel = $document->createElement(static::CHANNEL_NODE_TAGNAME);
$rss->appendChild($channel);
$document->appendChild($rss);
return $document;
}
/**
* Tells if the parser can handle the feed or not
* @param \DOMDocument $document
* @return boolean
*/
public function canHandle(\DOMDocument $document)
{
return static::ROOT_NODE_TAGNAME === $document->documentElement->tagName;
}
/**
* @param DOMDocument $document
* @return \DomElement
*/
public function getMainElement(\DOMDocument $document)
{
return $document->documentElement->getElementsByTagName(static::CHANNEL_NODE_TAGNAME)->item(0);
}
/**
* @return RuleSet
*/
public function buildFeedRuleSet()
{
$ruleSet = $this->buildItemRuleSet();
$ruleSet->add(
$this->getModifiedSinceRule('lastPubDate'),
array('lastBuildDate')
);
return $ruleSet;
}
/**
* @return RuleSet
*/
public function buildItemRuleSet()
{
$ruleSet = $this->buildBaseRuleSet();
$ruleSet
->add(new Author())
->add(new Link())
->add(new PublicId())
->add(new Description())
->add(new Media())
->add($this->getModifiedSinceRule(static::DATE_NODE_TAGNAME));
return $ruleSet;
}
/**
* @return RuleSet
*/
protected function buildBaseRuleSet()
{
$ruleSet = parent::buildBaseRuleSet();
$ruleSet->add(new Category());
return $ruleSet;
}
}
src/FeedIo/StandardAbstract.php 0000666 00000006407 13112056273 0012436 0 ustar 00 dateTimeBuilder = $dateTimeBuilder;
}
/**
* Formats the document according to the standard's specification
* @param \DOMDocument $document
* @return mixed
*/
abstract public function format(\DOMDocument $document);
/**
* Tells if the parser can handle the feed or not
* @param \DOMDocument $document
* @return mixed
*/
abstract public function canHandle(\DOMDocument $document);
/**
* @param \DOMDocument $document
* @return \DomElement
*/
abstract public function getMainElement(\DOMDocument $document);
/**
* Builds and returns a rule set to parse the root node
* @return \FeedIo\RuleSet
*/
abstract public function buildFeedRuleSet();
/**
* Builds and returns a rule set to parse an item
* @return \FeedIo\RuleSet
*/
abstract public function buildItemRuleSet();
/**
* @return string
*/
public function getItemNodeName()
{
return static::ITEM_NODE;
}
/**
* @return string
*/
public function getDefaultDateFormat()
{
return static::DATETIME_FORMAT;
}
/**
* @return array
*/
public function getMandatoryFields()
{
return $this->mandatoryFields;
}
/**
* Returns the RuleSet used to parse the feed's main node
* @return \FeedIo\RuleSet
*/
public function getFeedRuleSet()
{
if (is_null($this->feedRuleSet)) {
$this->feedRuleSet = $this->buildFeedRuleSet();
}
return $this->feedRuleSet;
}
/**
* @return \FeedIo\RuleSet
*/
public function getItemRuleSet()
{
if (is_null($this->itemRuleSet)) {
$this->itemRuleSet = $this->buildItemRuleSet();
}
return $this->itemRuleSet;
}
/**
* @param string $tagName
* @return ModifiedSince
*/
public function getModifiedSinceRule($tagName)
{
$rule = new ModifiedSince($tagName);
$rule->setDefaultFormat($this->getDefaultDateFormat());
$rule->setDateTimeBuilder($this->dateTimeBuilder);
return $rule;
}
/**
* @return RuleSet
*/
protected function buildBaseRuleSet()
{
$ruleSet = $ruleSet = new RuleSet();
$ruleSet->add(new Title());
return $ruleSet;
}
}
tests/FeedIo/Adapter/FileSystem/ClientTest.php 0000666 00000002454 13112056273 0015305 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Adapter\FileSystem;
class ClientTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \FeedIo\Adapter\FileSystem\Client
*/
protected $object;
protected function setUp()
{
$this->object = new Client();
}
public function testGetResponse()
{
$response = $this->object->getResponse(
__DIR__.'/../../../samples/sample-atom.xml',
new \DateTime()
);
$this->assertInstanceOf('\FeedIo\Adapter\ResponseInterface', $response);
$this->assertEquals(file_get_contents(__DIR__.'/../../../samples/sample-atom.xml'), $response->getBody());
$this->assertEquals(array(), $response->getHeaders());
$this->assertEquals('', $response->getHeader('name'));
$this->assertInstanceOf('\DateTime', $response->getLastModified());
}
/**
* @expectedException \FeedIo\Adapter\NotFoundException
*/
public function testGetNotFound()
{
$client = new Client();
$client->getResponse('/opt/nowhere.xml', new \DateTime());
}
}
tests/FeedIo/Adapter/Guzzle/ClientTest.php 0000666 00000005642 13112056273 0014503 0 ustar 00 a great stream
XML;
/**
* @var \FeedIo\Adapter\Guzzle\Client
*/
protected $object;
protected function setUp()
{
$this->object = new Client($this->getGuzzleClient());
}
public function testGetResponse()
{
$response = $this->object->getResponse('http://somewhere', new \DateTime());
$this->assertInstanceOf('\FeedIo\Adapter\ResponseInterface', $response);
$this->assertEquals($this->body, $response->getBody());
$this->assertEquals(array(), $response->getHeaders());
$this->assertEquals('Tue, 15 Nov 1994 12:45:26 GMT', $response->getHeader('name'));
$this->assertInstanceOf('\DateTime', $response->getLastModified());
$this->assertEquals(1994, $response->getLastModified()->format('Y'));
}
/**
* @expectedException \FeedIo\Adapter\NotFoundException
*/
public function testGetNotFound()
{
$client = new Client($this->getErroredClient(404));
$client->getResponse('http://test', new \DateTime());
}
/**
* @expectedException \FeedIo\Adapter\ServerErrorException
*/
public function testGetServerError()
{
$client = new Client($this->getErroredClient(500));
$client->getResponse('http://test', new \DateTime());
}
/**
* @param $statusCode
* @return \GuzzleHttp\ClientInterface
*/
protected function getErroredClient($statusCode)
{
$exception = new BadResponseException(
'message',
new \GuzzleHttp\Psr7\Request('get', 'http://test'),
new \GuzzleHttp\Psr7\Response("{$statusCode}")
);
$guzzleClient = $this->getMockForAbstractClass('\GuzzleHttp\ClientInterface');
$guzzleClient->expects($this->any())->method('request')->will($this->throwException($exception));
return $guzzleClient;
}
/**
* @return \GuzzleHttp\ClientInterface
*/
protected function getGuzzleClient()
{
$response = $this->getMockForAbstractClass('\Psr\Http\Message\ResponseInterface');
$response->expects($this->any())->method('getBody')->will($this->returnValue($this->body));
$response->expects($this->any())->method('getHeader')->will($this->returnValue('Tue, 15 Nov 1994 12:45:26 GMT'));
$response->expects($this->any())->method('getHeaders')->will($this->returnValue(array()));
$response->expects($this->any())->method('hasHeader')->will($this->returnValue(true));
$client = $this->createMock('\GuzzleHttp\Client');
$client->expects($this->any())->method('request')->will($this->returnValue($response));
return $client;
}
}
tests/FeedIo/Adapter/NullClientTest.php 0000666 00000001456 13112056273 0014055 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Adapter;
class NullClientTest extends \PHPUnit_Framework_TestCase
{
public function testGetResponse()
{
$client = new NullClient();
$response = $client->getResponse('', new \DateTime());
$this->assertInstanceOf('\FeedIo\Adapter\NullResponse', $response);
$this->assertInstanceOf('\DateTime', $response->getLastModified());
$this->assertNull($response->getBody());
$this->assertInternalType('array', $response->getHeaders());
$this->assertEquals('foo', $response->getHeader('foo'));
}
}
tests/FeedIo/DateRuleAbstractTest.php 0000666 00000002250 13112056273 0013606 0 ustar 00 object = $this->getDateRule();
}
public function testSetDateTimeBuilder()
{
$this->assertInstanceOf(
'\FeedIo\DateRuleAbstract',
$this->object->setDateTimeBuilder(new DateTimeBuilder())
);
}
public function testGetDateTimeBuilder()
{
$dateTimeBuilder = new DateTimeBuilder();
$this->object->setDateTimeBuilder($dateTimeBuilder);
$this->assertEquals($dateTimeBuilder, $this->object->getDateTimeBuilder());
}
/**
* @expectedException \UnexpectedValueException
*/
public function testGetDateTimeBuilderFailure()
{
$this->object->getDateTimeBuilder();
}
/**
* @return \FeedIo\DateRuleAbstract
*/
protected function getDateRule()
{
return $this->getMockForAbstractClass('\FeedIo\DateRuleAbstract');
}
}
tests/FeedIo/Factory/Builder/GuzzleClientBuilderTest.php 0000666 00000001323 13112056273 0017340 0 ustar 00 assertEquals('\GuzzleHttp\Client', $builder->getMainClassName());
}
public function testGetPackageName()
{
$builder = new GuzzleClientBuilder();
$this->assertEquals('guzzlehttp/guzzle', $builder->getPackageName());
}
public function testGetClient()
{
$builder = new GuzzleClientBuilder();
$this->assertInstanceOf('\FeedIo\Adapter\ClientInterface', $builder->getClient());
}
}
tests/FeedIo/Factory/Builder/MonologBuilderTest.php 0000666 00000002656 13112056273 0016345 0 ustar 00 assertEquals('Monolog\Logger', $builder->getMainClassName());
}
public function testGetPackageName()
{
$builder = new MonologBuilder();
$this->assertEquals('monolog/monolog', $builder->getPackageName());
}
public function testNewHandler()
{
$builder = new MonologBuilder();
$handler = $builder->newHandler('Monolog\Handler\StreamHandler', ['php://stdout', Logger::DEBUG]);
$this->assertInstanceOf('Monolog\Handler\StreamHandler', $handler);
}
/**
* @expectedException \InvalidArgumentException
*/
public function testNewInvalidHandler()
{
$builder = new MonologBuilder();
$handler = $builder->newHandler('stdClass', []);
}
public function testGetLogger()
{
$builder = new MonologBuilder();
$logger = $builder->getLogger();
$this->assertInstanceOf('Monolog\Logger', $logger);
$handlers = $logger->getHandlers();
$this->assertCount(1, $handlers);
foreach ( $handlers as $handler) {
$this->assertInstanceOf('Monolog\Handler\StreamHandler', $handler);
}
}
}
tests/FeedIo/Factory/Builder/NullLoggerBuilderTest.php 0000666 00000001232 13112056273 0016772 0 ustar 00 assertEquals('\Psr\Log\NullLogger', $builder->getMainClassName());
}
public function testGetPackageName()
{
$builder = new NullLoggerBuilder();
$this->assertEquals('psr/log', $builder->getPackageName());
}
public function testGetLogger()
{
$builder = new NullLoggerBuilder();
$logger = $builder->getLogger();
$this->assertInstanceOf('\Psr\Log\NullLogger', $logger);
}
}
tests/FeedIo/FactoryTest.php 0000666 00000007660 13112056273 0012036 0 ustar 00 assertTrue($factory->checkDependency(
$this->getBuilder('stdClass', 'php/php')
));
}
/**
* @expectedException FeedIo\Factory\MissingDependencyException
*/
public function testCheckMissingDependency()
{
$factory = new Factory();
$factory->checkDependency(
$this->getBuilder('IDontExist', 'php/php')
);
}
public function testSetLoggerBuilder()
{
$factory = new Factory();
$loggerBuilder = $this->getMockForAbstractClass('\FeedIo\Factory\LoggerBuilderInterface');
$factory->setLoggerBuilder($loggerBuilder);
$this->assertAttributeInstanceOf('\FeedIo\Factory\LoggerBuilderInterface', 'loggerBuilder', $factory);
}
public function testSetClientBuilder()
{
$factory = new Factory();
$clientBuilder = $this->getMockForAbstractClass('\FeedIo\Factory\ClientBuilderInterface');
$factory->setClientBuilder($clientBuilder);
$this->assertAttributeInstanceOf('\FeedIo\Factory\ClientBuilderInterface', 'clientBuilder', $factory);
}
public function testExtractConfig()
{
$config = ['foo' => 'bar'];
$builderConfig = ['config' => $config];
$factory = new Factory();
$this->assertEquals($config, $factory->extractConfig($builderConfig));
}
public function testExtractEmptyConfig()
{
$builderConfig = [];
$factory = new Factory();
$this->assertEquals([], $factory->extractConfig($builderConfig));
}
public function testCreate()
{
$factory = Factory::create();
$this->assertInstanceOf('\FeedIo\Factory', $factory);
}
public function testGetBuilder()
{
$factory = new Factory();
$this->assertInstanceOf('\FeedIo\Factory\Builder\\MonologBuilder', $factory->getBuilder('monolog'));
}
public function testGetExternalBuilder()
{
$factory = new Factory();
$this->assertInstanceOf('stdClass', $factory->getBuilder('stdClass'));
}
public function testCreateWithMonolog()
{
$factory = Factory::create(['builder' => 'monolog']);
$this->assertAttributeInstanceOf('\FeedIo\Factory\Builder\\MonologBuilder', 'loggerBuilder', $factory);
}
public function testGetFeedIoAfterCreate()
{
$factory = Factory::create();
$feedIo = $factory->getFeedIo();
$this->assertInstanceOf('\FeedIo\FeedIo', $feedIo);
}
public function testGetFeedIo()
{
$factory = new Factory();
$clientBuilder = $this->getMockForAbstractClass('\FeedIo\Factory\ClientBuilderInterface');
$clientBuilder
->expects($this->once())
->method('getClient')
->will($this->returnValue(new \FeedIo\Adapter\Guzzle\Client(new \GuzzleHttp\Client())));
$factory->setClientBuilder($clientBuilder);
$loggerBuilder = $this->getMockForAbstractClass('\FeedIo\Factory\LoggerBuilderInterface');
$loggerBuilder
->expects($this->once())
->method('getLogger')
->will($this->returnValue(new \Psr\Log\NullLogger));
$factory->setLoggerBuilder($loggerBuilder);
$this->assertInstanceOf('FeedIo\FeedIo', $factory->getFeedIo());
}
protected function getBuilder($className, $package)
{
$builder = $this->getMockForAbstractClass('\FeedIo\Factory\BuilderInterface');
$builder->expects($this->any())->method('getMainClassName')->will($this->returnValue($className));
$builder->expects($this->any())->method('getPackageName')->will($this->returnValue($package));
return $builder;
}
}
tests/FeedIo/Feed/ElementsAwareClass.php 0000666 00000001547 13112056273 0014152 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Feed;
/**
* Class ElementsAwareClass
* @package FeedIo\Feed
*
* Simple class using the ElementsAwareTrait to test this trait
*/
class ElementsAwareClass
{
use ElementsAwareTrait;
public function __construct()
{
$this->initElements();
}
/**
* @param string $name element name
* @param string $value element value
* @return $this
*/
public function set($name, $value)
{
$element = $this->newElement();
$element->setName($name);
$element->setValue($value);
$this->addElement($element);
return $this;
}
}
tests/FeedIo/Feed/ElementsAwareTraitTest.php 0000666 00000001201 13112056273 0015013 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Feed;
class ElementsAwareTraitTest extends \PHPUnit_Framework_TestCase
{
public function testGetElementsAsGenerator()
{
$object = new ElementsAwareClass();
$object->set('foo', 'bar');
$elements = $object->getElementsGenerator();
$this->assertEquals('foo', $elements->key());
$this->assertEquals('bar', $elements->current());
}
}
tests/FeedIo/Feed/Item/AuthorTest.php 0000666 00000001732 13112056273 0013424 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Feed\Item;
class AuthorTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \FeedIo\Feed\Item\Author
*/
protected $object;
protected function setUp()
{
$this->object = new Author();
}
public function testSetName()
{
$this->object->setName('John Doe');
$this->assertEquals('John Doe', $this->object->getName());
}
public function testSetUri()
{
$this->object->setUri('http://localhost');
$this->assertEquals('http://localhost', $this->object->getUri());
}
public function testSetEmail()
{
$this->object->setEmail('john@localhost');
$this->assertEquals('john@localhost', $this->object->getEmail());
}
}
tests/FeedIo/Feed/Item/MediaTest.php 0000666 00000001551 13112056273 0013200 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Feed\Item;
class MediaTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \FeedIo\Feed\Item\Media
*/
protected $object;
protected function setUp()
{
$this->object = new Media();
}
public function testSetType()
{
$this->object->setType('image/jpeg');
$this->assertEquals('image/jpeg', $this->object->getType());
}
public function testSetLength()
{
$this->object->setLength('87669');
$this->assertInternalType('integer', $this->object->getLength());
$this->assertEquals(87669, $this->object->getLength());
}
}
tests/FeedIo/Feed/ItemTest.php 0000666 00000011134 13112056273 0012157 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Feed;
use FeedIo\Feed\Node\Element;
use FeedIo\Feed\Item\Media;
use FeedIo\Feed\Item\Author;
class ItemTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \FeedIo\Feed\Item
*/
protected $object;
protected function setUp()
{
$this->object = new Item();
}
public function testGetElementIterator()
{
$element = new Element();
$element->setName('foo');
$this->object->addElement($element);
$element2 = new Element();
$element2->setName('bar');
$this->object->addElement($element2);
$iterator = $this->object->getElementIterator('foo');
$this->assertInstanceOf('\FeedIo\Feed\Node\ElementIterator', $iterator);
$this->assertTrue($iterator->count() > 0);
$count = 0;
foreach ($iterator as $element) {
$count++;
$this->assertEquals('foo', $element->getName());
}
$this->assertEquals(1, $count);
}
public function testNewElement()
{
$this->assertInstanceOf('\FeedIo\Feed\Node\ElementInterface', $this->object->newElement());
}
public function testSet()
{
$this->object->set('foo', 'bar');
$this->assertEquals('bar', $this->object->getValue('foo'));
}
public function testGetValue()
{
$this->assertNull($this->object->getValue('null'));
$this->object->set('name', 'value');
$this->assertEquals('value', $this->object->getValue('name'));
}
public function testSetValue()
{
$this->object->set('foo', 'bar');
$element = new Element();
$element->setName('foo');
$element->setValue('bar');
$this->assertAttributeContainsOnly($element, 'elements', $this->object);
}
public function testHasElement()
{
$this->assertFalse($this->object->hasElement('foo'));
$this->object->set('name', 'value');
$this->assertFalse($this->object->hasElement('foo'));
$this->assertTrue($this->object->hasElement('name'));
}
public function testGetAllElements()
{
$element = new Element();
$element->setName('foo');
$this->object->addElement($element);
$element2 = new Element();
$element2->setName('bar');
$this->object->addElement($element2);
$iterator = $this->object->getAllElements();
$this->assertInstanceOf('\ArrayIterator', $iterator);
$this->assertEquals(2, $iterator->count());
}
public function testListElements()
{
$element = new Element();
$element->setName('foo');
$this->object->addElement($element);
$element2 = new Element();
$element2->setName('bar');
$this->object->addElement($element2);
$elements = array();
foreach($this->object->listElements() as $element) {
$elements[] = $element;
}
$this->assertEquals(array('foo', 'bar'), $elements);
}
public function testNewMedia()
{
$this->assertInstanceOf('\FeedIo\Feed\Item\MediaInterface', $this->object->newMedia());
}
public function testAddMedia()
{
$media = new Media();
$media->setType('audio/mp3');
$this->assertInstanceOf('FeedIo\Feed\Item', $this->object->addMedia($media));
$this->assertAttributeContains($media, 'medias', $this->object);
}
public function testHasMedia()
{
$this->assertFalse($this->object->hasMedia());
$this->object->addMedia(new Media());
$this->assertTrue($this->object->hasMedia());
}
public function testGetMedias()
{
$this->object->addMedia(new Media());
$iterator = $this->object->getMedias();
$this->assertInstanceOf('\ArrayIterator', $iterator);
$count = 0;
foreach ($iterator as $media) {
$count++;
$this->assertInstanceOf('FeedIo\Feed\Item\MediaInterface', $media);
}
$this->assertEquals(1, $count);
}
public function testSetAuthor()
{
$author = new Author();
$author->setName('test');
$this->object->setAuthor($author);
$this->assertEquals($author->getName(), $this->object->getAuthor()->getName());
}
public function testNewAuthor()
{
$this->assertInstanceOf('\FeedIo\Feed\Item\AuthorInterface', $this->object->newAuthor());
}
}
tests/FeedIo/Feed/Node/CategoryTest.php 0000666 00000002063 13112056273 0013724 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Feed\Node;
class CategoryTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \FeedIo\Feed\Item\Category
*/
protected $object;
protected function setUp()
{
$this->object = new Category;
}
public function testScheme()
{
$scheme = 'http://...';
$this->object->setScheme($scheme);
$this->assertEquals($scheme, $this->object->getScheme());
}
public function testLabel()
{
$label = 'a nice label';
$this->object->setLabel($label);
$this->assertEquals($label, $this->object->getLabel());
}
public function testTerm()
{
$term = 'nice';
$this->object->setTerm($term);
$this->assertEquals($term, $this->object->getTerm());
}
}
tests/FeedIo/Feed/Node/ElementIteratorTest.php 0000666 00000002207 13112056273 0015252 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Feed\Node;
class ElementIteratorTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \FeedIo\Feed\Item\ElementIterator
*/
protected $object;
protected function setUp()
{
$array = new \ArrayIterator();
$element1 = new Element();
$element1->setName('foo');
$element2 = new Element();
$element2->setName('bar');
$array->append($element1);
$array->append($element2);
$this->object = new ElementIterator($array, 'foo');
}
public function testValid()
{
foreach ($this->object as $element) {
$this->assertEquals('foo', $element->getName());
}
}
public function testCount()
{
$this->assertEquals(1, $this->object->count());
$filter = new ElementIterator(new \ArrayIterator(), 'foo');
$this->assertEquals(0, $filter->count());
}
}
tests/FeedIo/Feed/Node/ElementTest.php 0000666 00000002334 13112056273 0013541 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Feed\Node;
class ElementTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \FeedIo\Feed\Item\Element
*/
protected $object;
public function testSetName()
{
$element = new Element();
$element->setName('foo');
$this->assertEquals('foo', $element->getName());
}
public function testSetValue()
{
$element = new Element();
$text = 'lorem ipsum';
$element->setValue($text);
$this->assertEquals($text, $element->getValue());
}
public function testAttributes()
{
$element = new Element();
$element->setAttribute('url', 'http://foo.com');
$this->assertEquals('http://foo.com', $element->getAttribute('url'));
$this->assertEquals(array('url' => 'http://foo.com'), $element->getAttributes());
}
public function testGetNullAttribute()
{
$element = new Element();
$this->assertNull($element->getAttribute('null'));
}
}
tests/FeedIo/Feed/NodeTest.php 0000666 00000006553 13112056273 0012157 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Feed;
use FeedIo\Feed\Node\Category;
class NodeTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \FeedIo\Feed\Node
*/
protected $object;
protected function setUp()
{
$this->object = new Node();
}
public function testTitle()
{
$title = 'my brilliant title';
$this->assertInstanceOf('\FeedIo\Feed\Node', $this->object->setTitle($title));
$this->assertEquals($title, $this->object->getTitle());
}
public function testPublicId()
{
$publicId = 'a12';
$this->assertInstanceOf('\FeedIo\Feed\Node', $this->object->setPublicId($publicId));
$this->assertEquals($publicId, $this->object->getPublicId());
}
public function testDescription()
{
$description = 'lorem ipsum';
$this->assertInstanceOf('\FeedIo\Feed\Node', $this->object->setDescription($description));
$this->assertEquals($description, $this->object->getDescription());
}
public function testLink()
{
$link = 'http://localhost';
$this->assertInstanceOf('\FeedIo\Feed\Node', $this->object->setLink($link));
$this->assertEquals($link, $this->object->getLink());
}
public function testLastModified()
{
$lastModified = new \DateTime();
$this->assertInstanceOf('\FeedIo\Feed\Node', $this->object->setLastModified($lastModified));
$this->assertEquals($lastModified, $this->object->getLastModified());
}
public function testNewCategory()
{
$this->assertInstanceOf('\FeedIo\Feed\Node\CategoryInterface', $this->object->newCategory());
}
public function testGetCategoryAsGenerator()
{
$category = new Category();
$category->setLabel('test');
$this->object->addCategory($category);
$categories = $this->object->getCategoriesGenerator();
$this->assertEquals('test', $categories->current());
}
public function testToArray()
{
$category = new Category();
$category->setLabel('test');
$this->object->set('foo', 'bar')
->setLastModified(new \DateTime())
->setTitle('my title')
->addCategory($category)
->setDescription('lorem ipsum');
$out = $this->object->toArray();
$this->assertEquals('lorem ipsum', $out['description']);
$this->assertEquals('my title', $out['title']);
$this->assertEquals('bar', $out['elements']['foo']);
$this->assertEquals('test', $out['categories'][0]);
$this->assertInternalType('string', $out['lastModified']);
}
public function testAddCategory()
{
$category = new \FeedIo\Feed\Node\Category;
$category->setTerm('term');
$this->object->addCategory($category);
$categories = $this->object->getCategories();
$count = 0;
foreach( $categories as $testedCategory ) {
$count++;
$this->assertEquals('term', $testedCategory->getTerm());
$this->assertEquals($category, $testedCategory);
}
$this->assertEquals(1, $count);
}
}
tests/FeedIo/FeedIoTest.php 0000666 00000013155 13112056273 0011556 0 ustar 00 getMockForAbstractClass('\FeedIo\Adapter\ClientInterface');
$response = $this->createMock('FeedIo\Adapter\ResponseInterface');
$response->expects($this->any())->method('getBody')->will($this->returnValue(
file_get_contents(dirname(__FILE__)."/../samples/expected-atom.xml")
));
$response->expects($this->any())->method('getLastModified')->will($this->returnValue(new \DateTime()));
$client->expects($this->any())->method('getResponse')->will($this->returnValue($response));
$this->object = new FeedIo($client, new \Psr\Log\NullLogger());
}
/**
* Tears down the fixture, for example, closes a network connection.
* This method is called after a test is executed.
*/
protected function tearDown()
{
}
/**
* @covers FeedIo\FeedIo::__construct
* @covers FeedIo\FeedIo::loadCommonStandards
*/
public function testConstruct()
{
$client = $this->getMockForAbstractClass('\FeedIo\Adapter\ClientInterface');
$feedIo = new FeedIo($client, new \Psr\Log\NullLogger());
$this->assertInstanceOf('\FeedIo\Reader', $feedIo->getReader());
}
/**
* @covers FeedIo\FeedIo::getCommonStandards
*/
public function testGetCommonStandards()
{
$standards = $this->object->getCommonStandards();
$this->assertInternalType('array', $standards);
foreach ($standards as $standard) {
$this->assertInstanceOf('\FeedIo\StandardAbstract', $standard);
}
}
public function testFixerSet()
{
$this->assertInstanceOf('\FeedIo\Reader\FixerSet', $this->object->getFixerSet());
}
public function testGetBaseFixers()
{
$fixers = $this->object->getBaseFixers();
foreach ($fixers as $fixer) {
$this->assertInstanceOf('\FeedIo\Reader\FixerAbstract', $fixer);
}
}
public function testAddFilter()
{
$filter = $this->getMockForAbstractClass('FeedIo\FilterInterface');
$this->object->addFilter($filter);
}
/**
* @covers FeedIo\FeedIo::addStandard
*/
public function testAddStandard()
{
$this->object->addStandard('atom2', new Atom(new DateTimeBuilder()));
$this->assertInstanceOf('\FeedIo\Standard\Atom', $this->object->getStandard('atom2'));
}
/**
* @covers FeedIo\FeedIo::getDateTimeBuilder
*/
public function testGetDateTimeBuilder()
{
$this->assertInstanceOf('\FeedIo\Rule\DateTimeBuilder', $this->object->getDateTimeBuilder());
}
/**
* @covers FeedIo\FeedIo::getReader
*/
public function testGetReader()
{
$this->assertInstanceOf('\FeedIo\Reader', $this->object->getReader());
}
/**
* @covers FeedIo\FeedIo::setReader
*/
public function testSetReader()
{
$logger = new \Psr\Log\NullLogger();
$reader = new Reader(
new Adapter\Guzzle\Client(
new \GuzzleHttp\Client(),
$logger
),
$logger
);
$this->object->setReader($reader);
$this->assertEquals($reader, $this->object->getReader());
}
/**
* @covers FeedIo\FeedIo::read
*/
public function testRead()
{
$result = $this->object->read('http://whatever.com');
$this->assertInstanceOf('\FeedIo\Reader\Result', $result);
$this->assertEquals('sample title', $result->getFeed()->getTitle());
}
/**
* @covers FeedIo\FeedIo::readSince
*/
public function testReadSince()
{
$result = $this->object->readSince('http://whatever.com', new \DateTime());
$this->assertInstanceOf('\FeedIo\Reader\Result', $result);
$this->assertEquals('sample title', $result->getFeed()->getTitle());
}
/**
* @covers FeedIo\FeedIo::format
* @covers FeedIo\FeedIo::logAction
*/
public function testFormat()
{
$feed = new Feed();
$feed->setLastModified(new \DateTime());
$document = $this->object->format($feed, 'atom');
$this->assertInstanceOf('DomDocument', $document);
}
/**
* @covers FeedIo\FeedIo::toRss
*/
public function testToRss()
{
$feed = new Feed();
$feed->setLastModified(new \DateTime());
$document = $this->object->toRss($feed);
$this->assertInstanceOf('DomDocument', $document);
$this->assertEquals('rss', $document->documentElement->tagName);
}
/**
* @covers FeedIo\FeedIo::toAtom
*/
public function testToAtom()
{
$feed = new Feed();
$feed->setLastModified(new \DateTime());
$document = $this->object->toAtom($feed);
$this->assertInstanceOf('DomDocument', $document);
$this->assertEquals('feed', $document->documentElement->tagName);
}
/**
* @covers FeedIo\FeedIo::getStandard
*/
public function testGetStandard()
{
$this->assertInstanceOf('\FeedIo\Standard\Atom', $this->object->getStandard('atom'));
}
/**
* @expectedException \OutOfBoundsException
*/
public function testWrongStandard()
{
$this->object->getStandard('fake');
}
}
tests/FeedIo/FeedTest.php 0000666 00000006114 13112056273 0011263 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo;
class FeedTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \FeedIo\Feed
*/
protected $object;
/**
*
*/
public function setUp()
{
$this->object = new Feed();
}
/**
* @covers FeedIo\Feed::__construct
*/
public function testConstruct()
{
$this->assertAttributeEquals(new \ArrayIterator(), 'items', $this->object);
}
public function testNext()
{
$item1 = new Feed\Item();
$item2 = clone $item1;
$item2->setTitle('item2');
$this->object->add($item1);
$this->object->add($item2);
$this->object->rewind();
$this->assertEquals($item1, $this->object->current());
$this->assertNull($this->object->next());
$this->assertEquals($item2, $this->object->current());
}
public function testIsValid()
{
$item = new Feed\Item();
$this->object->add($item);
$this->object->rewind();
$this->assertTrue($this->object->valid());
$this->object->next();
$this->assertFalse($this->object->valid());
}
public function testRewind()
{
$item = new Feed\Item();
$this->object->add($item);
$this->object->next();
$this->assertFalse($this->object->valid());
$this->object->rewind();
$this->assertEquals($item, $this->object->current());
}
public function testKey()
{
$this->assertNull($this->object->key());
$this->object->add(new Feed\Item());
$this->object->add(new Feed\Item());
$this->assertEquals(0, $this->object->key());
$this->object->next();
$this->assertEquals(1, $this->object->key());
}
public function testAdd()
{
$item = new Feed\Item();
$this->object->add($item);
$this->assertAttributeEquals(new \ArrayIterator(array($item)), 'items', $this->object);
$this->assertEquals($this->object->current(), $item);
}
public function testUrl()
{
$url = 'http://localhost';
$feed = new Feed;
$feed->setUrl($url);
$this->assertEquals($url, $feed->getUrl());
}
public function testToArray()
{
$item = new Feed\Item();
$item->setTitle('foo-bar');
$this->object->add($item);
$out = $this->object->toArray();
$this->assertEquals('foo-bar', $out['items'][0]['title']);
}
public function testJsonSerialize()
{
$item = new Feed\Item();
$item->setTitle('foo-bar');
$this->object->add($item);
$this->object->setTitle('hello');
$this->object->setLastModified(new \DateTime());
$json = json_encode($this->object);
$this->assertInternalType('string', $json);
$this->assertInstanceOf('stdClass', json_decode($json));
}
}
tests/FeedIo/Filter/ModifiedSinceTest.php 0000666 00000002077 13112056273 0014353 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Filter;
use FeedIo\Feed\Item;
use FeedIo\Feed;
class ModifiedSinceTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \FeedIo\Filter\ModifiedSince
*/
protected $object;
protected function setUp()
{
$this->object = new ModifiedSince(new \DateTime('-10 days'));
}
public function testIsValid()
{
$item = new Item();
$item->setLastModified(new \DateTime('-8 days'));
$this->assertTrue($this->object->isValid($item));
}
public function testIsTooOld()
{
$item = new Item();
$item->setLastModified(new \DateTime('-12 days'));
$this->assertFalse($this->object->isValid($item));
}
public function testIsNotValid()
{
$item = new Item();
$this->assertFalse($this->object->isValid($item));
}
}
tests/FeedIo/FormatterTest.php 0000666 00000006073 13112056273 0012367 0 ustar 00 add(new Title());
$document = new \DOMDocument();
$document->loadXML('');
$standard = $this->getMockForAbstractClass(
'\FeedIo\StandardAbstract',
array(new DateTimeBuilder()),
'StandardMock',
true,
true,
true,
['format', 'getMainElement', 'setHeaders', 'buildFeedRuleSet', 'buildItemRuleSet']
);
$standard->expects($this->any())->method('format')->will($this->returnValue(
$document
));
$standard->expects($this->any())->method('getMainElement')->will($this->returnValue(
$document->documentElement->firstChild
));
$standard->expects($this->any())->method('setHeaders')->will($this->returnSelf());
$standard->expects($this->any())->method('buildFeedRuleSet')->will($this->returnValue($ruleSet));
$standard->expects($this->any())->method('buildItemRuleSet')->will($this->returnValue($ruleSet));
$this->object = new Formatter($standard, new NullLogger());
}
public function testGetEmptyDocument()
{
$this->assertInstanceOf('\DomDocument', $this->object->getEmptyDocument());
}
public function testGetDocument()
{
$this->assertInstanceOf('\DomDocument', $this->object->getDocument());
}
public function testGetAllRules()
{
$item = new Item();
$item->set('title', 'the title');
$item->set('description', 'the description');
$rules = $this->object->getAllRules(new RuleSet(), $item);
$this->assertCount(2, $rules);
$ruleNames = array('title', 'description');
foreach ($rules as $rule) {
$this->assertEquals(current($ruleNames), $rule->getNodeName());
next($ruleNames);
}
}
public function testToString()
{
$feed = new Feed();
$feed->setTitle('foo-bar');
$out = $this->object->toString($feed);
$this->assertInternalType('string', $out);
$this->assertContains('foo-bar', $out);
$this->assertEquals('
foo-bar
', $out);
}
public function testToDom()
{
$feed = new Feed();
$this->assertInstanceOf('\DomDocument', $this->object->toDom($feed));
}
public function testSetItems()
{
$feed = new Feed();
$feed->add(new Item());
$feed->add(new Item());
$document = $this->object->getDocument();
$this->object->setItems($document, $feed);
$this->assertEquals(2, $document->getElementsByTagName('item')->length);
}
}
tests/FeedIo/Parser/AtomTest.php 0000666 00000002462 13112056273 0012556 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Parser;
use FeedIo\Feed;
use FeedIo\Rule\DateTimeBuilder;
use FeedIo\Standard\Atom;
class AtomTest extends ParserTestAbstract
{
const SAMPLE_FILE = 'sample-atom.xml';
const ENCLOSURE_FILE = 'enclosure-atom.xml';
/**
* @var \FeedIo\Parser\Atom
*/
protected $object;
/**
* @return \FeedIo\StandardAbstract
*/
public function getStandard()
{
return new Atom(new DateTimeBuilder());
}
public function testEnclosure()
{
$document = $this->buildDomDocument(static::ENCLOSURE_FILE);
$feed = $this->object->parse($document, new Feed());
$count = 0;
foreach ($feed as $item) {
$count++;
$this->assertTrue($item->hasMedia());
$media = $item->getMedias()->current();
$this->assertInstanceOf('\FeedIo\Feed\Item\MediaInterface', $media);
$this->assertEquals('video/mpeg', $media->getType());
$this->assertInternalType('string', $media->getUrl());
}
$this->assertEquals(1, $count);
}
}
tests/FeedIo/Parser/ParserTestAbstract.php 0000666 00000006474 13112056273 0014605 0 ustar 00 getStandard();
$this->object = new Parser($standard, new NullLogger());
}
public function testCanHandle()
{
$document = $this->buildDomDocument(static::SAMPLE_FILE);
$this->assertTrue($this->object->getStandard()->canHandle($document));
}
public function testGetMainElement()
{
$document = $this->buildDomDocument(static::SAMPLE_FILE);
$element = $this->object->getStandard()->getMainElement($document);
$this->assertInstanceOf('\DomElement', $element);
}
public function testBuildFeedRuleSet()
{
$ruleSet = $this->object->getStandard()->buildFeedRuleSet();
$this->assertInstanceOf('\FeedIo\RuleSet', $ruleSet);
}
public function testBuildItemRuleSet()
{
$ruleSet = $this->object->getStandard()->buildItemRuleSet();
$this->assertInstanceOf('\FeedIo\RuleSet', $ruleSet);
}
public function testParseBody()
{
$document = $this->buildDomDocument(static::SAMPLE_FILE);
$feed = $this->object->parse($document, new Feed());
$this->assertInstanceOf('\FeedIo\Feed', $feed);
$this->assertNotEmpty($feed->getTitle(), 'title must not be empty');
$this->assertNotEmpty($feed->getLink(), 'link must not be empty');
$this->assertNotEmpty($feed->getLastModified(), 'lastModified must not be empty');
$this->assertTrue($feed->valid(), 'the feed must contain an item');
$this->runCategoriesTest($feed);
$item = $feed->current();
$this->assertInstanceOf('\FeedIo\Feed\ItemInterface', $item);
if ($item instanceof \FeedIo\Feed\ItemInterface) {
$this->assertNotEmpty($item->getTitle());
$this->assertNotEmpty($item->getDescription());
$this->assertNotEmpty($item->getPublicId());
$this->assertNotEmpty($item->getLastModified());
$this->assertNotEmpty($item->getLink());
$this->assertCount(1, $item->getAllElements());
$this->assertTrue($item->hasElement('extra'));
$this->runCategoriesTest($item);
}
}
protected function runCategoriesTest(\FeedIo\Feed\NodeInterface $node)
{
$categories = $node->getCategories();
$this->assertCount(1, $categories);
$category = $categories->current();
$this->assertInstanceOf('\FeedIo\Feed\Node\CategoryInterface', $category);
$this->assertNotEmpty($category->getTerm());
$this->assertNotEmpty($category->getLabel());
}
/**
* @param $filename
* @return \DOMDocument
*/
protected function buildDomDocument($filename)
{
$file = dirname(__FILE__)."/../../samples/{$filename}";
$domDocument = new \DOMDocument();
$domDocument->load($file, LIBXML_NOBLANKS | LIBXML_COMPACT);
return $domDocument;
}
}
tests/FeedIo/Parser/RdfTest.php 0000666 00000002776 13112056273 0012401 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Parser;
use FeedIo\Feed;
use FeedIo\Rule\DateTimeBuilder;
use FeedIo\Standard\Rdf;
class RdfTest extends ParserTestAbstract
{
const SAMPLE_FILE = 'sample-rdf.xml';
/**
* @return \FeedIo\StandardAbstract
*/
public function getStandard()
{
return new Rdf(new DateTimeBuilder());
}
public function testParseBody()
{
$document = $this->buildDomDocument(static::SAMPLE_FILE);
$feed = $this->object->parse($document, new Feed());
$this->assertInstanceOf('\FeedIo\Feed', $feed);
$this->assertNotEmpty($feed->getTitle(), 'title must not be empty');
$this->assertNotEmpty($feed->getLink(), 'link must not be empty');
$this->assertNotEmpty($feed->getLastModified(), 'lastModified must not be empty');
$this->assertTrue($feed->valid(), 'the feed must contain an item');
$item = $feed->current();
$this->assertInstanceOf('\FeedIo\Feed\ItemInterface', $item);
if ($item instanceof \FeedIo\Feed\ItemInterface) {
$this->assertNotEmpty($item->getTitle());
$this->assertNotEmpty($item->getDescription());
$this->assertNotEmpty($item->getLastModified());
$this->assertNotEmpty($item->getLink());
}
}
}
tests/FeedIo/Parser/RssTest.php 0000666 00000002356 13112056273 0012427 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Parser;
use FeedIo\Feed;
use FeedIo\Rule\DateTimeBuilder;
use FeedIo\Standard\Rss;
class RssTest extends ParserTestAbstract
{
const SAMPLE_FILE = 'rss/sample-rss.xml';
const ENCLOSURE_FILE = 'rss/rss-enclosure.xml';
/**
* @return \FeedIo\StandardAbstract
*/
public function getStandard()
{
return new Rss(new DateTimeBuilder());
}
public function testEnclosure()
{
$document = $this->buildDomDocument(static::ENCLOSURE_FILE);
$feed = $this->object->parse($document, new Feed());
$count = 0;
foreach ($feed as $item) {
$count++;
$this->assertTrue($item->hasMedia());
$media = $item->getMedias()->current();
$this->assertInstanceOf('\FeedIo\Feed\Item\MediaInterface', $media);
$this->assertEquals('audio/mpeg', $media->getType());
$this->assertInternalType('string', $media->getUrl());
}
$this->assertEquals(1, $count);
}
}
tests/FeedIo/ParserTest.php 0000666 00000011575 13112056273 0011663 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo;
use FeedIo\Feed\Item;
use FeedIo\Rule\DateTimeBuilder;
use Psr\Log\NullLogger;
class ParserTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \FeedIo\ParserAbstract
*/
protected $object;
public function setUp()
{
$date = new DateTimeBuilder();
$date->addDateFormat(\DateTime::ATOM);
$standard = $this->getMockForAbstractClass(
'\FeedIo\StandardAbstract',
array($date),
'StandardMock',
true,
true,
true,
['canHandle', 'getMainElement', 'buildFeedRuleSet']
);
$standard->expects($this->any())->method('canHandle')->will($this->returnValue(true));
$standard->expects($this->any())->method('buildFeedRuleSet')->will($this->returnValue(new RuleSet()));
$standard->expects($this->any())->method('getMainElement')->will($this->returnValue(new \DOMElement('test')));
$this->object = new Parser($standard, new NullLogger());
}
public function testParse()
{
$document = new \DOMDocument();
$document->loadXML('');
$feed = $this->object->parse($document, new Feed());
$this->assertInstanceOf('FeedIo\Feed', $feed);
}
public function testParseNode()
{
$document = new \DOMDocument();
$xml = <<feed-io
https://github.com/alexdebril/feed-io
feed-io is a library
XML;
$document->loadXML($xml);
$feed = new Feed();
$this->object->parseNode($feed, $document->documentElement, new RuleSet());
$this->assertInstanceOf('\Iterator', $feed->getElementIterator('description'));
$iterator = $feed->getElementIterator('description');
$count = 0;
foreach ($iterator as $element) {
$this->assertInstanceOf('\FeedIo\Feed\Node\ElementInterface', $element);
$this->assertEquals('feed-io is a library', $element->getValue());
$count++;
}
$this->assertEquals(1, $count);
}
/**
* @expectedException \FeedIo\Parser\UnsupportedFormatException
*/
public function testParseBadDocument()
{
$document = new \DOMDocument();
$document->loadXML('');
$standard = $this->getMockForAbstractClass(
'\FeedIo\StandardAbstract',
array(new DateTimeBuilder())
);
$standard->expects($this->any())->method('canHandle')->will($this->returnValue(false));
$parser = new Parser($standard, new NullLogger());
$parser->parse($document, new Feed());
}
public function testIsValid()
{
$item = new Item();
$item->setLastModified(new \DateTime('-1day'));
$this->object->addFilter($this->getFilterMock(true));
$this->assertTrue($this->object->isValid($item));
}
public function testIsNotValid()
{
$item = new Item();
$this->object->addFilter($this->getFilterMock(false));
$this->assertFalse($this->object->isValid($item));
}
public function testCheckStructure()
{
$rss = <<RSS Title
RSS;
$document = new \DOMDocument();
$document->loadXML($rss);
$this->assertInstanceOf(
'\FeedIo\Parser',
$this->object->checkBodyStructure($document, array('channel', 'title'))
);
}
/**
* @expectedException \FeedIo\Parser\MissingFieldsException
*/
public function testCheckBadStructure()
{
$document = new \DOMDocument();
$document->loadXML('');
$this->assertInstanceOf(
'\FeedIo\Parser',
$this->object->checkBodyStructure($document, array('channel'))
);
}
public function testAddResetFilters()
{
$filter = $this->getMockForAbstractClass('\FeedIo\FilterInterface');
$this->object->addFilter($filter);
$this->assertAttributeCount(1, 'filters', $this->object);
$this->object->resetFilters();
$this->assertAttributeCount(0, 'filters', $this->object);
}
/**
* @param boolean $returnValue
* @return \FeedIo\FilterInterface
*/
protected function getFilterMock($returnValue)
{
$filter = $this->getMockForAbstractClass('\FeedIo\FilterInterface');
$filter->expects($this->once())
->method('isValid')
->will($this->returnValue($returnValue));
return $filter;
}
}
tests/FeedIo/Reader/Fixer/LastModifiedTest.php 0000666 00000002742 13112056273 0015246 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Reader\Fixer;
use FeedIo\Feed;
use FeedIo\Feed\Item;
use Psr\Log\NullLogger;
class LastModifiedTest extends \PHPUnit_Framework_TestCase
{
/**
* @var FeedIo\Reader\Fixer\LastModified
*/
protected $object;
/**
* @var \DateTime
*/
protected $newest;
protected function setUp()
{
$this->newest = new \DateTime('2014-01-01');
$this->object = new LastModified();
$this->object->setLogger(new NullLogger());
}
public function testSearchLastModified()
{
$feed = $this->getFeed();
$this->assertEquals(
$this->newest,
$this->object->searchLastModified($feed)
);
}
public function testCorrect()
{
$feed = $this->getFeed();
$this->assertNull($feed->getLastModified());
$this->object->correct($feed);
$this->assertEquals($this->newest, $feed->getLastModified());
}
protected function getFeed()
{
$item1 = new Item();
$item1->setLastModified($this->newest);
$item2 = new Item();
$item2->setLastModified(new \DateTime('2013-01-01'));
$feed = new Feed();
$feed->add($item1)->add($item2);
return $feed;
}
}
tests/FeedIo/Reader/Fixer/PublicIdTest.php 0000666 00000002671 13112056273 0014376 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Reader\Fixer;
use FeedIo\Feed;
use FeedIo\Feed\Item;
use Psr\Log\NullLogger;
class PublicIdTest extends \PHPUnit_Framework_TestCase
{
/**
* @var FeedIo\Reader\Fixer\PublicId
*/
protected $object;
protected function setUp()
{
$this->object = new PublicId();
$this->object->setLogger(new NullLogger());
}
public function testCorrect()
{
$feed = $this->getFeed();
$this->assertNull($feed->getPublicId());
$this->object->correct($feed);
$this->assertEquals($feed->getLink(), $feed->getPublicId());
foreach ($feed as $idx => $item) {
if ( 0 === $idx )
$this->assertEquals($item->getLink(), $item->getPublicId());
else
$this->assertEquals('2', $item->getPublicId());
}
}
protected function getFeed()
{
$item1 = new Item();
$item1->setLink('http://localhost/1');
$item2 = new Item();
$item2->setLink('http://localhost/2');
$item2->setPublicId('2');
$feed = new Feed();
$feed->add($item1)->setLink('http://localhost/');
$feed->add($item2);
return $feed;
}
}
tests/FeedIo/Reader/FixerMock.php 0000666 00000001250 13112056273 0012645 0 ustar 00 logger = $logger;
return $this;
}
/**
* @param FeedInterface $feed
* @return $this
*/
public function correct(FeedInterface $feed)
{
$feed->setTitle('corrected');
return $this;
}
}
tests/FeedIo/Reader/FixerSetTest.php 0000666 00000001565 13112056273 0013360 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Reader;
use FeedIo\Feed;
class FixerSetTest extends \PHPUnit_Framework_TestCase
{
public function testAdd()
{
$fixer = $this->getMockForAbstractClass('\FeedIo\Reader\FixerAbstract');
$fixerSet = new FixerSet();
$fixerSet->add($fixer);
$this->assertAttributeContainsOnly($fixer, 'fixers', $fixerSet);
}
public function testCorrect()
{
$fixer = new FixerMock();
$fixerSet = new FixerSet();
$fixerSet->add($fixer);
$feed = new Feed();
$fixerSet->correct($feed);
$this->assertEquals('corrected', $feed->getTitle());
}
}
tests/FeedIo/Reader/ResultTest.php 0000666 00000003010 13112056273 0013070 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Reader;
use FeedIo\Feed;
class ResultTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \FeedIo\Reader\Result
*/
protected $object;
protected $modifiedSince;
protected $resultDate;
protected function setUp()
{
$this->modifiedSince = new \DateTime('-10 days');
$this->resultDate = new \DateTime();
$response = $this->getMockForAbstractClass('\FeedIo\Adapter\ResponseInterface');
$this->object = new Result(
new \DOMDocument(),
new Feed(),
$this->modifiedSince,
$response,
'http://localhost'
);
}
public function testResult()
{
$this->assertInstanceOf('\DomDocument', $this->object->getDocument());
$this->assertInstanceOf('\FeedIo\FeedInterface', $this->object->getFeed());
$this->assertEquals($this->resultDate->format(\DateTime::ATOM), $this->object->getDate()->format(\DateTime::ATOM));
$this->assertEquals($this->modifiedSince->format(\DateTime::ATOM), $this->object->getModifiedSince()->format(\DateTime::ATOM));
$this->assertInstanceOf('\FeedIo\Adapter\ResponseInterface', $this->object->getresponse());
$this->assertEquals('http://localhost', $this->object->getUrl());
}
}
tests/FeedIo/ReaderTest.php 0000666 00000012036 13112056273 0011622 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo;
use FeedIo\Adapter\ServerErrorException;
use Psr\Log\NullLogger;
use FeedIo\Rule\DateTimeBuilder;
class ReaderTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \FeedIo\Reader
*/
protected $object;
public function setUp()
{
$this->object = new Reader(
$this->getClientMock(),
new NullLogger()
);
}
/**
* @return \FeedIo\Adapter\ClientInterface
*/
protected function getClientMock()
{
$client = $this->createMock('FeedIo\Adapter\ClientInterface');
$response = $this->createMock('FeedIo\Adapter\ResponseInterface');
$response->expects($this->any())->method('getBody')->will($this->returnValue(''));
$client->expects($this->any())->method('getResponse')->will($this->returnValue($response));
return $client;
}
/**
* @return \FeedIo\Adapter\ClientInterface
*/
protected function getFaultyClientMock()
{
$client = $this->createMock('FeedIo\Adapter\ClientInterface');
$client->expects($this->any())->method('getResponse')->will(
$this->throwException(new ServerErrorException())
);
return $client;
}
/**
* @return \FeedIo\Parser
*/
protected function getParser()
{
$standard = $this->getMockForAbstractClass(
'\FeedIo\StandardAbstract',
array(new DateTimeBuilder())
);
$standard->expects($this->any())->method('canHandle')->will($this->returnValue(true));
$standard->expects($this->any())->method('buildFeedRuleSet')->will($this->returnValue(new RuleSet()));
$standard->expects($this->any())->method('buildItemRuleSet')->will($this->returnValue(new RuleSet()));
$file = dirname(__FILE__)."/../samples/rss/sample-rss.xml";
$domDocument = new \DOMDocument();
$domDocument->load($file, LIBXML_NOBLANKS | LIBXML_COMPACT);
$standard->expects($this->any())->method('getMainElement')->will($this->returnValue(
$domDocument->documentElement->getElementsByTagName('channel')->item(0)
));
$parser = new Parser($standard, new NullLogger());
return $parser;
}
public function testLoadDocument()
{
$document = $this->object->loadDocument('');
$this->assertInstanceOf('\DomDocument', $document);
}
/**
* @expectedException InvalidArgumentException
*/
public function testLoadMalformedDocument()
{
$document = $this->object->loadDocument('');
$this->assertInstanceOf('\DomDocument', $document);
}
/**
* @covers \FeedIo\Reader::addParser
*/
public function testAddParser()
{
$parser = $this->getParser();
$this->object->addParser($parser);
$this->assertAttributeEquals(array($parser), 'parsers', $this->object);
}
public function testGetAccurateParser()
{
$this->object->addParser($this->getParser());
$parser = $this->object->getAccurateParser(new \DOMDocument());
$this->assertInstanceOf('\FeedIo\Parser', $parser);
}
/**
* @expectedException \FeedIo\Reader\NoAccurateParserException
*/
public function testGetAccurateParserFailure()
{
$this->object->getAccurateParser(new \DOMDocument());
}
public function testParseDocument()
{
$this->object->addParser($this->getParser());
$feed = $this->object->parseDocument(new \DOMDocument(), new Feed());
$this->assertInstanceOf('\FeedIo\Feed', $feed);
$this->assertEquals('This is an example of an RSS feed', $feed->getValue('description'));
}
/**
* @covers \FeedIo\Reader::read
*/
public function testReadWithModifiedSince()
{
$feed = new Feed();
$this->object->addParser($this->getParser());
$modifiedSince = new \DateTime();
$url = 'http://localhost';
$result = $this->object->read($url, $feed, $modifiedSince);
$this->assertEquals($url, $result->getUrl());
$this->assertEquals($modifiedSince, $result->getModifiedSince());
$this->assertInstanceOf('\DOMDocument', $result->getDocument());
}
/**
* @covers \FeedIo\Reader::read
*/
public function testReadWithoutModifiedSince()
{
$feed = new Feed();
$this->object->addParser($this->getParser());
$result = $this->object->read('fakeurl', $feed);
$this->assertEquals(new \DateTime('@0'), $result->getModifiedSince());
}
/**
* @covers \FeedIo\Reader::read
* @expectedException \FeedIo\Reader\ReadErrorException
*/
public function testReadException()
{
$reader = new Reader($this->getFaultyClientMock(), new NullLogger());
$reader->read('fault', new Feed());
}
}
tests/FeedIo/Rule/Atom/AuthorTest.php 0000666 00000004246 13112056273 0013475 0 ustar 00 object = new Author();
}
public function testGetNodeName()
{
$this->assertEquals('author', $this->object->getNodeName());
}
public function testSet()
{
$item = new Item();
$document = new \DOMDocument();
$author = $document->createElement('author');
$author->appendChild($document->createElement('name', 'John Doe'));
$author->appendChild($document->createElement('uri', 'http://localhost'));
$author->appendChild($document->createElement('email', 'john@localhost'));
$this->object->setProperty($item, $author);
$this->assertEquals('John Doe', $item->getAuthor()->getName());
$this->assertEquals('http://localhost', $item->getAuthor()->getUri());
$this->assertEquals('john@localhost', $item->getAuthor()->getEmail());
}
public function testGetChildValue()
{
$document = new \DOMDocument();
$author = $document->createElement('author');
$author->appendChild($document->createElement('name', 'John Doe'));
$this->assertEquals('John Doe', $this->object->getChildValue($author, 'name'));
}
public function testCreateElement()
{
$item = new Item();
$author = new \FeedIo\Feed\Item\Author;
$author->setName('John Doe');
$author->setUri('http://localhost');
$author->setEmail('john@localhost');
$item->setAuthor($author);
$document = new \DOMDocument();
$element = $this->object->createElement($document, $item);
$document->appendChild($element);
$this->assertInstanceOf('\DomElement', $element);
$this->assertEquals('author', $element->nodeName);
$this->assertXmlStringEqualsXmlString(
'John Doehttp://localhostjohn@localhost',
$document->saveXML());
}
}
tests/FeedIo/Rule/Atom/CategoryTest.php 0000666 00000004253 13112056273 0014006 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Rule\Atom;
use FeedIo\Feed\Item;
class CategoryTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \FeedIo\Rule\Atom\Category
*/
protected $object;
protected function setUp()
{
$this->object = new Category();
}
public function testSetProperty()
{
$item = new Item();
$document = new \DomDocument();
$element = $document->createElement('category');
$element->setAttribute('scheme', 'http');
$element->setAttribute('label', 'FooBar');
$element->setAttribute('term', 'foobar');
$this->object->setProperty($item, $element);
$count = 0;
foreach ($item->getCategories() as $category) {
$count++;
$this->assertEquals('foobar', $category->getTerm());
$this->assertEquals('FooBar', $category->getLabel());
$this->assertEquals('http', $category->getScheme());
}
$this->assertEquals(1, $count);
}
public function testCreateCategoryElement()
{
$category = new \FeedIo\Feed\Node\Category();
$category->setLabel('Foo');
$category->setTerm('foo');
$category->setScheme('bar');
$element = $this->object->createCategoryElement(new \DomDocument(), $category);
$this->assertEquals('Foo', $element->getAttribute('label'));
$this->assertEquals('foo', $element->getAttribute('term'));
$this->assertEquals('bar', $element->getAttribute('scheme'));
}
public function testCreateElement()
{
$category = new \FeedIo\Feed\Node\Category();
$category->setLabel('foo');
$item = new Item;
$item->addCategory($category);
$element = $this->object->createElement(new \DomDocument, $item);
$this->assertEquals('foo', $element->getAttribute('label'));
}
}
tests/FeedIo/Rule/Atom/LinkNodeTest.php 0000666 00000003473 13112056273 0013737 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Rule\Atom;
use FeedIo\Feed\Item;
class LinkNodeTest extends \PHPUnit_Framework_TestCase
{
/**
* @var Link
*/
protected $object;
const LINK = 'http://localhost';
protected function setUp()
{
$this->object = new LinkNode();
}
public function testSet()
{
$item = new Item();
$document = new \DOMDocument();
$link = $document->createElement('link');
$link->setAttribute('href', 'http://localhost');
$this->object->setProperty($item, $link);
$this->assertEquals('http://localhost', $item->getLink());
}
public function testSetMedia()
{
$item = new Item();
$document = new \DOMDocument();
$link = $document->createElement('link');
$link->setAttribute('href', 'http://localhost/video.mpeg');
$link->setAttribute('rel', 'enclosure');
$this->object->setProperty($item, $link);
$this->assertTrue($item->hasMedia());
$count = 0;
foreach ($item->getMedias() as $media) {
$count++;
$this->assertEquals($link->getAttribute('href'), $media->getUrl());
}
$this->assertEquals(1, $count);
}
public function testCreateElement()
{
$item = new Item();
$item->setLink(self::LINK);
$element = $this->object->createElement(new \DOMDocument(), $item);
$this->assertInstanceOf('\DomElement', $element);
$this->assertEquals(self::LINK, $element->getAttribute('href'));
$this->assertEquals('link', $element->nodeName);
}
}
tests/FeedIo/Rule/Atom/LinkTest.php 0000666 00000002330 13112056273 0013120 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Rule\Atom;
use FeedIo\Feed\Item;
class LinkTest extends \PHPUnit_Framework_TestCase
{
/**
* @var Link
*/
protected $object;
const LINK = 'http://localhost';
protected function setUp()
{
$this->object = new Link();
}
public function testSet()
{
$item = new Item();
$document = new \DOMDocument();
$link = $document->createElement('link');
$link->setAttribute('href', 'http://localhost');
$this->object->setProperty($item, $link);
$this->assertEquals('http://localhost', $item->getLink());
}
public function testCreateElement()
{
$item = new Item();
$item->setLink(self::LINK);
$element = $this->object->createElement(new \DOMDocument(), $item);
$this->assertInstanceOf('\DomElement', $element);
$this->assertEquals(self::LINK, $element->getAttribute('href'));
$this->assertEquals('link', $element->nodeName);
}
}
tests/FeedIo/Rule/AuthorTest.php 0000666 00000002202 13112056273 0012563 0 ustar 00 object = new Author();
}
public function testGetNodeName()
{
$this->assertEquals('author', $this->object->getNodeName());
}
public function testSet()
{
$item = new Item();
$this->object->setProperty($item, new \DOMElement('author', self::AUTHOR));
$this->assertEquals(self::AUTHOR, $item->getAuthor()->getName());
}
public function testCreateElement()
{
$item = new Item();
$author = new \FeedIo\Feed\Item\Author;
$author->setName(self::AUTHOR);
$item->setAuthor($author);
$element = $this->object->createElement(new \DOMDocument(), $item);
$this->assertInstanceOf('\DomElement', $element);
$this->assertEquals(self::AUTHOR, $element->nodeValue);
$this->assertEquals('author', $element->nodeName);
}
}
tests/FeedIo/Rule/CategoryTest.php 0000666 00000004266 13112056273 0013112 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Rule;
use FeedIo\Feed\Item;
class CategoryTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \FeedIo\Rule\Category
*/
protected $object;
protected function setUp()
{
$this->object = new Category();
}
public function testSetProperty()
{
$item = new Item();
$element = new \DomElement('category', 'foo');
$this->object->setProperty($item, $element);
$count = 0;
foreach ($item->getCategories() as $category) {
$count++;
$this->assertEquals('foo', $category->getTerm());
$this->assertEquals('foo', $category->getLabel());
}
$this->assertEquals(1, $count);
}
public function testCreateCategoryElement()
{
$category = new \FeedIo\Feed\Node\Category();
$category->setLabel('foo');
$category->setScheme('bar');
$element = $this->object->createCategoryElement(new \DomDocument(), $category);
$this->assertEquals('foo', $element->nodeValue);
$this->assertEquals('bar', $element->getAttribute('domain'));
}
public function testCreateCategoryElementUsingTerm()
{
$category = new \FeedIo\Feed\Node\Category();
$category->setTerm('foo');
$element = $this->object->createCategoryElement(new \DomDocument(), $category);
$this->assertEquals('foo', $element->nodeValue);
}
public function testCreateElement()
{
$category = new \FeedIo\Feed\Node\Category();
$category->setLabel('foo');
$item = new Item;
$this->assertNull($this->object->createElement(new \DomDocument, $item));
$item->addCategory($category);
$element = $this->object->createElement(new \DomDocument, $item);
$this->assertEquals('foo', $element->nodeValue);
}
}
tests/FeedIo/Rule/DateTest.php 0000666 00000006007 13112056273 0012205 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Rule;
class DateTest extends \PHPUnit_Framework_TestCase
{
/**
* Timezone used to test a timezone switch.
* Longyearbyen is the only place in the world where the testSetTimezone() test will fail,
* I hope it won't bother anyone
*/
const ALTERNATE_TIMEZONE = 'Arctic/Longyearbyen';
/**
* @var \FeedIo\Parser\DateTimeBuilder
*/
protected $object;
protected function setUp()
{
$this->object = new DateTimeBuilder();
}
public function testGetTimezone()
{
$timezone = $this->object->getTimezone();
$this->assertEquals(date_default_timezone_get(), $timezone->getName());
}
public function testSetDateFormats()
{
$formats = array(\DateTime::ATOM);
$this->object->setDateFormats($formats);
$this->assertAttributeEquals($formats, 'dateFormats', $this->object);
}
public function testGuessDateFormat()
{
$formats = array(\DateTime::ATOM, \DateTime::RFC1036);
$this->object->setDateFormats($formats);
$date = new \DateTime();
$format = $this->object->guessDateFormat($date->format(\DateTime::ATOM));
$this->assertEquals(\DateTime::ATOM, $format);
}
public function testDontGuessDateFormat()
{
$this->object->addDateFormat(\DateTime::ATOM);
$this->assertFalse($this->object->guessDateFormat('foo'));
}
public function testConvertDateFormat()
{
$formats = array(\DateTime::ATOM, \DateTime::RFC1036);
$this->object->setDateFormats($formats);
$date = new \DateTime('now');
$this->assertEquals($date->format(\DateTime::ATOM), $this->object->convertToDateTime($date->format(\DateTime::ATOM))->format(\DateTime::ATOM));
$this->assertEquals(\DateTime::ATOM, $this->object->getLastGuessedFormat());
$this->assertEquals($date->format(\DateTime::ATOM), $this->object->convertToDateTime($date->format(\DateTime::RFC1036))->format(\DateTime::ATOM));
$this->assertEquals(\DateTime::RFC1036, $this->object->getLastGuessedFormat());
}
/**
* @expectedException \InvalidArgumentException
*/
public function testDontConvertDateFormat()
{
$this->object->addDateFormat(\DateTime::ATOM);
$this->object->convertToDateTime('foo');
}
public function testSetTimezone()
{
$this->object->setTimezone(new \DateTimeZone(self::ALTERNATE_TIMEZONE));
$this->assertEquals(self::ALTERNATE_TIMEZONE, $this->object->getTimezone()->getName());
$this->object->addDateFormat(\DateTime::ATOM);
$date = new \DateTime();
$return = $this->object->convertToDateTime($date->format(\DateTime::ATOM));
$this->assertEquals(self::ALTERNATE_TIMEZONE, $return->getTimezone()->getName());
}
}
tests/FeedIo/Rule/DescriptionTest.php 0000666 00000003341 13112056273 0013611 0 ustar 00 a title
A paragraph
second paragraph
';
protected function setUp()
{
$this->object = new Description();
}
public function testGetNodeName()
{
$this->assertEquals('description', $this->object->getNodeName());
}
public function testSet()
{
$item = new Item();
$document = new \DOMDocument();
$element = $document->createElement('description', self::DESCRIPTION);
$document->appendChild($element);
$this->object->setProperty($item, $element);
$this->assertEquals(self::DESCRIPTION, $item->getDescription());
}
public function testSetProperty()
{
$item = new Item();
$document = new \DOMDocument();
$element = $document->createElement('description', self::HTML_DESCRIPTION);
$document->appendChild($element);
$this->object->setProperty($item, $element);
$this->assertEquals(htmlentities(self::HTML_DESCRIPTION), $item->getDescription());
}
public function testCreateElement()
{
$item = new Item();
$item->setDescription(self::DESCRIPTION);
$element = $this->object->createElement(new \DOMDocument(), $item);
$this->assertInstanceOf('\DomElement', $element);
$this->assertEquals(self::DESCRIPTION, $element->nodeValue);
$this->assertEquals('description', $element->nodeName);
}
}
tests/FeedIo/Rule/LinkTest.php 0000666 00000002063 13112056273 0012223 0 ustar 00 object = new Link();
}
public function testGetNodeName()
{
$this->assertEquals('link', $this->object->getNodeName());
}
public function testSet()
{
$item = new Item();
$this->object->setProperty($item, new \DOMElement('link', self::LINK));
$this->assertEquals(self::LINK, $item->getLink());
}
public function testCreateElement()
{
$item = new Item();
$item->setLink(self::LINK);
$element = $this->object->createElement(new \DOMDocument(), $item);
$this->assertInstanceOf('\DomElement', $element);
$this->assertEquals(self::LINK, $element->nodeValue);
$this->assertEquals('link', $element->nodeName);
}
}
tests/FeedIo/Rule/MediaTest.php 0000666 00000004541 13112056273 0012350 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Rule;
use FeedIo\Feed\Item;
use FeedIo\Feed\Item\MediaInterface;
class MediaTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \FeedIo\Rule\Media
*/
protected $object;
protected function setUp()
{
$this->object = new Media();
}
public function testSetProperty()
{
$document = new \DomDocument();
$media = $document->createElement('enclosure');
$media->setAttribute('url', 'http://localhost');
$media->setAttribute('length', '12345');
$media->setAttribute('type', 'audio/mp3');
$item = new Item();
$this->object->setProperty($item, $media);
$this->assertTrue($item->hasMedia());
$count = 0;
foreach ($item->getMedias() as $itemMedia) {
$this->assertInternalType('string', $itemMedia->getType());
$this->assertInternalType('string', $itemMedia->getUrl());
$this->assertInternalType('integer', $itemMedia->getLength());
$this->assertEquals($media->getAttribute('url'), $itemMedia->getUrl());
$count++;
}
$this->assertEquals(1, $count);
}
public function testCreateElement()
{
$item = new Item();
$this->assertNull($this->object->createElement(new \DomDocument(), $item));
$media = new \FeedIo\Feed\Item\Media();
$media->setType('audio')
->setUrl('http://localhost')
->setLength(123);
$item->addMedia($media);
$element = $this->object->createMediaElement(new \DomDocument(), $media);
$this->assertMediaEqualsElement($media, $element);
$secondElement = $this->object->createElement(new \DomDocument(), $item);
$this->assertMediaEqualsElement($media, $element);
}
protected function assertMediaEqualsElement(MediaInterface $media, \DomElement $element)
{
$this->assertEquals($media->getUrl(), $element->getAttribute('url'));
$this->assertEquals($media->getType(), $element->getAttribute('type'));
$this->assertEquals($media->getLength(), $element->getAttribute('length'));
}
}
tests/FeedIo/Rule/ModifiedSinceTest.php 0000666 00000004375 13112056273 0014040 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Rule;
use FeedIo\Feed\Item;
class ModifiedSinceTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \FeedIo\Rule\ModifiedSince
*/
protected $object;
protected function setUp()
{
$date = new DateTimeBuilder();
$date->addDateFormat(\DateTime::ATOM);
$this->object = new ModifiedSince();
$this->object->setDateTimeBuilder($date);
}
public function testSet()
{
$item = new Item();
$date = new \DateTime('-3 days');
$element = new \DOMElement('pubDate', $date->format(\DateTime::ATOM));
$this->object->setProperty($item, $element);
$this->assertEquals($date->format(\DateTime::ATOM), $item->getLastModified()->format(\DateTime::ATOM));
}
public function testAddedFormat()
{
$item = new Item();
$dateTime = new \DateTime('-3 days');
$element = new \DOMElement('pubDate', $dateTime->format(\DateTime::RSS));
$dateTimeBuilder = new DateTimeBuilder();
$dateTimeBuilder->addDateFormat(\DateTime::ATOM);
$modifiedSince = new ModifiedSince();
$modifiedSince->setDateTimeBuilder($dateTimeBuilder);
$dateTimeBuilder->addDateFormat(\DateTime::RSS);
$modifiedSince->setProperty($item, $element);
$this->assertEquals($dateTime->format(\DateTime::ATOM), $item->getLastModified()->format(\DateTime::ATOM));
}
public function testGetDate()
{
$this->assertInstanceOf('\FeedIo\Rule\DateTimeBuilder', $this->object->getDateTimeBuilder());
}
public function testCreateElement()
{
$item = new Item();
$date = new \DateTime();
$item->setLastModified($date);
$this->object->setDefaultFormat(\DateTime::ATOM);
$element = $this->object->createElement(new \DOMDocument(), $item);
$this->assertInstanceOf('\DomElement', $element);
$this->assertEquals($date->format(\DateTime::ATOM), $element->nodeValue);
$this->assertEquals('pubDate', $element->nodeName);
}
}
tests/FeedIo/Rule/OptionalFieldTest.php 0000666 00000011341 13112056273 0014056 0 ustar 00 object = new OptionalField();
}
public function testSetProperty()
{
$document = new \DomDocument();
$element = $document->createElement('test', 'a test value');
$element->setAttribute('foo', 'bar');
$item = new Item();
$this->object->setProperty($item, $element);
$this->assertTrue($item->hasElement('test'));
$this->assertEquals('a test value', $item->getValue('test'));
$itemElements = $item->getElementIterator('test');
$count = 0;
/** @var Element $itemElement */
foreach ($itemElements as $itemElement) {
$count++;
$this->assertEquals('bar', $itemElement->getAttribute('foo'));
}
$this->assertEquals(1, $count);
$subCount = 0;
foreach ($itemElement->getAllElements() as $subElement) {
$count++;
}
$this->assertEquals(0, $subCount);
}
public function testSetPropertyElementWithSubElements()
{
$document = new \DOMDocument();
$element = $document->createElement('test');
$subElementValues = [
'sub-test' => 'a test value',
'sub-test-2' => 'a test value 2'
];
foreach ($subElementValues as $name => $value) {
$element->appendChild($document->createElement($name, $value));
}
$item = new Item();
$this->object->setProperty($item, $element);
$testElementIterator = $item->getElementIterator('test');
$subElementCount = 0;
/** @var ElementInterface $testElement */
foreach ($testElementIterator as $testElement) {
$subTestElementIterator = $testElement->getAllElements();
if (null === $subTestElementIterator) {
$this->fail('No sub elements found but expected');
return;
}
$subTestElement = null;
foreach ($subTestElementIterator as $subTestElement) {
$subElementCount++;
$expectedValue = array_shift($subElementValues);
/** @var ElementInterface $subTestElement */
$this->assertEquals($expectedValue, $subTestElement->getValue());
}
}
$this->assertEquals(2, $subElementCount);
}
public function testCreateElement()
{
$item = new Item();
$item->set('default', 'a test value');
$element = $this->object->createElement(new \DOMDocument(), $item);
$this->assertEquals('default', $element->nodeName);
$this->assertEquals('a test value', $element->nodeValue);
}
public function testCreateElementWithSubElements()
{
$subElement = new Element();
$subElement->setName('subDefault');
$subElement->setValue('defaultValue');
$element = new Element();
$element->setName('default');
$element->addElement($subElement);
$item = new Item();
$item->addElement($element);
$domElement = $this->object->createElement(new \DOMDocument(), $item);
$subElementCount = 0;
/** @var \DOMNode $childNode */
foreach ($domElement->childNodes as $childNode) {
if ($childNode instanceof \DOMText) {
continue;
}
$subElementCount++;
$this->assertEquals('subDefault', $childNode->nodeName);
$this->assertEquals('defaultValue', $childNode->nodeValue);
}
$this->assertEquals(1, $subElementCount);
}
public function testCreateElementWithAttributes()
{
$element = new Element();
$element->setName('default');
$element->setValue('value');
$element->setAttribute('foo', 'bar');
$item = new Item();
$item->addElement($element);
$domElement = $this->object->createElement(new \DOMDocument(), $item);
$this->assertEquals('default', $domElement->nodeName);
$this->assertEquals('value', $domElement->nodeValue);
$this->assertTrue($domElement->hasAttribute('foo'));
}
public function testDontCreateElement()
{
$item = new Item();
$item->set('another', 'a test value');
$element = $this->object->createElement(new \DOMDocument(), $item);
$this->assertEquals('default', $element->nodeName);
$this->assertEquals('', $element->nodeValue);
}
}
tests/FeedIo/Rule/PublicIdTest.php 0000666 00000002062 13112056273 0013020 0 ustar 00 object = new PublicId();
}
public function testGetNodeName()
{
$this->assertEquals('guid', $this->object->getNodeName());
}
public function testSet()
{
$item = new Item();
$this->object->setProperty($item, new \DOMElement('guid', 'foo'));
$this->assertEquals('foo', $item->getPublicId());
}
public function testCreateElement()
{
$item = new Item();
$item->setPublicId(self::PUBLIC_ID);
$element = $this->object->createElement(new \DOMDocument(), $item);
$this->assertInstanceOf('\DomElement', $element);
$this->assertEquals(self::PUBLIC_ID, $element->nodeValue);
$this->assertEquals('guid', $element->nodeName);
}
}
tests/FeedIo/Rule/StructureTest.php 0000666 00000003245 13112056273 0013331 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Rule;
use FeedIo\RuleSet;
use FeedIo\Feed\Item;
class StructureTest extends \PHPUnit_Framework_TestCase
{
/**
* @var Structure
*/
protected $object;
protected function setUp()
{
$ruleSet = new RuleSet();
$ruleSet->add(new Title());
$this->object = new Structure('foo', $ruleSet);
}
public function testGetNodeName()
{
$this->assertEquals('foo', $this->object->getNodeName());
}
public function testConstruct()
{
$ruleSet = new RuleSet();
$ruleSet->add(new Title());
$structure = new Structure('foo', $ruleSet);
$this->assertAttributeEquals($ruleSet, 'ruleSet', $structure);
}
public function testSet()
{
$document = new \DomDocument();
$foo = $document->createElement('foo');
$document->appendChild($foo);
$bar = $document->createElement('title', 'hello');
$foo->appendChild($bar);
$item = new Item();
$this->object->setProperty($item, $foo);
$this->assertEquals('hello', $item->getTitle());
}
public function testCreateElement()
{
$item = new Item();
$item->setTitle('foo-bar');
$document = new \DomDocument();
$element = $this->object->createElement($document, $item);
$node = 'foo-bar';
$this->assertEquals($node, $document->saveXML($element));
}
}
tests/FeedIo/Rule/TitleTest.php 0000666 00000002325 13112056273 0012410 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Rule;
use FeedIo\Feed\Item;
class TitleTest extends \PHPUnit_Framework_TestCase
{
/**
* @var Title
*/
protected $object;
const TITLE = 'my great article';
protected function setUp()
{
$this->object = new Title();
}
public function testGetNodeName()
{
$this->assertEquals('title', $this->object->getNodeName());
}
public function testSet()
{
$item = new Item();
$this->object->setProperty($item, new \DOMElement('title', 'feed-io title'));
$this->assertEquals('feed-io title', $item->getTitle());
}
public function testCreateElement()
{
$item = new Item();
$item->setTitle(self::TITLE);
$element = $this->object->createElement(new \DOMDocument(), $item);
$this->assertInstanceOf('\DomElement', $element);
$this->assertEquals(self::TITLE, $element->nodeValue);
$this->assertEquals('title', $element->nodeName);
}
}
tests/FeedIo/RuleSetTest.php 0000666 00000003243 13112056273 0012003 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo;
use FeedIo\Rule\OptionalField;
class RuleSetTest extends \PHPUnit_Framework_TestCase
{
/**
* @var RuleSet
*/
protected $object;
protected function setUp()
{
$this->object = new RuleSet();
}
public function testAdd()
{
$rule = $this->getMockForAbstractClass('\FeedIo\RuleAbstract');
$this->object->add($rule);
$this->assertEquals($rule, $this->object->get('node'));
}
public function testAddAliases()
{
$name = 'main-node';
$aliases = array('node1', 'node2');
$this->object->addAliases($name, $aliases);
$this->assertEquals($name, $this->object->getNameForAlias('node1'));
$this->assertEquals($name, $this->object->getNameForAlias($name));
}
public function testGetByAlias()
{
$rule = $this->getMockForAbstractClass('\FeedIo\RuleAbstract');
$this->object->add($rule, array('alias'));
$this->assertEquals($rule, $this->object->get('alias'));
}
public function testGetRules()
{
$rule = $this->getMockForAbstractClass('\FeedIo\RuleAbstract');
$this->object->add($rule);
$rules = $this->object->getRules();
$rules[] = new OptionalField('test');
$this->assertCount(2, $rules, '$rules MUST have two offsets');
$this->assertCount(1, $this->object->getRules(), '$this->object->getRules() MUST have one offset');
}
}
tests/FeedIo/Standard/AtomTest.php 0000666 00000001432 13112056273 0013056 0 ustar 00
';
/**
* @var Atom
*/
protected $object;
protected function setUp()
{
$this->object = new Atom(
new DateTimeBuilder()
);
}
public function testFormat()
{
$dom = new \DOMDocument('1.0', 'utf-8');
$dom = $this->object->format($dom);
$this->assertEquals(
str_replace("\n", '', static::FORMATTED_DOCUMENT),
str_replace("\n", '', $dom->saveXML())
);
}
}
tests/FeedIo/Standard/RdfTest.php 0000666 00000001651 13112056273 0012674 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo\Standard;
use FeedIo\Rule\DateTimeBuilder;
class RdfTest extends \PHPUnit_Framework_TestCase
{
const FORMATTED_DOCUMENT = '';
/**
* @var Rdf
*/
protected $object;
protected function setUp()
{
$this->object = new Rdf(
new DateTimeBuilder()
);
}
public function testFormat()
{
$dom = new \DOMDocument('1.0', 'utf-8');
$dom = $this->object->format($dom);
$this->assertEquals(
str_replace("\n", '', static::FORMATTED_DOCUMENT),
str_replace("\n", '', $dom->saveXML())
);
}
}
tests/FeedIo/Standard/RssTest.php 0000666 00000001417 13112056273 0012730 0 ustar 00 ';
/**
* @var Atom
*/
protected $object;
protected function setUp()
{
$this->object = new Rss(
new DateTimeBuilder()
);
}
public function testFormat()
{
$dom = new \DOMDocument('1.0', 'utf-8');
$dom = $this->object->format($dom);
$this->assertEquals(
str_replace("\n", '', static::FORMATTED_DOCUMENT),
str_replace("\n", '', $dom->saveXML())
);
}
}
tests/FeedIo/StandardAbstractTest.php 0000666 00000004422 13112056273 0013644 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FeedIo;
use FeedIo\Rule\DateTimeBuilder;
class StandardAbstractTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \FeedIo\StandardAbstract
*/
protected $object;
public function setUp()
{
$date = new DateTimeBuilder();
$date->addDateFormat(\DateTime::ATOM);
$this->object = $this->getMockForAbstractClass(
'\FeedIo\StandardAbstract',
array($date)
);
$this->object->expects($this->any())->method('canHandle')->will($this->returnValue(true));
$this->object->expects($this->any())->method('buildFeedRuleSet')->will($this->returnValue(new RuleSet()));
$this->object->expects($this->any())->method('buildItemRuleSet')->will($this->returnValue(new RuleSet()));
$this->object->expects($this->any())->method('getMainElement')->will($this->returnValue(new \DOMElement('test')));
}
public function testGetItemNodeName()
{
$this->assertInternalType('string', $this->object->getItemNodeName());
}
public function testGetMandatoryFields()
{
$this->assertInternalType('array', $this->object->getMandatoryFields());
}
public function testGetFeedRuleSet()
{
$this->assertInstanceOf('\FeedIo\RuleSet', $this->object->getFeedRuleSet());
}
public function testGetItemRuleSet()
{
$this->assertInstanceOf('\FeedIo\RuleSet', $this->object->getItemRuleSet());
}
public function testGetModifiedSinceRule()
{
$modifiedSince = $this->object->getModifiedSinceRule('pubDate');
$this->assertInstanceOf('\FeedIo\Rule\ModifiedSince', $modifiedSince);
$this->assertEquals('pubDate', $modifiedSince->getNodeName());
}
public function testBuildBaseRuleSet()
{
$reflection = new \ReflectionClass(get_class($this->object));
$method = $reflection->getMethod('buildBaseRuleSet');
$method->setAccessible(true);
$ruleSet = $method->invoke($this->object);
$this->assertInstanceOf('\FeedIo\RuleSet', $ruleSet);
}
}
tests/FeedIo/StandardFormatter/AtomTest.php 0000666 00000000674 13112056273 0014751 0 ustar 00 standard = $this->newStandard();
}
public function testFormat()
{
$category = new Category();
$category->setTerm('sample');
$category->setLabel('sample');
$category->setScheme('http://localhost');
$date = new \DateTime('2014/12/01');
$feed = new Feed();
$feed->setTitle('sample title');
$feed->setLastModified($date);
$feed->setLink('http://localhost');
$feed->setPublicId(1);
$feed->addCategory($category);
$item = new Item();
$item->setPublicId(42);
$item->setLastModified($date);
$item->setTitle('item title');
$item->setDescription('A great description');
$item->setLink('http://localhost/item/1');
$item->set('author', 'name');
$item->addCategory($category);
$feed->add($item);
$formatter = new Formatter($this->standard, new NullLogger());
$document = $formatter->toDom($feed);
$this->assertXmlStringEqualsXmlFile($this->getSampleFile(), $document->saveXML());
}
protected function getSampleFile()
{
return dirname(__FILE__)."/../../samples/".static::SAMPLE_FILE;
}
}
tests/FeedIo/StandardFormatter/RssTest.php 0000666 00000000674 13112056273 0014620 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
$loader = require __DIR__."/../vendor/autoload.php";
$loader->addPsr4('FeedIo\\', __DIR__.'/FeedIo');
date_default_timezone_set('UTC');
tests/live-feeds/StandardFeedsTest.php 0000666 00000012356 13112056273 0014024 0 ustar 00 object = new FeedIo($client, $logger);
}
/**
* @dataProvider provideUrls
*/
public function testFeed($url)
{
try {
$result = $this->object->read($url);
$this->performAssertions($result);
} catch (\FeedIo\Reader\ReadErrorException $e) {
throw $e;
$this->markTestIncomplete("read error : {$e->getMessage()}");
}
}
protected function performAssertions(\FeedIo\Reader\Result $result)
{
$feed = $result->getFeed();
$this->assertInstanceOf('\FeedIo\FeedInterface', $feed);
$this->performStringAssertions(
array(
'title' => $feed->getTitle(),
'link' => $feed->getLink(),
)
);
$this->assertInstanceOf('\DateTime', $feed->getLastModified());
foreach ($feed as $item) {
$this->performItemAssertions($item);
}
}
protected function performItemAssertions(\FeedIo\Feed\ItemInterface $item)
{
$this->assertInstanceOf('\DateTime', $item->getLastModified());
$this->performStringAssertions(
array(
'title' => $item->getTitle(),
'link' => $item->getLink(),
'description' => $item->getDescription(),
)
);
}
protected function performStringAssertions(array $strings)
{
foreach ($strings as $name => $string) {
$this->assertInternalType('string', $string, "$name must be a string");
$this->assertTrue(strlen($string) > 0, "$name cannot be empty");
$this->assertEncodingIsUtf8($string, $name);
}
}
protected function assertEncodingIsUtf8($string, $name)
{
return $this->assertTrue(mb_check_encoding($string, 'utf-8'), "$name must be utf-8 encoded");
}
/**
* @return array
*/
public function provideUrls()
{
$urls = $this->getUrls();
$out = array();
foreach ($urls as $url) {
$out[] = array($url);
}
return $out;
}
protected function getUrls()
{
$localhost = array(
'http://127.0.0.1:8080/feed-io/tests/samples/expected-atom.xml',
'http://127.0.0.1:8080/feed-io/tests/samples/sample-atom.xml',
'http://127.0.0.1:8080/feed-io/tests/samples/sample-atom-html.xml',
'http://127.0.0.1:8080/feed-io/tests/samples/rss/expected-rss.xml',
'http://127.0.0.1:8080/feed-io/tests/samples/rss/sample-rss.xml',
'http://127.0.0.1:8080/feed-io/tests/samples/sample-rdf.xml',
);
$urls = array(
'http://feeds.bbci.co.uk/news/rss.xml?edition=uk',
'http://feeds.feedburner.com/dailyjs',
'http://feeds.feedburner.com/HighScalability',
'http://feeds.feedburner.com/symfony/blog',
'http://feeds.mashable.com/Mashable',
'http://feeds.slate.com/slate',
'http://feeds.wired.com/wired/index',
'http://feeds2.feedburner.com/blogspot/Egta',
'http://feeds2.feedburner.com/LeJournalduGeek',
'http://feeds2.feedburner.com/Webappers',
'http://liberation.fr.feedsportal.com/c/32268/fe.ed/rss.liberation.fr/rss/44/',
'http://liberation.fr.feedsportal.com/c/32268/fe.ed/rss.liberation.fr/rss/54/',
'http://liberation.fr.feedsportal.com/c/32268/fe.ed/rss.liberation.fr/rss/latest/',
'http://linuxfr.org/journaux.atom',
'http://php.net/feed.atom',
'http://pipes.yahoo.com/pipes/pipe.run?_id=647030be6aceb6d005c3775a1c19401c&_render=rss',
'http://rss.lemonde.fr/c/205/f/3050/index.rss',
'http://rss.slashdot.org/Slashdot/slashdot',
'http://rue89.feedsportal.com/c/33822/f/608948/index.rss',
'http://what-if.xkcd.com/feed.atom',
'http://www.debian.org/News/news',
'http://www.gizmodo.fr/feed',
'http://www.larvf.com/rss/article/10135',
'http://www.lemonde.fr/sciences/rss_full.xml',
'http://www.lemonde.fr/technologies/rss_full.xml',
'http://www.metalorgie.com/feed/news',
'http://www.sitepoint.com/feed/',
'http://www.slate.fr/rss.xml',
'http://xkcd.com/rss.xml',
);
return $this->isLocalhostUp() ? array_merge($localhost, $urls) : $urls;
}
/**
*
*/
protected function isLocalhostUp()
{
$client = new \GuzzleHttp\Client();
try {
$response = $client->get('http://127.0.0.1:8080/feed-io/tests/');
return 200 === (int) $response->getStatusCode();
} catch (\Exception $e) {
return false;
}
return true;
}
}
tests/samples/enclosure-atom.xml 0000666 00000001436 13112056273 0013041 0 ustar 00
Example FeedA subtitle.urn:uuid:60a76c80-d399-11d9-b91C-0003939e0af62003-12-13T18:30:02ZA partial entryurn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a2003-12-13T18:30:02Z
A title
A paragraph
tests/samples/expected-atom.xml 0000666 00000001205 13112056273 0012635 0 ustar 00
sample title1Mon, 01 Dec 2014 00:00:00 +0000item title42Mon, 01 Dec 2014 00:00:00 +0000A great descriptionname
tests/samples/rss/expected-rss.xml 0000666 00000001403 13112056273 0013313 0 ustar 00
sample titlesample
http://localhost
1Mon, 01 Dec 2014 00:00:00 +0000Mon, 01 Dec 2014 00:00:00 +0000item titlesample
http://localhost/item/1
42A great descriptionMon, 01 Dec 2014 00:00:00 +0000name
tests/samples/rss/rss-enclosure.xml 0000666 00000001637 13112056273 0013522 0 ustar 00
RSS TitleThis is an example of an RSS feed1
http://www.someexamplerssdomain.com/main.html
Mon, 06 Sep 2010 00:01:00 GMTMon, 06 Sep 2009 16:45:00 GMT1800Example entryHere is some text containing an interesting description.
http://www.wikipedia.org/
unique string per itemMon, 06 Sep 2009 16:45:00 GMTJohn Doe
tests/samples/rss/sample-rss-media.xml 0000666 00000001631 13112056273 0014053 0 ustar 00
RSS TitleThis is an example of an RSS feed
http://www.someexamplerssdomain.com/main.html
Mon, 06 Sep 2010 00:01:00 GMTMon, 06 Sep 2009 16:45:00 GMT1800Example entryHere is some text containing an interesting description.
http://www.wikipedia.org/
unique string per itemMon, 06 Sep 2009 16:45:00 GMTJohn Doe
tests/samples/rss/sample-rss-nodate.xml 0000666 00000002557 13112056273 0014256 0 ustar 00
RSS TitleThis is an example of an RSS feed
http://www.someexamplerssdomain.com/main.html
1800Example entryHere is some text containing an interesting description.
http://www.wikipedia.org/
unique string per itemMon, 06 Sep 2009 16:45:00 GMTJohn DoeExample entryHere is some text containing an interesting description.
http://www.wikipedia.org/
unique string per itemMon, 13 Sep 2009 16:45:00 GMTJohn DoeExample entryHere is some text containing an interesting description.
http://www.wikipedia.org/
unique string per itemMon, 31 Aug 2009 16:45:00 GMTJohn Doe
tests/samples/rss/sample-rss-pubdate.xml 0000666 00000001312 13112056273 0014414 0 ustar 00
RSS TitleThis is an example of an RSS feed
http://www.someexamplerssdomain.com/main.html
Mon, 06 Sep 2009 16:45:00 GMT1800Example entryHere is some text containing an interesting description.
http://www.wikipedia.org/
unique string per itemMon, 06 Sep 2009 16:45:00 GMTJohn Doe
tests/samples/rss/sample-rss.xml 0000666 00000001755 13112056273 0013005 0 ustar 00
RSS TitleThis is an example of an RSS feed1sample
http://www.someexamplerssdomain.com/main.html
Mon, 06 Sep 2010 00:01:00 GMTMon, 06 Sep 2009 16:45:00 GMT1800somethingExample entryHere is some text containing an interesting description.
http://www.wikipedia.org/
unique string per itemMon, 06 Sep 2009 16:45:00 GMTJohn Doe
Some content
tests/samples/rss/truncated-rss.xml 0000666 00000001172 13112056273 0013506 0 ustar 00
RSS TitleThis is an example of an RSS feed
http://www.someexamplerssdomain.com/main.html
1800Example entryHere is some text containing an interesting description.
http://www.wikipedia.org/
unique string per itemMon, 06 Sep 2009 16:45:00 +0000
tests/samples/sample-atom-html.xml 0000666 00000002040 13112056273 0013255 0 ustar 00
Example FeedA subtitle.urn:uuid:60a76c80-d399-11d9-b91C-0003939e0af62003-12-13T18:30:02ZAtom-Powered Robots Run Amokurn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a2003-12-13T18:30:02Z
<div> A title </div>
<p> A paragraph </p>
John Doejohndoe@example.comhttp://johndoe.com
tests/samples/sample-atom-namespaced.xml 0000666 00000003021 13112056273 0014411 0 ustar 00
Example FeedA subtitle.urn:uuid:60a76c80-d399-11d9-b91C-0003939e0af62003-12-13T18:30:02ZAtom-Powered Robots Run Amokurn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a2003-12-13T18:30:02Z
A title
A paragraph
John Doejohndoe@example.comhttp://johndoe.comhttp://original-link.com/item.htmlA partial entryurn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a2003-12-13T18:30:02Z
A title
A paragraph
tests/samples/sample-atom.xml 0000666 00000003120 13112056273 0012313 0 ustar 00
Example FeedA subtitle.urn:uuid:60a76c80-d399-11d9-b91C-0003939e0af62003-12-13T18:30:02ZAtom-Powered Robots Run Amokurn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a2003-12-13T18:30:02Z
A title
A paragraph
John Doejohndoe@example.comhttp://johndoe.com
Some content
A partial entryurn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a2003-12-13T18:30:02Z