2013-08-12 09:49:28 +02:00
< ? php #
2011-12-13 12:29:05 +01:00
if ( IN_serendipity !== true ) {
die ( " Don't hack! " );
}
// NOTES:
//
// If using MagpieRSS as RSS fetching tool, this plugin is licensed as GPL.
// If using the Onyx parser, this plugin is licensed as BSD.
//
// *****************************************************************
//
// LAYOUT NOTE:
// For best "planet experience" you are advised to create your own template and
// disable s9y-specific options which do not make sense in a planet environment.
// A suggestion is to display the originating feed URL inside entries.tpl via:
//
// {$entry.properties.ep_aggregator_feedname}
// {$entry.properties.ep_aggregator_feedurl}
// {$entry.properties.ep_aggregator_htmlurl}
// {$entry.properties.ep_aggregator_articleurl}
// {$entry.properties.ep_aggregator_author}
//
// See, eg. suggestions in file:
//
// [serendipity]/plugins/serendipity_event_aggregator/theme-patch.diff
//
// *****************************************************************
//
// Smarty plugin API hook to fetch and display feeds in a static page or template:
//
// {serendipity_hookPlugin hook='aggregator_feedlist' hookAll=true data="category:9|cachetime:3600|template:feedlist.tpl"}
//
// Currently supported parameters are only "category" and "cachetime". The ID of a category
// corresponds with the ID of the category that the feeds are associated to in the aggregator configuration.
// You can see the categoryIDs in the backend of managing categories in the URL ("cid"). Multiple categories
// can be separated with a comma (,).
//
// Calling the update like that does NOT STORE THE ENTRIES in your usual blog database, but in a seperate
// one. So this does not really aggregate entries, but simply display them. The cachetime means how many
// seconds must pass until the feeds are refreshed when called.
// The template (by default: feedlist.tpl) can be stored either in the plugin directory or your custom
// template directory and is used to render the items.
// The icon of a feed can be either manually specified in the configuration of available feeds
// or it can be autodetected (only when using simplepie as parser).
// *****************************************************************
// Probe for a language include with constants. Still include defines later on, if some constants were missing
$probelang = dirname ( __FILE__ ) . '/' . $serendipity [ 'charset' ] . 'lang_' . $serendipity [ 'lang' ] . '.inc.php' ;
if ( file_exists ( $probelang )) {
include $probelang ;
}
include dirname ( __FILE__ ) . '/lang_en.inc.php' ;
class serendipity_event_aggregator extends serendipity_event {
var $debug ;
function introspect ( & $propbag ) {
global $serendipity ;
$propbag -> add ( 'name' , PLUGIN_AGGREGATOR_TITLE );
$propbag -> add ( 'description' , PLUGIN_AGGREGATOR_DESC );
$propbag -> add ( 'requirements' , array (
'serendipity' => '0.8' ,
'smarty' => '2.6.7' ,
'php' => '4.1.0'
));
2016-10-26 15:07:46 +02:00
$propbag -> add ( 'version' , '0.34' );
2011-12-13 12:29:05 +01:00
$propbag -> add ( 'author' , 'Evan Nemerson, Garvin Hicking, Kristian Koehntopp, Thomas Schulz, Claus Schmidt' );
$propbag -> add ( 'stackable' , false );
$propbag -> add ( 'event_hooks' , array (
'external_plugin' => true ,
'backend_sidebar_entries' => true ,
'backend_sidebar_entries_event_display_aggregator' => true ,
'cronjob' => true ,
'aggregator_feedlist' => true
)
);
$propbag -> add ( 'configuration' , array ( 'cronjob' , 'engine' , 'publishflag' , 'expire' , 'expire_md5' , 'ignore_updates' , 'delete_dependencies' , 'allow_comments' , 'markup' , 'debug' ));
$propbag -> add ( 'groups' , array ( 'FRONTEND_FULL_MODS' ));
$propbag -> add ( 'license' , 'GPL' );
$this -> dependencies = array ( 'serendipity_event_entryproperties' => 'keep' );
}
function introspect_config_item ( $name , & $propbag )
{
switch ( $name ) {
case 'publishflag' :
$propbag -> add ( 'type' , 'radio' );
$propbag -> add ( 'name' , PLUGIN_AGGREGATOR_PUBLISH );
$propbag -> add ( 'description' , '' );
$propbag -> add ( 'radio' , array (
'value' => array ( 'true' , 'false' ),
'desc' => array ( PUBLISH , DRAFT )
));
$propbag -> add ( 'default' , 'true' );
break ;
case 'cronjob' :
if ( class_exists ( 'serendipity_event_cronjob' )) {
$propbag -> add ( 'type' , 'select' );
$propbag -> add ( 'name' , PLUGIN_EVENT_CRONJOB_CHOOSE );
$propbag -> add ( 'description' , '' );
$propbag -> add ( 'default' , 'daily' );
$propbag -> add ( 'select_values' , serendipity_event_cronjob :: getValues ());
} else {
$propbag -> add ( 'type' , 'content' );
$propbag -> add ( 'default' , PLUGIN_AGGREGATOR_CRONJOB );
}
break ;
case 'debug' :
$propbag -> add ( 'type' , 'boolean' );
$propbag -> add ( 'name' , PLUGIN_AGGREGATOR_DEBUG );
$propbag -> add ( 'description' , PLUGIN_AGGREGATOR_DEBUG_BLAHBLAH );
$propbag -> add ( 'default' , false );
break ;
case 'markup' :
$plugins = serendipity_plugin_api :: get_event_plugins ();
$markups = array ();
if ( is_array ( $plugins )) {
// foreach() operates on copies of values, but we want to operate on references, so we use while()
@ reset ( $plugins );
while ( list ( $plugin , $plugin_data ) = each ( $plugins )) {
if ( ! is_array ( $plugin_data [ 'p' ] -> markup_elements )) {
continue ;
}
2014-11-25 01:15:57 +01:00
$markups [ $plugin_data [ 'p' ] -> instance ] = ( function_exists ( 'serendipity_specialchars' ) ? serendipity_specialchars ( $plugin_data [ 'p' ] -> title ) : htmlspecialchars ( $plugin_data [ 'p' ] -> title , ENT_COMPAT , LANG_CHARSET ));
2011-12-13 12:29:05 +01:00
}
}
$propbag -> add ( 'type' , 'multiselect' );
$propbag -> add ( 'name' , PLUGIN_AGGREGATOR_MARKUP_DISABLE );
$propbag -> add ( 'description' , PLUGIN_AGGREGATOR_MARKUP_DISABLE_DESC );
$propbag -> add ( 'select_values' , $markups );
$propbag -> add ( 'select_size' , 6 );
$propbag -> add ( 'default' , '' );
break ;
case 'engine' :
$propbag -> add ( 'type' , 'radio' );
$propbag -> add ( 'radio' , array ( 'value' => array ( 'onyx' , 'magpierss' , 'simplepie' ),
'desc' => array ( 'Onyx [BSD]' , 'MagpieRSS [GPL]' , 'SimplePie' )));
$propbag -> add ( 'name' , PLUGIN_AGGREGATOR_CHOOSE_ENGINE );
$propbag -> add ( 'description' , PLUGIN_AGGREGATOR_CHOOSE_ENGINE_DESC );
$propbag -> add ( 'default' , 'onyx' );
break ;
case 'delete_dependencies' :
$propbag -> add ( 'type' , 'boolean' );
$propbag -> add ( 'name' , PLUGIN_AGGREGATOR_DELETEDEPENDENCIES );
$propbag -> add ( 'description' , PLUGIN_AGGREGATOR_DELETEDEPENDENCIES_DESC );
$propbag -> add ( 'default' , true );
break ;
case 'expire' :
$propbag -> add ( 'type' , 'string' );
$propbag -> add ( 'name' , PLUGIN_AGGREGATOR_EXPIRE );
$propbag -> add ( 'description' , PLUGIN_AGGREGATOR_EXPIRE_BLAHBLAH );
$propbag -> add ( 'default' , 2 );
break ;
case 'expire_md5' :
$propbag -> add ( 'type' , 'string' );
$propbag -> add ( 'name' , PLUGIN_AGGREGATOR_EXPIRE_MD5 );
$propbag -> add ( 'description' , PLUGIN_AGGREGATOR_EXPIRE_MD5_BLAHBLAH );
$propbag -> add ( 'default' , 90 );
break ;
case 'ignore_updates' :
$propbag -> add ( 'type' , 'boolean' );
$propbag -> add ( 'name' , PLUGIN_AGGREGATOR_IGNORE_UPDATES );
$propbag -> add ( 'description' , PLUGIN_AGGREGATOR_IGNORE_UPDATES_DESC );
$propbag -> add ( 'default' , false );
break ;
case 'allow_comments' :
$propbag -> add ( 'type' , 'boolean' );
$propbag -> add ( 'name' , COMMENTS_ENABLE );
$propbag -> add ( 'description' , '' );
$propbag -> add ( 'default' , false );
break ;
default :
return false ;
}
return true ;
}
function setupDB () {
global $serendipity ;
# Old Schema
if ( ! serendipity_db_bool ( $this -> get_config ( 'db_built' , false ))) {
$sql = " CREATE TABLE { $serendipity [ 'dbPrefix' ] } aggregator_feeds (
feedid { AUTOINCREMENT } { PRIMARY },
feedname varchar ( 255 ) NOT NULL default '' ,
feedurl varchar ( 255 ) NOT NULL default '' ,
htmlurl varchar ( 255 ) NOT NULL default '' ,
categoryid int ( 11 ) default NULL ,
last_update int ( 10 ) { UNSIGNED } default null ,
charset varchar ( 255 ) NOT NULL default ''
); " ;
serendipity_db_schema_import ( $sql );
$this -> set_config ( 'db_built' , 'true' );
}
# Schema extension (version 2)
if ( $this -> get_config ( 'db_version' ) < 2 ) {
echo " *** setup DB version " . $this -> get_config ( 'db_version' ) . " <br /> \n " ;
$sql = " CREATE TABLE { $serendipity [ 'dbPrefix' ] } aggregator_md5 (
entryid { AUTOINCREMENT } { PRIMARY },
md5 varchar ( 32 ) NOT NULL default '' ,
timestamp int ( 10 ) { UNSIGNED } default null ,
key md5_idx ( md5 ),
key timestamp_idx ( timestamp )
); " ;
serendipity_db_schema_import ( $sql );
$sql = " INSERT INTO { $serendipity [ 'dbPrefix' ] } aggregator_md5
( entryid , md5 , timestamp )
SELECT entryid , value , " . time() .
" FROM { $serendipity [ 'dbPrefix' ] } entryproperties
WHERE property = 'ep_aggregator_md5' " ;
serendipity_db_query ( $sql );
$sql = " DELETE FROM { $serendipity [ 'dbPrefix' ] } entryproperties
WHERE property = 'ep_aggregator_md5' " ;
serendipity_db_query ( $sql );
$this -> set_config ( 'db_version' , '2' );
}
# Schema extension (version 3)
if ( $this -> get_config ( 'db_version' ) < 3 ) {
echo " *** setup DB version " . $this -> get_config ( 'db_version' ) . " <br /> \n " ;
$sql = " CREATE TABLE { $serendipity [ 'dbPrefix' ] } aggregator_feedcat (
feedid int ( 11 ) not null ,
categoryid int ( 11 ) not null
); " ;
serendipity_db_schema_import ( $sql );
$sql = " CREATE UNIQUE INDEX feedid_idx
ON { $serendipity [ 'dbPrefix' ]} aggregator_feedcat ( feedid , categoryid ); " ;
serendipity_db_schema_import ( $sql );
$sql = " INSERT INTO { $serendipity [ 'dbPrefix' ] } aggregator_feedcat
( feedid , categoryid )
SELECT feedid , categoryid
FROM { $serendipity [ 'dbPrefix' ]} aggregator_feeds " ;
serendipity_db_query ( $sql );
$sql = " DELETE FROM { $serendipity [ 'dbPrefix' ] } entryproperties
WHERE property = 'ep_aggregator_md5' " ;
serendipity_db_query ( $sql );
$sql = " ALTER TABLE { $serendipity [ 'dbPrefix' ] } aggregator_feeds
DROP categoryid ; " ;
serendipity_db_schema_import ( $sql );
$this -> set_config ( 'db_version' , '3' );
}
# Schema extension (version 4)
if ( $this -> get_config ( 'db_version' ) < 4 ) {
$sql = " ALTER TABLE { $serendipity [ 'dbPrefix' ] } aggregator_feeds
ADD COLUMN charset varchar ( 255 ); " ;
serendipity_db_schema_import ( $sql );
$this -> set_config ( 'db_version' , '4' );
}
# Schema extension (version 5)
if ( $this -> get_config ( 'db_version' ) < 5 ) {
$sql = " ALTER TABLE { $serendipity [ 'dbPrefix' ] } aggregator_feeds
ADD COLUMN match_expression varchar ( 255 ); " ;
serendipity_db_schema_import ( $sql );
$this -> set_config ( 'db_version' , '5' );
}
# Schema extension (version 6)
if ( $this -> get_config ( 'db_version' ) < 6 ) {
$sql = " CREATE TABLE { $serendipity [ 'dbPrefix' ] } aggregator_feedlist (
id { AUTOINCREMENT } { PRIMARY },
feedid int ( 11 ) not null ,
categoryid int ( 11 ) not null ,
entrydate int ( 11 ) not null ,
entrytitle text ,
entrybody longtext ,
entryurl text
); " ;
serendipity_db_schema_import ( $sql );
$sql = " ALTER TABLE { $serendipity [ 'dbPrefix' ] } aggregator_feeds
ADD COLUMN feedicon text ; " ;
serendipity_db_schema_import ( $sql );
$this -> set_config ( 'db_version' , '6' );
}
if ( $this -> get_config ( 'db_version' ) < 7 ) {
$sql = " CREATE INDEX fl_feedid ON { $serendipity [ 'dbPrefix' ] } aggregator_feedlist (feedid) " ;
serendipity_db_schema_import ( $sql );
$sql = " CREATE INDEX fl_entrydate ON { $serendipity [ 'dbPrefix' ] } aggregator_feedlist (entrydate) " ;
serendipity_db_schema_import ( $sql );
$sql = " CREATE INDEX fl_categoryid ON { $serendipity [ 'dbPrefix' ] } aggregator_feedlist (categoryid) " ;
serendipity_db_schema_import ( $sql );
$sql = " CREATE INDEX fl_feedid_2 ON { $serendipity [ 'dbPrefix' ] } aggregator_feedlist (feedid, entrydate) " ;
serendipity_db_schema_import ( $sql );
$sql = " CREATE INDEX fl_feedid_3 ON { $serendipity [ 'dbPrefix' ] } aggregator_feedlist (feedid, entrydate, categoryid) " ;
serendipity_db_schema_import ( $sql );
$this -> set_config ( 'db_version' , '7' );
}
}
function & getFeeds ( $opt = null ) {
global $serendipity ;
$this -> setupDB ();
if ( $opt [ 'category' ] > 0 ) {
$where = " WHERE fc.categoryid IN ( " . $opt [ 'category' ] . " ) " ;
}
$sql = " SELECT f.feedid, f.feedname, f.feedurl, f.htmlurl, fc.categoryid, f.last_update, f.charset, f.feedicon, f.match_expression
FROM { $serendipity [ 'dbPrefix' ]} aggregator_feeds AS f
LEFT OUTER JOIN { $serendipity [ 'dbPrefix' ]} aggregator_feedcat AS fc
ON f . feedid = fc . feedid
$where
ORDER BY feedname , f . feedid
" ;
$feeds = serendipity_db_query ( $sql , false , 'assoc' );
// prepare array
$ret = array ();
if ( is_array ( $feeds )) {
foreach ( $feeds as $feed ) {
$category = $feed [ 'categoryid' ];
if ( ! isset ( $ret [ $feed [ 'feedid' ]])) {
unset ( $feed [ 'categoryid' ]);
$ret [ $feed [ 'feedid' ]] = $feed ;
}
$ret [ $feed [ 'feedid' ]][ 'categoryids' ][] = $category ;
}
}
$feeds = array_values ( $ret );
if ( ! is_array ( $feeds )) {
return array ();
} else {
return $feeds ;
}
}
function removeFeeds () {
global $serendipity ;
if ( ! serendipity_db_query ( " DELETE FROM { $serendipity [ 'dbPrefix' ] } aggregator_feedcat " )) {
return false ;
}
return serendipity_db_query ( " DELETE FROM { $serendipity [ 'dbPrefix' ] } aggregator_feeds " );
}
function createFeeds () {
global $serendipity ;
$this -> setupDB ();
$feeds = $this -> getFeeds ();
foreach ( $serendipity [ 'POST' ][ 'feed' ] AS $idx => $array ) {
if ( empty ( $idx )) {
if ( empty ( $array [ 'feedurl' ]) && empty ( $array [ 'feedname' ]) && empty ( $array [ 'htmlurl' ])) {
continue ;
} elseif ( empty ( $array [ 'feedurl' ]) || empty ( $array [ 'feedname' ])) {
echo '<div class="serendipityAdminMsgError"><img style="width: 22px; height: 22px; border: 0px; padding-right: 4px; vertical-align: middle" src="' . serendipity_getTemplateFile ( 'admin/img/admin_msg_error.png' ) . '" alt="" />' . PLUGIN_AGGREGATOR_FEED_MISSINGDATA . '</div>' ;
} else {
$this -> insertFeed ( $array );
}
} elseif ( is_numeric ( $idx )) {
if ( empty ( $array [ 'feedurl' ]) || empty ( $array [ 'feedname' ])) {
$this -> deleteFeed ( $idx , $array );
} else {
$this -> updateFeed ( $idx , $array );
}
}
}
}
function purgeEntries ( $id_list ) {
global $serendipity ;
$a = serendipity_db_query ( " DELETE FROM { $serendipity [ 'dbPrefix' ] } entries WHERE id IN ( " . implode ( " , " , $id_list ) . " ) " );
$b = serendipity_db_query ( " DELETE FROM { $serendipity [ 'dbPrefix' ] } entrycat WHERE entryid IN ( " . implode ( " , " , $id_list ) . " ) " );
$c = serendipity_db_query ( " DELETE FROM { $serendipity [ 'dbPrefix' ] } entryproperties WHERE entryid IN ( " . implode ( " , " , $id_list ) . " ) " );
$d = serendipity_db_query ( " DELETE FROM { $serendipity [ 'dbPrefix' ] } references WHERE entry_id IN ( " . implode ( " , " , $id_list ) . " ) " );
$e = serendipity_db_query ( " DELETE FROM { $serendipity [ 'dbPrefix' ] } exits WHERE entry_id IN ( " . implode ( " , " , $id_list ) . " ) " );
return true ;
}
function expireFeedEntries ( $age ) {
global $serendipity ;
// CLSC: 86400 = number of seconds in 24 hours
$t = time () - 86400 * $age ;
if ( $this -> debug ) printf ( " DEBUG: Expire cutoff %s \n " , $t );
$q = " SELECT e.id
FROM { $serendipity [ 'dbPrefix' ]} entries AS e
LEFT OUTER JOIN { $serendipity [ 'dbPrefix' ]} entryproperties AS ep
ON e . id = ep . entryid
LEFT OUTER JOIN { $serendipity [ 'dbPrefix' ]} aggregator_feeds AS af
ON ep . value = af . feedid
WHERE ep . property = 'ep_aggregator_feed'
AND e . comments < 1
AND e . extended IS NULL
AND e . timestamp < " . (int) $t ;
$entries = serendipity_db_query ( $q );
if ( ! is_array ( $entries )) {
if ( $this -> debug ) printf ( " DEBUG: Nothing to expire. \n " );
return false ;
}
$id_list = array ();
foreach ( $entries AS $entry ) {
if ( $this -> debug ) printf ( " Expire entry %s \n " , $entry [ 'id' ]);
$id_list [] = $entry [ 'id' ];
}
$this -> purgeEntries ( $id_list );
return ;
}
function purgeMD5 ( $id_list ) {
global $serendipity ;
$a = serendipity_db_query ( " DELETE FROM { $serendipity [ 'dbPrefix' ] } aggregator_md5 WHERE entryid IN ( " . implode ( " , " , $id_list ) . " ) " );
return true ;
}
function expireFeedMD5 ( $age ) {
global $serendipity ;
// CLSC: 86400 = number of seconds in 24 hours
$t = time () - 86400 * $age ;
if ( $this -> debug ) printf ( " DEBUG: MD5 Expire cutoff %s \n " , $t );
$q = " SELECT entryid FROM { $serendipity [ 'dbPrefix' ] } aggregator_md5 WHERE timestamp < " . ( int ) $t ;
$entries = serendipity_db_query ( $q );
if ( ! is_array ( $entries )) {
if ( $this -> debug ) printf ( " DEBUG: Nothing to expire. \n " );
return false ;
}
$id_list = array ();
foreach ( $entries AS $entry ) {
if ( $this -> debug ) printf ( " Expire MD5 %s \n " , $entry [ 'entryid' ]);
$id_list [] = $entry [ 'entryid' ];
}
$this -> purgeMD5 ( $id_list );
return ;
}
function expireFeeds () {
$t = & $this -> get_config ( 'expire' );
if ( $t > 0 ) {
$this -> expireFeedEntries ( $t );
}
$t = & $this -> get_config ( 'expire_md5' );
if ( $t > 0 ) {
$this -> expireFeedMD5 ( $t );
}
return ;
}
function updateFeed ( $idx , & $array ) {
global $serendipity ;
$q = " UPDATE { $serendipity [ 'dbPrefix' ] } aggregator_feeds
SET feedname = '" . serendipity_db_escape_string($array[' feedname ']) . "' ,
feedurl = '" . serendipity_db_escape_string($array[' feedurl ']) . "' ,
match_expression = '" . serendipity_db_escape_string($array[' match_expression ']) . "' ,
feedicon = '" . serendipity_db_escape_string($array[' feedicon ']) . "' ,
htmlurl = '" . serendipity_db_escape_string($array[' htmlurl ']) . "'
WHERE feedid = " . (int) $idx ;
if ( ! serendipity_db_query ( $q )) {
return false ;
}
// delete old categories
if ( ! $this -> deleteFeedCats ( $idx )) {
return false ;
}
// add changed categories
return $this -> insertFeedCats ( $idx , $array [ 'categoryids' ]);
}
function deleteFeed ( $idx , & $array ) {
global $serendipity ;
if ( serendipity_db_bool ( $this -> get_config ( 'delete_dependencies' ))) {
$q = " SELECT e.id
FROM { $serendipity [ 'dbPrefix' ]} entries AS e
LEFT OUTER JOIN { $serendipity [ 'dbPrefix' ]} entryproperties AS ep
ON e . id = ep . entryid
WHERE ep . property = 'ep_aggregator_feed'
AND ep . value = " . (int) $idx ;
$entries = serendipity_db_query ( $q );
if ( is_array ( $entries )) {
$id_list = array ();
foreach ( $entries AS $entry ) {
$id_list [] = $entry [ 'id' ];
}
$this -> purgeEntries ( $id_list );
}
}
if ( ! $this -> deleteFeedCats ( $idx )) {
return false ;
}
$q = " DELETE FROM { $serendipity [ 'dbPrefix' ] } aggregator_feeds
WHERE feedid = " . (int) $idx ;
return serendipity_db_query ( $q );
}
function insertFeed ( & $array ) {
global $serendipity ;
$query = " SELECT authorid
FROM { $serendipity [ 'dbPrefix' ]} authors
WHERE realname = '" . serendipity_db_escape_string($array[' feedname ']) . "' " ;
if ( ! is_array ( $res = serendipity_db_query ( $query ))) {
serendipity_db_insert ( 'authors' , array ( 'username' => $array [ 'feedname' ],
'realname' => $array [ 'feedname' ],
'password' => md5 ( mt_rand ()),
'email' => $array [ 'htmlurl' ],
'userlevel' => 0 ,
'right_publish' => 1 ));
$res = serendipity_db_query ( $query );
}
$r = serendipity_db_query ( " INSERT INTO { $serendipity [ 'dbPrefix' ] } aggregator_feeds
( feedname , feedurl , htmlurl , charset , match_expression , feedicon , last_update )
VALUES ( '" . serendipity_db_escape_string($array[' feedname ']) . "' ,
'" . serendipity_db_escape_string($array[' feedurl ']) . "' ,
'" . serendipity_db_escape_string($array[' htmlurl ']) . "' ,
'" . serendipity_db_escape_string($array[' charset ']) . "' ,
'" . serendipity_db_escape_string($array[' match_expression ']) . "' ,
'" . serendipity_db_escape_string($array[' feedicon ']) . "' ,
'" . time() . "' ) " );
if ( $r == false ) {
return $r ;
}
if ( ! is_array ( $array [ 'categoryids' ])) {
$array [ 'categoryids' ] = array ();
$array [ 'categoryids' ][] = $array [ 'categoryid' ];
}
return $this -> insertFeedCats ( serendipity_db_insert_id (), $array [ 'categoryids' ]);
}
function insertFeedCats ( $idx , $categories ) {
global $serendipity ;
if ( ! is_array ( $categories )) {
return true ;
}
foreach ( $categories as $categoryid ) {
$r = serendipity_db_query ( " INSERT INTO { $serendipity [ 'dbPrefix' ] } aggregator_feedcat
( feedid , categoryid )
VALUES ( '" . $idx . "' ,
'" . (int)$categoryid . "' ) " );
if ( $r == false ) {
return false ;
}
}
return true ;
}
function deleteFeedCats ( $idx ) {
global $serendipity ;
$q = " DELETE FROM { $serendipity [ 'dbPrefix' ] } aggregator_feedcat
WHERE feedid = " . (int) $idx ;
return serendipity_db_query ( $q );
}
function & fetchCat ( $name , $selected = 0 ) {
global $serendipity ;
$n = " \n " ;
$cat_list = '<select name="' . $name . '" multiple="multiple" size="4">' ;
$cat_list .= ' <option value="0"' . ( empty ( $selected ) ? ' selected="selected"' : '' ) . '>[' . NO_CATEGORY . ']</option>' . $n ;
if ( is_array ( $cats = serendipity_fetchCategories ())) {
$cats = serendipity_walkRecursive ( $cats , 'categoryid' , 'parentid' , VIEWMODE_THREADED );
foreach ( $cats as $cat ) {
$cat_list .= '<option value="' . $cat [ 'categoryid' ] . '"' . ( in_array ( $cat [ 'categoryid' ], $selected ) ? ' selected="selected"' : '' ) . '>' . str_repeat ( ' ' , $cat [ 'depth' ]) . $cat [ 'category_name' ] . '</option>' . " \n " ;
}
}
$cat_list .= '</select>' ;
return $cat_list ;
}
function showFeeds () {
# Shows feeds in admin area
global $serendipity ;
2014-06-07 11:32:13 +02:00
echo '<h2>' . PLUGIN_AGGREGATOR_TITLE . '</h2>' ;
2011-12-13 12:29:05 +01:00
if ( ! empty ( $serendipity [ 'POST' ][ 'aggregatorAction' ])) {
$this -> createFeeds ();
} elseif ( ! empty ( $serendipity [ 'POST' ][ 'aggregatorOPMLImport' ])) {
$this -> importOPML ();
}
$feeds = $this -> getFeeds ();
$feeds [] = array (
'feedid' => 0 ,
'feedname' => '' ,
'feedurl' => '' ,
'charset' => '' ,
'htmlurl' => '' ,
'match_expression' => '' ,
'feedicon' => '' ,
'categoryids' => array (),
'last_update' => time ()
);
2016-09-22 16:03:33 +02:00
if ( $serendipity [ 'version' ][ 0 ] > 1 ) {
2016-10-26 15:07:46 +02:00
echo '<span class="msg_notice"><span class="icon-info-circled" aria-hidden="true"></span> ' ;
2014-06-07 11:32:13 +02:00
}
echo PLUGIN_AGGREGATOR_DESC ;
if ( $serendipity [ 'version' ][ 0 ] == '1' ) {
echo '<br /><br />' ;
} else {
echo '</span>' ;
}
2016-09-22 16:03:33 +02:00
if ( $serendipity [ 'version' ][ 0 ] > 1 ) {
2016-10-26 15:07:46 +02:00
echo '<span class="msg_hint"><span class="icon-help-circled" aria-hidden="true"></span> ' ;
2014-06-07 11:32:13 +02:00
}
echo PLUGIN_AGGREGATOR_FEEDLIST ;
if ( $serendipity [ 'version' ][ 0 ] == '1' ) {
echo '<br /><br />' ;
} else {
echo '</span>' ;
}
2011-12-13 12:29:05 +01:00
echo '
< form action = " ? " method = " post " >
< div >
< input type = " hidden " name = " serendipity[adminModule] " value = " event_display " />
< input type = " hidden " name = " serendipity[adminAction] " value = " aggregator " />
2014-06-07 11:32:13 +02:00
</ div > ' ;
if ( $serendipity [ 'version' ][ 0 ] == '1' ) {
echo '<table align="center" width="100%" cellpadding="5" cellspacing="0" border=0>' ;
} else {
echo '<table>' ;
}
echo '
< thead >
2011-12-13 12:29:05 +01:00
< tr >
< th > #</th>
< th > ' . PLUGIN_AGGREGATOR_FEEDNAME . ' </ th >
2014-06-07 11:32:13 +02:00
< th > ' . PLUGIN_AGGREGATOR_FEEDURI . ' / ' . PLUGIN_AGGREGATOR_HTMLURI . ' </ th >
2011-12-13 12:29:05 +01:00
< th > ' . PLUGIN_AGGREGATOR_CATEGORIES . ' </ th >
< th > ' . PLUGIN_AGGREGATOR_MATCH_EXPRESSION . ' * / ' . PLUGIN_AGGREGATOR_FEEDICON . ' </ th >
2014-06-07 11:32:13 +02:00
</ tr >
</ thead >
< tbody > ' ;
2011-12-13 12:29:05 +01:00
$evenidx = 0 ;
foreach ( $feeds AS $idx => $feed ) {
$cat = $this -> fetchCat ( " serendipity[feed][ { $feed [ 'feedid' ] } ][categoryids][] " , $feed [ 'categoryids' ]);
$even = ( $evenidx ++ % 2 ? 'even' : 'uneven' );
echo '
< tr style = " padding: 10px; " class = " serendipity_admin_list_item serendipity_admin_list_item_' . $even . ' " >
< td valign = " top " >< em > ' . $idx . ' </ em ></ td >
< td valign = " top " >
2014-11-25 01:15:57 +01:00
< input class = " input_textbox " type = " text " name = " serendipity[feed][' . $feed['feedid'] . '][feedname] " value = " ' . (function_exists('serendipity_specialchars') ? serendipity_specialchars( $feed['feedname'] ) : htmlspecialchars( $feed['feedname'] , ENT_COMPAT, LANG_CHARSET)) . ' " /> ' . (function_exists(' serendipity_specialchars ') ? serendipity_specialchars($feed[' charset ']) : htmlspecialchars($feed[' charset '], ENT_COMPAT, LANG_CHARSET)) . '
2011-12-13 12:29:05 +01:00
</ td >
< td width = " 100% " valign = " top " >
2014-11-25 01:15:57 +01:00
< input class = " input_textbox " style = " width: 100% " type = " text " name = " serendipity[feed][' . $feed['feedid'] . '][feedurl] " value = " ' . (function_exists('serendipity_specialchars') ? serendipity_specialchars( $feed['feedurl'] ) : htmlspecialchars( $feed['feedurl'] , ENT_COMPAT, LANG_CHARSET)) . ' " />
< input class = " input_textbox " style = " width: 65%; margin-top: 2px; " type = " text " name = " serendipity[feed][' . $feed['feedid'] . '][htmlurl] " value = " ' . (function_exists('serendipity_specialchars') ? serendipity_specialchars( $feed['htmlurl'] ) : htmlspecialchars( $feed['htmlurl'] , ENT_COMPAT, LANG_CHARSET)) . ' " />
2011-12-13 12:29:05 +01:00
</ td >
< td valign = " top " rowspan = " 2 " > ' . $cat . ' </ td >
2014-11-25 01:15:57 +01:00
< td valign = " top " rowspan = " 2 " >< textarea rows = 6 cols = 25 name = " serendipity[feed][' . $feed['feedid'] . '][match_expression] " > ' . (function_exists(' serendipity_specialchars ') ? serendipity_specialchars($feed[' match_expression ']) : htmlspecialchars($feed[' match_expression '], ENT_COMPAT, LANG_CHARSET)) . ' </ textarea >< br />
< input class = " input_textbox " style = " width: 65%; margin-top: 2px; " type = " text " name = " serendipity[feed][' . $feed['feedid'] . '][feedicon] " value = " ' . (function_exists('serendipity_specialchars') ? serendipity_specialchars( $feed['feedicon'] ) : htmlspecialchars( $feed['feedicon'] , ENT_COMPAT, LANG_CHARSET)) . ' " />
2011-12-13 12:29:05 +01:00
</ tr >
< tr style = " padding: 10px; " class = " serendipity_admin_list_item serendipity_admin_list_item_' . $even . ' " >
< td ></ td >
< td colspan = " 2 " valign = " top " >
< div style = " font-size: 8pt; " > ' . PLUGIN_AGGREGATOR_FEEDUPDATE . ' ' . serendipity_formatTime(DATE_FORMAT_SHORT, $feed[' last_update ']) . ' </ div >
</ td >
</ tr > ' ;
}
echo '
< tr >
< td colspan = " 4 " >< br />
< input type = " submit " name = " serendipity[aggregatorAction] " value = " ' . GO . ' " class = " serendipityPrettyButton input_button " />
</ td >
</ tr >
2014-06-07 11:32:13 +02:00
</ tbody >
2011-12-13 12:29:05 +01:00
</ table >
* ' . PLUGIN_AGGREGATOR_MATCH_EXPRESSION_DESC . '
</ form > ' ;
echo '
< form action = " ? " method = " post " >
< div >
< input type = " hidden " name = " serendipity[adminModule] " value = " event_display " />
< input type = " hidden " name = " serendipity[adminAction] " value = " aggregator " />
2014-06-07 11:32:13 +02:00
</ div > ' ;
2011-12-13 12:29:05 +01:00
2014-06-07 11:32:13 +02:00
if ( $serendipity [ 'version' ][ 0 ] == '1' ) {
echo '
2011-12-13 12:29:05 +01:00
< div >
< hr />< strong >
' . PLUGIN_AGGREGATOR_IMPORTFEEDLIST. ' </ strong >< br />< br />
' . PLUGIN_AGGREGATOR_IMPORTFEEDLIST_DESC . ' < br />< br />
URL : < input class = " input_textbox " type = " text " name = " serendipity[aggregatorOPML] " value = " http:// " />< br />
< input class = " input_checkbox " type = " checkbox " id = " import_categories " name = " serendipity[aggregatorOPMLCategories] " value = " true " />< label for = " import_categories " > ' . PLUGIN_AGGREGATOR_IMPORTCATEGORIES . ' </ label >
< input class = " input_checkbox " type = " checkbox " id = " import_categories2 " name = " serendipity[aggregatorOPMLCategoriesNoNesting] " value = " true " />< label for = " import_categories2 " > ' . PLUGIN_AGGREGATOR_IMPORTCATEGORIES2 . ' </ label >
< br />< br />
< input type = " submit " name = " serendipity[aggregatorOPMLImport] " value = " ' . PLUGIN_AGGREGATOR_IMPORTFEEDLIST_BUTTON . ' " class = " serendipityPrettyButton input_button " />
2014-06-07 11:32:13 +02:00
</ div > ' ;
} else {
echo '
< h3 > ' . PLUGIN_AGGREGATOR_IMPORTFEEDLIST . ' </ h3 >
2016-10-26 15:07:46 +02:00
< span class = " msg_hint " >< span class = " icon-help-circled " aria - hidden = " true " ></ span > ' . PLUGIN_AGGREGATOR_IMPORTFEEDLIST_DESC . ' </ span >
2014-06-07 11:32:13 +02:00
< div class = " form_field " >
< label for = " serendipity_aggregator_opml " > URL </ label >
< input id = " serendipity_aggregator_opml " type = " text " name = " serendipity[aggregatorOPML] " value = " http:// " >
2011-12-13 12:29:05 +01:00
</ div >
2014-06-07 11:32:13 +02:00
< div class = " form_check " >
< input type = " checkbox " id = " import_categories " name = " serendipity[aggregatorOPMLCategories] " value = " true " >< label for = " import_categories " > ' . PLUGIN_AGGREGATOR_IMPORTCATEGORIES . ' </ label >
< input type = " checkbox " id = " import_categories2 " name = " serendipity[aggregatorOPMLCategoriesNoNesting] " value = " true " >< label for = " import_categories2 " > ' . PLUGIN_AGGREGATOR_IMPORTCATEGORIES2 . ' </ label >
</ div > ' ;
}
2011-12-13 12:29:05 +01:00
2014-06-07 11:32:13 +02:00
if ( $serendipity [ 'version' ][ 0 ] == '1' ) {
echo '
2011-12-13 12:29:05 +01:00
< div >
< hr />< strong >
' . PLUGIN_AGGREGATOR_EXPORTFEEDLIST. ' </ strong >< br />< br />
< a href = " ' . serendipity_rewriteURL('plugin/opmlfeeds.xml') . ' " class = " serendipityPrettyButton " > ' . PLUGIN_AGGREGATOR_EXPORTFEEDLIST_BUTTON . ' </ a >
</ div >
</ form > ' ;
2014-06-07 11:32:13 +02:00
} else {
echo '
< h3 > ' . PLUGIN_AGGREGATOR_EXPORTFEEDLIST . ' </ h3 >
2016-10-26 15:07:46 +02:00
< a class = " button_link " href = " ' . serendipity_rewriteURL('plugin/opmlfeeds.xml') .' " >< span class = " icon-rss " aria - hidden = " true " ></ span > ' . PLUGIN_AGGREGATOR_EXPORTFEEDLIST_BUTTON . ' </ a >
2014-06-07 11:32:13 +02:00
</ form > ' ;
}
2011-12-13 12:29:05 +01:00
}
function importOPML () {
$tree = $this -> importFeeds ();
if ( ! $tree ) {
return ;
}
$this -> removeFeeds ();
$this -> cats = serendipity_fetchCategories ();
foreach ( $tree AS $xml_base ) {
if ( $xml_base [ 'tag' ] != 'opml' || ! is_array ( $xml_base [ 'children' ])) {
continue ;
}
foreach ( $xml_base [ 'children' ] AS $xml_body ) {
if ( $xml_body [ 'tag' ] != 'body' || ! is_array ( $xml_body [ 'children' ])) {
continue ;
}
foreach ( $xml_body [ 'children' ] AS $xml_outline ) {
$this -> parseOutline ( $xml_outline );
}
}
}
serendipity_rebuildCategoryTree ();
}
function serendipity_addCategory ( $name , $desc , $authorid , $icon , $parentid ) {
global $serendipity ;
$query = " INSERT INTO { $serendipity [ 'dbPrefix' ] } category
( category_name , category_description , authorid , category_icon , parentid , category_left , category_right )
VALUES
( '". serendipity_db_escape_string($name) ."' ,
'". serendipity_db_escape_string($desc) ."' ,
" . (int) $authorid . " ,
'". serendipity_db_escape_string($icon) ."' ,
" . (int) $parentid . " ,
0 ,
0 ) " ;
return serendipity_db_query ( $query );
}
function newCategory ( $parent , $last_parent_id ) {
global $serendipity ;
if ( function_exists ( 'serendipity_addCategory' )) {
$parent_id = serendipity_addCategory ( $parent , '' , 0 , '' , $last_parent_id );
} else {
$this -> serendipity_addCategory ( $parent , '' , 0 , '' , $last_parent_id );
$parent_id = serendipity_db_insert_id ( 'category' , 'categoryid' );
}
return $parent_id ;
}
function fetchCategoryParent ( $parentname ) {
if ( ! is_array ( $this -> cats )) {
return false ;
}
foreach ( $this -> cats AS $cat ) {
if ( $cat [ 'category_name' ] == $parentname ) {
return $cat [ 'categoryid' ];
}
}
return false ;
}
function parseOutline ( & $xml_outline , $last_parent_name = '' , $last_parent_id = 0 ) {
global $serendipity ;
if ( ! empty ( $xml_outline [ 'attributes' ][ 'title' ])) {
$parent = $xml_outline [ 'attributes' ][ 'title' ];
} elseif ( ! empty ( $xml_outline [ 'attributes' ][ 'text' ])) {
$parent = $xml_outline [ 'attributes' ][ 'text' ];
} elseif ( ! empty ( $xml_outline [ 'attributes' ][ 'id' ])) {
$parent = $xml_outline [ 'attributes' ][ 'id' ];
} else {
$parent = time ();
}
if ( $xml_outline [ 'tag' ] == 'outline' && is_array ( $xml_outline [ 'children' ])) {
if ( $serendipity [ 'POST' ][ 'aggregatorOPMLCategories' ] && $parent_id = $this -> fetchCategoryParent ( $parent )) {
printf ( PLUGIN_AGGREGATOR_CATEGORYSKIPPED , $parent );
echo " <br /> \n " ;
} elseif ( $serendipity [ 'POST' ][ 'aggregatorOPMLCategories' ]) {
$parent_id = $this -> newCategory ( $parent , $last_parent_id );
}
foreach ( $xml_outline [ 'children' ] AS $xml_child ) {
$this -> parseOutline ( $xml_child , $parent , $parent_id );
}
} else {
if ( $serendipity [ 'POST' ][ 'aggregatorOPMLCategoriesNoNesting' ]) {
$last_parent_id = $this -> newCategory ( $parent , $last_parent_id );
}
$newfeed = array (
'feedname' => $parent ,
'feedurl' => $xml_outline [ 'attributes' ][ 'xmlUrl' ],
'htmlurl' => $xml_outline [ 'attributes' ][ 'htmlUrl' ],
'categoryid' => $last_parent_id ,
'charset' => ''
);
$this -> insertFeed ( $newfeed );
}
return true ;
}
function & importFeeds () {
// Used by ImportOPML routine
global $serendipity ;
$file = $serendipity [ 'POST' ][ 'aggregatorOPML' ];
2016-09-22 16:03:33 +02:00
if ( function_exists ( 'serendipity_request_url' )) {
$data = serendipity_request_url ( $file );
if ( empty ( $data )) return false ;
2011-12-13 12:29:05 +01:00
} else {
2016-09-22 16:03:33 +02:00
require_once ( defined ( 'S9Y_PEAR_PATH' ) ? S9Y_PEAR_PATH : S9Y_INCLUDE_PATH . 'bundled-libs/' ) . 'HTTP/Request.php' ;
if ( function_exists ( 'serendipity_request_start' )) {
serendipity_request_start ();
}
$req = new HTTP_Request ( $file );
if ( PEAR :: isError ( $req -> sendRequest ()) || $req -> getResponseCode () != '200' ) {
$data = file_get_contents ( $file );
if ( empty ( $data )) {
return false ;
}
} else {
// Fetch file
$data = $req -> getResponseBody ();
}
2011-12-13 12:29:05 +01:00
2016-09-22 16:03:33 +02:00
if ( function_exists ( 'serendipity_request_end' )) {
serendipity_request_end ();
}
2011-12-13 12:29:05 +01:00
}
// XML functions
$xml_string = '<?xml version="1.0" encoding="UTF-8" ?>' ;
if ( preg_match ( '@(<\?xml.+\?>)@imsU' , $data , $xml_head )) {
$xml_string = $xml_head [ 1 ];
}
$encoding = 'UTF-8' ;
if ( preg_match ( '@encoding="([^"]+)"@' , $xml_string , $xml_encoding )) {
$encoding = $xml_encoding [ 1 ];
}
// Global replacements
// by: waldo@wh-e.com - trim space around tags not within
$data = preg_replace ( '@>[[:space:]]+<@i' , '><' , $data );
switch ( strtolower ( $encoding )) {
case 'iso-8859-1' :
case 'utf-8' :
$p = xml_parser_create ( $encoding );
break ;
default :
$p = xml_parser_create ( '' );
}
// by: anony@mous.com - meets XML 1.0 specification
xml_parser_set_option ( $p , XML_OPTION_CASE_FOLDING , 0 );
@ xml_parser_set_option ( $p , XML_OPTION_TARGET_ENCODING , LANG_CHARSET );
xml_parse_into_struct ( $p , $data , $vals , $index );
xml_parser_free ( $p );
$i = 0 ;
$tree = array ();
$tree [] = array (
'tag' => $vals [ $i ][ 'tag' ],
'attributes' => $vals [ $i ][ 'attributes' ],
'value' => $vals [ $i ][ 'value' ],
'children' => $this -> GetChildren ( $vals , $i )
);
return $tree ;
}
function & GetChildren ( $vals , & $i ) {
$children = array ();
$cnt = sizeof ( $vals );
while ( ++ $i < $cnt ) {
// compare type
switch ( $vals [ $i ][ 'type' ]) {
case 'cdata' :
$children [] = $vals [ $i ][ 'value' ];
break ;
case 'complete' :
$children [] = array (
'tag' => $vals [ $i ][ 'tag' ],
'attributes' => $vals [ $i ][ 'attributes' ],
'value' => $vals [ $i ][ 'value' ]
);
break ;
case 'open' :
$children [] = array (
'tag' => $vals [ $i ][ 'tag' ],
'attributes' => $vals [ $i ][ 'attributes' ],
'value' => $vals [ $i ][ 'value' ],
'children' => $this -> GetChildren ( $vals , $i )
);
break ;
case 'close' :
return $children ;
}
}
}
function insertProperties ( $entryid , $feed , $md5hash = null ) {
global $serendipity ;
$sql = " SELECT * FROM { $serendipity [ 'dbPrefix' ] } entryproperties WHERE entryid = $entryid AND property = 'ep_aggregator_feed' " ;
$props = serendipity_db_query ( $sql , true );
if ( ! is_array ( $props ) || empty ( $props [ 'entryid' ])) {
$sql = " INSERT INTO { $serendipity [ 'dbPrefix' ] } entryproperties
( entryid , property , value )
VALUES ( '$entryid' , 'ep_aggregator_feed' , '" . serendipity_db_escape_string($feed[' feedid ']) . "' ) " ;
serendipity_db_query ( $sql );
$sql = " INSERT INTO { $serendipity [ 'dbPrefix' ] } entryproperties
( entryid , property , value )
VALUES ( '$entryid' , 'ep_aggregator_feedname' , '" . serendipity_db_escape_string($feed[' feedname ']) . "' ) " ;
serendipity_db_query ( $sql );
$sql = " INSERT INTO { $serendipity [ 'dbPrefix' ] } entryproperties
( entryid , property , value )
VALUES ( '$entryid' , 'ep_aggregator_feedurl' , '" . serendipity_db_escape_string($feed[' feedurl ']) . "' ) " ;
serendipity_db_query ( $sql );
$sql = " INSERT INTO { $serendipity [ 'dbPrefix' ] } entryproperties
( entryid , property , value )
VALUES ( '$entryid' , 'ep_aggregator_htmlurl' , '" . serendipity_db_escape_string($feed[' htmlurl ']) . "' ) " ;
serendipity_db_query ( $sql );
$sql = " INSERT INTO { $serendipity [ 'dbPrefix' ] } entryproperties
( entryid , property , value )
VALUES ( '$entryid' , 'ep_aggregator_categoryid' , '" . serendipity_db_escape_string($feed[' categoryid ']) . "' ) " ;
serendipity_db_query ( $sql );
$sql = " INSERT INTO { $serendipity [ 'dbPrefix' ] } entryproperties
( entryid , property , value )
VALUES ( '$entryid' , 'ep_aggregator_articleurl' , '" . serendipity_db_escape_string($feed[' articleurl ']) . "' ) " ;
serendipity_db_query ( $sql );
$sql = " INSERT INTO { $serendipity [ 'dbPrefix' ] } entryproperties
( entryid , property , value )
VALUES ( '$entryid' , 'ep_aggregator_author' , '" . serendipity_db_escape_string($feed[' author ']) . "' ) " ;
serendipity_db_query ( $sql );
$sql = " INSERT INTO { $serendipity [ 'dbPrefix' ] } entryproperties
( entryid , property , value )
VALUES ( '$entryid' , 'ep_flattr_active' , '-1' ) " ;
serendipity_db_query ( $sql );
# We will be using this for duplicate detection
# same articleurl and same md5 property -> dupe
$t = time ();
$sql = " INSERT INTO { $serendipity [ 'dbPrefix' ] } aggregator_md5
( entryid , md5 , timestamp )
VALUES ( '$entryid' , '$md5hash' , '$t' ) " ;
serendipity_db_query ( $sql );
}
$this -> feedupdate_finish ( $feed , $entryid );
}
function feedupdate_finish ( & $feed , $entryid ) {
global $serendipity ;
$t = time ();
$sql = " UPDATE { $serendipity [ 'dbPrefix' ] } aggregator_feeds SET last_update = " . time () . " WHERE feedid = " . ( int ) $feed [ 'feedid' ];
serendipity_db_query ( $sql );
if ( empty ( $feed [ 'feedicon' ]) && ! empty ( $feed [ 'new_feedicon' ])) {
$sql = " UPDATE { $serendipity [ 'dbPrefix' ] } aggregator_feeds SET feedicon = ' " . serendipity_db_escape_string ( $feed [ 'new_feedicon' ]) . " ' WHERE feedid = " . ( int ) $feed [ 'feedid' ];
serendipity_db_query ( $sql );
}
# Always update the MD5 hash, to catch updates of an entry properly. Patch by jerwarren!
$sql = " UPDATE { $serendipity [ 'dbPrefix' ] } aggregator_md5 SET timestamp = ' $t ', md5=' $md5hash ' WHERE entryid = " . ( int ) $entryid ;
serendipity_db_query ( $sql );
}
function decode ( $charset , & $array )
{
if ( LANG_CHARSET == 'ISO-8859-1' || LANG_CHARSET == 'UTF-8' )
{
// Luckily PHP5 supports
// xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, LANG_CHARSET);
// which means we need no transcoding here.
return true ;
}
if ( $charset == LANG_CHARSET ) {
return true ;
} elseif ( $charset == 'utf-8' ) {
foreach ( $array AS $key => $val ) {
$array [ $key ] = utf8_decode ( $val );
}
} elseif ( $charset == 'iso-8859-1' ) {
foreach ( $array AS $key => $val ) {
if ( function_exists ( 'iconv' )) {
$array [ $key ] = iconv ( 'ISO-8859-1' , LANG_CHARSET , $val );
} elseif ( function_exists ( 'recode' )) {
$array [ $key ] = recode ( 'iso-8859-1..' . LANG_CHARSET , $val );
}
}
}
return true ;
}
function parseDate ( $time ) {
if ( empty ( $time )) {
if ( $this -> debug ) printf ( " DEBUG: parseDate(%s) is empty \n " , $time );
return - 1 ;
}
$date = strtotime ( $time );
if ( $date > 0 ) {
if ( $this -> debug ) printf ( " DEBUG: parseDate(%s) as %s (strtotime) \n " , $time , date ( 'Y-m-d H:i:s' , $date ));
return $date ;
}
if ( preg_match ( '@^([0-9]{4})\-([0-9]{2})\-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(?::\-([0-9]{2}):([0-9]{2}))?@' , $time , $timematch )) {
$date = mktime ( $timematch [ 4 ] - $timematch [ 7 ], $timematch [ 5 ] - $timematch [ 8 ], $timematch [ 6 ], $timematch [ 2 ], $timematch [ 3 ], $timematch [ 1 ]);
if ( $this -> debug ) printf ( " DEBUG: parseDate(%s) as %s (preg_match) \n " , $time , date ( 'Y-m-d H:i:s' , $date ));
return $date ;
}
if ( $this -> debug ) printf ( " DEBUG: parseDate(%s) is unparseable \n " , $time );
return - 1 ;
}
function checkCharset ( & $feed )
{
global $serendipity ;
2016-09-22 16:03:33 +02:00
if ( function_exists ( 'serendipity_request_url' )) {
$data = serendipity_request_url ( $feed [ 'feedurl' ]);
if ( empty ( $data )) return false ;
2011-12-13 12:29:05 +01:00
} else {
2016-09-22 16:03:33 +02:00
require_once ( defined ( 'S9Y_PEAR_PATH' ) ? S9Y_PEAR_PATH : S9Y_INCLUDE_PATH . 'bundled-libs/' ) . 'HTTP/Request.php' ;
$req = new HTTP_Request ( $feed [ 'feedurl' ]);
if ( PEAR :: isError ( $req -> sendRequest ()) || $req -> getResponseCode () != '200' ) {
$data = file_get_contents ( $feed [ 'feedurl' ]);
if ( empty ( $data )) {
return false ;
}
} else {
# Fetch file
$data = $req -> getResponseBody ();
}
2011-12-13 12:29:05 +01:00
}
#XML functions
$xml_string = '<' . '?xml version="1.0" encoding="UTF-8"?' . '>' ;
if ( preg_match ( '@(\<\?xml.+\?\>)@imsU' , $data , $xml_head )) {
$xml_string = $xml_head [ 1 ];
}
$encoding = 'UTF-8' ;
if ( preg_match ( '@encoding="([^"]+)"@' , $xml_string , $xml_encoding )) {
# may return iso-8859-15 or windows-1252, which are not valid
# for the XML parser in PHP
$encoding = $xml_encoding [ 1 ];
}
if ( preg_match ( '@utf@i' , $encoding )) {
$encoding = " UTF-8 " ;
} else {
$encoding = " iso-8859-1 " ;
}
serendipity_db_query ( " UPDATE { $serendipity [ 'dbPrefix' ] } aggregator_feeds
SET charset = '" . serendipity_db_escape_string($encoding) . "'
WHERE feedid = " . (int) $feed['feedid'] );
$feed [ 'charset' ] = $encoding ;
return $encoding ;
}
function fetchFeeds ( $opt = null )
{
global $serendipity ;
set_time_limit ( 360 );
ignore_user_abort ( true );
$_SESSION [ 'serendipityRightPublish' ] = true ;
$serendipity [ 'noautodiscovery' ] = true ;
$this -> setupDB ();
$feeds = $this -> getFeeds ( $opt );
$engine = $this -> get_config ( 'engine' , 'onyx' );
if ( $engine == 'onyx' ) {
require_once ( defined ( 'S9Y_PEAR_PATH' ) ? S9Y_PEAR_PATH : S9Y_INCLUDE_PATH . 'bundled-libs/' ) . 'Onyx/RSS.php' ;
} elseif ( $engine == 'magpierss' ) {
// CLSC: NEW "MagpieRSS" include
require_once dirname ( __FILE__ ) . '/magpierss/rss_fetch.inc' ;
} elseif ( $engine == 'simplepie' ) {
//hwa: NEW "SimplePie" include
require_once dirname ( __FILE__ ) . '/simplepie/simplepie.inc' ;
}
$cache_authors = array ();
$cache_entries = array ();
$cache_md5 = array ();
$sql_cache_authors = serendipity_db_Query ( " SELECT authorid, realname
FROM { $serendipity [ 'dbPrefix' ]} authors " );
if ( is_array ( $sql_cache_authors )) {
foreach ( $sql_cache_authors AS $idx => $author ) {
$cache_authors [ $author [ 'realname' ]] = $author [ 'authorid' ];
}
}
if ( $this -> debug ) printf ( " DEBUG: cache_authors['realname'] = authorid has %d entries \n " , count ( $cache_authors ));
if ( $opt [ 'store_seperate' ]) {
$sql_cache_entries = serendipity_db_query ( " SELECT e.feedid, e.id, e.entrydate, e.entrytitle
FROM { $serendipity [ 'dbPrefix' ]} aggregator_feedlist AS e " );
if ( is_array ( $sql_cache_entries )) {
foreach ( $sql_cache_entries AS $idx => $entry ) {
$cache_entries [ $entry [ 'entrytitle' ]][ $entry [ 'feedid' ]][ $entry [ 'entrydate' ]] = $entry [ 'id' ];
}
}
} else {
$sql_cache_entries = serendipity_db_query ( " SELECT e.id, e.timestamp, e.authorid, e.title, ep.value
FROM { $serendipity [ 'dbPrefix' ]} entries AS e ,
{ $serendipity [ 'dbPrefix' ]} entryproperties AS ep
WHERE e . id = ep . entryid
AND ep . property = 'ep_aggregator_feed' " );
if ( is_array ( $sql_cache_entries )) {
foreach ( $sql_cache_entries AS $idx => $entry ) {
$cache_entries [ $entry [ 'title' ]][ $entry [ 'authorid' ]][ $entry [ 'timestamp' ]] = $entry [ 'id' ];
}
}
}
if ( $this -> debug ) printf ( " DEBUG: cache_entries['title']['authorid']['timestamp'] = entryid has %d entries. \n " , count ( $cache_entries ));
$sql_cache_md5 = serendipity_db_query ( " SELECT entryid, md5, timestamp
FROM { $serendipity [ 'dbPrefix' ]} aggregator_md5 " );
if ( is_array ( $sql_cache_md5 )) {
foreach ( $sql_cache_md5 AS $idx => $entry ) {
$cache_md5 [ $entry [ 'md5' ]][ 'entryid' ] = $entry [ 'entryid' ];
$cache_md5 [ $entry [ 'md5' ]][ 'timestamp' ] = $entry [ 'timestamp' ];
}
}
if ( $this -> debug ) printf ( " DEBUG: cache_md5['md5'] = entryid has %d entries. \n " , count ( $cache_md5 ));
foreach ( $feeds AS $feed ) {
if ( ! $opt [ 'store_seperate' ]) printf ( " Read %s. \n " , $feed [ 'feedurl' ]);
flush ();
$feed_authorid = $cache_authors [ $feed [ 'feedname' ]];
if ( empty ( $feed_authorid ))
{
$feed_authorid = 0 ;
}
if ( $this -> debug ) printf ( " DEBUG: Current authorid = %d \n " , $feed_authorid );
$stack = array ();
if ( $engine == 'onyx' ) {
if ( empty ( $feed [ 'charset' ])) {
$this -> checkCharset ( $feed );
}
# test multiple likely charsets
$charsets = array ( $feed [ 'charset' ], " ISO-8859-1 " , " utf-8 " );
$retry = false ;
foreach ( $charsets as $ch ) {
if ( $retry ) printf ( " DEBUG: Retry with charset %s instead of %s \n " , $ch , $feed [ 'charset' ]);
$retry = true ;
$c = new Onyx_RSS ( $ch );
# does it parse? if so, all is fine...
if ( $c -> parse ( $feed [ 'feedurl' ]))
break ;
}
while ( $item = $c -> getNextItem ()) {
/* Okay this is where things get tricky . Everybody
* encodes their information differently . For now I ' m going to focus on
* s9y weblogs . */
$fake_timestamp = false ;
$date = $this -> parseDate ( $item [ 'pubdate' ]);
if ( $this -> debug ) printf ( " DEBUG: pubDate %s = %s \n " , $item [ 'pubdate' ], $date );
if ( $date == - 1 ) {
// Fallback to try for dc:date
$date = $this -> parseDate ( $item [ 'dc:date' ]);
if ( $this -> debug ) printf ( " DEBUG: falling back to dc:date % s= %s \n " , $item [ 'dc:date' ], $date );
}
if ( $date == - 1 ) {
// Couldn't figure out the date string. Set it to "now" and hope that the md5hash will get it.
$date = time ();
$fake_timestamp = true ;
if ( $this -> debug ) printf ( " DEBUG: falling back to time() = %s \n " , $date );
}
if ( empty ( $item [ 'title' ])) {
if ( $this -> debug ) printf ( " DEBUG: skip item: title was empty for %s \n " , print_r ( $item , true ));
continue ;
}
$this -> decode ( $c -> rss [ 'encoding' ], $item );
$item [ 'date' ] = $date ;
$stack [] = $item ;
}
} elseif ( $engine == 'magpierss' ) {
// ----------------------------------------------------------
// CLSC: New MagpieRSS code start
// ----------------------------------------------------------
$rss = fetch_rss ( $feed [ 'feedurl' ]);
foreach ( $rss -> items as $item ) {
$fake_timestamp = false ;
$date = $item [ 'pubdate' ];
if ( $this -> debug ) printf ( " DEBUG: pubdate = %s \n " , $item [ 'pubdate' ], $date );
// ----------------------------------------------------------
// CLSC: Try a few different types of timestamp fields
// So that we might get lucky even with non-standard feeds
// ----------------------------------------------------------
if ( $date == " " ) {
// CLSC: magpie syntax for nested fields
$date = $item [ 'dc' ][ 'date' ];
if ( $this -> debug ) printf ( " DEBUG: falling back to [dc][date] = %s \n " , $item [ 'dc:date' ], $date );
}
if ( $date == " " ) {
$date = $item [ 'modified' ];
if ( $this -> debug ) printf ( " DEBUG: falling back to modified = %s \n " , $item [ 'modified' ], $date );
}
if ( $date == " " ) {
$date = $item [ 'PubDate' ];
if ( $this -> debug ) printf ( " DEBUG: falling back PubDate = %s \n " , $item [ 'PubDate' ], $date );
}
if ( $date == " " ) {
$date = $item [ 'created' ];
if ( $this -> debug ) printf ( " DEBUG: falling back to created = %s \n " , $item [ 'created' ], $date );
}
if ( $date == " " ) {
// CLSC: not proper magpie syntax but still catches some
$date = $item [ 'dc:date' ];
if ( $this -> debug ) printf ( " DEBUG: falling back to dc:date = %s \n " , $item [ 'dc:date' ], $date );
}
if ( $date == " " ) {
$date = $item [ 'updated' ];
if ( $this -> debug ) printf ( " DEBUG: falling back to updated = %s \n " , $item [ 'updated' ], $date );
}
if ( $date == " " ) {
$date = $item [ 'published' ];
if ( $this -> debug ) printf ( " DEBUG: falling back to published = %s \n " , $item [ 'published' ], $date );
}
if ( $date == " " ) {
// ----------------------------------------------------------
// CLSC: If none of the above managed to identify a date:
// Set date to "now" and hope that the md5hash will get it.
// ----------------------------------------------------------
$date = time ();
$fake_timestamp = true ;
if ( $this -> debug ) printf ( " DEBUG: falling back to time() = %s \n " , $date );
}
// CLSC: if date is set to "now" parseDate can't parse it.
if ( $fake_timestamp != true ) {
$date = $this -> parseDate ( $date );
}
if ( $item [ 'title' ] == " " ) {
if ( $this -> debug ) printf ( " DEBUG: skip item: title was empty for %s \n " , print_r ( $item , true ));
continue ;
}
$item [ 'date' ] = $date ;
$stack [] = $item ;
// ----------------------------------------------------------
// CLSC: New MagpieRSS code end
// ----------------------------------------------------------
}
} elseif ( $engine == 'simplepie' ) {
// hwa: new SimplePie code ; lifted from the SimplePie demo
$simplefeed = new SimplePie ();
$simplefeed -> cache = false ;
$simplefeed -> set_feed_url ( $feed [ 'feedurl' ]);
// Initialize the whole SimplePie object. Read the feed, process it, parse it, cache it, and
// all that other good stuff. The feed's information will not be available to SimplePie before
// this is called.
$success = $simplefeed -> init ();
// We'll make sure that the right content type and character encoding gets set automatically.
// This function will grab the proper character encoding, as well as set the content type to text/html.
$simplefeed -> set_output_encoding ( LANG_CHARSET );
$simplefeed -> handle_content_type ();
$item [ 'new_feedicon' ] = $simplefeed -> get_favicon ();
// error handling
if ( $simplefeed -> error ()) {
2014-11-25 01:15:57 +01:00
if ( ! $opt [ 'store_seperate' ]) printf ( '<p><b>ERROR:</b> ' . ( function_exists ( 'serendipity_specialchars' ) ? serendipity_specialchars ( $simplefeed -> error ()) : htmlspecialchars ( $simplefeed -> error (), ENT_COMPAT , LANG_CHARSET )) . " </p> \r \n " ) ;
2011-12-13 12:29:05 +01:00
}
if ( $success ) {
foreach ( $simplefeed -> get_items () as $simpleitem ) {
// map SimplePie items to s9y items
$item [ 'title' ] = $simpleitem -> get_title () ;
$item [ 'date' ] = $simpleitem -> get_date ( 'U' );
$item [ 'pubdate' ] = $simpleitem -> get_date ( 'U' );
$item [ 'description' ] = $simpleitem -> get_description ();
$item [ 'content' ] = $simpleitem -> get_content ();
$item [ 'link' ] = $simpleitem -> get_permalink ();
$item [ 'author' ] = $simpleitem -> get_author ();
//if ($this->debug) {
// printf("DEBUG: SimplePie item: author: $item['author'], title: $item['title'], date: $item['date']\n");
//}
$stack [] = $item ;
}
} else {
if ( ! $opt [ 'store_seperate' ]) printf ( '<p><b>ERROR:</b> ' . print_r ( $success , true ) . " </p> \r \n " ) ;
}
}
while ( list ( $key , $item ) = each ( $stack )) {
if ( $opt [ 'store_seperate' ]) {
$ep_id = $cache_entries [ $item [ 'title' ]][ $feed [ 'feedid' ]][ $item [ 'date' ]];
if ( $this -> debug ) {
printf ( " DEBUG: lookup cache_entries[%s][%s][%s] finds %s. \n " ,
$item [ 'title' ],
$feed [ 'feedid' ],
$item [ 'date' ],
empty ( $ep_id ) ? " nothing " : $ep_id
);
}
} else {
$ep_id = $cache_entries [ $item [ 'title' ]][ $feed_authorid ][ $item [ 'date' ]];
if ( $this -> debug ) {
printf ( " DEBUG: lookup cache_entries[%s][%s][%s] finds %s. \n " ,
$item [ 'title' ],
$feed_authorid ,
$item [ 'date' ],
empty ( $ep_id ) ? " nothing " : $ep_id
);
}
}
if ( ! empty ( $ep_id ) and serendipity_db_bool ( $this -> get_config ( 'ignore_updates' ))) {
if ( $this -> debug ) printf ( " DEBUG: entry %s is known and ignore_updates is set. \n " , $ep_id );
continue ;
}
# NOTE: If $ep_id is NULL or EMPTY, it means that an entry with this title does not
# yet exist. Later on we check if a similar entry with the body exists and skip
# updates in this case. Else it means that the new entry needs to be inserted
# as a new one.
# The entry is probably new?
$entry = array ( 'id' => $ep_id ,
'title' => $item [ 'title' ],
'timestamp' => $item [ 'date' ],
'extended' => '' ,
'isdraft' => serendipity_db_bool ( $this -> get_config ( 'publishflag' )) ? 'false' : 'true' ,
'allow_comments' => serendipity_db_bool ( $this -> get_config ( 'allow_comments' )) ? 'true' : 'false' ,
'categories' => $feed [ 'categoryids' ],
'author' => $feed [ 'feedname' ],
'authorid' => $feed_authorid );
// ----------------------------------------------------------
// CLSC: Added a few flavours
if ( $item [ 'content:encoded' ]) {
$entry [ 'body' ] = $item [ 'content:encoded' ];
} elseif ( $item [ 'description' ]) {
$entry [ 'body' ] = $item [ 'description' ];
} elseif ( $item [ 'content' ][ 'encoded' ]) {
$entry [ 'body' ] = $item [ 'content' ][ 'encoded' ];
} elseif ( $item [ 'atom_content' ]) {
$entry [ 'body' ] = $item [ 'atom_content' ];
} elseif ( $item [ 'content' ]) {
$entry [ 'body' ] = $item [ 'content' ];
}
$md5hash = md5 ( $feed_authorid . $item [ 'title' ] . $entry [ 'body' ]);
# Check 1: Have we seen this MD5?
if ( $this -> debug ) {
printf ( " DEBUG: lookup cache_md5[%s] finds %s. \n " ,
$md5hash ,
empty ( $cache_md5 [ $md5hash ]) ? " nothing " : $cache_md5 [ $md5hash ][ 'entryid' ]
);
}
# If we have this md5, title and body for this article
# are unchanged. We do not need to do anything.
if ( isset ( $cache_md5 [ $md5hash ])) {
continue ;
}
# Check 2 (conditional: expire enabled?):
# Is this article too old?
if ( $this -> get_config ( 'expire' ) > 0 ) {
$expire = time () - 86400 * $this -> get_config ( 'expire' );
if ( $item [ 'date' ] < $expire ) {
if ( $this -> debug ) printf ( " DEBUG: '%s' is too old (%s < %s). \n " , $item [ 'title' ], $item [ 'date' ] , $expire );
continue ;
}
}
# Check 3: Does this article match our expressions?
if ( ! empty ( $feed [ 'match_expression' ])) {
$expressions = explode ( " ~ " , $feed [ 'match_expression' ]);
$match = 0 ;
foreach ( $expressions as $expression ) {
$expression = ltrim ( rtrim ( $expression ));
if ( preg_match ( " ~ $expression ~imsU " , $entry [ 'title' ] . $entry [ 'body' ])) {
$match = 1 ;
}
}
if ( $match == 0 ) {
continue ;
}
}
$feed [ 'articleurl' ] = $item [ 'link' ];
if ( $item [ 'author' ]) {
$feed [ 'author' ] = $item [ 'author' ];
} elseif ( $item [ 'dc:creator' ]) {
$feed [ 'author' ] = $item [ 'dc:creator' ];
}
// Store as property
// Plugins might need this.
$serendipity [ 'POST' ][ 'properties' ] = array ( 'fake' => 'fake' );
$markups = explode ( '^' , $this -> get_config ( 'markup' ));
if ( is_array ( $markups )) {
foreach ( $markups AS $markup ) {
$serendipity [ 'POST' ][ 'properties' ][ 'disable_markups' ][] = $markup ;
}
}
if ( $opt [ 'store_seperate' ]) {
if ( $entry [ 'id' ] > 0 ) {
serendipity_db_query ( " UPDATE { $serendipity [ 'dbPrefix' ] } aggregator_feedlist
SET feedid = '" . $feed[' feedid '] . "' ,
categoryid = '" . $feed[' categoryids '][0] . "' ,
entrydate = '" . serendipity_db_escape_string($entry[' timestamp ']) . "' ,
entrytitle = '" . serendipity_db_escape_string($entry[' title ']) . "' ,
entrybody = '" . serendipity_db_escape_string($entry[' body ']) . "' ,
entryurl = '" . serendipity_db_escape_string($item[' link ']) . "'
WHERE id = " . $entry['id'] );
$entryid = $entry [ 'id' ];
} else {
serendipity_db_query ( " INSERT INTO { $serendipity [ 'dbPrefix' ] } aggregator_feedlist (
feedid ,
categoryid ,
entrydate ,
entrytitle ,
entrybody ,
entryurl
) VALUES (
'" . $feed[' feedid '] . "' ,
'" . $feed[' categoryids '][0] . "' ,
'" . serendipity_db_escape_string($entry[' timestamp ']) . "' ,
'" . serendipity_db_escape_string($entry[' title ']) . "' ,
'" . serendipity_db_escape_string($entry[' body ']) . "' ,
'" . serendipity_db_escape_string($item[' link ']) . "'
) " );
$entryid = serendipity_db_insert_id ();
}
$this -> feedupdate_finish ( $feed , $entryid );
} else {
$entryid = serendipity_updertEntry ( $entry );
$this -> insertProperties ( $entryid , $feed , $md5hash );
}
if ( ! $opt [ 'store_seperate' ]) printf ( " Save '%s' as %s. \n " , $item [ 'title' ], $entryid );
}
if ( ! $opt [ 'store_seperate' ]) printf ( " Finish feed. \n " );
}
if ( ! $opt [ 'store_seperate' ]) printf ( " Finish planetarium. \n " );
}
function generate_content ( & $title ) {
$title = PLUGIN_AGGREGATOR_TITLE ;
}
function showRecursive ( $ary , & $xml , $child_name = 'id' , $parent_name = 'parent_id' , $parentid = 0 ) {
global $serendipity ;
if ( sizeof ( $ary ) == 0 ) {
return array ();
}
if ( $parentid === VIEWMODE_THREADED ) {
$parentid = 0 ;
}
foreach ( $ary as $data ) {
if ( $parentid === VIEWMODE_LINEAR || ! isset ( $data [ $parent_name ]) || $data [ $parent_name ] == $parentid ) {
echo '<outline title="' . serendipity_utf8_encode ( $data [ 'category_name' ]) . '">' . " \n " ;
if ( is_array ( $xml [ $data [ 'categoryid' ]])) {
foreach ( $xml [ $data [ 'categoryid' ]] AS $feed ) {
if ( empty ( $feed [ 'feedurl' ])) {
continue ;
}
printf ( ' <outline title="%s" xmlUrl="%s" htmlUrl="%s" description="%s" />' . " \n " ,
2014-11-25 01:15:57 +01:00
serendipity_utf8_encode (( function_exists ( 'serendipity_specialchars' ) ? serendipity_specialchars ( $feed [ 'feedname' ]) : htmlspecialchars ( $feed [ 'feedname' ], ENT_COMPAT , LANG_CHARSET ))),
serendipity_utf8_encode (( function_exists ( 'serendipity_specialchars' ) ? serendipity_specialchars ( $feed [ 'feedurl' ]) : htmlspecialchars ( $feed [ 'feedurl' ], ENT_COMPAT , LANG_CHARSET ))),
serendipity_utf8_encode (( function_exists ( 'serendipity_specialchars' ) ? serendipity_specialchars ( $feed [ 'htmlurl' ]) : htmlspecialchars ( $feed [ 'htmlurl' ], ENT_COMPAT , LANG_CHARSET ))),
serendipity_utf8_encode (( function_exists ( 'serendipity_specialchars' ) ? serendipity_specialchars ( $feed [ 'feedname' ]) : htmlspecialchars ( $feed [ 'feedname' ], ENT_COMPAT , LANG_CHARSET )))
2011-12-13 12:29:05 +01:00
);
}
}
if ( $data [ $child_name ] && $parentid !== VIEWMODE_LINEAR ) {
$this -> showRecursive ( $ary , $xml , $child_name , $parent_name , $data [ $child_name ]);
}
echo " </outline> \n " ;
}
}
return true ;
}
function parseShowFeed ( & $eventData ) {
global $serendipity ;
$cmd = explode ( '|' , $eventData );
$opt = array ();
foreach ( $cmd AS $cmdpart ) {
$cmdpart = trim ( $cmdpart );
$cmdpart2 = explode ( ':' , $cmdpart );
if ( ! empty ( $cmdpart ) && ! empty ( $cmdpart2 [ 1 ])) {
$opt [ $cmdpart2 [ 0 ]] = $cmdpart2 [ 1 ];
}
}
if ( empty ( $opt [ 'cachetime' ])) {
$opt [ 'cachetime' ] = 3600 ;
}
if ( empty ( $opt [ 'template' ])) {
$opt [ 'template' ] = 'feedlist.tpl' ;
}
$opt [ 'store_seperate' ] = true ;
$fkey = 'last_showfeed_' . md5 ( serialize ( $opt ));
if ( time () - $this -> get_config ( $fkey ) > $opt [ 'cachetime' ]) {
$this -> set_config ( $fkey , time ());
$this -> fetchFeeds ( $opt );
}
$q = " SELECT fl.*,
f . feedname ,
f . htmlurl ,
f . feedicon
FROM { $serendipity [ 'dbPrefix' ]} aggregator_feedlist AS fl
LEFT OUTER JOIN { $serendipity [ 'dbPrefix' ]} aggregator_feedlist AS fl2
ON ( fl . feedid = fl2 . feedid AND fl . entrydate < fl2 . entrydate )
JOIN { $serendipity [ 'dbPrefix' ]} aggregator_feeds AS f
ON fl . feedid = f . feedid
WHERE fl2 . feedid IS NULL
" . ( $opt['category'] > 0 ? " AND fl . categoryid IN ( " . $opt['category'] . " ) " : " " ) . "
GROUP BY fl . feedid
ORDER BY fl . entrydate DESC
" ;
/*
$q = " SELECT fl.*,
f . feedname ,
f . htmlurl ,
f . feedicon
FROM { $serendipity [ 'dbPrefix' ]} aggregator_feedlist AS fl
JOIN { $serendipity [ 'dbPrefix' ]} aggregator_feeds AS f
ON fl . feedid = f . feedid
" . ( $opt['category'] > 0 ? " WHERE fl . categoryid IN ( " . $opt['category'] . " ) " : " " ) . "
GROUP BY fl . feedid
ORDER BY fl . entrydate DESC
" ;
*/
$show = serendipity_db_query ( $q );
$serendipity [ 'smarty' ] -> assign ( 'feedlist_entries' , $show );
echo $this -> parse_template ( $opt [ 'template' ]);
//
// Feed Icon parsen und in feeds speichern
return true ;
}
2016-10-26 15:07:46 +02:00
2011-12-13 12:29:05 +01:00
function parse_template ( $filename ) {
global $serendipity ;
$filename = basename ( $filename );
$tfile = serendipity_getTemplateFile ( $filename , 'serendipityPath' );
if ( ! $tfile || $tfile == $filename ) {
$tfile = dirname ( __FILE__ ) . '/' . $filename ;
}
$inclusion = $serendipity [ 'smarty' ] -> security_settings [ INCLUDE_ANY ];
$serendipity [ 'smarty' ] -> security_settings [ INCLUDE_ANY ] = true ;
$content = $serendipity [ 'smarty' ] -> fetch ( 'file:' . $tfile );
$serendipity [ 'smarty' ] -> security_settings [ INCLUDE_ANY ] = $inclusion ;
return $content ;
}
2012-06-13 14:47:45 +02:00
function event_hook ( $event , & $bag , & $eventData , $addData = null ) {
2011-12-13 12:29:05 +01:00
global $serendipity ;
$hooks = & $bag -> get ( 'event_hooks' );
$this -> debug = serendipity_db_bool ( $this -> get_config ( 'debug' ));
if ( isset ( $hooks [ $event ])) {
switch ( $event ) {
case 'backend_sidebar_entries' :
if ( $serendipity [ 'serendipityUserlevel' ] >= USERLEVEL_CHIEF ) {
2014-06-07 11:32:13 +02:00
if ( $serendipity [ 'version' ][ 0 ] == '1' ) {
2011-12-13 12:29:05 +01:00
?>
2014-06-07 11:32:13 +02:00
< li class = " serendipitySideBarMenuLink serendipitySideBarMenuEntryLinks " >< a href = " ?serendipity[adminModule]=event_display&serendipity[adminAction]=aggregator " >< ? php echo PLUGIN_AGGREGATOR_TITLE ; ?> </a></li>
2011-12-13 12:29:05 +01:00
< ? php
2014-06-07 11:32:13 +02:00
} else {
?>
< li >< a href = " ?serendipity[adminModule]=event_display&serendipity[adminAction]=aggregator " >< ? php echo PLUGIN_AGGREGATOR_TITLE ; ?> </a></li>
< ? php
}
2011-12-13 12:29:05 +01:00
}
break ;
case 'backend_sidebar_entries_event_display_aggregator' :
$this -> showFeeds ();
break ;
case 'cronjob' :
if ( $this -> get_config ( 'cronjob' ) == $eventData ) {
serendipity_event_cronjob :: log ( 'Aggregator' , 'plugin' );
$this -> fetchFeeds ();
# Fetch first, expire later (some feeds offer old stuff)
$this -> expireFeeds ();
}
return true ;
break ;
case 'aggregator_feedlist' :
$this -> parseShowFeed ( $eventData );
return true ;
break ;
case 'external_plugin' :
if ( $eventData == 'opmlfeeds.xml' ) {
header ( 'Content-Type: text/xml; charset=utf-8' );
echo '<?xml version="1.0" encoding="utf-8" ?>' . " \n " ;
$modified = gmdate ( 'D, d M Y H:i:s \G\M\T' , serendipity_serverOffsetHour ( time (), true ));
print <<< EOF
< opml version = " 1.0 " >
< head >
< title > { $serendipity [ 'blogTitle' ]} </ title >
< dateModified > { $modified } </ dateModified >
< ownerName > Serendipity - http :// www . s9y . org /</ ownerName >
</ head >
< body >
EOF ;
$feeds = serendipity_db_Query ( "
SELECT c . categoryid ,
f . feedname ,
f . feedurl ,
f . htmlurl
FROM { $serendipity [ 'dbPrefix' ]} category AS c
LEFT JOIN { $serendipity [ 'dbPrefix' ]} aggregator_feedcat AS fc
ON fc . categoryid = c . categoryid
LEFT JOIN { $serendipity [ 'dbPrefix' ]} aggregator_feeds AS f
ON fc . feedid = f . feedid " , false, 'assoc');
$xml = array ();
if ( is_array ( $feeds )) {
foreach ( $feeds AS $feed ) {
$xml [ $feed [ 'categoryid' ]][] = $feed ;
}
}
if ( is_array ( $cats = serendipity_fetchCategories ())) {
$cats = $this -> showRecursive ( $cats , $xml , 'categoryid' , 'parentid' , VIEWMODE_THREADED );
}
print " </body> \n </opml> " ;
return ;
}
if ( $eventData != 'aggregator' ) {
return ;
}
$this -> fetchFeeds ();
# Fetch first, expire later (some feeds offer old stuff)
$this -> expireFeeds ();
break ;
}
}
return true ;
}
}
2016-10-26 15:07:46 +02:00
/* vim: set sts=4 ts=4 expandtab : */