Upgrade to PicoFeed v0.1.23
- OPML import/export with categories - New Feed export (bookmarks)
This commit is contained in:
parent
e0e95d67f7
commit
427b41f892
@ -15,7 +15,7 @@
|
|||||||
"fguillot/simple-validator": "v1.0.0",
|
"fguillot/simple-validator": "v1.0.0",
|
||||||
"fguillot/json-rpc": "v1.0.2",
|
"fguillot/json-rpc": "v1.0.2",
|
||||||
"fguillot/picodb": "v1.0.2",
|
"fguillot/picodb": "v1.0.2",
|
||||||
"fguillot/picofeed": "v0.1.21"
|
"fguillot/picofeed": "v0.1.23"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "4.8.3",
|
"phpunit/phpunit": "4.8.3",
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use PicoFeed\Syndication\Atom;
|
use PicoFeed\Syndication\AtomFeedBuilder;
|
||||||
|
use PicoFeed\Syndication\AtomItemBuilder;
|
||||||
|
|
||||||
// Ajax call to add or remove a bookmark
|
// Ajax call to add or remove a bookmark
|
||||||
Router\post_action('bookmark', function() {
|
Router\post_action('bookmark', function() {
|
||||||
|
|
||||||
$id = Request\param('id');
|
$id = Request\param('id');
|
||||||
$value = Request\int_param('value');
|
$value = Request\int_param('value');
|
||||||
|
|
||||||
@ -17,7 +17,6 @@ Router\post_action('bookmark', function() {
|
|||||||
|
|
||||||
// Add new bookmark
|
// Add new bookmark
|
||||||
Router\get_action('bookmark', function() {
|
Router\get_action('bookmark', function() {
|
||||||
|
|
||||||
$id = Request\param('id');
|
$id = Request\param('id');
|
||||||
$menu = Request\param('menu', 'unread');
|
$menu = Request\param('menu', 'unread');
|
||||||
$source = Request\param('source', 'unread');
|
$source = Request\param('source', 'unread');
|
||||||
@ -27,21 +26,22 @@ Router\get_action('bookmark', function() {
|
|||||||
Model\Item\set_bookmark_value($id, Request\int_param('value'));
|
Model\Item\set_bookmark_value($id, Request\int_param('value'));
|
||||||
|
|
||||||
if ($source === 'show') {
|
if ($source === 'show') {
|
||||||
Response\Redirect('?action=show&menu='.$menu.'&id='.$id);
|
Response\redirect('?action=show&menu='.$menu.'&id='.$id);
|
||||||
}
|
}
|
||||||
|
|
||||||
Response\Redirect('?action='.$menu.'&offset='.$offset.'&feed_id='.$feed_id.'#item-'.$id);
|
Response\redirect('?action='.$menu.'&offset='.$offset.'&feed_id='.$feed_id.'#item-'.$id);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Display bookmarks page
|
// Display bookmarks page
|
||||||
Router\get_action('bookmarks', function() {
|
Router\get_action('bookmarks', function() {
|
||||||
|
|
||||||
$offset = Request\int_param('offset', 0);
|
$offset = Request\int_param('offset', 0);
|
||||||
$group_id = Request\int_param('group_id', null);
|
$group_id = Request\int_param('group_id', null);
|
||||||
$feed_ids = array();
|
$feed_ids = array();
|
||||||
|
|
||||||
if (! is_null($group_id)) {
|
if (! is_null($group_id)) {
|
||||||
$feed_ids = Model\Group\get_feeds_by_group($group_id);
|
$feed_ids = Model\Group\get_feeds_by_group($group_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
$nb_items = Model\Item\count_bookmarks($feed_ids);
|
$nb_items = Model\Item\count_bookmarks($feed_ids);
|
||||||
$items = Model\Item\get_bookmarks(
|
$items = Model\Item\get_bookmarks(
|
||||||
$offset,
|
$offset,
|
||||||
@ -71,9 +71,9 @@ Router\get_action('bookmarks', function() {
|
|||||||
|
|
||||||
// Display bookmark feeds
|
// Display bookmark feeds
|
||||||
Router\get_action('bookmark-feed', function() {
|
Router\get_action('bookmark-feed', function() {
|
||||||
|
|
||||||
// Select database if the parameter is set
|
// Select database if the parameter is set
|
||||||
$database = Request\param('database');
|
$database = Request\param('database');
|
||||||
|
|
||||||
if (!empty($database)) {
|
if (!empty($database)) {
|
||||||
Model\Database\select($database);
|
Model\Database\select($database);
|
||||||
}
|
}
|
||||||
@ -87,25 +87,30 @@ Router\get_action('bookmark-feed', function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Build Feed
|
// Build Feed
|
||||||
$writer = new Atom;
|
|
||||||
$writer->title = t('Bookmarks').' - Miniflux';
|
|
||||||
$writer->site_url = Helper\get_current_base_url();
|
|
||||||
$writer->feed_url = $writer->site_url.'?action=bookmark-feed&token='.urlencode($feed_token);
|
|
||||||
|
|
||||||
$bookmarks = Model\Item\get_bookmarks();
|
$bookmarks = Model\Item\get_bookmarks();
|
||||||
|
|
||||||
|
$feedBuilder = AtomFeedBuilder::create()
|
||||||
|
->withTitle(t('Bookmarks').' - Miniflux')
|
||||||
|
->withFeedUrl(Helper\get_current_base_url().'?action=bookmark-feed&token='.urlencode($feed_token))
|
||||||
|
->withSiteUrl(Helper\get_current_base_url())
|
||||||
|
->withDate(new DateTime())
|
||||||
|
;
|
||||||
|
|
||||||
foreach ($bookmarks as $bookmark) {
|
foreach ($bookmarks as $bookmark) {
|
||||||
|
|
||||||
$article = Model\Item\get($bookmark['id']);
|
$article = Model\Item\get($bookmark['id']);
|
||||||
|
$articleDate = new DateTime();
|
||||||
|
$articleDate->setTimestamp($article['updated']);
|
||||||
|
|
||||||
$writer->items[] = array(
|
$feedBuilder
|
||||||
'id' => $article['id'],
|
->withItem(AtomItemBuilder::create($feedBuilder)
|
||||||
'title' => $article['title'],
|
->withId($article['id'])
|
||||||
'updated' => $article['updated'],
|
->withTitle($article['title'])
|
||||||
'url' => $article['url'],
|
->withUrl($article['url'])
|
||||||
'content' => $article['content'],
|
->withUpdatedDate($articleDate)
|
||||||
);
|
->withPublishedDate($articleDate)
|
||||||
|
->withContent($article['content'])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Response\xml($writer->execute());
|
Response\xml($feedBuilder->build());
|
||||||
});
|
});
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
// Called before each action
|
// Called before each action
|
||||||
Router\before(function($action) {
|
Router\before(function($action) {
|
||||||
|
|
||||||
Session\open(BASE_URL_DIRECTORY, SESSION_SAVE_PATH, 0);
|
Session\open(BASE_URL_DIRECTORY, SESSION_SAVE_PATH, 0);
|
||||||
|
|
||||||
// Select the requested database either from post param database or from the
|
// Select the requested database either from post param database or from the
|
||||||
@ -58,13 +57,11 @@ Router\before(function($action) {
|
|||||||
|
|
||||||
// Show help
|
// Show help
|
||||||
Router\get_action('show-help', function() {
|
Router\get_action('show-help', function() {
|
||||||
|
|
||||||
Response\html(Template\load('show_help'));
|
Response\html(Template\load('show_help'));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Show the menu for the mobile view
|
// Show the menu for the mobile view
|
||||||
Router\get_action('more', function() {
|
Router\get_action('more', function() {
|
||||||
|
|
||||||
Response\html(Template\layout('show_more', array('menu' => 'more')));
|
Response\html(Template\layout('show_more', array('menu' => 'more')));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -4,9 +4,7 @@ use PicoDb\Database;
|
|||||||
|
|
||||||
// Display a form to add a new database
|
// Display a form to add a new database
|
||||||
Router\get_action('new-db', function() {
|
Router\get_action('new-db', function() {
|
||||||
|
|
||||||
if (ENABLE_MULTIPLE_DB) {
|
if (ENABLE_MULTIPLE_DB) {
|
||||||
|
|
||||||
Response\html(Template\layout('new_db', array(
|
Response\html(Template\layout('new_db', array(
|
||||||
'errors' => array(),
|
'errors' => array(),
|
||||||
'values' => array(
|
'values' => array(
|
||||||
@ -23,9 +21,7 @@ Router\get_action('new-db', function() {
|
|||||||
|
|
||||||
// Create a new database
|
// Create a new database
|
||||||
Router\post_action('new-db', function() {
|
Router\post_action('new-db', function() {
|
||||||
|
|
||||||
if (ENABLE_MULTIPLE_DB) {
|
if (ENABLE_MULTIPLE_DB) {
|
||||||
|
|
||||||
$values = Request\values();
|
$values = Request\values();
|
||||||
Model\Config\check_csrf_values($values);
|
Model\Config\check_csrf_values($values);
|
||||||
list($valid, $errors) = Model\Database\validate($values);
|
list($valid, $errors) = Model\Database\validate($values);
|
||||||
@ -56,7 +52,6 @@ Router\post_action('new-db', function() {
|
|||||||
|
|
||||||
// Confirmation box before auto-update
|
// Confirmation box before auto-update
|
||||||
Router\get_action('confirm-auto-update', function() {
|
Router\get_action('confirm-auto-update', function() {
|
||||||
|
|
||||||
Response\html(Template\layout('confirm_auto_update', array(
|
Response\html(Template\layout('confirm_auto_update', array(
|
||||||
'nb_unread_items' => Model\Item\count_by_status('unread'),
|
'nb_unread_items' => Model\Item\count_by_status('unread'),
|
||||||
'menu' => 'config',
|
'menu' => 'config',
|
||||||
@ -66,13 +61,10 @@ Router\get_action('confirm-auto-update', function() {
|
|||||||
|
|
||||||
// Auto-update
|
// Auto-update
|
||||||
Router\get_action('auto-update', function() {
|
Router\get_action('auto-update', function() {
|
||||||
|
|
||||||
if (ENABLE_AUTO_UPDATE) {
|
if (ENABLE_AUTO_UPDATE) {
|
||||||
|
|
||||||
if (Model\AutoUpdate\execute(Model\Config\get('auto_update_url'))) {
|
if (Model\AutoUpdate\execute(Model\Config\get('auto_update_url'))) {
|
||||||
Session\flash(t('Miniflux is updated!'));
|
Session\flash(t('Miniflux is updated!'));
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
Session\flash_error(t('Unable to update Miniflux, check the console for errors.'));
|
Session\flash_error(t('Unable to update Miniflux, check the console for errors.'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -82,7 +74,6 @@ Router\get_action('auto-update', function() {
|
|||||||
|
|
||||||
// Re-generate tokens
|
// Re-generate tokens
|
||||||
Router\get_action('generate-tokens', function() {
|
Router\get_action('generate-tokens', function() {
|
||||||
|
|
||||||
if (Model\Config\check_csrf(Request\param('csrf'))) {
|
if (Model\Config\check_csrf(Request\param('csrf'))) {
|
||||||
Model\Config\new_tokens();
|
Model\Config\new_tokens();
|
||||||
}
|
}
|
||||||
@ -92,7 +83,6 @@ Router\get_action('generate-tokens', function() {
|
|||||||
|
|
||||||
// Optimize the database manually
|
// Optimize the database manually
|
||||||
Router\get_action('optimize-db', function() {
|
Router\get_action('optimize-db', function() {
|
||||||
|
|
||||||
if (Model\Config\check_csrf(Request\param('csrf'))) {
|
if (Model\Config\check_csrf(Request\param('csrf'))) {
|
||||||
Database::getInstance('db')->getConnection()->exec('VACUUM');
|
Database::getInstance('db')->getConnection()->exec('VACUUM');
|
||||||
}
|
}
|
||||||
@ -102,7 +92,6 @@ Router\get_action('optimize-db', function() {
|
|||||||
|
|
||||||
// Download the compressed database
|
// Download the compressed database
|
||||||
Router\get_action('download-db', function() {
|
Router\get_action('download-db', function() {
|
||||||
|
|
||||||
if (Model\Config\check_csrf(Request\param('csrf'))) {
|
if (Model\Config\check_csrf(Request\param('csrf'))) {
|
||||||
Response\force_download('db.sqlite.gz');
|
Response\force_download('db.sqlite.gz');
|
||||||
Response\binary(gzencode(file_get_contents(Model\Database\get_path())));
|
Response\binary(gzencode(file_get_contents(Model\Database\get_path())));
|
||||||
@ -111,7 +100,6 @@ Router\get_action('download-db', function() {
|
|||||||
|
|
||||||
// Display preferences page
|
// Display preferences page
|
||||||
Router\get_action('config', function() {
|
Router\get_action('config', function() {
|
||||||
|
|
||||||
Response\html(Template\layout('config', array(
|
Response\html(Template\layout('config', array(
|
||||||
'errors' => array(),
|
'errors' => array(),
|
||||||
'values' => Model\Config\get_all() + array('csrf' => Model\Config\generate_csrf()),
|
'values' => Model\Config\get_all() + array('csrf' => Model\Config\generate_csrf()),
|
||||||
@ -133,7 +121,6 @@ Router\get_action('config', function() {
|
|||||||
|
|
||||||
// Update preferences
|
// Update preferences
|
||||||
Router\post_action('config', function() {
|
Router\post_action('config', function() {
|
||||||
|
|
||||||
$values = Request\values() + array('nocontent' => 0, 'image_proxy' => 0, 'favicons' => 0, 'debug_mode' => 0, 'original_marks_read' => 0);
|
$values = Request\values() + array('nocontent' => 0, 'image_proxy' => 0, 'favicons' => 0, 'debug_mode' => 0, 'original_marks_read' => 0);
|
||||||
Model\Config\check_csrf_values($values);
|
Model\Config\check_csrf_values($values);
|
||||||
list($valid, $errors) = Model\Config\validate_modification($values);
|
list($valid, $errors) = Model\Config\validate_modification($values);
|
||||||
@ -188,7 +175,6 @@ Router\post_action('get-config', function() {
|
|||||||
|
|
||||||
// Display help page
|
// Display help page
|
||||||
Router\get_action('help', function() {
|
Router\get_action('help', function() {
|
||||||
|
|
||||||
Response\html(Template\layout('help', array(
|
Response\html(Template\layout('help', array(
|
||||||
'config' => Model\Config\get_all(),
|
'config' => Model\Config\get_all(),
|
||||||
'nb_unread_items' => Model\Item\count_by_status('unread'),
|
'nb_unread_items' => Model\Item\count_by_status('unread'),
|
||||||
@ -199,7 +185,6 @@ Router\get_action('help', function() {
|
|||||||
|
|
||||||
// Display about page
|
// Display about page
|
||||||
Router\get_action('about', function() {
|
Router\get_action('about', function() {
|
||||||
|
|
||||||
Response\html(Template\layout('about', array(
|
Response\html(Template\layout('about', array(
|
||||||
'csrf' => Model\Config\generate_csrf(),
|
'csrf' => Model\Config\generate_csrf(),
|
||||||
'config' => Model\Config\get_all(),
|
'config' => Model\Config\get_all(),
|
||||||
@ -212,7 +197,6 @@ Router\get_action('about', function() {
|
|||||||
|
|
||||||
// Display database page
|
// Display database page
|
||||||
Router\get_action('database', function() {
|
Router\get_action('database', function() {
|
||||||
|
|
||||||
Response\html(Template\layout('database', array(
|
Response\html(Template\layout('database', array(
|
||||||
'csrf' => Model\Config\generate_csrf(),
|
'csrf' => Model\Config\generate_csrf(),
|
||||||
'config' => Model\Config\get_all(),
|
'config' => Model\Config\get_all(),
|
||||||
@ -225,7 +209,6 @@ Router\get_action('database', function() {
|
|||||||
|
|
||||||
// Display API page
|
// Display API page
|
||||||
Router\get_action('api', function() {
|
Router\get_action('api', function() {
|
||||||
|
|
||||||
Response\html(Template\layout('api', array(
|
Response\html(Template\layout('api', array(
|
||||||
'config' => Model\Config\get_all(),
|
'config' => Model\Config\get_all(),
|
||||||
'nb_unread_items' => Model\Item\count_by_status('unread'),
|
'nb_unread_items' => Model\Item\count_by_status('unread'),
|
||||||
@ -236,7 +219,6 @@ Router\get_action('api', function() {
|
|||||||
|
|
||||||
// Display bookmark services page
|
// Display bookmark services page
|
||||||
Router\get_action('services', function() {
|
Router\get_action('services', function() {
|
||||||
|
|
||||||
Response\html(Template\layout('services', array(
|
Response\html(Template\layout('services', array(
|
||||||
'errors' => array(),
|
'errors' => array(),
|
||||||
'values' => Model\Config\get_all() + array('csrf' => Model\Config\generate_csrf()),
|
'values' => Model\Config\get_all() + array('csrf' => Model\Config\generate_csrf()),
|
||||||
@ -247,7 +229,6 @@ Router\get_action('services', function() {
|
|||||||
|
|
||||||
// Update bookmark services
|
// Update bookmark services
|
||||||
Router\post_action('services', function() {
|
Router\post_action('services', function() {
|
||||||
|
|
||||||
$values = Request\values() + array('pinboard_enabled' => 0, 'instapaper_enabled' => 0);
|
$values = Request\values() + array('pinboard_enabled' => 0, 'instapaper_enabled' => 0);
|
||||||
Model\Config\check_csrf_values($values);
|
Model\Config\check_csrf_values($values);
|
||||||
|
|
||||||
|
@ -2,14 +2,12 @@
|
|||||||
|
|
||||||
// Flush console messages
|
// Flush console messages
|
||||||
Router\get_action('flush-console', function() {
|
Router\get_action('flush-console', function() {
|
||||||
|
|
||||||
@unlink(DEBUG_FILENAME);
|
@unlink(DEBUG_FILENAME);
|
||||||
Response\redirect('?action=console');
|
Response\redirect('?action=console');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Display console
|
// Display console
|
||||||
Router\get_action('console', function() {
|
Router\get_action('console', function() {
|
||||||
|
|
||||||
Response\html(Template\layout('console', array(
|
Response\html(Template\layout('console', array(
|
||||||
'content' => @file_get_contents(DEBUG_FILENAME),
|
'content' => @file_get_contents(DEBUG_FILENAME),
|
||||||
'nb_unread_items' => Model\Item\count_by_status('unread'),
|
'nb_unread_items' => Model\Item\count_by_status('unread'),
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use PicoFeed\Parser\MalformedXmlException;
|
||||||
|
|
||||||
// Refresh all feeds, used when Javascript is disabled
|
// Refresh all feeds, used when Javascript is disabled
|
||||||
Router\get_action('refresh-all', function() {
|
Router\get_action('refresh-all', function() {
|
||||||
|
|
||||||
Model\Feed\refresh_all();
|
Model\Feed\refresh_all();
|
||||||
Session\flash(t('Your subscriptions are updated'));
|
Session\flash(t('Your subscriptions are updated'));
|
||||||
Response\redirect('?action=unread');
|
Response\redirect('?action=unread');
|
||||||
@ -10,7 +11,6 @@ Router\get_action('refresh-all', function() {
|
|||||||
|
|
||||||
// Edit feed form
|
// Edit feed form
|
||||||
Router\get_action('edit-feed', function() {
|
Router\get_action('edit-feed', function() {
|
||||||
|
|
||||||
$id = Request\int_param('feed_id');
|
$id = Request\int_param('feed_id');
|
||||||
|
|
||||||
$values = Model\Feed\get($id);
|
$values = Model\Feed\get($id);
|
||||||
@ -30,7 +30,6 @@ Router\get_action('edit-feed', function() {
|
|||||||
|
|
||||||
// Submit edit feed form
|
// Submit edit feed form
|
||||||
Router\post_action('edit-feed', function() {
|
Router\post_action('edit-feed', function() {
|
||||||
|
|
||||||
$values = Request\values();
|
$values = Request\values();
|
||||||
$values += array(
|
$values += array(
|
||||||
'enabled' => 0,
|
'enabled' => 0,
|
||||||
@ -65,7 +64,6 @@ Router\post_action('edit-feed', function() {
|
|||||||
|
|
||||||
// Confirmation box to remove a feed
|
// Confirmation box to remove a feed
|
||||||
Router\get_action('confirm-remove-feed', function() {
|
Router\get_action('confirm-remove-feed', function() {
|
||||||
|
|
||||||
$id = Request\int_param('feed_id');
|
$id = Request\int_param('feed_id');
|
||||||
|
|
||||||
Response\html(Template\layout('confirm_remove_feed', array(
|
Response\html(Template\layout('confirm_remove_feed', array(
|
||||||
@ -78,7 +76,6 @@ Router\get_action('confirm-remove-feed', function() {
|
|||||||
|
|
||||||
// Remove a feed
|
// Remove a feed
|
||||||
Router\get_action('remove-feed', function() {
|
Router\get_action('remove-feed', function() {
|
||||||
|
|
||||||
$id = Request\int_param('feed_id');
|
$id = Request\int_param('feed_id');
|
||||||
|
|
||||||
if ($id && Model\Feed\remove($id)) {
|
if ($id && Model\Feed\remove($id)) {
|
||||||
@ -93,7 +90,6 @@ Router\get_action('remove-feed', function() {
|
|||||||
|
|
||||||
// Refresh one feed and redirect to unread items
|
// Refresh one feed and redirect to unread items
|
||||||
Router\get_action('refresh-feed', function() {
|
Router\get_action('refresh-feed', function() {
|
||||||
|
|
||||||
$feed_id = Request\int_param('feed_id');
|
$feed_id = Request\int_param('feed_id');
|
||||||
$redirect = Request\param('redirect', 'unread');
|
$redirect = Request\param('redirect', 'unread');
|
||||||
|
|
||||||
@ -103,7 +99,6 @@ Router\get_action('refresh-feed', function() {
|
|||||||
|
|
||||||
// Ajax call to refresh one feed
|
// Ajax call to refresh one feed
|
||||||
Router\post_action('refresh-feed', function() {
|
Router\post_action('refresh-feed', function() {
|
||||||
|
|
||||||
$feed_id = Request\int_param('feed_id', 0);
|
$feed_id = Request\int_param('feed_id', 0);
|
||||||
|
|
||||||
Response\json(array(
|
Response\json(array(
|
||||||
@ -136,7 +131,6 @@ Router\get_action('feeds', function() {
|
|||||||
|
|
||||||
// Display form to add one feed
|
// Display form to add one feed
|
||||||
Router\get_action('add', function() {
|
Router\get_action('add', function() {
|
||||||
|
|
||||||
$values = array(
|
$values = array(
|
||||||
'download_content' => 0,
|
'download_content' => 0,
|
||||||
'rtl' => 0,
|
'rtl' => 0,
|
||||||
@ -157,13 +151,11 @@ Router\get_action('add', function() {
|
|||||||
|
|
||||||
// Add a feed with the form or directly from the url, it can be used by a bookmarklet by example
|
// Add a feed with the form or directly from the url, it can be used by a bookmarklet by example
|
||||||
Router\action('subscribe', function() {
|
Router\action('subscribe', function() {
|
||||||
|
|
||||||
if (Request\is_post()) {
|
if (Request\is_post()) {
|
||||||
$values = Request\values();
|
$values = Request\values();
|
||||||
Model\Config\check_csrf_values($values);
|
Model\Config\check_csrf_values($values);
|
||||||
$url = isset($values['url']) ? $values['url'] : '';
|
$url = isset($values['url']) ? $values['url'] : '';
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
$values = array();
|
$values = array();
|
||||||
$url = Request\param('url');
|
$url = Request\param('url');
|
||||||
$token = Request\param('token');
|
$token = Request\param('token');
|
||||||
@ -247,14 +239,12 @@ Router\action('subscribe', function() {
|
|||||||
|
|
||||||
// OPML export
|
// OPML export
|
||||||
Router\get_action('export', function() {
|
Router\get_action('export', function() {
|
||||||
|
|
||||||
Response\force_download('feeds.opml');
|
Response\force_download('feeds.opml');
|
||||||
Response\xml(Model\Feed\export_opml());
|
Response\xml(Model\Feed\export_opml());
|
||||||
});
|
});
|
||||||
|
|
||||||
// OPML import form
|
// OPML import form
|
||||||
Router\get_action('import', function() {
|
Router\get_action('import', function() {
|
||||||
|
|
||||||
Response\html(Template\layout('import', array(
|
Response\html(Template\layout('import', array(
|
||||||
'errors' => array(),
|
'errors' => array(),
|
||||||
'nb_unread_items' => Model\Item\count_by_status('unread'),
|
'nb_unread_items' => Model\Item\count_by_status('unread'),
|
||||||
@ -265,15 +255,12 @@ Router\get_action('import', function() {
|
|||||||
|
|
||||||
// OPML importation
|
// OPML importation
|
||||||
Router\post_action('import', function() {
|
Router\post_action('import', function() {
|
||||||
|
try {
|
||||||
if (Model\Feed\import_opml(Request\file_content('file'))) {
|
Model\Feed\import_opml(Request\file_content('file'));
|
||||||
|
|
||||||
Session\flash(t('Your feeds have been imported.'));
|
Session\flash(t('Your feeds have been imported.'));
|
||||||
Response\redirect('?action=feeds');
|
Response\redirect('?action=feeds');
|
||||||
}
|
} catch (MalformedXmlException $e) {
|
||||||
else {
|
Session\flash_error(t('Unable to import your OPML file.').' ('.$e->getMessage().')');
|
||||||
|
|
||||||
Session\flash_error(t('Unable to import your OPML file.'));
|
|
||||||
Response\redirect('?action=import');
|
Response\redirect('?action=import');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
// Display history page
|
// Display history page
|
||||||
Router\get_action('history', function() {
|
Router\get_action('history', function() {
|
||||||
|
|
||||||
$offset = Request\int_param('offset', 0);
|
$offset = Request\int_param('offset', 0);
|
||||||
$group_id = Request\int_param('group_id', null);
|
$group_id = Request\int_param('group_id', null);
|
||||||
$feed_ids = array();
|
$feed_ids = array();
|
||||||
|
|
||||||
if (! is_null($group_id)) {
|
if (! is_null($group_id)) {
|
||||||
$feed_ids = Model\Group\get_feeds_by_group($group_id);
|
$feed_ids = Model\Group\get_feeds_by_group($group_id);
|
||||||
}
|
}
|
||||||
@ -44,6 +44,7 @@ Router\get_action('history', function() {
|
|||||||
// Confirmation box to flush history
|
// Confirmation box to flush history
|
||||||
Router\get_action('confirm-flush-history', function() {
|
Router\get_action('confirm-flush-history', function() {
|
||||||
$group_id = Request\int_param('group_id', null);
|
$group_id = Request\int_param('group_id', null);
|
||||||
|
|
||||||
Response\html(Template\layout('confirm_flush_items', array(
|
Response\html(Template\layout('confirm_flush_items', array(
|
||||||
'group_id' => $group_id,
|
'group_id' => $group_id,
|
||||||
'nb_unread_items' => Model\Item\count_by_status('unread'),
|
'nb_unread_items' => Model\Item\count_by_status('unread'),
|
||||||
@ -55,10 +56,12 @@ Router\get_action('confirm-flush-history', function() {
|
|||||||
// Flush history
|
// Flush history
|
||||||
Router\get_action('flush-history', function() {
|
Router\get_action('flush-history', function() {
|
||||||
$group_id = Request\int_param('group_id', null);
|
$group_id = Request\int_param('group_id', null);
|
||||||
|
|
||||||
if (!is_null($group_id)) {
|
if (!is_null($group_id)) {
|
||||||
Model\Item\mark_group_as_removed($group_id);
|
Model\Item\mark_group_as_removed($group_id);
|
||||||
} else {
|
} else {
|
||||||
Model\Item\mark_all_as_removed();
|
Model\Item\mark_all_as_removed();
|
||||||
}
|
}
|
||||||
|
|
||||||
Response\redirect('?action=history');
|
Response\redirect('?action=history');
|
||||||
});
|
});
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
// Display unread items
|
// Display unread items
|
||||||
Router\get_action('unread', function() {
|
Router\get_action('unread', function() {
|
||||||
|
|
||||||
Model\Item\autoflush_read();
|
Model\Item\autoflush_read();
|
||||||
Model\Item\autoflush_unread();
|
Model\Item\autoflush_unread();
|
||||||
|
|
||||||
@ -54,7 +53,6 @@ Router\get_action('unread', function() {
|
|||||||
|
|
||||||
// Show item
|
// Show item
|
||||||
Router\get_action('show', function() {
|
Router\get_action('show', function() {
|
||||||
|
|
||||||
$id = Request\param('id');
|
$id = Request\param('id');
|
||||||
$menu = Request\param('menu');
|
$menu = Request\param('menu');
|
||||||
$item = Model\Item\get($id);
|
$item = Model\Item\get($id);
|
||||||
@ -101,7 +99,6 @@ Router\get_action('show', function() {
|
|||||||
|
|
||||||
// Display feed items page
|
// Display feed items page
|
||||||
Router\get_action('feed-items', function() {
|
Router\get_action('feed-items', function() {
|
||||||
|
|
||||||
$feed_id = Request\int_param('feed_id', 0);
|
$feed_id = Request\int_param('feed_id', 0);
|
||||||
$offset = Request\int_param('offset', 0);
|
$offset = Request\int_param('offset', 0);
|
||||||
$nb_items = Model\Item\count_by_feed($feed_id);
|
$nb_items = Model\Item\count_by_feed($feed_id);
|
||||||
@ -143,28 +140,24 @@ Router\post_action('download-item', function() {
|
|||||||
|
|
||||||
// Ajax call to mark item read
|
// Ajax call to mark item read
|
||||||
Router\post_action('mark-item-read', function() {
|
Router\post_action('mark-item-read', function() {
|
||||||
|
|
||||||
Model\Item\set_read(Request\param('id'));
|
Model\Item\set_read(Request\param('id'));
|
||||||
Response\json(array('Ok'));
|
Response\json(array('Ok'));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Ajax call to mark item as removed
|
// Ajax call to mark item as removed
|
||||||
Router\post_action('mark-item-removed', function() {
|
Router\post_action('mark-item-removed', function() {
|
||||||
|
|
||||||
Model\Item\set_removed(Request\param('id'));
|
Model\Item\set_removed(Request\param('id'));
|
||||||
Response\json(array('Ok'));
|
Response\json(array('Ok'));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Ajax call to mark item unread
|
// Ajax call to mark item unread
|
||||||
Router\post_action('mark-item-unread', function() {
|
Router\post_action('mark-item-unread', function() {
|
||||||
|
|
||||||
Model\Item\set_unread(Request\param('id'));
|
Model\Item\set_unread(Request\param('id'));
|
||||||
Response\json(array('Ok'));
|
Response\json(array('Ok'));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Mark unread items as read
|
// Mark unread items as read
|
||||||
Router\get_action('mark-all-read', function() {
|
Router\get_action('mark-all-read', function() {
|
||||||
|
|
||||||
$group_id = Request\int_param('group_id', null);
|
$group_id = Request\int_param('group_id', null);
|
||||||
|
|
||||||
if (!is_null($group_id)) {
|
if (!is_null($group_id)) {
|
||||||
@ -179,11 +172,9 @@ Router\get_action('mark-all-read', function() {
|
|||||||
|
|
||||||
// Mark all unread items as read for a specific feed
|
// Mark all unread items as read for a specific feed
|
||||||
Router\get_action('mark-feed-as-read', function() {
|
Router\get_action('mark-feed-as-read', function() {
|
||||||
|
|
||||||
$feed_id = Request\int_param('feed_id');
|
$feed_id = Request\int_param('feed_id');
|
||||||
|
|
||||||
Model\Item\mark_feed_as_read($feed_id);
|
Model\Item\mark_feed_as_read($feed_id);
|
||||||
|
|
||||||
Response\redirect('?action=feed-items&feed_id='.$feed_id);
|
Response\redirect('?action=feed-items&feed_id='.$feed_id);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -192,7 +183,6 @@ Router\get_action('mark-feed-as-read', function() {
|
|||||||
// that where marked read from the frontend, since the number of unread items
|
// that where marked read from the frontend, since the number of unread items
|
||||||
// on page 2+ is unknown.
|
// on page 2+ is unknown.
|
||||||
Router\post_action('mark-feed-as-read', function() {
|
Router\post_action('mark-feed-as-read', function() {
|
||||||
|
|
||||||
Model\Item\mark_feed_as_read(Request\int_param('feed_id'));
|
Model\Item\mark_feed_as_read(Request\int_param('feed_id'));
|
||||||
$nb_items = Model\Item\count_by_status('unread');
|
$nb_items = Model\Item\count_by_status('unread');
|
||||||
|
|
||||||
@ -201,41 +191,35 @@ Router\post_action('mark-feed-as-read', function() {
|
|||||||
|
|
||||||
// Mark item as read and redirect to the listing page
|
// Mark item as read and redirect to the listing page
|
||||||
Router\get_action('mark-item-read', function() {
|
Router\get_action('mark-item-read', function() {
|
||||||
|
|
||||||
$id = Request\param('id');
|
$id = Request\param('id');
|
||||||
$redirect = Request\param('redirect', 'unread');
|
$redirect = Request\param('redirect', 'unread');
|
||||||
$offset = Request\int_param('offset', 0);
|
$offset = Request\int_param('offset', 0);
|
||||||
$feed_id = Request\int_param('feed_id', 0);
|
$feed_id = Request\int_param('feed_id', 0);
|
||||||
|
|
||||||
Model\Item\set_read($id);
|
Model\Item\set_read($id);
|
||||||
|
Response\redirect('?action='.$redirect.'&offset='.$offset.'&feed_id='.$feed_id.'#item-'.$id);
|
||||||
Response\Redirect('?action='.$redirect.'&offset='.$offset.'&feed_id='.$feed_id.'#item-'.$id);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Mark item as unread and redirect to the listing page
|
// Mark item as unread and redirect to the listing page
|
||||||
Router\get_action('mark-item-unread', function() {
|
Router\get_action('mark-item-unread', function() {
|
||||||
|
|
||||||
$id = Request\param('id');
|
$id = Request\param('id');
|
||||||
$redirect = Request\param('redirect', 'history');
|
$redirect = Request\param('redirect', 'history');
|
||||||
$offset = Request\int_param('offset', 0);
|
$offset = Request\int_param('offset', 0);
|
||||||
$feed_id = Request\int_param('feed_id', 0);
|
$feed_id = Request\int_param('feed_id', 0);
|
||||||
|
|
||||||
Model\Item\set_unread($id);
|
Model\Item\set_unread($id);
|
||||||
|
Response\redirect('?action='.$redirect.'&offset='.$offset.'&feed_id='.$feed_id.'#item-'.$id);
|
||||||
Response\Redirect('?action='.$redirect.'&offset='.$offset.'&feed_id='.$feed_id.'#item-'.$id);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Mark item as removed and redirect to the listing page
|
// Mark item as removed and redirect to the listing page
|
||||||
Router\get_action('mark-item-removed', function() {
|
Router\get_action('mark-item-removed', function() {
|
||||||
|
|
||||||
$id = Request\param('id');
|
$id = Request\param('id');
|
||||||
$redirect = Request\param('redirect', 'history');
|
$redirect = Request\param('redirect', 'history');
|
||||||
$offset = Request\int_param('offset', 0);
|
$offset = Request\int_param('offset', 0);
|
||||||
$feed_id = Request\int_param('feed_id', 0);
|
$feed_id = Request\int_param('feed_id', 0);
|
||||||
|
|
||||||
Model\Item\set_removed($id);
|
Model\Item\set_removed($id);
|
||||||
|
Response\redirect('?action='.$redirect.'&offset='.$offset.'&feed_id='.$feed_id);
|
||||||
Response\Redirect('?action='.$redirect.'&offset='.$offset.'&feed_id='.$feed_id);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Router\post_action('latest-feeds-items', function() {
|
Router\post_action('latest-feeds-items', function() {
|
||||||
|
@ -2,14 +2,12 @@
|
|||||||
|
|
||||||
// Logout and destroy session
|
// Logout and destroy session
|
||||||
Router\get_action('logout', function() {
|
Router\get_action('logout', function() {
|
||||||
|
|
||||||
Model\User\logout();
|
Model\User\logout();
|
||||||
Response\redirect('?action=login');
|
Response\redirect('?action=login');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Display form login
|
// Display form login
|
||||||
Router\get_action('login', function() {
|
Router\get_action('login', function() {
|
||||||
|
|
||||||
if (Model\User\is_loggedin()) {
|
if (Model\User\is_loggedin()) {
|
||||||
Response\redirect('?action=unread');
|
Response\redirect('?action=unread');
|
||||||
}
|
}
|
||||||
@ -26,7 +24,6 @@ Router\get_action('login', function() {
|
|||||||
|
|
||||||
// Check credentials and redirect to unread items
|
// Check credentials and redirect to unread items
|
||||||
Router\post_action('login', function() {
|
Router\post_action('login', function() {
|
||||||
|
|
||||||
$values = Request\values();
|
$values = Request\values();
|
||||||
Model\Config\check_csrf_values($values);
|
Model\Config\check_csrf_values($values);
|
||||||
list($valid, $errors) = Model\User\validate_login($values);
|
list($valid, $errors) = Model\User\validate_login($values);
|
||||||
|
@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
namespace Model\Feed;
|
namespace Model\Feed;
|
||||||
|
|
||||||
|
use PicoFeed\Serialization\Subscription;
|
||||||
|
use PicoFeed\Serialization\SubscriptionList;
|
||||||
|
use PicoFeed\Serialization\SubscriptionListBuilder;
|
||||||
|
use PicoFeed\Serialization\SubscriptionListParser;
|
||||||
use UnexpectedValueException;
|
use UnexpectedValueException;
|
||||||
use Model\Config;
|
use Model\Config;
|
||||||
use Model\Item;
|
use Model\Item;
|
||||||
@ -11,11 +15,8 @@ use Helper;
|
|||||||
use SimpleValidator\Validator;
|
use SimpleValidator\Validator;
|
||||||
use SimpleValidator\Validators;
|
use SimpleValidator\Validators;
|
||||||
use PicoDb\Database;
|
use PicoDb\Database;
|
||||||
use PicoFeed\Serialization\Export;
|
|
||||||
use PicoFeed\Serialization\Import;
|
|
||||||
use PicoFeed\Reader\Reader;
|
use PicoFeed\Reader\Reader;
|
||||||
use PicoFeed\PicoFeedException;
|
use PicoFeed\PicoFeedException;
|
||||||
use PicoFeed\Client\InvalidUrlException;
|
|
||||||
|
|
||||||
const LIMIT_ALL = -1;
|
const LIMIT_ALL = -1;
|
||||||
|
|
||||||
@ -53,43 +54,61 @@ function update(array $values)
|
|||||||
// Export all feeds
|
// Export all feeds
|
||||||
function export_opml()
|
function export_opml()
|
||||||
{
|
{
|
||||||
$opml = new Export(get_all());
|
$feeds = get_all();
|
||||||
return $opml->execute();
|
$subscriptionList = SubscriptionList::create()->setTitle(t('Subscriptions'));
|
||||||
|
|
||||||
|
foreach ($feeds as $feed) {
|
||||||
|
$groups = Group\get_feed_groups($feed['id']);
|
||||||
|
$category = '';
|
||||||
|
|
||||||
|
if (!empty($groups)) {
|
||||||
|
$category = $groups[0]['title'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$subscriptionList->addSubscription(Subscription::create()
|
||||||
|
->setTitle($feed['title'])
|
||||||
|
->setSiteUrl($feed['site_url'])
|
||||||
|
->setFeedUrl($feed['feed_url'])
|
||||||
|
->setCategory($category)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SubscriptionListBuilder::create($subscriptionList)->build();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Import OPML file
|
// Import OPML file
|
||||||
function import_opml($content)
|
function import_opml($content)
|
||||||
{
|
{
|
||||||
$import = new Import($content);
|
$subscriptionList = SubscriptionListParser::create($content)->parse();
|
||||||
$feeds = $import->execute();
|
|
||||||
|
|
||||||
if ($feeds) {
|
$db = Database::getInstance('db');
|
||||||
|
$db->startTransaction();
|
||||||
|
|
||||||
$db = Database::getInstance('db');
|
foreach ($subscriptionList->subscriptions as $subscription) {
|
||||||
$db->startTransaction();
|
if (! $db->table('feeds')->eq('feed_url', $subscription->getFeedUrl())->exists()) {
|
||||||
|
$db->table('feeds')->insert(array(
|
||||||
|
'title' => $subscription->getTitle(),
|
||||||
|
'site_url' => $subscription->getSiteUrl(),
|
||||||
|
'feed_url' => $subscription->getFeedUrl(),
|
||||||
|
));
|
||||||
|
|
||||||
foreach ($feeds as $feed) {
|
if ($subscription->getCategory() !== '') {
|
||||||
|
$feed_id = $db->getLastId();
|
||||||
|
$group_id = Group\get_group_id($subscription->getCategory());
|
||||||
|
|
||||||
if (! $db->table('feeds')->eq('feed_url', $feed->feed_url)->count()) {
|
if (empty($group_id)) {
|
||||||
|
$group_id = Group\create($subscription->getCategory());
|
||||||
|
}
|
||||||
|
|
||||||
$db->table('feeds')->save(array(
|
Group\add($feed_id, array($group_id));
|
||||||
'title' => $feed->title,
|
|
||||||
'site_url' => $feed->site_url,
|
|
||||||
'feed_url' => $feed->feed_url
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$db->closeTransaction();
|
|
||||||
|
|
||||||
Config\write_debug();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$db->closeTransaction();
|
||||||
Config\write_debug();
|
Config\write_debug();
|
||||||
|
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a new feed from an URL
|
// Add a new feed from an URL
|
||||||
@ -339,7 +358,7 @@ function update_cache($feed_id, $last_modified, $etag)
|
|||||||
function remove($feed_id)
|
function remove($feed_id)
|
||||||
{
|
{
|
||||||
Group\remove_all($feed_id);
|
Group\remove_all($feed_id);
|
||||||
|
|
||||||
// Items are removed by a sql constraint
|
// Items are removed by a sql constraint
|
||||||
$result = Database::getInstance('db')->table('feeds')->eq('id', $feed_id)->remove();
|
$result = Database::getInstance('db')->table('feeds')->eq('id', $feed_id)->remove();
|
||||||
Favicon\purge_favicons();
|
Favicon\purge_favicons();
|
||||||
|
@ -80,6 +80,16 @@ function get_feed_group_ids($feed_id)
|
|||||||
->findAllByColumn('id');
|
->findAllByColumn('id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function get_feed_groups($feed_id)
|
||||||
|
{
|
||||||
|
return Database::getInstance('db')
|
||||||
|
->table('groups')
|
||||||
|
->columns('groups.id', 'groups.title')
|
||||||
|
->join('feeds_groups', 'group_id', 'id')
|
||||||
|
->eq('feed_id', $feed_id)
|
||||||
|
->findAll();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the id of a group
|
* Get the id of a group
|
||||||
*
|
*
|
||||||
@ -143,7 +153,7 @@ function create($title)
|
|||||||
* @param array $group_ids array of group ids
|
* @param array $group_ids array of group ids
|
||||||
* @return boolean true on success, false on error
|
* @return boolean true on success, false on error
|
||||||
*/
|
*/
|
||||||
function add($feed_id, $group_ids)
|
function add($feed_id, array $group_ids)
|
||||||
{
|
{
|
||||||
foreach ($group_ids as $group_id){
|
foreach ($group_ids as $group_id){
|
||||||
$data = array('feed_id' => $feed_id, 'group_id' => $group_id);
|
$data = array('feed_id' => $feed_id, 'group_id' => $group_id);
|
||||||
@ -167,7 +177,7 @@ function add($feed_id, $group_ids)
|
|||||||
* @param array $group_ids array of group ids
|
* @param array $group_ids array of group ids
|
||||||
* @return boolean true on success, false on error
|
* @return boolean true on success, false on error
|
||||||
*/
|
*/
|
||||||
function remove($feed_id, $group_ids)
|
function remove($feed_id, array $group_ids)
|
||||||
{
|
{
|
||||||
$result = Database::getInstance('db')
|
$result = Database::getInstance('db')
|
||||||
->table('feeds_groups')
|
->table('feeds_groups')
|
||||||
@ -212,7 +222,7 @@ function purge_groups()
|
|||||||
$groups = Database::getInstance('db')
|
$groups = Database::getInstance('db')
|
||||||
->table('groups')
|
->table('groups')
|
||||||
->join('feeds_groups', 'group_id', 'id')
|
->join('feeds_groups', 'group_id', 'id')
|
||||||
->isnull('feed_id')
|
->isNull('feed_id')
|
||||||
->findAllByColumn('id');
|
->findAllByColumn('id');
|
||||||
|
|
||||||
if (! empty($groups)) {
|
if (! empty($groups)) {
|
||||||
@ -231,7 +241,7 @@ function purge_groups()
|
|||||||
* @param string $create_group group to create and assign to feed
|
* @param string $create_group group to create and assign to feed
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
function update_feed_groups($feed_id, $group_ids, $create_group = '')
|
function update_feed_groups($feed_id, array $group_ids, $create_group = '')
|
||||||
{
|
{
|
||||||
if ($create_group !== '') {
|
if ($create_group !== '') {
|
||||||
$id = create($create_group);
|
$id = create($create_group);
|
||||||
|
@ -4,6 +4,7 @@ namespace Model\Proxy;
|
|||||||
|
|
||||||
use Helper;
|
use Helper;
|
||||||
use Model\Config;
|
use Model\Config;
|
||||||
|
use PicoFeed\Client\ClientException;
|
||||||
use PicoFeed\Config\Config as PicoFeedConfig;
|
use PicoFeed\Config\Config as PicoFeedConfig;
|
||||||
use PicoFeed\Filter\Filter;
|
use PicoFeed\Filter\Filter;
|
||||||
use PicoFeed\Client\Client;
|
use PicoFeed\Client\Client;
|
||||||
@ -51,7 +52,6 @@ function rewrite_html($html, $website, $proxy_images, $cloak_referrer)
|
|||||||
function download($url)
|
function download($url)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|
||||||
if ((bool) Config\get('debug_mode')) {
|
if ((bool) Config\get('debug_mode')) {
|
||||||
Logger::enable();
|
Logger::enable();
|
||||||
}
|
}
|
||||||
@ -61,7 +61,7 @@ function download($url)
|
|||||||
$client->enablePassthroughMode();
|
$client->enablePassthroughMode();
|
||||||
$client->execute($url);
|
$client->execute($url);
|
||||||
}
|
}
|
||||||
catch (\PicoFeed\Client\ClientException $e) {}
|
catch (ClientException $e) {}
|
||||||
|
|
||||||
Config\write_debug();
|
Config\write_debug();
|
||||||
}
|
}
|
||||||
|
2
vendor/autoload.php
vendored
2
vendor/autoload.php
vendored
@ -4,4 +4,4 @@
|
|||||||
|
|
||||||
require_once __DIR__ . '/composer' . '/autoload_real.php';
|
require_once __DIR__ . '/composer' . '/autoload_real.php';
|
||||||
|
|
||||||
return ComposerAutoloaderInit00bf4499632e34ac01e60c409b852c25::getLoader();
|
return ComposerAutoloaderInitfd7e8d436e1dc450edc3153ac8bc31b4::getLoader();
|
||||||
|
18
vendor/composer/autoload_classmap.php
vendored
18
vendor/composer/autoload_classmap.php
vendored
@ -78,11 +78,19 @@ return array(
|
|||||||
'PicoFeed\\Scraper\\RuleLoader' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Scraper/RuleLoader.php',
|
'PicoFeed\\Scraper\\RuleLoader' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Scraper/RuleLoader.php',
|
||||||
'PicoFeed\\Scraper\\RuleParser' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Scraper/RuleParser.php',
|
'PicoFeed\\Scraper\\RuleParser' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Scraper/RuleParser.php',
|
||||||
'PicoFeed\\Scraper\\Scraper' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Scraper/Scraper.php',
|
'PicoFeed\\Scraper\\Scraper' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Scraper/Scraper.php',
|
||||||
'PicoFeed\\Serialization\\Export' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Serialization/Export.php',
|
'PicoFeed\\Serialization\\Subscription' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Serialization/Subscription.php',
|
||||||
'PicoFeed\\Serialization\\Import' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Serialization/Import.php',
|
'PicoFeed\\Serialization\\SubscriptionList' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Serialization/SubscriptionList.php',
|
||||||
'PicoFeed\\Syndication\\Atom' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Syndication/Atom.php',
|
'PicoFeed\\Serialization\\SubscriptionListBuilder' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Serialization/SubscriptionListBuilder.php',
|
||||||
'PicoFeed\\Syndication\\Rss20' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Syndication/Rss20.php',
|
'PicoFeed\\Serialization\\SubscriptionListParser' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Serialization/SubscriptionListParser.php',
|
||||||
'PicoFeed\\Syndication\\Writer' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Syndication/Writer.php',
|
'PicoFeed\\Serialization\\SubscriptionParser' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Serialization/SubscriptionParser.php',
|
||||||
|
'PicoFeed\\Syndication\\AtomFeedBuilder' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Syndication/AtomFeedBuilder.php',
|
||||||
|
'PicoFeed\\Syndication\\AtomHelper' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Syndication/AtomHelper.php',
|
||||||
|
'PicoFeed\\Syndication\\AtomItemBuilder' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Syndication/AtomItemBuilder.php',
|
||||||
|
'PicoFeed\\Syndication\\FeedBuilder' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Syndication/FeedBuilder.php',
|
||||||
|
'PicoFeed\\Syndication\\ItemBuilder' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Syndication/ItemBuilder.php',
|
||||||
|
'PicoFeed\\Syndication\\Rss20FeedBuilder' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Syndication/Rss20FeedBuilder.php',
|
||||||
|
'PicoFeed\\Syndication\\Rss20Helper' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Syndication/Rss20Helper.php',
|
||||||
|
'PicoFeed\\Syndication\\Rss20ItemBuilder' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Syndication/Rss20ItemBuilder.php',
|
||||||
'SimpleValidator\\Validator' => $vendorDir . '/fguillot/simple-validator/src/SimpleValidator/Validator.php',
|
'SimpleValidator\\Validator' => $vendorDir . '/fguillot/simple-validator/src/SimpleValidator/Validator.php',
|
||||||
'SimpleValidator\\Validators\\Alpha' => $vendorDir . '/fguillot/simple-validator/src/SimpleValidator/Validators/Alpha.php',
|
'SimpleValidator\\Validators\\Alpha' => $vendorDir . '/fguillot/simple-validator/src/SimpleValidator/Validators/Alpha.php',
|
||||||
'SimpleValidator\\Validators\\AlphaNumeric' => $vendorDir . '/fguillot/simple-validator/src/SimpleValidator/Validators/AlphaNumeric.php',
|
'SimpleValidator\\Validators\\AlphaNumeric' => $vendorDir . '/fguillot/simple-validator/src/SimpleValidator/Validators/AlphaNumeric.php',
|
||||||
|
10
vendor/composer/autoload_real.php
vendored
10
vendor/composer/autoload_real.php
vendored
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
// autoload_real.php @generated by Composer
|
// autoload_real.php @generated by Composer
|
||||||
|
|
||||||
class ComposerAutoloaderInit00bf4499632e34ac01e60c409b852c25
|
class ComposerAutoloaderInitfd7e8d436e1dc450edc3153ac8bc31b4
|
||||||
{
|
{
|
||||||
private static $loader;
|
private static $loader;
|
||||||
|
|
||||||
@ -19,9 +19,9 @@ class ComposerAutoloaderInit00bf4499632e34ac01e60c409b852c25
|
|||||||
return self::$loader;
|
return self::$loader;
|
||||||
}
|
}
|
||||||
|
|
||||||
spl_autoload_register(array('ComposerAutoloaderInit00bf4499632e34ac01e60c409b852c25', 'loadClassLoader'), true, true);
|
spl_autoload_register(array('ComposerAutoloaderInitfd7e8d436e1dc450edc3153ac8bc31b4', 'loadClassLoader'), true, true);
|
||||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
||||||
spl_autoload_unregister(array('ComposerAutoloaderInit00bf4499632e34ac01e60c409b852c25', 'loadClassLoader'));
|
spl_autoload_unregister(array('ComposerAutoloaderInitfd7e8d436e1dc450edc3153ac8bc31b4', 'loadClassLoader'));
|
||||||
|
|
||||||
$map = require __DIR__ . '/autoload_namespaces.php';
|
$map = require __DIR__ . '/autoload_namespaces.php';
|
||||||
foreach ($map as $namespace => $path) {
|
foreach ($map as $namespace => $path) {
|
||||||
@ -42,14 +42,14 @@ class ComposerAutoloaderInit00bf4499632e34ac01e60c409b852c25
|
|||||||
|
|
||||||
$includeFiles = require __DIR__ . '/autoload_files.php';
|
$includeFiles = require __DIR__ . '/autoload_files.php';
|
||||||
foreach ($includeFiles as $file) {
|
foreach ($includeFiles as $file) {
|
||||||
composerRequire00bf4499632e34ac01e60c409b852c25($file);
|
composerRequirefd7e8d436e1dc450edc3153ac8bc31b4($file);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $loader;
|
return $loader;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function composerRequire00bf4499632e34ac01e60c409b852c25($file)
|
function composerRequirefd7e8d436e1dc450edc3153ac8bc31b4($file)
|
||||||
{
|
{
|
||||||
require $file;
|
require $file;
|
||||||
}
|
}
|
||||||
|
12
vendor/composer/installed.json
vendored
12
vendor/composer/installed.json
vendored
@ -163,17 +163,17 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "fguillot/picofeed",
|
"name": "fguillot/picofeed",
|
||||||
"version": "v0.1.21",
|
"version": "v0.1.23",
|
||||||
"version_normalized": "0.1.21.0",
|
"version_normalized": "0.1.23.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/fguillot/picoFeed.git",
|
"url": "https://github.com/fguillot/picoFeed.git",
|
||||||
"reference": "2baff3240ef187c9f443656ab26b0b626aec5776"
|
"reference": "a7c3d420c239fe9ffc39b0d06b6e57db39ce3797"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/fguillot/picoFeed/zipball/2baff3240ef187c9f443656ab26b0b626aec5776",
|
"url": "https://api.github.com/repos/fguillot/picoFeed/zipball/a7c3d420c239fe9ffc39b0d06b6e57db39ce3797",
|
||||||
"reference": "2baff3240ef187c9f443656ab26b0b626aec5776",
|
"reference": "a7c3d420c239fe9ffc39b0d06b6e57db39ce3797",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -188,7 +188,7 @@
|
|||||||
"suggest": {
|
"suggest": {
|
||||||
"ext-curl": "PicoFeed will use cURL if present"
|
"ext-curl": "PicoFeed will use cURL if present"
|
||||||
},
|
},
|
||||||
"time": "2016-03-31 00:39:41",
|
"time": "2016-04-17 22:31:55",
|
||||||
"bin": [
|
"bin": [
|
||||||
"picofeed"
|
"picofeed"
|
||||||
],
|
],
|
||||||
|
@ -354,15 +354,15 @@ class Curl extends Client
|
|||||||
{
|
{
|
||||||
switch ($errno) {
|
switch ($errno) {
|
||||||
case 78: // CURLE_REMOTE_FILE_NOT_FOUND
|
case 78: // CURLE_REMOTE_FILE_NOT_FOUND
|
||||||
throw new InvalidUrlException('Resource not found');
|
throw new InvalidUrlException('Resource not found', $errno);
|
||||||
case 6: // CURLE_COULDNT_RESOLVE_HOST
|
case 6: // CURLE_COULDNT_RESOLVE_HOST
|
||||||
throw new InvalidUrlException('Unable to resolve hostname');
|
throw new InvalidUrlException('Unable to resolve hostname', $errno);
|
||||||
case 7: // CURLE_COULDNT_CONNECT
|
case 7: // CURLE_COULDNT_CONNECT
|
||||||
throw new InvalidUrlException('Unable to connect to the remote host');
|
throw new InvalidUrlException('Unable to connect to the remote host', $errno);
|
||||||
case 23: // CURLE_WRITE_ERROR
|
case 23: // CURLE_WRITE_ERROR
|
||||||
throw new MaxSizeException('Maximum response size exceeded');
|
throw new MaxSizeException('Maximum response size exceeded', $errno);
|
||||||
case 28: // CURLE_OPERATION_TIMEDOUT
|
case 28: // CURLE_OPERATION_TIMEDOUT
|
||||||
throw new TimeoutException('Operation timeout');
|
throw new TimeoutException('Operation timeout', $errno);
|
||||||
case 35: // CURLE_SSL_CONNECT_ERROR
|
case 35: // CURLE_SSL_CONNECT_ERROR
|
||||||
case 51: // CURLE_PEER_FAILED_VERIFICATION
|
case 51: // CURLE_PEER_FAILED_VERIFICATION
|
||||||
case 58: // CURLE_SSL_CERTPROBLEM
|
case 58: // CURLE_SSL_CERTPROBLEM
|
||||||
@ -372,13 +372,15 @@ class Curl extends Client
|
|||||||
case 66: // CURLE_SSL_ENGINE_INITFAILED
|
case 66: // CURLE_SSL_ENGINE_INITFAILED
|
||||||
case 77: // CURLE_SSL_CACERT_BADFILE
|
case 77: // CURLE_SSL_CACERT_BADFILE
|
||||||
case 83: // CURLE_SSL_ISSUER_ERROR
|
case 83: // CURLE_SSL_ISSUER_ERROR
|
||||||
throw new InvalidCertificateException('Invalid SSL certificate');
|
$msg = 'Invalid SSL certificate caused by CURL error number ' .
|
||||||
|
$errno;
|
||||||
|
throw new InvalidCertificateException($msg, $errno);
|
||||||
case 47: // CURLE_TOO_MANY_REDIRECTS
|
case 47: // CURLE_TOO_MANY_REDIRECTS
|
||||||
throw new MaxRedirectException('Maximum number of redirections reached');
|
throw new MaxRedirectException('Maximum number of redirections reached', $errno);
|
||||||
case 63: // CURLE_FILESIZE_EXCEEDED
|
case 63: // CURLE_FILESIZE_EXCEEDED
|
||||||
throw new MaxSizeException('Maximum response size exceeded');
|
throw new MaxSizeException('Maximum response size exceeded', $errno);
|
||||||
default:
|
default:
|
||||||
throw new InvalidUrlException('Unable to fetch the URL');
|
throw new InvalidUrlException('Unable to fetch the URL', $errno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ class Atom extends Parser
|
|||||||
*/
|
*/
|
||||||
public function findFeedUrl(SimpleXMLElement $xml, Feed $feed)
|
public function findFeedUrl(SimpleXMLElement $xml, Feed $feed)
|
||||||
{
|
{
|
||||||
$feed->feed_url = $this->getUrl($xml, 'self');
|
$feed->setFeedUrl($this->getUrl($xml, 'self'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -52,7 +52,7 @@ class Atom extends Parser
|
|||||||
*/
|
*/
|
||||||
public function findSiteUrl(SimpleXMLElement $xml, Feed $feed)
|
public function findSiteUrl(SimpleXMLElement $xml, Feed $feed)
|
||||||
{
|
{
|
||||||
$feed->site_url = $this->getUrl($xml, 'alternate', true);
|
$feed->setSiteUrl($this->getUrl($xml, 'alternate', true));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -66,7 +66,7 @@ class Atom extends Parser
|
|||||||
$description = XmlParser::getXPathResult($xml, 'atom:subtitle', $this->namespaces)
|
$description = XmlParser::getXPathResult($xml, 'atom:subtitle', $this->namespaces)
|
||||||
?: XmlParser::getXPathResult($xml, 'subtitle');
|
?: XmlParser::getXPathResult($xml, 'subtitle');
|
||||||
|
|
||||||
$feed->description = (string) current($description);
|
$feed->setDescription(XmlParser::getValue($description));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -80,7 +80,7 @@ class Atom extends Parser
|
|||||||
$logo = XmlParser::getXPathResult($xml, 'atom:logo', $this->namespaces)
|
$logo = XmlParser::getXPathResult($xml, 'atom:logo', $this->namespaces)
|
||||||
?: XmlParser::getXPathResult($xml, 'logo');
|
?: XmlParser::getXPathResult($xml, 'logo');
|
||||||
|
|
||||||
$feed->logo = (string) current($logo);
|
$feed->setLogo(XmlParser::getValue($logo));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -94,7 +94,7 @@ class Atom extends Parser
|
|||||||
$icon = XmlParser::getXPathResult($xml, 'atom:icon', $this->namespaces)
|
$icon = XmlParser::getXPathResult($xml, 'atom:icon', $this->namespaces)
|
||||||
?: XmlParser::getXPathResult($xml, 'icon');
|
?: XmlParser::getXPathResult($xml, 'icon');
|
||||||
|
|
||||||
$feed->icon = (string) current($icon);
|
$feed->setIcon(XmlParser::getValue($icon));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -108,7 +108,7 @@ class Atom extends Parser
|
|||||||
$title = XmlParser::getXPathResult($xml, 'atom:title', $this->namespaces)
|
$title = XmlParser::getXPathResult($xml, 'atom:title', $this->namespaces)
|
||||||
?: XmlParser::getXPathResult($xml, 'title');
|
?: XmlParser::getXPathResult($xml, 'title');
|
||||||
|
|
||||||
$feed->title = Filter::stripWhiteSpace((string) current($title)) ?: $feed->getSiteUrl();
|
$feed->setTitle(Filter::stripWhiteSpace(XmlParser::getValue($title)) ?: $feed->getSiteUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -122,7 +122,7 @@ class Atom extends Parser
|
|||||||
$language = XmlParser::getXPathResult($xml, '*[not(self::atom:entry)]/@xml:lang', $this->namespaces)
|
$language = XmlParser::getXPathResult($xml, '*[not(self::atom:entry)]/@xml:lang', $this->namespaces)
|
||||||
?: XmlParser::getXPathResult($xml, '@xml:lang');
|
?: XmlParser::getXPathResult($xml, '@xml:lang');
|
||||||
|
|
||||||
$feed->language = (string) current($language);
|
$feed->setLanguage(XmlParser::getValue($language));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -136,7 +136,7 @@ class Atom extends Parser
|
|||||||
$id = XmlParser::getXPathResult($xml, 'atom:id', $this->namespaces)
|
$id = XmlParser::getXPathResult($xml, 'atom:id', $this->namespaces)
|
||||||
?: XmlParser::getXPathResult($xml, 'id');
|
?: XmlParser::getXPathResult($xml, 'id');
|
||||||
|
|
||||||
$feed->id = (string) current($id);
|
$feed->setId(XmlParser::getValue($id));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -150,7 +150,7 @@ class Atom extends Parser
|
|||||||
$updated = XmlParser::getXPathResult($xml, 'atom:updated', $this->namespaces)
|
$updated = XmlParser::getXPathResult($xml, 'atom:updated', $this->namespaces)
|
||||||
?: XmlParser::getXPathResult($xml, 'updated');
|
?: XmlParser::getXPathResult($xml, 'updated');
|
||||||
|
|
||||||
$feed->date = $this->getDateParser()->getDateTime((string) current($updated));
|
$feed->setDate($this->getDateParser()->getDateTime(XmlParser::getValue($updated)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -172,11 +172,11 @@ class Atom extends Parser
|
|||||||
$updated = !empty($updated) ? $this->getDateParser()->getDateTime((string) current($updated)) : null;
|
$updated = !empty($updated) ? $this->getDateParser()->getDateTime((string) current($updated)) : null;
|
||||||
|
|
||||||
if ($published === null && $updated === null) {
|
if ($published === null && $updated === null) {
|
||||||
$item->date = $feed->getDate(); // We use the feed date if there is no date for the item
|
$item->setDate($feed->getDate()); // We use the feed date if there is no date for the item
|
||||||
} elseif ($published !== null && $updated !== null) {
|
} elseif ($published !== null && $updated !== null) {
|
||||||
$item->date = max($published, $updated); // We use the most recent date between published and updated
|
$item->setDate(max($published, $updated)); // We use the most recent date between published and updated
|
||||||
} else {
|
} else {
|
||||||
$item->date = $updated ?: $published;
|
$item->setDate($updated ?: $published);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,7 +191,7 @@ class Atom extends Parser
|
|||||||
$title = XmlParser::getXPathResult($entry, 'atom:title', $this->namespaces)
|
$title = XmlParser::getXPathResult($entry, 'atom:title', $this->namespaces)
|
||||||
?: XmlParser::getXPathResult($entry, 'title');
|
?: XmlParser::getXPathResult($entry, 'title');
|
||||||
|
|
||||||
$item->title = Filter::stripWhiteSpace((string) current($title)) ?: $item->url;
|
$item->setTitle(Filter::stripWhiteSpace(XmlParser::getValue($title)) ?: $item->getUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -208,7 +208,7 @@ class Atom extends Parser
|
|||||||
?: XmlParser::getXPathResult($xml, 'atom:author/atom:name', $this->namespaces)
|
?: XmlParser::getXPathResult($xml, 'atom:author/atom:name', $this->namespaces)
|
||||||
?: XmlParser::getXPathResult($xml, 'author/name');
|
?: XmlParser::getXPathResult($xml, 'author/name');
|
||||||
|
|
||||||
$item->author = (string) current($author);
|
$item->setAuthor(XmlParser::getValue($author));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -219,7 +219,7 @@ class Atom extends Parser
|
|||||||
*/
|
*/
|
||||||
public function findItemContent(SimpleXMLElement $entry, Item $item)
|
public function findItemContent(SimpleXMLElement $entry, Item $item)
|
||||||
{
|
{
|
||||||
$item->content = $this->getContent($entry);
|
$item->setContent($this->getContent($entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -230,7 +230,7 @@ class Atom extends Parser
|
|||||||
*/
|
*/
|
||||||
public function findItemUrl(SimpleXMLElement $entry, Item $item)
|
public function findItemUrl(SimpleXMLElement $entry, Item $item)
|
||||||
{
|
{
|
||||||
$item->url = $this->getUrl($entry, 'alternate', true);
|
$item->setUrl($this->getUrl($entry, 'alternate', true));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -246,11 +246,11 @@ class Atom extends Parser
|
|||||||
?: XmlParser::getXPathResult($entry, 'id');
|
?: XmlParser::getXPathResult($entry, 'id');
|
||||||
|
|
||||||
if (!empty($id)) {
|
if (!empty($id)) {
|
||||||
$item->id = $this->generateId((string) current($id));
|
$item->setId($this->generateId(XmlParser::getValue($id)));
|
||||||
} else {
|
} else {
|
||||||
$item->id = $this->generateId(
|
$item->setId($this->generateId(
|
||||||
$item->getTitle(), $item->getUrl(), $item->getContent()
|
$item->getTitle(), $item->getUrl(), $item->getContent()
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,8 +266,8 @@ class Atom extends Parser
|
|||||||
$enclosure = $this->findLink($entry, 'enclosure');
|
$enclosure = $this->findLink($entry, 'enclosure');
|
||||||
|
|
||||||
if ($enclosure) {
|
if ($enclosure) {
|
||||||
$item->enclosure_url = Url::resolve((string) $enclosure['href'], $feed->getSiteUrl());
|
$item->setEnclosureUrl(Url::resolve((string) $enclosure['href'], $feed->getSiteUrl()));
|
||||||
$item->enclosure_type = (string) $enclosure['type'];
|
$item->setEnclosureType((string) $enclosure['type']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,8 +281,7 @@ class Atom extends Parser
|
|||||||
public function findItemLanguage(SimpleXMLElement $entry, Item $item, Feed $feed)
|
public function findItemLanguage(SimpleXMLElement $entry, Item $item, Feed $feed)
|
||||||
{
|
{
|
||||||
$language = XmlParser::getXPathResult($entry, './/@xml:lang');
|
$language = XmlParser::getXPathResult($entry, './/@xml:lang');
|
||||||
|
$item->setLanguage(XmlParser::getValue($language) ?: $feed->getLanguage());
|
||||||
$item->language = (string) current($language) ?: $feed->language;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -303,7 +302,6 @@ class Atom extends Parser
|
|||||||
|
|
||||||
if ($fallback) {
|
if ($fallback) {
|
||||||
$link = $this->findLink($xml, '');
|
$link = $this->findLink($xml, '');
|
||||||
|
|
||||||
return $link ? (string) $link['href'] : '';
|
return $link ? (string) $link['href'] : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,7 +327,7 @@ class Atom extends Parser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,14 +42,14 @@ class Feed
|
|||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
public $feed_url = '';
|
public $feedUrl = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Site url.
|
* Site url.
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
public $site_url = '';
|
public $siteUrl = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Feed date.
|
* Feed date.
|
||||||
@ -86,7 +86,7 @@ class Feed
|
|||||||
{
|
{
|
||||||
$output = '';
|
$output = '';
|
||||||
|
|
||||||
foreach (array('id', 'title', 'feed_url', 'site_url', 'language', 'description', 'logo') as $property) {
|
foreach (array('id', 'title', 'feedUrl', 'siteUrl', 'language', 'description', 'logo') as $property) {
|
||||||
$output .= 'Feed::'.$property.' = '.$this->$property.PHP_EOL;
|
$output .= 'Feed::'.$property.' = '.$this->$property.PHP_EOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ class Feed
|
|||||||
*/
|
*/
|
||||||
public function getFeedUrl()
|
public function getFeedUrl()
|
||||||
{
|
{
|
||||||
return $this->feed_url;
|
return $this->feedUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -147,7 +147,7 @@ class Feed
|
|||||||
*/
|
*/
|
||||||
public function getSiteUrl()
|
public function getSiteUrl()
|
||||||
{
|
{
|
||||||
return $this->site_url;
|
return $this->siteUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -191,4 +191,124 @@ class Feed
|
|||||||
{
|
{
|
||||||
return Parser::isLanguageRTL($this->language);
|
return Parser::isLanguageRTL($this->language);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set feed items.
|
||||||
|
*
|
||||||
|
* @param Item[] $items
|
||||||
|
* @return Feed
|
||||||
|
*/
|
||||||
|
public function setItems(array $items)
|
||||||
|
{
|
||||||
|
$this->items = $items;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set feed id.
|
||||||
|
*
|
||||||
|
* @param string $id
|
||||||
|
* @return Feed
|
||||||
|
*/
|
||||||
|
public function setId($id)
|
||||||
|
{
|
||||||
|
$this->id = $id;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set feed title.
|
||||||
|
*
|
||||||
|
* @param string $title
|
||||||
|
* @return Feed
|
||||||
|
*/
|
||||||
|
public function setTitle($title)
|
||||||
|
{
|
||||||
|
$this->title = $title;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set feed description.
|
||||||
|
*
|
||||||
|
* @param string $description
|
||||||
|
* @return Feed
|
||||||
|
*/
|
||||||
|
public function setDescription($description)
|
||||||
|
{
|
||||||
|
$this->description = $description;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set feed url.
|
||||||
|
*
|
||||||
|
* @param string $feedUrl
|
||||||
|
* @return Feed
|
||||||
|
*/
|
||||||
|
public function setFeedUrl($feedUrl)
|
||||||
|
{
|
||||||
|
$this->feedUrl = $feedUrl;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set feed website url.
|
||||||
|
*
|
||||||
|
* @param string $siteUrl
|
||||||
|
* @return Feed
|
||||||
|
*/
|
||||||
|
public function setSiteUrl($siteUrl)
|
||||||
|
{
|
||||||
|
$this->siteUrl = $siteUrl;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set feed date.
|
||||||
|
*
|
||||||
|
* @param \DateTime $date
|
||||||
|
* @return Feed
|
||||||
|
*/
|
||||||
|
public function setDate($date)
|
||||||
|
{
|
||||||
|
$this->date = $date;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set feed language.
|
||||||
|
*
|
||||||
|
* @param string $language
|
||||||
|
* @return Feed
|
||||||
|
*/
|
||||||
|
public function setLanguage($language)
|
||||||
|
{
|
||||||
|
$this->language = $language;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set feed logo.
|
||||||
|
*
|
||||||
|
* @param string $logo
|
||||||
|
* @return Feed
|
||||||
|
*/
|
||||||
|
public function setLogo($logo)
|
||||||
|
{
|
||||||
|
$this->logo = $logo;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set feed icon.
|
||||||
|
*
|
||||||
|
* @param string $icon
|
||||||
|
* @return Feed
|
||||||
|
*/
|
||||||
|
public function setIcon($icon)
|
||||||
|
{
|
||||||
|
$this->icon = $icon;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ class Item
|
|||||||
/**
|
/**
|
||||||
* List of known RTL languages.
|
* List of known RTL languages.
|
||||||
*
|
*
|
||||||
* @var public
|
* @var string[]
|
||||||
*/
|
*/
|
||||||
public $rtl = array(
|
public $rtl = array(
|
||||||
'ar', // Arabic (ar-**)
|
'ar', // Arabic (ar-**)
|
||||||
@ -72,14 +72,14 @@ class Item
|
|||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
public $enclosure_url = '';
|
public $enclosureUrl = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Item enclusure type.
|
* Item enclusure type.
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
public $enclosure_type = '';
|
public $enclosureType = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Item language.
|
* Item language.
|
||||||
@ -140,12 +140,14 @@ class Item
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Return item information.
|
* Return item information.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function __toString()
|
public function __toString()
|
||||||
{
|
{
|
||||||
$output = '';
|
$output = '';
|
||||||
|
|
||||||
foreach (array('id', 'title', 'url', 'language', 'author', 'enclosure_url', 'enclosure_type') as $property) {
|
foreach (array('id', 'title', 'url', 'language', 'author', 'enclosureUrl', 'enclosureType') as $property) {
|
||||||
$output .= 'Item::'.$property.' = '.$this->$property.PHP_EOL;
|
$output .= 'Item::'.$property.' = '.$this->$property.PHP_EOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,6 +160,8 @@ class Item
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get title.
|
* Get title.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getTitle()
|
public function getTitle()
|
||||||
{
|
{
|
||||||
@ -190,6 +194,8 @@ class Item
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get id.
|
* Get id.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getId()
|
public function getId()
|
||||||
{
|
{
|
||||||
@ -198,6 +204,8 @@ class Item
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get date.
|
* Get date.
|
||||||
|
*
|
||||||
|
* @return \DateTime
|
||||||
*/
|
*/
|
||||||
public function getDate()
|
public function getDate()
|
||||||
{
|
{
|
||||||
@ -206,6 +214,8 @@ class Item
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get content.
|
* Get content.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getContent()
|
public function getContent()
|
||||||
{
|
{
|
||||||
@ -227,22 +237,28 @@ class Item
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get enclosure url.
|
* Get enclosure url.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getEnclosureUrl()
|
public function getEnclosureUrl()
|
||||||
{
|
{
|
||||||
return $this->enclosure_url;
|
return $this->enclosureUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get enclosure type.
|
* Get enclosure type.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getEnclosureType()
|
public function getEnclosureType()
|
||||||
{
|
{
|
||||||
return $this->enclosure_type;
|
return $this->enclosureType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get language.
|
* Get language.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getLanguage()
|
public function getLanguage()
|
||||||
{
|
{
|
||||||
@ -251,6 +267,8 @@ class Item
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get author.
|
* Get author.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getAuthor()
|
public function getAuthor()
|
||||||
{
|
{
|
||||||
@ -266,4 +284,132 @@ class Item
|
|||||||
{
|
{
|
||||||
return Parser::isLanguageRTL($this->language);
|
return Parser::isLanguageRTL($this->language);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set item id.
|
||||||
|
*
|
||||||
|
* @param string $id
|
||||||
|
* @return Item
|
||||||
|
*/
|
||||||
|
public function setId($id)
|
||||||
|
{
|
||||||
|
$this->id = $id;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set item title.
|
||||||
|
*
|
||||||
|
* @param string $title
|
||||||
|
* @return Item
|
||||||
|
*/
|
||||||
|
public function setTitle($title)
|
||||||
|
{
|
||||||
|
$this->title = $title;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set author.
|
||||||
|
*
|
||||||
|
* @param string $author
|
||||||
|
* @return Item
|
||||||
|
*/
|
||||||
|
public function setAuthor($author)
|
||||||
|
{
|
||||||
|
$this->author = $author;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set item date.
|
||||||
|
*
|
||||||
|
* @param \DateTime $date
|
||||||
|
* @return Item
|
||||||
|
*/
|
||||||
|
public function setDate($date)
|
||||||
|
{
|
||||||
|
$this->date = $date;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set enclosure url.
|
||||||
|
*
|
||||||
|
* @param string $enclosureUrl
|
||||||
|
* @return Item
|
||||||
|
*/
|
||||||
|
public function setEnclosureUrl($enclosureUrl)
|
||||||
|
{
|
||||||
|
$this->enclosureUrl = $enclosureUrl;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set enclosure type.
|
||||||
|
*
|
||||||
|
* @param string $enclosureType
|
||||||
|
* @return Item
|
||||||
|
*/
|
||||||
|
public function setEnclosureType($enclosureType)
|
||||||
|
{
|
||||||
|
$this->enclosureType = $enclosureType;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set item language.
|
||||||
|
*
|
||||||
|
* @param string $language
|
||||||
|
* @return Item
|
||||||
|
*/
|
||||||
|
public function setLanguage($language)
|
||||||
|
{
|
||||||
|
$this->language = $language;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set raw XML.
|
||||||
|
*
|
||||||
|
* @param \SimpleXMLElement $xml
|
||||||
|
* @return Item
|
||||||
|
*/
|
||||||
|
public function setXml($xml)
|
||||||
|
{
|
||||||
|
$this->xml = $xml;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get raw XML.
|
||||||
|
*
|
||||||
|
* @return \SimpleXMLElement
|
||||||
|
*/
|
||||||
|
public function getXml()
|
||||||
|
{
|
||||||
|
return $this->xml;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set XML namespaces.
|
||||||
|
*
|
||||||
|
* @param array $namespaces
|
||||||
|
* @return Item
|
||||||
|
*/
|
||||||
|
public function setNamespaces($namespaces)
|
||||||
|
{
|
||||||
|
$this->namespaces = $namespaces;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get XML namespaces.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getNamespaces()
|
||||||
|
{
|
||||||
|
return $this->namespaces;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -180,9 +180,9 @@ abstract class Parser
|
|||||||
public function checkFeedUrl(Feed $feed)
|
public function checkFeedUrl(Feed $feed)
|
||||||
{
|
{
|
||||||
if ($feed->getFeedUrl() === '') {
|
if ($feed->getFeedUrl() === '') {
|
||||||
$feed->feed_url = $this->fallback_url;
|
$feed->feedUrl = $this->fallback_url;
|
||||||
} else {
|
} else {
|
||||||
$feed->feed_url = Url::resolve($feed->getFeedUrl(), $this->fallback_url);
|
$feed->feedUrl = Url::resolve($feed->getFeedUrl(), $this->fallback_url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,9 +194,9 @@ abstract class Parser
|
|||||||
public function checkSiteUrl(Feed $feed)
|
public function checkSiteUrl(Feed $feed)
|
||||||
{
|
{
|
||||||
if ($feed->getSiteUrl() === '') {
|
if ($feed->getSiteUrl() === '') {
|
||||||
$feed->site_url = Url::base($feed->getFeedUrl());
|
$feed->siteUrl = Url::base($feed->getFeedUrl());
|
||||||
} else {
|
} else {
|
||||||
$feed->site_url = Url::resolve($feed->getSiteUrl(), $this->fallback_url);
|
$feed->siteUrl = Url::resolve($feed->getSiteUrl(), $this->fallback_url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,8 @@ class Rss10 extends Parser
|
|||||||
public function getItemsTree(SimpleXMLElement $xml)
|
public function getItemsTree(SimpleXMLElement $xml)
|
||||||
{
|
{
|
||||||
return XmlParser::getXPathResult($xml, 'rss:item', $this->namespaces)
|
return XmlParser::getXPathResult($xml, 'rss:item', $this->namespaces)
|
||||||
?: XmlParser::getXPathResult($xml, 'item');
|
?: XmlParser::getXPathResult($xml, 'item')
|
||||||
|
?: $xml->item;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -43,7 +44,7 @@ class Rss10 extends Parser
|
|||||||
*/
|
*/
|
||||||
public function findFeedUrl(SimpleXMLElement $xml, Feed $feed)
|
public function findFeedUrl(SimpleXMLElement $xml, Feed $feed)
|
||||||
{
|
{
|
||||||
$feed->feed_url = '';
|
$feed->setFeedUrl('');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,10 +55,11 @@ class Rss10 extends Parser
|
|||||||
*/
|
*/
|
||||||
public function findSiteUrl(SimpleXMLElement $xml, Feed $feed)
|
public function findSiteUrl(SimpleXMLElement $xml, Feed $feed)
|
||||||
{
|
{
|
||||||
$site_url = XmlParser::getXPathResult($xml, 'rss:channel/rss:link', $this->namespaces)
|
$value = XmlParser::getXPathResult($xml, 'rss:channel/rss:link', $this->namespaces)
|
||||||
?: XmlParser::getXPathResult($xml, 'channel/link');
|
?: XmlParser::getXPathResult($xml, 'channel/link')
|
||||||
|
?: $xml->channel->link;
|
||||||
|
|
||||||
$feed->site_url = (string) current($site_url);
|
$feed->setSiteUrl(XmlParser::getValue($value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -69,9 +71,10 @@ class Rss10 extends Parser
|
|||||||
public function findFeedDescription(SimpleXMLElement $xml, Feed $feed)
|
public function findFeedDescription(SimpleXMLElement $xml, Feed $feed)
|
||||||
{
|
{
|
||||||
$description = XmlParser::getXPathResult($xml, 'rss:channel/rss:description', $this->namespaces)
|
$description = XmlParser::getXPathResult($xml, 'rss:channel/rss:description', $this->namespaces)
|
||||||
?: XmlParser::getXPathResult($xml, 'channel/description');
|
?: XmlParser::getXPathResult($xml, 'channel/description')
|
||||||
|
?: $xml->channel->description;
|
||||||
|
|
||||||
$feed->description = (string) current($description);
|
$feed->setDescription(XmlParser::getValue($description));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -83,9 +86,9 @@ class Rss10 extends Parser
|
|||||||
public function findFeedLogo(SimpleXMLElement $xml, Feed $feed)
|
public function findFeedLogo(SimpleXMLElement $xml, Feed $feed)
|
||||||
{
|
{
|
||||||
$logo = XmlParser::getXPathResult($xml, 'rss:image/rss:url', $this->namespaces)
|
$logo = XmlParser::getXPathResult($xml, 'rss:image/rss:url', $this->namespaces)
|
||||||
?: XmlParser::getXPathResult($xml, 'image/url');
|
?: XmlParser::getXPathResult($xml, 'image/url');
|
||||||
|
|
||||||
$feed->logo = (string) current($logo);
|
$feed->setLogo(XmlParser::getValue($logo));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -96,7 +99,7 @@ class Rss10 extends Parser
|
|||||||
*/
|
*/
|
||||||
public function findFeedIcon(SimpleXMLElement $xml, Feed $feed)
|
public function findFeedIcon(SimpleXMLElement $xml, Feed $feed)
|
||||||
{
|
{
|
||||||
$feed->icon = '';
|
$feed->setIcon('');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -108,9 +111,10 @@ class Rss10 extends Parser
|
|||||||
public function findFeedTitle(SimpleXMLElement $xml, Feed $feed)
|
public function findFeedTitle(SimpleXMLElement $xml, Feed $feed)
|
||||||
{
|
{
|
||||||
$title = XmlParser::getXPathResult($xml, 'rss:channel/rss:title', $this->namespaces)
|
$title = XmlParser::getXPathResult($xml, 'rss:channel/rss:title', $this->namespaces)
|
||||||
?: XmlParser::getXPathResult($xml, 'channel/title');
|
?: XmlParser::getXPathResult($xml, 'channel/title')
|
||||||
|
?: $xml->channel->title;
|
||||||
|
|
||||||
$feed->title = Filter::stripWhiteSpace((string) current($title)) ?: $feed->getSiteUrl();
|
$feed->setTitle(Filter::stripWhiteSpace(XmlParser::getValue($title)) ?: $feed->getSiteUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -124,7 +128,7 @@ class Rss10 extends Parser
|
|||||||
$language = XmlParser::getXPathResult($xml, 'rss:channel/dc:language', $this->namespaces)
|
$language = XmlParser::getXPathResult($xml, 'rss:channel/dc:language', $this->namespaces)
|
||||||
?: XmlParser::getXPathResult($xml, 'channel/dc:language', $this->namespaces);
|
?: XmlParser::getXPathResult($xml, 'channel/dc:language', $this->namespaces);
|
||||||
|
|
||||||
$feed->language = (string) current($language);
|
$feed->setLanguage(XmlParser::getValue($language));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -135,7 +139,7 @@ class Rss10 extends Parser
|
|||||||
*/
|
*/
|
||||||
public function findFeedId(SimpleXMLElement $xml, Feed $feed)
|
public function findFeedId(SimpleXMLElement $xml, Feed $feed)
|
||||||
{
|
{
|
||||||
$feed->id = $feed->getFeedUrl() ?: $feed->getSiteUrl();
|
$feed->setId($feed->getFeedUrl() ?: $feed->getSiteUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -149,7 +153,7 @@ class Rss10 extends Parser
|
|||||||
$date = XmlParser::getXPathResult($xml, 'rss:channel/dc:date', $this->namespaces)
|
$date = XmlParser::getXPathResult($xml, 'rss:channel/dc:date', $this->namespaces)
|
||||||
?: XmlParser::getXPathResult($xml, 'channel/dc:date', $this->namespaces);
|
?: XmlParser::getXPathResult($xml, 'channel/dc:date', $this->namespaces);
|
||||||
|
|
||||||
$feed->date = $this->getDateParser()->getDateTime((string) current($date));
|
$feed->setDate($this->getDateParser()->getDateTime(XmlParser::getValue($date)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -163,7 +167,7 @@ class Rss10 extends Parser
|
|||||||
{
|
{
|
||||||
$date = XmlParser::getXPathResult($entry, 'dc:date', $this->namespaces);
|
$date = XmlParser::getXPathResult($entry, 'dc:date', $this->namespaces);
|
||||||
|
|
||||||
$item->date = empty($date) ? $feed->getDate() : $this->getDateParser()->getDateTime((string) current($date));
|
$item->setDate(empty($date) ? $feed->getDate() : $this->getDateParser()->getDateTime(XmlParser::getValue($date)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -175,9 +179,10 @@ class Rss10 extends Parser
|
|||||||
public function findItemTitle(SimpleXMLElement $entry, Item $item)
|
public function findItemTitle(SimpleXMLElement $entry, Item $item)
|
||||||
{
|
{
|
||||||
$title = XmlParser::getXPathResult($entry, 'rss:title', $this->namespaces)
|
$title = XmlParser::getXPathResult($entry, 'rss:title', $this->namespaces)
|
||||||
?: XmlParser::getXPathResult($entry, 'title');
|
?: XmlParser::getXPathResult($entry, 'title')
|
||||||
|
?: $entry->title;
|
||||||
|
|
||||||
$item->title = Filter::stripWhiteSpace((string) current($title)) ?: $item->url;
|
$item->setTitle(Filter::stripWhiteSpace(XmlParser::getValue($title)) ?: $item->getUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -193,7 +198,7 @@ class Rss10 extends Parser
|
|||||||
?: XmlParser::getXPathResult($xml, 'rss:channel/dc:creator', $this->namespaces)
|
?: XmlParser::getXPathResult($xml, 'rss:channel/dc:creator', $this->namespaces)
|
||||||
?: XmlParser::getXPathResult($xml, 'channel/dc:creator', $this->namespaces);
|
?: XmlParser::getXPathResult($xml, 'channel/dc:creator', $this->namespaces);
|
||||||
|
|
||||||
$item->author = (string) current($author);
|
$item->setAuthor(XmlParser::getValue($author));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -206,12 +211,13 @@ class Rss10 extends Parser
|
|||||||
{
|
{
|
||||||
$content = XmlParser::getXPathResult($entry, 'content:encoded', $this->namespaces);
|
$content = XmlParser::getXPathResult($entry, 'content:encoded', $this->namespaces);
|
||||||
|
|
||||||
if (trim((string) current($content)) === '') {
|
if (XmlParser::getValue($content) === '') {
|
||||||
$content = XmlParser::getXPathResult($entry, 'rss:description', $this->namespaces)
|
$content = XmlParser::getXPathResult($entry, 'rss:description', $this->namespaces)
|
||||||
?: XmlParser::getXPathResult($entry, 'description');
|
?: XmlParser::getXPathResult($entry, 'description')
|
||||||
|
?: $entry->description;
|
||||||
}
|
}
|
||||||
|
|
||||||
$item->content = (string) current($content);
|
$item->setContent(XmlParser::getValue($content));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -223,10 +229,11 @@ class Rss10 extends Parser
|
|||||||
public function findItemUrl(SimpleXMLElement $entry, Item $item)
|
public function findItemUrl(SimpleXMLElement $entry, Item $item)
|
||||||
{
|
{
|
||||||
$link = XmlParser::getXPathResult($entry, 'feedburner:origLink', $this->namespaces)
|
$link = XmlParser::getXPathResult($entry, 'feedburner:origLink', $this->namespaces)
|
||||||
?: XmlParser::getXPathResult($entry, 'rss:link', $this->namespaces)
|
?: XmlParser::getXPathResult($entry, 'rss:link', $this->namespaces)
|
||||||
?: XmlParser::getXPathResult($entry, 'link');
|
?: XmlParser::getXPathResult($entry, 'link')
|
||||||
|
?: $entry->link;
|
||||||
|
|
||||||
$item->url = trim((string) current($link));
|
$item->setUrl(XmlParser::getValue($link));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -238,9 +245,9 @@ class Rss10 extends Parser
|
|||||||
*/
|
*/
|
||||||
public function findItemId(SimpleXMLElement $entry, Item $item, Feed $feed)
|
public function findItemId(SimpleXMLElement $entry, Item $item, Feed $feed)
|
||||||
{
|
{
|
||||||
$item->id = $this->generateId(
|
$item->setId($this->generateId(
|
||||||
$item->getTitle(), $item->getUrl(), $item->getContent()
|
$item->getTitle(), $item->getUrl(), $item->getContent()
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -265,6 +272,6 @@ class Rss10 extends Parser
|
|||||||
{
|
{
|
||||||
$language = XmlParser::getXPathResult($entry, 'dc:language', $this->namespaces);
|
$language = XmlParser::getXPathResult($entry, 'dc:language', $this->namespaces);
|
||||||
|
|
||||||
$item->language = (string) current($language) ?: $feed->language;
|
$item->setLanguage(XmlParser::getValue($language) ?: $feed->getLanguage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ class Rss20 extends Parser
|
|||||||
*/
|
*/
|
||||||
public function findFeedUrl(SimpleXMLElement $xml, Feed $feed)
|
public function findFeedUrl(SimpleXMLElement $xml, Feed $feed)
|
||||||
{
|
{
|
||||||
$feed->feed_url = '';
|
$feed->setFeedUrl('');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,8 +54,8 @@ class Rss20 extends Parser
|
|||||||
*/
|
*/
|
||||||
public function findSiteUrl(SimpleXMLElement $xml, Feed $feed)
|
public function findSiteUrl(SimpleXMLElement $xml, Feed $feed)
|
||||||
{
|
{
|
||||||
$site_url = XmlParser::getXPathResult($xml, 'channel/link');
|
$value = XmlParser::getXPathResult($xml, 'channel/link');
|
||||||
$feed->site_url = (string) current($site_url);
|
$feed->setSiteUrl(XmlParser::getValue($value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -66,8 +66,8 @@ class Rss20 extends Parser
|
|||||||
*/
|
*/
|
||||||
public function findFeedDescription(SimpleXMLElement $xml, Feed $feed)
|
public function findFeedDescription(SimpleXMLElement $xml, Feed $feed)
|
||||||
{
|
{
|
||||||
$description = XmlParser::getXPathResult($xml, 'channel/description');
|
$value = XmlParser::getXPathResult($xml, 'channel/description');
|
||||||
$feed->description = (string) current($description);
|
$feed->setDescription(XmlParser::getValue($value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -78,8 +78,8 @@ class Rss20 extends Parser
|
|||||||
*/
|
*/
|
||||||
public function findFeedLogo(SimpleXMLElement $xml, Feed $feed)
|
public function findFeedLogo(SimpleXMLElement $xml, Feed $feed)
|
||||||
{
|
{
|
||||||
$logo = XmlParser::getXPathResult($xml, 'channel/image/url');
|
$value = XmlParser::getXPathResult($xml, 'channel/image/url');
|
||||||
$feed->logo = (string) current($logo);
|
$feed->setLogo(XmlParser::getValue($value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -90,7 +90,7 @@ class Rss20 extends Parser
|
|||||||
*/
|
*/
|
||||||
public function findFeedIcon(SimpleXMLElement $xml, Feed $feed)
|
public function findFeedIcon(SimpleXMLElement $xml, Feed $feed)
|
||||||
{
|
{
|
||||||
$feed->icon = '';
|
$feed->setIcon('');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -102,7 +102,7 @@ class Rss20 extends Parser
|
|||||||
public function findFeedTitle(SimpleXMLElement $xml, Feed $feed)
|
public function findFeedTitle(SimpleXMLElement $xml, Feed $feed)
|
||||||
{
|
{
|
||||||
$title = XmlParser::getXPathResult($xml, 'channel/title');
|
$title = XmlParser::getXPathResult($xml, 'channel/title');
|
||||||
$feed->title = Filter::stripWhiteSpace((string) current($title)) ?: $feed->getSiteUrl();
|
$feed->setTitle(Filter::stripWhiteSpace(XmlParser::getValue($title)) ?: $feed->getSiteUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -113,8 +113,8 @@ class Rss20 extends Parser
|
|||||||
*/
|
*/
|
||||||
public function findFeedLanguage(SimpleXMLElement $xml, Feed $feed)
|
public function findFeedLanguage(SimpleXMLElement $xml, Feed $feed)
|
||||||
{
|
{
|
||||||
$language = XmlParser::getXPathResult($xml, 'channel/language');
|
$value = XmlParser::getXPathResult($xml, 'channel/language');
|
||||||
$feed->language = (string) current($language);
|
$feed->setLanguage(XmlParser::getValue($value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -125,7 +125,7 @@ class Rss20 extends Parser
|
|||||||
*/
|
*/
|
||||||
public function findFeedId(SimpleXMLElement $xml, Feed $feed)
|
public function findFeedId(SimpleXMLElement $xml, Feed $feed)
|
||||||
{
|
{
|
||||||
$feed->id = $feed->getFeedUrl() ?: $feed->getSiteUrl();
|
$feed->setId($feed->getFeedUrl() ?: $feed->getSiteUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -139,15 +139,15 @@ class Rss20 extends Parser
|
|||||||
$publish_date = XmlParser::getXPathResult($xml, 'channel/pubDate');
|
$publish_date = XmlParser::getXPathResult($xml, 'channel/pubDate');
|
||||||
$update_date = XmlParser::getXPathResult($xml, 'channel/lastBuildDate');
|
$update_date = XmlParser::getXPathResult($xml, 'channel/lastBuildDate');
|
||||||
|
|
||||||
$published = !empty($publish_date) ? $this->getDateParser()->getDateTime((string) current($publish_date)) : null;
|
$published = !empty($publish_date) ? $this->getDateParser()->getDateTime(XmlParser::getValue($publish_date)) : null;
|
||||||
$updated = !empty($update_date) ? $this->getDateParser()->getDateTime((string) current($update_date)) : null;
|
$updated = !empty($update_date) ? $this->getDateParser()->getDateTime(XmlParser::getValue($update_date)) : null;
|
||||||
|
|
||||||
if ($published === null && $updated === null) {
|
if ($published === null && $updated === null) {
|
||||||
$feed->date = $this->getDateParser()->getCurrentDateTime(); // We use the current date if there is no date for the feed
|
$feed->setDate($this->getDateParser()->getCurrentDateTime()); // We use the current date if there is no date for the feed
|
||||||
} elseif ($published !== null && $updated !== null) {
|
} elseif ($published !== null && $updated !== null) {
|
||||||
$feed->date = max($published, $updated); // We use the most recent date between published and updated
|
$feed->setDate(max($published, $updated)); // We use the most recent date between published and updated
|
||||||
} else {
|
} else {
|
||||||
$feed->date = $updated ?: $published;
|
$feed->setDate($updated ?: $published);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,7 +162,7 @@ class Rss20 extends Parser
|
|||||||
{
|
{
|
||||||
$date = XmlParser::getXPathResult($entry, 'pubDate');
|
$date = XmlParser::getXPathResult($entry, 'pubDate');
|
||||||
|
|
||||||
$item->date = empty($date) ? $feed->getDate() : $this->getDateParser()->getDateTime((string) current($date));
|
$item->setDate(empty($date) ? $feed->getDate() : $this->getDateParser()->getDateTime(XmlParser::getValue($date)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -173,8 +173,8 @@ class Rss20 extends Parser
|
|||||||
*/
|
*/
|
||||||
public function findItemTitle(SimpleXMLElement $entry, Item $item)
|
public function findItemTitle(SimpleXMLElement $entry, Item $item)
|
||||||
{
|
{
|
||||||
$title = XmlParser::getXPathResult($entry, 'title');
|
$value = XmlParser::getXPathResult($entry, 'title');
|
||||||
$item->title = Filter::stripWhiteSpace((string) current($title)) ?: $item->url;
|
$item->setTitle(Filter::stripWhiteSpace(XmlParser::getValue($value)) ?: $item->getUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -186,12 +186,12 @@ class Rss20 extends Parser
|
|||||||
*/
|
*/
|
||||||
public function findItemAuthor(SimpleXMLElement $xml, SimpleXMLElement $entry, Item $item)
|
public function findItemAuthor(SimpleXMLElement $xml, SimpleXMLElement $entry, Item $item)
|
||||||
{
|
{
|
||||||
$author = XmlParser::getXPathResult($entry, 'dc:creator', $this->namespaces)
|
$value = XmlParser::getXPathResult($entry, 'dc:creator', $this->namespaces)
|
||||||
?: XmlParser::getXPathResult($entry, 'author')
|
?: XmlParser::getXPathResult($entry, 'author')
|
||||||
?: XmlParser::getXPathResult($xml, 'channel/dc:creator', $this->namespaces)
|
?: XmlParser::getXPathResult($xml, 'channel/dc:creator', $this->namespaces)
|
||||||
?: XmlParser::getXPathResult($xml, 'channel/managingEditor');
|
?: XmlParser::getXPathResult($xml, 'channel/managingEditor');
|
||||||
|
|
||||||
$item->author = (string) current($author);
|
$item->setAuthor(XmlParser::getValue($value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -204,11 +204,11 @@ class Rss20 extends Parser
|
|||||||
{
|
{
|
||||||
$content = XmlParser::getXPathResult($entry, 'content:encoded', $this->namespaces);
|
$content = XmlParser::getXPathResult($entry, 'content:encoded', $this->namespaces);
|
||||||
|
|
||||||
if (trim((string) current($content)) === '') {
|
if (XmlParser::getValue($content) === '') {
|
||||||
$content = XmlParser::getXPathResult($entry, 'description');
|
$content = XmlParser::getXPathResult($entry, 'description');
|
||||||
}
|
}
|
||||||
|
|
||||||
$item->content = (string) current($content);
|
$item->setContent(XmlParser::getValue($content));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -224,13 +224,13 @@ class Rss20 extends Parser
|
|||||||
?: XmlParser::getXPathResult($entry, 'atom:link/@href', $this->namespaces);
|
?: XmlParser::getXPathResult($entry, 'atom:link/@href', $this->namespaces);
|
||||||
|
|
||||||
if (!empty($link)) {
|
if (!empty($link)) {
|
||||||
$item->url = trim((string) current($link));
|
$item->setUrl(XmlParser::getValue($link));
|
||||||
} else {
|
} else {
|
||||||
$link = XmlParser::getXPathResult($entry, 'guid');
|
$link = XmlParser::getXPathResult($entry, 'guid');
|
||||||
$link = trim((string) current($link));
|
$link = XmlParser::getValue($link);
|
||||||
|
|
||||||
if (filter_var($link, FILTER_VALIDATE_URL) !== false) {
|
if (filter_var($link, FILTER_VALIDATE_URL) !== false) {
|
||||||
$item->url = $link;
|
$item->setUrl($link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -244,14 +244,14 @@ class Rss20 extends Parser
|
|||||||
*/
|
*/
|
||||||
public function findItemId(SimpleXMLElement $entry, Item $item, Feed $feed)
|
public function findItemId(SimpleXMLElement $entry, Item $item, Feed $feed)
|
||||||
{
|
{
|
||||||
$id = (string) current(XmlParser::getXPathResult($entry, 'guid'));
|
$id = XmlParser::getValue(XmlParser::getXPathResult($entry, 'guid'));
|
||||||
|
|
||||||
if ($id) {
|
if ($id) {
|
||||||
$item->id = $this->generateId($id);
|
$item->setId($this->generateId($id));
|
||||||
} else {
|
} else {
|
||||||
$item->id = $this->generateId(
|
$item->setId($this->generateId(
|
||||||
$item->getTitle(), $item->getUrl(), $item->getContent()
|
$item->getTitle(), $item->getUrl(), $item->getContent()
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,13 +265,12 @@ class Rss20 extends Parser
|
|||||||
public function findItemEnclosure(SimpleXMLElement $entry, Item $item, Feed $feed)
|
public function findItemEnclosure(SimpleXMLElement $entry, Item $item, Feed $feed)
|
||||||
{
|
{
|
||||||
if (isset($entry->enclosure)) {
|
if (isset($entry->enclosure)) {
|
||||||
$enclosure_url = XmlParser::getXPathResult($entry, 'feedburner:origEnclosureLink', $this->namespaces)
|
$type = XmlParser::getXPathResult($entry, 'enclosure/@type');
|
||||||
?: XmlParser::getXPathResult($entry, 'enclosure/@url');
|
$url = XmlParser::getXPathResult($entry, 'feedburner:origEnclosureLink', $this->namespaces)
|
||||||
|
?: XmlParser::getXPathResult($entry, 'enclosure/@url');
|
||||||
|
|
||||||
$enclosure_type = XmlParser::getXPathResult($entry, 'enclosure/@type');
|
$item->setEnclosureUrl(Url::resolve(XmlParser::getValue($url), $feed->getSiteUrl()));
|
||||||
|
$item->setEnclosureType(XmlParser::getValue($type));
|
||||||
$item->enclosure_url = Url::resolve((string) current($enclosure_url), $feed->getSiteUrl());
|
|
||||||
$item->enclosure_type = (string) current($enclosure_type);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,7 +284,6 @@ class Rss20 extends Parser
|
|||||||
public function findItemLanguage(SimpleXMLElement $entry, Item $item, Feed $feed)
|
public function findItemLanguage(SimpleXMLElement $entry, Item $item, Feed $feed)
|
||||||
{
|
{
|
||||||
$language = XmlParser::getXPathResult($entry, 'dc:language', $this->namespaces);
|
$language = XmlParser::getXPathResult($entry, 'dc:language', $this->namespaces);
|
||||||
|
$item->setLanguage(XmlParser::getValue($language) ?: $feed->getLanguage());
|
||||||
$item->language = (string) current($language) ?: $feed->language;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ namespace PicoFeed\Parser;
|
|||||||
|
|
||||||
use DomDocument;
|
use DomDocument;
|
||||||
use SimpleXmlElement;
|
use SimpleXmlElement;
|
||||||
use Exception;
|
|
||||||
|
|
||||||
use ZendXml\Security;
|
use ZendXml\Security;
|
||||||
|
|
||||||
@ -21,9 +20,7 @@ class XmlParser
|
|||||||
* Get a SimpleXmlElement instance or return false.
|
* Get a SimpleXmlElement instance or return false.
|
||||||
*
|
*
|
||||||
* @static
|
* @static
|
||||||
*
|
|
||||||
* @param string $input XML content
|
* @param string $input XML content
|
||||||
*
|
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public static function getSimpleXml($input)
|
public static function getSimpleXml($input)
|
||||||
@ -35,9 +32,7 @@ class XmlParser
|
|||||||
* Get a DomDocument instance or return false.
|
* Get a DomDocument instance or return false.
|
||||||
*
|
*
|
||||||
* @static
|
* @static
|
||||||
*
|
|
||||||
* @param string $input XML content
|
* @param string $input XML content
|
||||||
*
|
|
||||||
* @return \DOMDocument
|
* @return \DOMDocument
|
||||||
*/
|
*/
|
||||||
public static function getDomDocument($input)
|
public static function getDomDocument($input)
|
||||||
@ -59,6 +54,7 @@ class XmlParser
|
|||||||
/**
|
/**
|
||||||
* Small wrapper around ZendXml to turn their exceptions into picoFeed
|
* Small wrapper around ZendXml to turn their exceptions into picoFeed
|
||||||
* exceptions
|
* exceptions
|
||||||
|
*
|
||||||
* @param $input the xml to load
|
* @param $input the xml to load
|
||||||
* @param $dom pass in a dom document or use null/omit if simpleXml should
|
* @param $dom pass in a dom document or use null/omit if simpleXml should
|
||||||
* be used
|
* be used
|
||||||
@ -76,9 +72,7 @@ class XmlParser
|
|||||||
* Load HTML document by using a DomDocument instance or return false on failure.
|
* Load HTML document by using a DomDocument instance or return false on failure.
|
||||||
*
|
*
|
||||||
* @static
|
* @static
|
||||||
*
|
|
||||||
* @param string $input XML content
|
* @param string $input XML content
|
||||||
*
|
|
||||||
* @return \DOMDocument
|
* @return \DOMDocument
|
||||||
*/
|
*/
|
||||||
public static function getHtmlDocument($input)
|
public static function getHtmlDocument($input)
|
||||||
@ -112,7 +106,6 @@ class XmlParser
|
|||||||
public static function htmlToXml($html)
|
public static function htmlToXml($html)
|
||||||
{
|
{
|
||||||
$dom = self::getHtmlDocument('<?xml version="1.0" encoding="UTF-8">'.$html);
|
$dom = self::getHtmlDocument('<?xml version="1.0" encoding="UTF-8">'.$html);
|
||||||
|
|
||||||
return $dom->saveXML($dom->getElementsByTagName('body')->item(0));
|
return $dom->saveXML($dom->getElementsByTagName('body')->item(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +113,6 @@ class XmlParser
|
|||||||
* Get XML parser errors.
|
* Get XML parser errors.
|
||||||
*
|
*
|
||||||
* @static
|
* @static
|
||||||
*
|
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function getErrors()
|
public static function getErrors()
|
||||||
@ -143,9 +135,7 @@ class XmlParser
|
|||||||
* Get the encoding from a xml tag.
|
* Get the encoding from a xml tag.
|
||||||
*
|
*
|
||||||
* @static
|
* @static
|
||||||
*
|
|
||||||
* @param string $data Input data
|
* @param string $data Input data
|
||||||
*
|
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function getEncodingFromXmlTag($data)
|
public static function getEncodingFromXmlTag($data)
|
||||||
@ -172,9 +162,7 @@ class XmlParser
|
|||||||
* Get the charset from a meta tag.
|
* Get the charset from a meta tag.
|
||||||
*
|
*
|
||||||
* @static
|
* @static
|
||||||
*
|
|
||||||
* @param string $data Input data
|
* @param string $data Input data
|
||||||
*
|
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function getEncodingFromMetaTag($data)
|
public static function getEncodingFromMetaTag($data)
|
||||||
@ -193,7 +181,6 @@ class XmlParser
|
|||||||
*
|
*
|
||||||
* @param string $query XPath query
|
* @param string $query XPath query
|
||||||
* @param array $ns Prefix to namespace URI mapping
|
* @param array $ns Prefix to namespace URI mapping
|
||||||
*
|
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function replaceXPathPrefixWithNamespaceURI($query, array $ns)
|
public static function replaceXPathPrefixWithNamespaceURI($query, array $ns)
|
||||||
@ -215,8 +202,7 @@ class XmlParser
|
|||||||
* @param \SimpleXMLElement $xml XML element
|
* @param \SimpleXMLElement $xml XML element
|
||||||
* @param string $query XPath query
|
* @param string $query XPath query
|
||||||
* @param array $ns Prefix to namespace URI mapping
|
* @param array $ns Prefix to namespace URI mapping
|
||||||
*
|
* @return \SimpleXMLElement[]
|
||||||
* @return \SimpleXMLElement
|
|
||||||
*/
|
*/
|
||||||
public static function getXPathResult(SimpleXMLElement $xml, $query, array $ns = array())
|
public static function getXPathResult(SimpleXMLElement $xml, $query, array $ns = array())
|
||||||
{
|
{
|
||||||
@ -226,4 +212,25 @@ class XmlParser
|
|||||||
|
|
||||||
return $xml->xpath($query);
|
return $xml->xpath($query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the first Xpath result or SimpleXMLElement value
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @access public
|
||||||
|
* @param mixed $value
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function getValue($value)
|
||||||
|
{
|
||||||
|
$result = '';
|
||||||
|
|
||||||
|
if (is_array($value) && count($value) > 0) {
|
||||||
|
$result = (string) $value[0];
|
||||||
|
} elseif (is_a($value, 'SimpleXMLElement')) {
|
||||||
|
return $result = (string) $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return trim($result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
return array(
|
return array(
|
||||||
'grabber' => array(
|
'grabber' => array(
|
||||||
'%.*%' => array(
|
'%.*%' => array(
|
||||||
'test_url' => 'http://www.sciencemag.org/news/2016/01/could-bright-foamy-wak$
|
'test_url' => 'http://www.sciencemag.org/news/2016/01/could-bright-foamy-wak$',
|
||||||
'body' => array(
|
'body' => array(
|
||||||
'//div[@class="row--hero"]',
|
'//div[@class="row--hero"]',
|
||||||
'//article[contains(@class,"primary")]',
|
'//article[contains(@class,"primary")]',
|
||||||
|
@ -1,122 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace PicoFeed\Serialization;
|
|
||||||
|
|
||||||
use SimpleXMLElement;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* OPML export class.
|
|
||||||
*
|
|
||||||
* @author Frederic Guillot
|
|
||||||
*/
|
|
||||||
class Export
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* List of feeds to exports.
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $content = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List of required properties for each feed.
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $required_fields = array(
|
|
||||||
'title',
|
|
||||||
'site_url',
|
|
||||||
'feed_url',
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param array $content List of feeds
|
|
||||||
*/
|
|
||||||
public function __construct(array $content)
|
|
||||||
{
|
|
||||||
$this->content = $content;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the OPML document.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function execute()
|
|
||||||
{
|
|
||||||
$xml = new SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?><opml/>');
|
|
||||||
|
|
||||||
$head = $xml->addChild('head');
|
|
||||||
$head->addChild('title', 'OPML Export');
|
|
||||||
|
|
||||||
$body = $xml->addChild('body');
|
|
||||||
|
|
||||||
foreach ($this->content as $category => $values) {
|
|
||||||
if (is_string($category)) {
|
|
||||||
$this->createCategory($body, $category, $values);
|
|
||||||
} else {
|
|
||||||
$this->createEntry($body, $values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $xml->asXML();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a feed entry.
|
|
||||||
*
|
|
||||||
* @param SimpleXMLElement $parent Parent Element
|
|
||||||
* @param array $feed Feed properties
|
|
||||||
*/
|
|
||||||
public function createEntry(SimpleXMLElement $parent, array $feed)
|
|
||||||
{
|
|
||||||
$valid = true;
|
|
||||||
|
|
||||||
foreach ($this->required_fields as $field) {
|
|
||||||
if (!isset($feed[$field])) {
|
|
||||||
$valid = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($valid) {
|
|
||||||
$outline = $parent->addChild('outline');
|
|
||||||
$outline->addAttribute('xmlUrl', $feed['feed_url']);
|
|
||||||
$outline->addAttribute('htmlUrl', $feed['site_url']);
|
|
||||||
$outline->addAttribute('title', $feed['title']);
|
|
||||||
$outline->addAttribute('text', $feed['title']);
|
|
||||||
$outline->addAttribute('description', isset($feed['description']) ? $feed['description'] : $feed['title']);
|
|
||||||
$outline->addAttribute('type', 'rss');
|
|
||||||
$outline->addAttribute('version', 'RSS');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create entries for a feed list.
|
|
||||||
*
|
|
||||||
* @param SimpleXMLElement $parent Parent Element
|
|
||||||
* @param array $feeds Feed list
|
|
||||||
*/
|
|
||||||
public function createEntries(SimpleXMLElement $parent, array $feeds)
|
|
||||||
{
|
|
||||||
foreach ($feeds as $feed) {
|
|
||||||
$this->createEntry($parent, $feed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a category entry.
|
|
||||||
*
|
|
||||||
* @param SimpleXMLElement $parent Parent Element
|
|
||||||
* @param string $category Category
|
|
||||||
* @param array $feeds Feed properties
|
|
||||||
*/
|
|
||||||
public function createCategory(SimpleXMLElement $parent, $category, array $feeds)
|
|
||||||
{
|
|
||||||
$outline = $parent->addChild('outline');
|
|
||||||
$outline->addAttribute('text', $category);
|
|
||||||
$this->createEntries($outline, $feeds);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,162 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace PicoFeed\Serialization;
|
|
||||||
|
|
||||||
use SimpleXmlElement;
|
|
||||||
use StdClass;
|
|
||||||
use PicoFeed\Logging\Logger;
|
|
||||||
use PicoFeed\Parser\XmlParser;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* OPML Import.
|
|
||||||
*
|
|
||||||
* @author Frederic Guillot
|
|
||||||
*/
|
|
||||||
class Import
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* OPML file content.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private $content = '';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Subscriptions.
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $items = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param string $content OPML file content
|
|
||||||
*/
|
|
||||||
public function __construct($content)
|
|
||||||
{
|
|
||||||
$this->content = $content;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse the OPML file.
|
|
||||||
*
|
|
||||||
* @return array|false
|
|
||||||
*/
|
|
||||||
public function execute()
|
|
||||||
{
|
|
||||||
Logger::setMessage(get_called_class().': start importation');
|
|
||||||
|
|
||||||
$xml = XmlParser::getSimpleXml(trim($this->content));
|
|
||||||
|
|
||||||
if ($xml === false || $xml->getName() !== 'opml' || !isset($xml->body)) {
|
|
||||||
Logger::setMessage(get_called_class().': OPML tag not found or malformed XML document');
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->parseEntries($xml->body);
|
|
||||||
Logger::setMessage(get_called_class().': '.count($this->items).' subscriptions found');
|
|
||||||
|
|
||||||
return $this->items;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse each entries of the subscription list.
|
|
||||||
*
|
|
||||||
* @param SimpleXMLElement $tree XML node
|
|
||||||
*/
|
|
||||||
public function parseEntries(SimpleXMLElement $tree)
|
|
||||||
{
|
|
||||||
if (isset($tree->outline)) {
|
|
||||||
foreach ($tree->outline as $item) {
|
|
||||||
if (isset($item->outline)) {
|
|
||||||
$this->parseEntries($item);
|
|
||||||
} elseif ((isset($item['text']) || isset($item['title'])) && isset($item['xmlUrl'])) {
|
|
||||||
$entry = new StdClass();
|
|
||||||
$entry->category = $this->findCategory($tree);
|
|
||||||
$entry->title = $this->findTitle($item);
|
|
||||||
$entry->feed_url = $this->findFeedUrl($item);
|
|
||||||
$entry->site_url = $this->findSiteUrl($item, $entry);
|
|
||||||
$entry->type = $this->findType($item);
|
|
||||||
$entry->description = $this->findDescription($item, $entry);
|
|
||||||
$this->items[] = $entry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find category.
|
|
||||||
*
|
|
||||||
* @param SimpleXmlElement $tree XML tree
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function findCategory(SimpleXmlElement $tree)
|
|
||||||
{
|
|
||||||
return isset($tree['title']) ? (string) $tree['title'] : (string) $tree['text'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find title.
|
|
||||||
*
|
|
||||||
* @param SimpleXmlElement $item XML tree
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function findTitle(SimpleXmlElement $item)
|
|
||||||
{
|
|
||||||
return isset($item['title']) ? (string) $item['title'] : (string) $item['text'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find feed url.
|
|
||||||
*
|
|
||||||
* @param SimpleXmlElement $item XML tree
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function findFeedUrl(SimpleXmlElement $item)
|
|
||||||
{
|
|
||||||
return (string) $item['xmlUrl'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find site url.
|
|
||||||
*
|
|
||||||
* @param SimpleXmlElement $item XML tree
|
|
||||||
* @param StdClass $entry Feed entry
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function findSiteUrl(SimpleXmlElement $item, StdClass $entry)
|
|
||||||
{
|
|
||||||
return isset($item['htmlUrl']) ? (string) $item['htmlUrl'] : $entry->feed_url;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find type.
|
|
||||||
*
|
|
||||||
* @param SimpleXmlElement $item XML tree
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function findType(SimpleXmlElement $item)
|
|
||||||
{
|
|
||||||
return isset($item['version']) ? (string) $item['version'] : isset($item['type']) ? (string) $item['type'] : 'rss';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find description.
|
|
||||||
*
|
|
||||||
* @param SimpleXmlElement $item XML tree
|
|
||||||
* @param StdClass $entry Feed entry
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function findDescription(SimpleXmlElement $item, StdClass $entry)
|
|
||||||
{
|
|
||||||
return isset($item['description']) ? (string) $item['description'] : $entry->title;
|
|
||||||
}
|
|
||||||
}
|
|
175
vendor/fguillot/picofeed/lib/PicoFeed/Serialization/Subscription.php
vendored
Normal file
175
vendor/fguillot/picofeed/lib/PicoFeed/Serialization/Subscription.php
vendored
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PicoFeed\Serialization;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Subscription
|
||||||
|
*
|
||||||
|
* @package PicoFeed\Serialization
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class Subscription
|
||||||
|
{
|
||||||
|
protected $title = '';
|
||||||
|
protected $feedUrl = '';
|
||||||
|
protected $siteUrl = '';
|
||||||
|
protected $category = '';
|
||||||
|
protected $description = '';
|
||||||
|
protected $type = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create object instance
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @access public
|
||||||
|
* @return Subscription
|
||||||
|
*/
|
||||||
|
public static function create()
|
||||||
|
{
|
||||||
|
return new static();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set title
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $title
|
||||||
|
* @return Subscription
|
||||||
|
*/
|
||||||
|
public function setTitle($title)
|
||||||
|
{
|
||||||
|
$this->title = $title;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get title
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getTitle()
|
||||||
|
{
|
||||||
|
return $this->title;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set feed URL
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $feedUrl
|
||||||
|
* @return Subscription
|
||||||
|
*/
|
||||||
|
public function setFeedUrl($feedUrl)
|
||||||
|
{
|
||||||
|
$this->feedUrl = $feedUrl;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get feed URL
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getFeedUrl()
|
||||||
|
{
|
||||||
|
return $this->feedUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set site URL
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $siteUrl
|
||||||
|
* @return Subscription
|
||||||
|
*/
|
||||||
|
public function setSiteUrl($siteUrl)
|
||||||
|
{
|
||||||
|
$this->siteUrl = $siteUrl;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get site URL
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getSiteUrl()
|
||||||
|
{
|
||||||
|
return $this->siteUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set category
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $category
|
||||||
|
* @return Subscription
|
||||||
|
*/
|
||||||
|
public function setCategory($category)
|
||||||
|
{
|
||||||
|
$this->category = $category;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get category
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getCategory()
|
||||||
|
{
|
||||||
|
return $this->category;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set description
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $description
|
||||||
|
* @return Subscription
|
||||||
|
*/
|
||||||
|
public function setDescription($description)
|
||||||
|
{
|
||||||
|
$this->description = $description;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get description
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getDescription()
|
||||||
|
{
|
||||||
|
return $this->description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set type
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $type
|
||||||
|
* @return Subscription
|
||||||
|
*/
|
||||||
|
public function setType($type)
|
||||||
|
{
|
||||||
|
$this->type = $type;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get type
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getType()
|
||||||
|
{
|
||||||
|
return $this->type;
|
||||||
|
}
|
||||||
|
}
|
75
vendor/fguillot/picofeed/lib/PicoFeed/Serialization/SubscriptionList.php
vendored
Normal file
75
vendor/fguillot/picofeed/lib/PicoFeed/Serialization/SubscriptionList.php
vendored
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PicoFeed\Serialization;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class SubscriptionList
|
||||||
|
*
|
||||||
|
* @package PicoFeed\Serialization
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class SubscriptionList
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* OPML entries
|
||||||
|
*
|
||||||
|
* @var Subscription[]
|
||||||
|
*/
|
||||||
|
public $subscriptions = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Title
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $title = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create object instance
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @access public
|
||||||
|
* @return SubscriptionList
|
||||||
|
*/
|
||||||
|
public static function create()
|
||||||
|
{
|
||||||
|
return new static();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set title
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $title
|
||||||
|
* @return SubscriptionList
|
||||||
|
*/
|
||||||
|
public function setTitle($title)
|
||||||
|
{
|
||||||
|
$this->title = $title;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get title
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getTitle()
|
||||||
|
{
|
||||||
|
return $this->title;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add subscription
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param Subscription $subscription
|
||||||
|
* @return SubscriptionList
|
||||||
|
*/
|
||||||
|
public function addSubscription(Subscription $subscription)
|
||||||
|
{
|
||||||
|
$this->subscriptions[] = $subscription;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
204
vendor/fguillot/picofeed/lib/PicoFeed/Serialization/SubscriptionListBuilder.php
vendored
Normal file
204
vendor/fguillot/picofeed/lib/PicoFeed/Serialization/SubscriptionListBuilder.php
vendored
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PicoFeed\Serialization;
|
||||||
|
|
||||||
|
use DOMDocument;
|
||||||
|
use DOMElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class SubscriptionListBuilder
|
||||||
|
*
|
||||||
|
* @package PicoFeed\Serialization
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class SubscriptionListBuilder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var SubscriptionList
|
||||||
|
*/
|
||||||
|
protected $subscriptionList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var DOMDocument
|
||||||
|
*/
|
||||||
|
protected $document;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param SubscriptionList $subscriptionList
|
||||||
|
*/
|
||||||
|
public function __construct(SubscriptionList $subscriptionList)
|
||||||
|
{
|
||||||
|
$this->subscriptionList = $subscriptionList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get object instance
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @access public
|
||||||
|
* @param SubscriptionList $subscriptionList
|
||||||
|
* @return SubscriptionListBuilder
|
||||||
|
*/
|
||||||
|
public static function create(SubscriptionList $subscriptionList)
|
||||||
|
{
|
||||||
|
return new static($subscriptionList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build OPML feed
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $filename
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function build($filename = '')
|
||||||
|
{
|
||||||
|
$this->document = new DomDocument('1.0', 'UTF-8');
|
||||||
|
$this->document->formatOutput = true;
|
||||||
|
|
||||||
|
$opmlElement = $this->document->createElement('opml');
|
||||||
|
$opmlElement->setAttribute('version', '1.0');
|
||||||
|
|
||||||
|
$headElement = $this->document->createElement('head');
|
||||||
|
|
||||||
|
if ($this->subscriptionList->getTitle() !== '') {
|
||||||
|
$titleElement = $this->document->createElement('title');
|
||||||
|
$titleElement->appendChild($this->document->createTextNode($this->subscriptionList->getTitle()));
|
||||||
|
$headElement->appendChild($titleElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
$opmlElement->appendChild($headElement);
|
||||||
|
$opmlElement->appendChild($this->buildBody());
|
||||||
|
$this->document->appendChild($opmlElement);
|
||||||
|
|
||||||
|
if ($filename !== '') {
|
||||||
|
$this->document->save($filename);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->document->saveXML();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if the list has categories
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function hasCategories()
|
||||||
|
{
|
||||||
|
foreach ($this->subscriptionList->subscriptions as $subscription) {
|
||||||
|
if ($subscription->getCategory() !== '') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build OPML body
|
||||||
|
*
|
||||||
|
* @access protected
|
||||||
|
* @return DOMElement
|
||||||
|
*/
|
||||||
|
protected function buildBody()
|
||||||
|
{
|
||||||
|
$bodyElement = $this->document->createElement('body');
|
||||||
|
|
||||||
|
if ($this->hasCategories()) {
|
||||||
|
$this->buildCategories($bodyElement);
|
||||||
|
return $bodyElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->subscriptionList->subscriptions as $subscription) {
|
||||||
|
$bodyElement->appendChild($this->buildSubscription($subscription));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $bodyElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build categories section
|
||||||
|
*
|
||||||
|
* @access protected
|
||||||
|
* @param DOMElement $bodyElement
|
||||||
|
*/
|
||||||
|
protected function buildCategories(DOMElement $bodyElement)
|
||||||
|
{
|
||||||
|
$categories = $this->groupByCategories();
|
||||||
|
|
||||||
|
foreach ($categories as $category => $subscriptions) {
|
||||||
|
$bodyElement->appendChild($this->buildCategory($category, $subscriptions));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build category tag
|
||||||
|
*
|
||||||
|
* @access protected
|
||||||
|
* @param string $category
|
||||||
|
* @param array $subscriptions
|
||||||
|
* @return DOMElement
|
||||||
|
*/
|
||||||
|
protected function buildCategory($category, array $subscriptions)
|
||||||
|
{
|
||||||
|
$outlineElement = $this->document->createElement('outline');
|
||||||
|
$outlineElement->setAttribute('text', $category);
|
||||||
|
|
||||||
|
foreach ($subscriptions as $subscription) {
|
||||||
|
$outlineElement->appendChild($this->buildSubscription($subscription));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $outlineElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build subscription entry
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param Subscription $subscription
|
||||||
|
* @return DOMElement
|
||||||
|
*/
|
||||||
|
protected function buildSubscription(Subscription $subscription)
|
||||||
|
{
|
||||||
|
$outlineElement = $this->document->createElement('outline');
|
||||||
|
$outlineElement->setAttribute('type', $subscription->getType() ?: 'rss');
|
||||||
|
$outlineElement->setAttribute('text', $subscription->getTitle() ?: $subscription->getFeedUrl());
|
||||||
|
$outlineElement->setAttribute('xmlUrl', $subscription->getFeedUrl());
|
||||||
|
|
||||||
|
if ($subscription->getTitle() !== '') {
|
||||||
|
$outlineElement->setAttribute('title', $subscription->getTitle());
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($subscription->getDescription() !== '') {
|
||||||
|
$outlineElement->setAttribute('description', $subscription->getDescription());
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($subscription->getSiteUrl() !== '') {
|
||||||
|
$outlineElement->setAttribute('htmlUrl', $subscription->getSiteUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $outlineElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Group subscriptions by category
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function groupByCategories()
|
||||||
|
{
|
||||||
|
$categories = array();
|
||||||
|
|
||||||
|
foreach ($this->subscriptionList->subscriptions as $subscription) {
|
||||||
|
$categories[$subscription->getCategory()][] = $subscription;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $categories;
|
||||||
|
}
|
||||||
|
}
|
100
vendor/fguillot/picofeed/lib/PicoFeed/Serialization/SubscriptionListParser.php
vendored
Normal file
100
vendor/fguillot/picofeed/lib/PicoFeed/Serialization/SubscriptionListParser.php
vendored
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PicoFeed\Serialization;
|
||||||
|
|
||||||
|
use PicoFeed\Parser\MalformedXmlException;
|
||||||
|
use PicoFeed\Parser\XmlParser;
|
||||||
|
use SimpleXMLElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class SubscriptionListParser
|
||||||
|
*
|
||||||
|
* @package PicoFeed\Serialization
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class SubscriptionListParser
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var SubscriptionList
|
||||||
|
*/
|
||||||
|
protected $subscriptionList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $data
|
||||||
|
*/
|
||||||
|
public function __construct($data)
|
||||||
|
{
|
||||||
|
$this->subscriptionList = new SubscriptionList();
|
||||||
|
$this->data = trim($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get object instance
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @access public
|
||||||
|
* @param string $data
|
||||||
|
* @return SubscriptionListParser
|
||||||
|
*/
|
||||||
|
public static function create($data)
|
||||||
|
{
|
||||||
|
return new static($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a subscription list entry
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @throws MalformedXmlException
|
||||||
|
* @return SubscriptionList
|
||||||
|
*/
|
||||||
|
public function parse()
|
||||||
|
{
|
||||||
|
$xml = XmlParser::getSimpleXml($this->data);
|
||||||
|
|
||||||
|
if (! $xml || !isset($xml->head) || !isset($xml->body)) {
|
||||||
|
throw new MalformedXmlException('Unable to parse OPML file: invalid XML');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->parseTitle($xml->head);
|
||||||
|
$this->parseEntries($xml->body);
|
||||||
|
|
||||||
|
return $this->subscriptionList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse title
|
||||||
|
*
|
||||||
|
* @access protected
|
||||||
|
* @param SimpleXMLElement $xml
|
||||||
|
*/
|
||||||
|
protected function parseTitle(SimpleXMLElement $xml)
|
||||||
|
{
|
||||||
|
$this->subscriptionList->setTitle((string) $xml->title);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse entries
|
||||||
|
*
|
||||||
|
* @access protected
|
||||||
|
* @param SimpleXMLElement $body
|
||||||
|
*/
|
||||||
|
private function parseEntries(SimpleXMLElement $body)
|
||||||
|
{
|
||||||
|
foreach ($body->outline as $outlineElement) {
|
||||||
|
if (isset($outlineElement->outline)) {
|
||||||
|
$this->parseEntries($outlineElement);
|
||||||
|
} else {
|
||||||
|
$this->subscriptionList->subscriptions[] = SubscriptionParser::create($body, $outlineElement)->parse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
142
vendor/fguillot/picofeed/lib/PicoFeed/Serialization/SubscriptionParser.php
vendored
Normal file
142
vendor/fguillot/picofeed/lib/PicoFeed/Serialization/SubscriptionParser.php
vendored
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PicoFeed\Serialization;
|
||||||
|
|
||||||
|
use SimpleXMLElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class SubscriptionParser
|
||||||
|
*
|
||||||
|
* @package PicoFeed\Serialization
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class SubscriptionParser
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Subscription
|
||||||
|
*/
|
||||||
|
protected $subscription;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var SimpleXMLElement
|
||||||
|
*/
|
||||||
|
private $outlineElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var SimpleXMLElement
|
||||||
|
*/
|
||||||
|
private $parentElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param SimpleXMLElement $parentElement
|
||||||
|
* @param SimpleXMLElement $outlineElement
|
||||||
|
*/
|
||||||
|
public function __construct(SimpleXMLElement $parentElement, SimpleXMLElement $outlineElement)
|
||||||
|
{
|
||||||
|
$this->parentElement = $parentElement;
|
||||||
|
$this->outlineElement = $outlineElement;
|
||||||
|
$this->subscription = new Subscription();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get object instance
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @access public
|
||||||
|
* @param SimpleXMLElement $parentElement
|
||||||
|
* @param SimpleXMLElement $outlineElement
|
||||||
|
* @return SubscriptionParser
|
||||||
|
*/
|
||||||
|
public static function create(SimpleXMLElement $parentElement, SimpleXMLElement $outlineElement)
|
||||||
|
{
|
||||||
|
return new static($parentElement, $outlineElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse subscription entry
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return Subscription
|
||||||
|
*/
|
||||||
|
public function parse()
|
||||||
|
{
|
||||||
|
$this->subscription->setCategory($this->findCategory());
|
||||||
|
$this->subscription->setTitle($this->findTitle());
|
||||||
|
$this->subscription->setFeedUrl($this->findFeedUrl());
|
||||||
|
$this->subscription->setSiteUrl($this->findSiteUrl());
|
||||||
|
$this->subscription->setType($this->findType());
|
||||||
|
$this->subscription->setDescription($this->findDescription());
|
||||||
|
|
||||||
|
return $this->subscription;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find category.
|
||||||
|
*
|
||||||
|
* @access protected
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function findCategory()
|
||||||
|
{
|
||||||
|
return isset($this->parentElement['text']) ? (string) $this->parentElement['text'] : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find title.
|
||||||
|
*
|
||||||
|
* @access protected
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function findTitle()
|
||||||
|
{
|
||||||
|
return isset($this->outlineElement['title']) ? (string) $this->outlineElement['title'] : (string) $this->outlineElement['text'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find feed url.
|
||||||
|
*
|
||||||
|
* @access protected
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function findFeedUrl()
|
||||||
|
{
|
||||||
|
return (string) $this->outlineElement['xmlUrl'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find site url.
|
||||||
|
*
|
||||||
|
* @access protected
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function findSiteUrl()
|
||||||
|
{
|
||||||
|
return isset($this->outlineElement['htmlUrl']) ? (string) $this->outlineElement['htmlUrl'] : $this->findFeedUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find type.
|
||||||
|
*
|
||||||
|
* @access protected
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function findType()
|
||||||
|
{
|
||||||
|
return isset($this->outlineElement['version']) ? (string) $this->outlineElement['version'] :
|
||||||
|
isset($this->outlineElement['type']) ? (string) $this->outlineElement['type'] : 'rss';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find description.
|
||||||
|
*
|
||||||
|
* @access protected
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function findDescription()
|
||||||
|
{
|
||||||
|
return isset($this->outlineElement['description']) ? (string) $this->outlineElement['description'] : $this->findTitle();
|
||||||
|
}
|
||||||
|
}
|
@ -1,215 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace PicoFeed\Syndication;
|
|
||||||
|
|
||||||
use DomDocument;
|
|
||||||
use DomElement;
|
|
||||||
use DomAttr;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Atom writer class.
|
|
||||||
*
|
|
||||||
* @author Frederic Guillot
|
|
||||||
*/
|
|
||||||
class Atom extends Writer
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* List of required properties for each feed.
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $required_feed_properties = array(
|
|
||||||
'title',
|
|
||||||
'site_url',
|
|
||||||
'feed_url',
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List of required properties for each item.
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $required_item_properties = array(
|
|
||||||
'title',
|
|
||||||
'url',
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the Atom document.
|
|
||||||
*
|
|
||||||
* @param string $filename Optional filename
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function execute($filename = '')
|
|
||||||
{
|
|
||||||
$this->checkRequiredProperties($this->required_feed_properties, $this);
|
|
||||||
|
|
||||||
$this->dom = new DomDocument('1.0', 'UTF-8');
|
|
||||||
$this->dom->formatOutput = true;
|
|
||||||
|
|
||||||
// <feed/>
|
|
||||||
$feed = $this->dom->createElement('feed');
|
|
||||||
$feed->setAttributeNodeNS(new DomAttr('xmlns', 'http://www.w3.org/2005/Atom'));
|
|
||||||
|
|
||||||
// <generator/>
|
|
||||||
$generator = $this->dom->createElement('generator', 'PicoFeed');
|
|
||||||
$generator->setAttribute('uri', 'https://github.com/fguillot/picoFeed');
|
|
||||||
$feed->appendChild($generator);
|
|
||||||
|
|
||||||
// <title/>
|
|
||||||
$title = $this->dom->createElement('title');
|
|
||||||
$title->appendChild($this->dom->createTextNode($this->title));
|
|
||||||
$feed->appendChild($title);
|
|
||||||
|
|
||||||
// <id/>
|
|
||||||
$id = $this->dom->createElement('id');
|
|
||||||
$id->appendChild($this->dom->createTextNode($this->site_url));
|
|
||||||
$feed->appendChild($id);
|
|
||||||
|
|
||||||
// <updated/>
|
|
||||||
$this->addUpdated($feed, $this->updated);
|
|
||||||
|
|
||||||
// <link rel="alternate" type="text/html" href="http://example.org/"/>
|
|
||||||
$this->addLink($feed, $this->site_url);
|
|
||||||
|
|
||||||
// <link rel="self" type="application/atom+xml" href="http://example.org/feed.atom"/>
|
|
||||||
$this->addLink($feed, $this->feed_url, 'self', 'application/atom+xml');
|
|
||||||
|
|
||||||
// <author/>
|
|
||||||
if (isset($this->author)) {
|
|
||||||
$this->addAuthor($feed, $this->author);
|
|
||||||
}
|
|
||||||
|
|
||||||
// <entry/>
|
|
||||||
foreach ($this->items as $item) {
|
|
||||||
$this->checkRequiredProperties($this->required_item_properties, $item);
|
|
||||||
$feed->appendChild($this->createEntry($item));
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->dom->appendChild($feed);
|
|
||||||
|
|
||||||
if ($filename) {
|
|
||||||
$this->dom->save($filename);
|
|
||||||
} else {
|
|
||||||
return $this->dom->saveXML();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create item entry.
|
|
||||||
*
|
|
||||||
* @param arrray $item Item properties
|
|
||||||
*
|
|
||||||
* @return DomElement
|
|
||||||
*/
|
|
||||||
public function createEntry(array $item)
|
|
||||||
{
|
|
||||||
$entry = $this->dom->createElement('entry');
|
|
||||||
|
|
||||||
// <title/>
|
|
||||||
$title = $this->dom->createElement('title');
|
|
||||||
$title->appendChild($this->dom->createTextNode($item['title']));
|
|
||||||
$entry->appendChild($title);
|
|
||||||
|
|
||||||
// <id/>
|
|
||||||
$id = $this->dom->createElement('id');
|
|
||||||
$id->appendChild($this->dom->createTextNode(isset($item['id']) ? $item['id'] : $item['url']));
|
|
||||||
$entry->appendChild($id);
|
|
||||||
|
|
||||||
// <updated/>
|
|
||||||
$this->addUpdated($entry, isset($item['updated']) ? $item['updated'] : '');
|
|
||||||
|
|
||||||
// <published/>
|
|
||||||
if (isset($item['published'])) {
|
|
||||||
$entry->appendChild($this->dom->createElement('published', date(DATE_ATOM, $item['published'])));
|
|
||||||
}
|
|
||||||
|
|
||||||
// <link rel="alternate" type="text/html" href="http://example.org/"/>
|
|
||||||
$this->addLink($entry, $item['url']);
|
|
||||||
|
|
||||||
// <summary/>
|
|
||||||
if (isset($item['summary'])) {
|
|
||||||
$summary = $this->dom->createElement('summary');
|
|
||||||
$summary->appendChild($this->dom->createTextNode($item['summary']));
|
|
||||||
$entry->appendChild($summary);
|
|
||||||
}
|
|
||||||
|
|
||||||
// <content/>
|
|
||||||
if (isset($item['content'])) {
|
|
||||||
$content = $this->dom->createElement('content');
|
|
||||||
$content->setAttribute('type', 'html');
|
|
||||||
$content->appendChild($this->dom->createCDATASection($item['content']));
|
|
||||||
$entry->appendChild($content);
|
|
||||||
}
|
|
||||||
|
|
||||||
// <author/>
|
|
||||||
if (isset($item['author'])) {
|
|
||||||
$this->addAuthor($entry, $item['author']);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add Link.
|
|
||||||
*
|
|
||||||
* @param DomElement $xml XML node
|
|
||||||
* @param string $url URL
|
|
||||||
* @param string $rel Link rel attribute
|
|
||||||
* @param string $type Link type attribute
|
|
||||||
*/
|
|
||||||
public function addLink(DomElement $xml, $url, $rel = 'alternate', $type = 'text/html')
|
|
||||||
{
|
|
||||||
$link = $this->dom->createElement('link');
|
|
||||||
$link->setAttribute('rel', $rel);
|
|
||||||
$link->setAttribute('type', $type);
|
|
||||||
$link->setAttribute('href', $url);
|
|
||||||
$xml->appendChild($link);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add publication date.
|
|
||||||
*
|
|
||||||
* @param DomElement $xml XML node
|
|
||||||
* @param int $value Timestamp
|
|
||||||
*/
|
|
||||||
public function addUpdated(DomElement $xml, $value = 0)
|
|
||||||
{
|
|
||||||
$xml->appendChild($this->dom->createElement(
|
|
||||||
'updated',
|
|
||||||
date(DATE_ATOM, $value ?: time())
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add author.
|
|
||||||
*
|
|
||||||
* @param DomElement $xml XML node
|
|
||||||
* @param array $values Author name and email
|
|
||||||
*/
|
|
||||||
public function addAuthor(DomElement $xml, array $values)
|
|
||||||
{
|
|
||||||
$author = $this->dom->createElement('author');
|
|
||||||
|
|
||||||
if (isset($values['name'])) {
|
|
||||||
$name = $this->dom->createElement('name');
|
|
||||||
$name->appendChild($this->dom->createTextNode($values['name']));
|
|
||||||
$author->appendChild($name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($values['email'])) {
|
|
||||||
$email = $this->dom->createElement('email');
|
|
||||||
$email->appendChild($this->dom->createTextNode($values['email']));
|
|
||||||
$author->appendChild($email);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($values['url'])) {
|
|
||||||
$uri = $this->dom->createElement('uri');
|
|
||||||
$uri->appendChild($this->dom->createTextNode($values['url']));
|
|
||||||
$author->appendChild($uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
$xml->appendChild($author);
|
|
||||||
}
|
|
||||||
}
|
|
65
vendor/fguillot/picofeed/lib/PicoFeed/Syndication/AtomFeedBuilder.php
vendored
Normal file
65
vendor/fguillot/picofeed/lib/PicoFeed/Syndication/AtomFeedBuilder.php
vendored
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PicoFeed\Syndication;
|
||||||
|
|
||||||
|
use DOMAttr;
|
||||||
|
use DOMElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Atom Feed Builder
|
||||||
|
*
|
||||||
|
* @package PicoFeed\Syndication
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class AtomFeedBuilder extends FeedBuilder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var DOMElement
|
||||||
|
*/
|
||||||
|
protected $feedElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var AtomHelper
|
||||||
|
*/
|
||||||
|
protected $helper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build feed
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $filename
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function build($filename = '')
|
||||||
|
{
|
||||||
|
$this->helper = new AtomHelper($this->getDocument());
|
||||||
|
|
||||||
|
$this->feedElement = $this->getDocument()->createElement('feed');
|
||||||
|
$this->feedElement->setAttributeNodeNS(new DomAttr('xmlns', 'http://www.w3.org/2005/Atom'));
|
||||||
|
|
||||||
|
$generator = $this->getDocument()->createElement('generator', 'PicoFeed');
|
||||||
|
$generator->setAttribute('uri', 'https://github.com/fguillot/picoFeed');
|
||||||
|
$this->feedElement->appendChild($generator);
|
||||||
|
|
||||||
|
$this->helper
|
||||||
|
->buildTitle($this->feedElement, $this->feedTitle)
|
||||||
|
->buildId($this->feedElement, $this->feedUrl)
|
||||||
|
->buildDate($this->feedElement, $this->feedDate)
|
||||||
|
->buildLink($this->feedElement, $this->siteUrl)
|
||||||
|
->buildLink($this->feedElement, $this->feedUrl, 'self', 'application/atom+xml')
|
||||||
|
->buildAuthor($this->feedElement, $this->authorName, $this->authorEmail, $this->authorUrl)
|
||||||
|
;
|
||||||
|
|
||||||
|
foreach ($this->items as $item) {
|
||||||
|
$this->feedElement->appendChild($item->build());
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->getDocument()->appendChild($this->feedElement);
|
||||||
|
|
||||||
|
if ($filename !== '') {
|
||||||
|
$this->getDocument()->save($filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->getDocument()->saveXML();
|
||||||
|
}
|
||||||
|
}
|
139
vendor/fguillot/picofeed/lib/PicoFeed/Syndication/AtomHelper.php
vendored
Normal file
139
vendor/fguillot/picofeed/lib/PicoFeed/Syndication/AtomHelper.php
vendored
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PicoFeed\Syndication;
|
||||||
|
|
||||||
|
use DateTime;
|
||||||
|
use DOMDocument;
|
||||||
|
use DOMElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class AtomHelper
|
||||||
|
*
|
||||||
|
* @package PicoFeed\Syndication
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class AtomHelper
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var DOMDocument
|
||||||
|
*/
|
||||||
|
protected $document;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param DOMDocument $document
|
||||||
|
*/
|
||||||
|
public function __construct(DOMDocument $document)
|
||||||
|
{
|
||||||
|
$this->document = $document;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build node
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param DOMElement $element
|
||||||
|
* @param string $tag
|
||||||
|
* @param string $value
|
||||||
|
* @return AtomHelper
|
||||||
|
*/
|
||||||
|
public function buildNode(DOMElement $element, $tag, $value)
|
||||||
|
{
|
||||||
|
$node = $this->document->createElement($tag);
|
||||||
|
$node->appendChild($this->document->createTextNode($value));
|
||||||
|
$element->appendChild($node);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build title
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param DOMElement $element
|
||||||
|
* @param string $title
|
||||||
|
* @return AtomHelper
|
||||||
|
*/
|
||||||
|
public function buildTitle(DOMElement $element, $title)
|
||||||
|
{
|
||||||
|
return $this->buildNode($element, 'title', $title);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build id
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param DOMElement $element
|
||||||
|
* @param string $id
|
||||||
|
* @return AtomHelper
|
||||||
|
*/
|
||||||
|
public function buildId(DOMElement $element, $id)
|
||||||
|
{
|
||||||
|
return $this->buildNode($element, 'id', $id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build date element
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param DOMElement $element
|
||||||
|
* @param DateTime $date
|
||||||
|
* @param string $type
|
||||||
|
* @return AtomHelper
|
||||||
|
*/
|
||||||
|
public function buildDate(DOMElement $element, DateTime $date, $type = 'updated')
|
||||||
|
{
|
||||||
|
return $this->buildNode($element, $type, $date->format(DateTime::ATOM));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build link element
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param DOMElement $element
|
||||||
|
* @param string $url
|
||||||
|
* @param string $rel
|
||||||
|
* @param string $type
|
||||||
|
* @return AtomHelper
|
||||||
|
*/
|
||||||
|
public function buildLink(DOMElement $element, $url, $rel = 'alternate', $type = 'text/html')
|
||||||
|
{
|
||||||
|
$node = $this->document->createElement('link');
|
||||||
|
$node->setAttribute('rel', $rel);
|
||||||
|
$node->setAttribute('type', $type);
|
||||||
|
$node->setAttribute('href', $url);
|
||||||
|
$element->appendChild($node);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build author element
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param DOMElement $element
|
||||||
|
* @param string $authorName
|
||||||
|
* @param string $authorEmail
|
||||||
|
* @param string $authorUrl
|
||||||
|
* @return AtomHelper
|
||||||
|
*/
|
||||||
|
public function buildAuthor(DOMElement $element, $authorName, $authorEmail, $authorUrl)
|
||||||
|
{
|
||||||
|
if (!empty($authorName)) {
|
||||||
|
$author = $this->document->createElement('author');
|
||||||
|
$this->buildNode($author, 'name', $authorName);
|
||||||
|
|
||||||
|
if (!empty($authorEmail)) {
|
||||||
|
$this->buildNode($author, 'email', $authorEmail);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($authorUrl)) {
|
||||||
|
$this->buildNode($author, 'uri', $authorUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
$element->appendChild($author);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
63
vendor/fguillot/picofeed/lib/PicoFeed/Syndication/AtomItemBuilder.php
vendored
Normal file
63
vendor/fguillot/picofeed/lib/PicoFeed/Syndication/AtomItemBuilder.php
vendored
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PicoFeed\Syndication;
|
||||||
|
|
||||||
|
use DOMElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Atom Item Builder
|
||||||
|
*
|
||||||
|
* @package PicoFeed\Syndication
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class AtomItemBuilder extends ItemBuilder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var DOMElement
|
||||||
|
*/
|
||||||
|
protected $itemElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var AtomHelper
|
||||||
|
*/
|
||||||
|
protected $helper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build item
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return DOMElement
|
||||||
|
*/
|
||||||
|
public function build()
|
||||||
|
{
|
||||||
|
$this->itemElement = $this->feedBuilder->getDocument()->createElement('entry');
|
||||||
|
$this->helper = new AtomHelper($this->feedBuilder->getDocument());
|
||||||
|
|
||||||
|
if (!empty($this->itemId)) {
|
||||||
|
$this->helper->buildId($this->itemElement, $this->itemId);
|
||||||
|
} else {
|
||||||
|
$this->helper->buildId($this->itemElement, $this->itemUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->helper
|
||||||
|
->buildTitle($this->itemElement, $this->itemTitle)
|
||||||
|
->buildLink($this->itemElement, $this->itemUrl)
|
||||||
|
->buildDate($this->itemElement, $this->itemUpdatedDate, 'updated')
|
||||||
|
->buildDate($this->itemElement, $this->itemPublishedDate, 'published')
|
||||||
|
->buildAuthor($this->itemElement, $this->authorName, $this->authorEmail, $this->authorUrl)
|
||||||
|
;
|
||||||
|
|
||||||
|
if (!empty($this->itemSummary)) {
|
||||||
|
$this->helper->buildNode($this->itemElement, 'summary', $this->itemSummary);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($this->itemContent)) {
|
||||||
|
$node = $this->feedBuilder->getDocument()->createElement('content');
|
||||||
|
$node->setAttribute('type', 'html');
|
||||||
|
$node->appendChild($this->feedBuilder->getDocument()->createCDATASection($this->itemContent));
|
||||||
|
$this->itemElement->appendChild($node);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->itemElement;
|
||||||
|
}
|
||||||
|
}
|
185
vendor/fguillot/picofeed/lib/PicoFeed/Syndication/FeedBuilder.php
vendored
Normal file
185
vendor/fguillot/picofeed/lib/PicoFeed/Syndication/FeedBuilder.php
vendored
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PicoFeed\Syndication;
|
||||||
|
|
||||||
|
use DateTime;
|
||||||
|
use DOMDocument;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class FeedBuilder
|
||||||
|
*
|
||||||
|
* @package PicoFeed\Syndication
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
abstract class FeedBuilder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var DOMDocument
|
||||||
|
*/
|
||||||
|
protected $document;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $feedTitle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $feedUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $siteUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $authorName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $authorEmail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $authorUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var DateTime
|
||||||
|
*/
|
||||||
|
protected $feedDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ItemBuilder[]
|
||||||
|
*/
|
||||||
|
protected $items;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->document = new DomDocument('1.0', 'UTF-8');
|
||||||
|
$this->document->formatOutput = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get new object instance
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
|
public static function create()
|
||||||
|
{
|
||||||
|
return new static();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add feed title
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $title
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withTitle($title)
|
||||||
|
{
|
||||||
|
$this->feedTitle = $title;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add feed url
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $url
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withFeedUrl($url)
|
||||||
|
{
|
||||||
|
$this->feedUrl = $url;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add website url
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $url
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withSiteUrl($url)
|
||||||
|
{
|
||||||
|
$this->siteUrl = $url;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add feed date
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param DateTime $date
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withDate(DateTime $date)
|
||||||
|
{
|
||||||
|
$this->feedDate = $date;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add feed author
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $name
|
||||||
|
* @param string $email
|
||||||
|
* @param string $url
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withAuthor($name, $email = '', $url ='')
|
||||||
|
{
|
||||||
|
$this->authorName = $name;
|
||||||
|
$this->authorEmail = $email;
|
||||||
|
$this->authorUrl = $url;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add feed item
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param ItemBuilder $item
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withItem(ItemBuilder $item)
|
||||||
|
{
|
||||||
|
$this->items[] = $item;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get DOM document
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return DOMDocument
|
||||||
|
*/
|
||||||
|
public function getDocument()
|
||||||
|
{
|
||||||
|
return $this->document;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build feed
|
||||||
|
*
|
||||||
|
* @abstract
|
||||||
|
* @access public
|
||||||
|
* @param string $filename
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
abstract public function build($filename = '');
|
||||||
|
}
|
209
vendor/fguillot/picofeed/lib/PicoFeed/Syndication/ItemBuilder.php
vendored
Normal file
209
vendor/fguillot/picofeed/lib/PicoFeed/Syndication/ItemBuilder.php
vendored
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PicoFeed\Syndication;
|
||||||
|
|
||||||
|
use DateTime;
|
||||||
|
use DOMElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ItemBuilder
|
||||||
|
*
|
||||||
|
* @package PicoFeed\Syndication
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
abstract class ItemBuilder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $itemTitle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $itemId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $itemSummary;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $authorName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $authorEmail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $authorUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var DateTime
|
||||||
|
*/
|
||||||
|
protected $itemPublishedDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var DateTime
|
||||||
|
*/
|
||||||
|
protected $itemUpdatedDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $itemContent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $itemUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var FeedBuilder
|
||||||
|
*/
|
||||||
|
protected $feedBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param FeedBuilder $feedBuilder
|
||||||
|
*/
|
||||||
|
public function __construct(FeedBuilder $feedBuilder)
|
||||||
|
{
|
||||||
|
$this->feedBuilder = $feedBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get new object instance
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param FeedBuilder $feedBuilder
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
|
public static function create(FeedBuilder $feedBuilder)
|
||||||
|
{
|
||||||
|
return new static($feedBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add item title
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $title
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withTitle($title)
|
||||||
|
{
|
||||||
|
$this->itemTitle = $title;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add item id
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $id
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withId($id)
|
||||||
|
{
|
||||||
|
$this->itemId = $id;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add item url
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $url
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withUrl($url)
|
||||||
|
{
|
||||||
|
$this->itemUrl = $url;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add item summary
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $summary
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withSummary($summary)
|
||||||
|
{
|
||||||
|
$this->itemSummary = $summary;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add item content
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $content
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withContent($content)
|
||||||
|
{
|
||||||
|
$this->itemContent = $content;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add item updated date
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param DateTime $date
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withUpdatedDate(DateTime $date)
|
||||||
|
{
|
||||||
|
$this->itemUpdatedDate = $date;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add item published date
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param DateTime $date
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withPublishedDate(DateTime $date)
|
||||||
|
{
|
||||||
|
$this->itemPublishedDate = $date;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add item author
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $name
|
||||||
|
* @param string $email
|
||||||
|
* @param string $url
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withAuthor($name, $email = '', $url ='')
|
||||||
|
{
|
||||||
|
$this->authorName = $name;
|
||||||
|
$this->authorEmail = $email;
|
||||||
|
$this->authorUrl = $url;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build item
|
||||||
|
*
|
||||||
|
* @abstract
|
||||||
|
* @access public
|
||||||
|
* @return DOMElement
|
||||||
|
*/
|
||||||
|
abstract public function build();
|
||||||
|
}
|
@ -1,206 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace PicoFeed\Syndication;
|
|
||||||
|
|
||||||
use DomDocument;
|
|
||||||
use DomAttr;
|
|
||||||
use DomElement;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Rss 2.0 writer class.
|
|
||||||
*
|
|
||||||
* @author Frederic Guillot
|
|
||||||
*/
|
|
||||||
class Rss20 extends Writer
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* List of required properties for each feed.
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $required_feed_properties = array(
|
|
||||||
'title',
|
|
||||||
'site_url',
|
|
||||||
'feed_url',
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List of required properties for each item.
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $required_item_properties = array(
|
|
||||||
'title',
|
|
||||||
'url',
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the Rss 2.0 document.
|
|
||||||
*
|
|
||||||
* @param string $filename Optional filename
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function execute($filename = '')
|
|
||||||
{
|
|
||||||
$this->checkRequiredProperties($this->required_feed_properties, $this);
|
|
||||||
|
|
||||||
$this->dom = new DomDocument('1.0', 'UTF-8');
|
|
||||||
$this->dom->formatOutput = true;
|
|
||||||
|
|
||||||
// <rss/>
|
|
||||||
$rss = $this->dom->createElement('rss');
|
|
||||||
$rss->setAttribute('version', '2.0');
|
|
||||||
$rss->setAttributeNodeNS(new DomAttr('xmlns:content', 'http://purl.org/rss/1.0/modules/content/'));
|
|
||||||
$rss->setAttributeNodeNS(new DomAttr('xmlns:atom', 'http://www.w3.org/2005/Atom'));
|
|
||||||
|
|
||||||
$channel = $this->dom->createElement('channel');
|
|
||||||
|
|
||||||
// <generator/>
|
|
||||||
$generator = $this->dom->createElement('generator', 'PicoFeed (https://github.com/fguillot/picoFeed)');
|
|
||||||
$channel->appendChild($generator);
|
|
||||||
|
|
||||||
// <title/>
|
|
||||||
$title = $this->dom->createElement('title');
|
|
||||||
$title->appendChild($this->dom->createTextNode($this->title));
|
|
||||||
$channel->appendChild($title);
|
|
||||||
|
|
||||||
// <description/>
|
|
||||||
$description = $this->dom->createElement('description');
|
|
||||||
$description->appendChild($this->dom->createTextNode($this->description ?: $this->title));
|
|
||||||
$channel->appendChild($description);
|
|
||||||
|
|
||||||
// <pubDate/>
|
|
||||||
$this->addPubDate($channel, $this->updated);
|
|
||||||
|
|
||||||
// <atom:link/>
|
|
||||||
$link = $this->dom->createElement('atom:link');
|
|
||||||
$link->setAttribute('href', $this->feed_url);
|
|
||||||
$link->setAttribute('rel', 'self');
|
|
||||||
$link->setAttribute('type', 'application/rss+xml');
|
|
||||||
$channel->appendChild($link);
|
|
||||||
|
|
||||||
// <link/>
|
|
||||||
$link = $this->dom->createElement('link');
|
|
||||||
$link->appendChild($this->dom->createTextNode($this->site_url));
|
|
||||||
$channel->appendChild($link);
|
|
||||||
|
|
||||||
// <webMaster/>
|
|
||||||
if (isset($this->author)) {
|
|
||||||
$this->addAuthor($channel, 'webMaster', $this->author);
|
|
||||||
}
|
|
||||||
|
|
||||||
// <item/>
|
|
||||||
foreach ($this->items as $item) {
|
|
||||||
$this->checkRequiredProperties($this->required_item_properties, $item);
|
|
||||||
$channel->appendChild($this->createEntry($item));
|
|
||||||
}
|
|
||||||
|
|
||||||
$rss->appendChild($channel);
|
|
||||||
$this->dom->appendChild($rss);
|
|
||||||
|
|
||||||
if ($filename) {
|
|
||||||
$this->dom->save($filename);
|
|
||||||
} else {
|
|
||||||
return $this->dom->saveXML();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create item entry.
|
|
||||||
*
|
|
||||||
* @param arrray $item Item properties
|
|
||||||
*
|
|
||||||
* @return DomElement
|
|
||||||
*/
|
|
||||||
public function createEntry(array $item)
|
|
||||||
{
|
|
||||||
$entry = $this->dom->createElement('item');
|
|
||||||
|
|
||||||
// <title/>
|
|
||||||
$title = $this->dom->createElement('title');
|
|
||||||
$title->appendChild($this->dom->createTextNode($item['title']));
|
|
||||||
$entry->appendChild($title);
|
|
||||||
|
|
||||||
// <link/>
|
|
||||||
$link = $this->dom->createElement('link');
|
|
||||||
$link->appendChild($this->dom->createTextNode($item['url']));
|
|
||||||
$entry->appendChild($link);
|
|
||||||
|
|
||||||
// <guid/>
|
|
||||||
if (isset($item['id'])) {
|
|
||||||
$guid = $this->dom->createElement('guid');
|
|
||||||
$guid->setAttribute('isPermaLink', 'false');
|
|
||||||
$guid->appendChild($this->dom->createTextNode($item['id']));
|
|
||||||
$entry->appendChild($guid);
|
|
||||||
} else {
|
|
||||||
$guid = $this->dom->createElement('guid');
|
|
||||||
$guid->setAttribute('isPermaLink', 'true');
|
|
||||||
$guid->appendChild($this->dom->createTextNode($item['url']));
|
|
||||||
$entry->appendChild($guid);
|
|
||||||
}
|
|
||||||
|
|
||||||
// <pubDate/>
|
|
||||||
$this->addPubDate($entry, isset($item['updated']) ? $item['updated'] : '');
|
|
||||||
|
|
||||||
// <description/>
|
|
||||||
if (isset($item['summary'])) {
|
|
||||||
$description = $this->dom->createElement('description');
|
|
||||||
$description->appendChild($this->dom->createTextNode($item['summary']));
|
|
||||||
$entry->appendChild($description);
|
|
||||||
}
|
|
||||||
|
|
||||||
// <content/>
|
|
||||||
if (isset($item['content'])) {
|
|
||||||
$content = $this->dom->createElement('content:encoded');
|
|
||||||
$content->appendChild($this->dom->createCDATASection($item['content']));
|
|
||||||
$entry->appendChild($content);
|
|
||||||
}
|
|
||||||
|
|
||||||
// <author/>
|
|
||||||
if (isset($item['author'])) {
|
|
||||||
$this->addAuthor($entry, 'author', $item['author']);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add publication date.
|
|
||||||
*
|
|
||||||
* @param DomElement $xml XML node
|
|
||||||
* @param int $value Timestamp
|
|
||||||
*/
|
|
||||||
public function addPubDate(DomElement $xml, $value = 0)
|
|
||||||
{
|
|
||||||
$xml->appendChild($this->dom->createElement(
|
|
||||||
'pubDate',
|
|
||||||
date(DATE_RSS, $value ?: time())
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add author.
|
|
||||||
*
|
|
||||||
* @param DomElement $xml XML node
|
|
||||||
* @param string $tag Tag name
|
|
||||||
* @param array $values Author name and email
|
|
||||||
*/
|
|
||||||
public function addAuthor(DomElement $xml, $tag, array $values)
|
|
||||||
{
|
|
||||||
$value = '';
|
|
||||||
|
|
||||||
if (isset($values['email'])) {
|
|
||||||
$value .= $values['email'];
|
|
||||||
}
|
|
||||||
if ($value && isset($values['name'])) {
|
|
||||||
$value .= ' ('.$values['name'].')';
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($value) {
|
|
||||||
$author = $this->dom->createElement($tag);
|
|
||||||
$author->appendChild($this->dom->createTextNode($value));
|
|
||||||
$xml->appendChild($author);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
76
vendor/fguillot/picofeed/lib/PicoFeed/Syndication/Rss20FeedBuilder.php
vendored
Normal file
76
vendor/fguillot/picofeed/lib/PicoFeed/Syndication/Rss20FeedBuilder.php
vendored
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PicoFeed\Syndication;
|
||||||
|
|
||||||
|
use DOMAttr;
|
||||||
|
use DOMElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rss20 Feed Builder
|
||||||
|
*
|
||||||
|
* @package PicoFeed\Syndication
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class Rss20FeedBuilder extends FeedBuilder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var DOMElement
|
||||||
|
*/
|
||||||
|
protected $rssElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Rss20Helper
|
||||||
|
*/
|
||||||
|
protected $helper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var DOMElement
|
||||||
|
*/
|
||||||
|
protected $channelElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build feed
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $filename
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function build($filename = '')
|
||||||
|
{
|
||||||
|
$this->helper = new Rss20Helper($this->getDocument());
|
||||||
|
|
||||||
|
$this->rssElement = $this->getDocument()->createElement('rss');
|
||||||
|
$this->rssElement->setAttribute('version', '2.0');
|
||||||
|
$this->rssElement->setAttributeNodeNS(new DomAttr('xmlns:content', 'http://purl.org/rss/1.0/modules/content/'));
|
||||||
|
$this->rssElement->setAttributeNodeNS(new DomAttr('xmlns:atom', 'http://www.w3.org/2005/Atom'));
|
||||||
|
|
||||||
|
$this->channelElement = $this->getDocument()->createElement('channel');
|
||||||
|
$this->helper
|
||||||
|
->buildNode($this->channelElement, 'generator', 'PicoFeed (https://github.com/fguillot/picoFeed)')
|
||||||
|
->buildTitle($this->channelElement, $this->feedTitle)
|
||||||
|
->buildNode($this->channelElement, 'description', $this->feedTitle)
|
||||||
|
->buildDate($this->channelElement, $this->feedDate)
|
||||||
|
->buildAuthor($this->channelElement, 'webMaster', $this->authorName, $this->authorEmail)
|
||||||
|
->buildLink($this->channelElement, $this->siteUrl)
|
||||||
|
;
|
||||||
|
|
||||||
|
$link = $this->getDocument()->createElement('atom:link');
|
||||||
|
$link->setAttribute('href', $this->feedUrl);
|
||||||
|
$link->setAttribute('rel', 'self');
|
||||||
|
$link->setAttribute('type', 'application/rss+xml');
|
||||||
|
$this->channelElement->appendChild($link);
|
||||||
|
|
||||||
|
foreach ($this->items as $item) {
|
||||||
|
$this->channelElement->appendChild($item->build());
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->rssElement->appendChild($this->channelElement);
|
||||||
|
$this->getDocument()->appendChild($this->rssElement);
|
||||||
|
|
||||||
|
if ($filename !== '') {
|
||||||
|
$this->getDocument()->save($filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->getDocument()->saveXML();
|
||||||
|
}
|
||||||
|
}
|
115
vendor/fguillot/picofeed/lib/PicoFeed/Syndication/Rss20Helper.php
vendored
Normal file
115
vendor/fguillot/picofeed/lib/PicoFeed/Syndication/Rss20Helper.php
vendored
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PicoFeed\Syndication;
|
||||||
|
|
||||||
|
use DateTime;
|
||||||
|
use DOMDocument;
|
||||||
|
use DOMElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Rss20Helper
|
||||||
|
*
|
||||||
|
* @package PicoFeed\Syndication
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class Rss20Helper
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var DOMDocument
|
||||||
|
*/
|
||||||
|
protected $document;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param DOMDocument $document
|
||||||
|
*/
|
||||||
|
public function __construct(DOMDocument $document)
|
||||||
|
{
|
||||||
|
$this->document = $document;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build node
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param DOMElement $element
|
||||||
|
* @param string $tag
|
||||||
|
* @param string $value
|
||||||
|
* @return AtomHelper
|
||||||
|
*/
|
||||||
|
public function buildNode(DOMElement $element, $tag, $value)
|
||||||
|
{
|
||||||
|
$node = $this->document->createElement($tag);
|
||||||
|
$node->appendChild($this->document->createTextNode($value));
|
||||||
|
$element->appendChild($node);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build title
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param DOMElement $element
|
||||||
|
* @param string $title
|
||||||
|
* @return AtomHelper
|
||||||
|
*/
|
||||||
|
public function buildTitle(DOMElement $element, $title)
|
||||||
|
{
|
||||||
|
return $this->buildNode($element, 'title', $title);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build date element
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param DOMElement $element
|
||||||
|
* @param DateTime $date
|
||||||
|
* @param string $type
|
||||||
|
* @return AtomHelper
|
||||||
|
*/
|
||||||
|
public function buildDate(DOMElement $element, DateTime $date, $type = 'pubDate')
|
||||||
|
{
|
||||||
|
return $this->buildNode($element, $type, $date->format(DateTime::RSS));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build link element
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param DOMElement $element
|
||||||
|
* @param string $url
|
||||||
|
* @return AtomHelper
|
||||||
|
*/
|
||||||
|
public function buildLink(DOMElement $element, $url)
|
||||||
|
{
|
||||||
|
return $this->buildNode($element, 'link', $url);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build author element
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param DOMElement $element
|
||||||
|
* @param string $tag
|
||||||
|
* @param string $authorName
|
||||||
|
* @param string $authorEmail
|
||||||
|
* @return AtomHelper
|
||||||
|
*/
|
||||||
|
public function buildAuthor(DOMElement $element, $tag, $authorName, $authorEmail)
|
||||||
|
{
|
||||||
|
if (!empty($authorName)) {
|
||||||
|
$value = '';
|
||||||
|
|
||||||
|
if (!empty($authorEmail)) {
|
||||||
|
$value .= $authorEmail.' ('.$authorName.')';
|
||||||
|
} else {
|
||||||
|
$value = $authorName;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->buildNode($element, $tag, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
67
vendor/fguillot/picofeed/lib/PicoFeed/Syndication/Rss20ItemBuilder.php
vendored
Normal file
67
vendor/fguillot/picofeed/lib/PicoFeed/Syndication/Rss20ItemBuilder.php
vendored
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PicoFeed\Syndication;
|
||||||
|
|
||||||
|
use DOMElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rss20 Item Builder
|
||||||
|
*
|
||||||
|
* @package PicoFeed\Syndication
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class Rss20ItemBuilder extends ItemBuilder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var DOMElement
|
||||||
|
*/
|
||||||
|
protected $itemElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Rss20Helper
|
||||||
|
*/
|
||||||
|
protected $helper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build item
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return DOMElement
|
||||||
|
*/
|
||||||
|
public function build()
|
||||||
|
{
|
||||||
|
$this->itemElement = $this->feedBuilder->getDocument()->createElement('item');
|
||||||
|
$this->helper = new Rss20Helper($this->feedBuilder->getDocument());
|
||||||
|
|
||||||
|
if (!empty($this->itemId)) {
|
||||||
|
$guid = $this->feedBuilder->getDocument()->createElement('guid');
|
||||||
|
$guid->setAttribute('isPermaLink', 'false');
|
||||||
|
$guid->appendChild($this->feedBuilder->getDocument()->createTextNode($this->itemId));
|
||||||
|
$this->itemElement->appendChild($guid);
|
||||||
|
} else {
|
||||||
|
$guid = $this->feedBuilder->getDocument()->createElement('guid');
|
||||||
|
$guid->setAttribute('isPermaLink', 'true');
|
||||||
|
$guid->appendChild($this->feedBuilder->getDocument()->createTextNode($this->itemUrl));
|
||||||
|
$this->itemElement->appendChild($guid);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->helper
|
||||||
|
->buildTitle($this->itemElement, $this->itemTitle)
|
||||||
|
->buildLink($this->itemElement, $this->itemUrl)
|
||||||
|
->buildDate($this->itemElement, $this->itemPublishedDate)
|
||||||
|
->buildAuthor($this->itemElement, 'author', $this->authorName, $this->authorEmail)
|
||||||
|
;
|
||||||
|
|
||||||
|
if (!empty($this->itemSummary)) {
|
||||||
|
$this->helper->buildNode($this->itemElement, 'description', $this->itemSummary);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($this->itemContent)) {
|
||||||
|
$node = $this->feedBuilder->getDocument()->createElement('content:encoded');
|
||||||
|
$node->appendChild($this->feedBuilder->getDocument()->createCDATASection($this->itemContent));
|
||||||
|
$this->itemElement->appendChild($node);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->itemElement;
|
||||||
|
}
|
||||||
|
}
|
@ -1,95 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace PicoFeed\Syndication;
|
|
||||||
|
|
||||||
use RuntimeException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base writer class.
|
|
||||||
*
|
|
||||||
* @author Frederic Guillot
|
|
||||||
*/
|
|
||||||
abstract class Writer
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Dom object.
|
|
||||||
*
|
|
||||||
* @var \DomDocument
|
|
||||||
*/
|
|
||||||
protected $dom;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Items.
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
public $items = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Author.
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
public $author = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Feed URL.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
public $feed_url = '';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Website URL.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
public $site_url = '';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Feed title.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
public $title = '';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Feed description.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
public $description = '';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Feed modification date (timestamp).
|
|
||||||
*
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
public $updated = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate the XML document.
|
|
||||||
*
|
|
||||||
* @abstract
|
|
||||||
*
|
|
||||||
* @param string $filename Optional filename
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
abstract public function execute($filename = '');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check required properties to generate the output.
|
|
||||||
*
|
|
||||||
* @param array $properties List of properties
|
|
||||||
* @param mixed $container Object or array container
|
|
||||||
*/
|
|
||||||
public function checkRequiredProperties(array $properties, $container)
|
|
||||||
{
|
|
||||||
foreach ($properties as $property) {
|
|
||||||
if ((is_object($container) && !isset($container->$property)) || (is_array($container) && !isset($container[$property]))) {
|
|
||||||
throw new RuntimeException('Required property missing: '.$property);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user