| 1 |
<?php |
<?php |
| 2 |
/* $Id: aggregator2.module,v 1.31.2.1 2005-12-15 10:43:31 ahwayakchih Exp $ */ |
/* $Id: aggregator2.module,v 1.31.2.2 2006/02/03 10:02:15 ahwayakchih Exp $ */ |
| 3 |
|
|
| 4 |
/** |
/** |
| 5 |
* @file |
* @file |
| 32 |
|
|
| 33 |
define("AGGREGATOR2_PERM_EDIT_OWN_FEED_TAXONOMY", "edit own feed taxonomy"); |
define("AGGREGATOR2_PERM_EDIT_OWN_FEED_TAXONOMY", "edit own feed taxonomy"); |
| 34 |
define("AGGREGATOR2_PERM_EDIT_OWN_ITEM_TAXONOMY", "edit own item taxonomy"); |
define("AGGREGATOR2_PERM_EDIT_OWN_ITEM_TAXONOMY", "edit own item taxonomy"); |
| 35 |
|
define("AGGREGATOR2_PERM_ACCESS_VOCABS", "see all vocabularies on edit page"); |
| 36 |
|
|
| 37 |
define("AGGREGATOR2_PERM_ACCESS_FEED", "access feeds"); |
define("AGGREGATOR2_PERM_ACCESS_FEED", "access feeds"); |
| 38 |
define("AGGREGATOR2_PERM_ACCESS_ITEM", "access feed items"); |
define("AGGREGATOR2_PERM_ACCESS_ITEM", "access feed items"); |
| 100 |
* Implementation of hook_perm(). |
* Implementation of hook_perm(). |
| 101 |
*/ |
*/ |
| 102 |
function aggregator2_perm() { |
function aggregator2_perm() { |
| 103 |
return array(AGGREGATOR2_PERM_CREATE_FEED, AGGREGATOR2_PERM_EDIT_OWN_FEED, AGGREGATOR2_PERM_EDIT_OWN_ITEM, AGGREGATOR2_PERM_REFRESH_OWN_FEED, AGGREGATOR2_PERM_ACCESS_FEED, AGGREGATOR2_PERM_ACCESS_ITEM, AGGREGATOR2_PERM_EDIT_OWN_FEED_TAXONOMY, AGGREGATOR2_PERM_EDIT_OWN_ITEM_TAXONOMY); |
return array(AGGREGATOR2_PERM_CREATE_FEED, AGGREGATOR2_PERM_EDIT_OWN_FEED, AGGREGATOR2_PERM_EDIT_OWN_ITEM, AGGREGATOR2_PERM_REFRESH_OWN_FEED, AGGREGATOR2_PERM_ACCESS_FEED, AGGREGATOR2_PERM_ACCESS_ITEM, AGGREGATOR2_PERM_EDIT_OWN_FEED_TAXONOMY, AGGREGATOR2_PERM_EDIT_OWN_ITEM_TAXONOMY, AGGREGATOR2_PERM_ACCESS_VOCABS); |
| 104 |
} |
} |
| 105 |
|
|
| 106 |
/** |
/** |
| 169 |
if (($node->item_show_link == AGGREGATOR2_SHOW_LINK_ALWAYS) || |
if (($node->item_show_link == AGGREGATOR2_SHOW_LINK_ALWAYS) || |
| 170 |
($teaser && $node->item_show_link == AGGREGATOR2_SHOW_LINK_TEASER_ONLY) || |
($teaser && $node->item_show_link == AGGREGATOR2_SHOW_LINK_TEASER_ONLY) || |
| 171 |
(!$teaser && $node->item_show_link == AGGREGATOR2_SHOW_LINK_PAGE_ONLY)) { |
(!$teaser && $node->item_show_link == AGGREGATOR2_SHOW_LINK_PAGE_ONLY)) { |
| 172 |
if ($node->type == 'aggregator2-item') { |
if ($node->type == 'aggregator2_item') { |
| 173 |
$links[] = '<a href="'. $node->link .'">'. t('full article') .'</a>'; |
$links[] = theme('aggregator2_link_full_article', $node); |
| 174 |
} |
} |
| 175 |
else if ($node->type == 'aggregator2-feed') { |
else if ($node->type == 'aggregator2_feed') { |
| 176 |
$links[] = '<a href="'. $node->link .'">'. t('visit site') .'</a>'; |
$links[] = theme('aggregator2_link_visit_site', $node); |
| 177 |
} |
} |
| 178 |
} |
} |
| 179 |
global $user; |
global $user; |
| 213 |
break; |
break; |
| 214 |
} |
} |
| 215 |
} |
} |
| 216 |
|
if (!aggregator2_is_valid_url($node->url)) { |
| 217 |
|
form_set_error('url', t('That URL is not allowed.')); |
| 218 |
|
} |
| 219 |
} |
} |
| 220 |
|
|
| 221 |
// Remove "empty" terms |
// Remove "empty" terms |
| 236 |
// TODO: it uses url field as a way to check if it was edited already or not. I didn't want to add special idden field for that, but maybe that would be a better way? |
// TODO: it uses url field as a way to check if it was edited already or not. I didn't want to add special idden field for that, but maybe that would be a better way? |
| 237 |
global $AGGREGATOR2_REFRESH_FEED_RUNNING; |
global $AGGREGATOR2_REFRESH_FEED_RUNNING; |
| 238 |
if (!$AGGREGATOR2_REFRESH_FEED_RUNNING && (!user_access('administer nodes') || (!$node->nid && !isset($node->url)))) { |
if (!$AGGREGATOR2_REFRESH_FEED_RUNNING && (!user_access('administer nodes') || (!$node->nid && !isset($node->url)))) { |
| 239 |
$options = variable_get('aggregator2_feed_defs', array('freezed' => 0, 'update_items' => 1, 'item_status' => 1)); |
$options = variable_get('aggregator2_feed_defs', array('refresh' => 3600, 'freezed' => 0, 'enable_block' => 0, 'update_items' => 1, 'item_status' => 1)); |
| 240 |
|
$node->refresh = $options['refresh']; |
| 241 |
$node->update_items = $options['update_items']; |
$node->update_items = $options['update_items']; |
| 242 |
$node->item_status = $options['item_status']; |
$node->item_status = $options['item_status']; |
| 243 |
$node->item_delete_mode = $options['item_delete_mode']; |
$node->item_delete_mode = $options['item_delete_mode']; |
| 244 |
$node->clear_items = $options['clear_items']; |
$node->clear_items = $options['clear_items']; |
| 245 |
$node->promoted_items = $options['promoted_items']; |
$node->promoted_items = $options['promoted_items']; |
| 246 |
$node->freezed = $options['freezed']; |
$node->freezed = $options['freezed']; |
| 247 |
|
$node->enable_block = $options['enable_block']; |
| 248 |
$node->change_existing_items = $options['change_existing_items']; |
$node->change_existing_items = $options['change_existing_items']; |
| 249 |
$node->guid_items = $options['guid_items']; |
$node->guid_items = $options['guid_items']; |
| 250 |
$node->item_date_source = $options['item_date_source']; |
$node->item_date_source = $options['item_date_source']; |
| 251 |
$node->item_show_link = $options['item_show_link']; |
$node->item_show_link = $options['item_show_link']; |
| 252 |
} |
} |
| 253 |
} |
} |
| 254 |
|
else if ($node->type == 'aggregator2-item') { |
| 255 |
|
if ($node->link && !aggregator2_is_valid_url($node->link)) { |
| 256 |
|
form_set_error('url', t('That URL is not allowed.')); |
| 257 |
|
} |
| 258 |
|
} |
| 259 |
} |
} |
| 260 |
|
|
| 261 |
/** |
/** |
| 270 |
} |
} |
| 271 |
} |
} |
| 272 |
|
|
| 273 |
db_query("INSERT INTO {aggregator2_feed} (nid, author, url, image, freezed, refresh, clear_items, update_items, guid_items, promoted_items, item_status, item_taxonomy, item_date_source, item_show_link, item_delete_mode) VALUES (%d, '%s', '%s', '%s', %d, %d, %d, %d, %d, %d, %d, '%s', %d, %d, %d)", $node->nid, $node->author, $node->url, $node->image, $node->freezed, $node->refresh, $node->clear_items, $node->update_items, $node->guid_items, $node->promoted_items, $node->item_status, serialize($node->feed_item_taxonomy), $node->item_date_source, $node->item_show_link, $node->item_delete_mode); |
db_query("INSERT INTO {aggregator2_feed} (nid, author, url, image, freezed, enable_block, refresh, clear_items, update_items, guid_items, promoted_items, item_status, item_taxonomy, item_date_source, item_show_link, item_delete_mode) VALUES (%d, '%s', '%s', '%s', %d, %d, %d, %d, %d, %d, %d, %d, '%s', %d, %d, %d)", $node->nid, $node->author, $node->url, $node->image, $node->freezed, $node->enable_block, $node->refresh, $node->clear_items, $node->update_items, $node->guid_items, $node->promoted_items, $node->item_status, serialize($node->feed_item_taxonomy), $node->item_date_source, $node->item_show_link, $node->item_delete_mode); |
| 274 |
|
|
| 275 |
cache_clear_all('aggregator2:block:sources'); |
cache_clear_all('aggregator2:block:sources'); |
| 276 |
} |
} |
| 277 |
else if ($node->type == 'aggregator2-item') { |
else if ($node->type == 'aggregator2-item') { |
| 278 |
db_query("INSERT INTO {aggregator2_item} (nid, fid, author, link, guid, source_link, source_title) VALUES (%d, %d, '%s', '%s', '%s', '%s', '%s')", $node->nid, $node->fid, $node->author, $node->link, $node->guid, $node->source_link, $node->source_title); |
db_query("INSERT INTO {aggregator2_item} (nid, fid, author, link, guid, source_link, source_xml, source_title) VALUES (%d, %d, '%s', '%s', '%s', '%s', '%s', '%s')", $node->nid, $node->fid, $node->author, $node->link, $node->guid, $node->source_link, $node->source_xml, $node->source_title); |
| 279 |
} |
} |
| 280 |
} |
} |
| 281 |
|
|
| 291 |
} |
} |
| 292 |
} |
} |
| 293 |
|
|
| 294 |
db_query("UPDATE {aggregator2_feed} SET author = '%s', url = '%s', freezed = %d, refresh = %d, clear_items = %d, update_items = %d, guid_items = %d, promoted_items = %d, checked = %d, link = '%s', image = '%s', etag = '%s', modified = %d, item_status = %d, item_taxonomy = '%s', item_date_source = %d, item_show_link = %d, item_delete_mode = %d WHERE nid = %d", $node->author, $node->url, $node->freezed, $node->refresh, $node->clear_items, $node->update_items, $node->guid_items, $node->promoted_items, $node->checked, $node->link, $node->image, $node->etag, $node->modified, $node->item_status, serialize($node->feed_item_taxonomy), $node->item_date_source, $node->item_show_link, $node->item_delete_mode, $node->nid); |
db_query("UPDATE {aggregator2_feed} SET author = '%s', url = '%s', freezed = %d, enable_block = %d, refresh = %d, clear_items = %d, update_items = %d, guid_items = %d, promoted_items = %d, checked = %d, link = '%s', image = '%s', etag = '%s', modified = %d, item_status = %d, item_taxonomy = '%s', item_date_source = %d, item_show_link = %d, item_delete_mode = %d WHERE nid = %d", $node->author, $node->url, $node->freezed, $node->enable_block, $node->refresh, $node->clear_items, $node->update_items, $node->guid_items, $node->promoted_items, $node->checked, $node->link, $node->image, $node->etag, $node->modified, $node->item_status, serialize($node->feed_item_taxonomy), $node->item_date_source, $node->item_show_link, $node->item_delete_mode, $node->nid); |
| 295 |
// update taxonomy for already existing nodes, it may take a while... |
// update taxonomy for already existing nodes, it may take a while... |
| 296 |
// TODO: find a way to split work and run it at cron run? |
// TODO: find a way to split work and run it at cron run? |
| 297 |
// maybe store serialized array as drupal variable (for example: aggregator2_update_items_[FEED->NID]) |
// maybe store serialized array as drupal variable (for example: aggregator2_update_items_[FEED->NID]) |
| 346 |
return $temp; |
return $temp; |
| 347 |
} |
} |
| 348 |
if ($node->type == 'aggregator2-item') { |
if ($node->type == 'aggregator2-item') { |
| 349 |
$temp = db_fetch_object(db_query('SELECT ai.fid, ai.link, ai.source_link, ai.source_title, ai.author AS author, n.title AS feed_title, af.url AS feed_url, af.item_show_link AS item_show_link FROM {aggregator2_item} ai LEFT JOIN {aggregator2_feed} af ON af.nid = ai.fid LEFT JOIN {node} n ON n.nid = ai.fid WHERE ai.nid = %d', $node->nid)); |
$temp = db_fetch_object(db_query('SELECT ai.fid, ai.link, ai.source_link, ai.source_xml, ai.source_title, ai.author AS author, n.title AS feed_title, af.url AS feed_url, af.link AS feed_link, af.item_show_link AS item_show_link FROM {aggregator2_item} ai LEFT JOIN {aggregator2_feed} af ON af.nid = ai.fid LEFT JOIN {node} n ON n.nid = ai.fid WHERE ai.nid = %d', $node->nid)); |
| 350 |
return $temp; |
return $temp; |
| 351 |
} |
} |
| 352 |
} |
} |
| 413 |
$type = ($node->type ? $node->type : arg(2)); |
$type = ($node->type ? $node->type : arg(2)); |
| 414 |
|
|
| 415 |
if ($type == 'aggregator2-feed') { |
if ($type == 'aggregator2-feed') { |
|
if (!$node->nid) { |
|
|
$node->refresh = 3600; |
|
|
} |
|
| 416 |
$output .= form_textfield(t('URL'), 'url', $node->url, 60, 250, NULL, NULL, TRUE); |
$output .= form_textfield(t('URL'), 'url', $node->url, 60, 250, NULL, NULL, TRUE); |
| 417 |
|
} |
| 418 |
|
|
| 419 |
|
if (user_access('administer nodes') && $type == 'aggregator2-feed') { |
| 420 |
$period = drupal_map_assoc(array(900, 1800, 3600, 7200, 10800, 21600, 32400, 43200, 64800, 86400, 172800, 259200, 604800, 1209600, 2419200), 'format_interval'); |
$period = drupal_map_assoc(array(900, 1800, 3600, 7200, 10800, 21600, 32400, 43200, 64800, 86400, 172800, 259200, 604800, 1209600, 2419200), 'format_interval'); |
| 421 |
$output .= form_select(t('Update interval'), 'refresh', $node->refresh, $period, t('The refresh interval indicating how often you want to update this feed. Requires crontab.')); |
$output .= form_select(t('Update interval'), 'refresh', $node->refresh, $period, t('The refresh interval indicating how often you want to update this feed. Requires crontab.')); |
|
} |
|
| 422 |
|
|
|
if (user_access('administer nodes') && $type == 'aggregator2-feed') { |
|
| 423 |
$output .= form_textfield(t('Original author'), 'author', $node->author, 60, 60, NULL, NULL, NULL); |
$output .= form_textfield(t('Original author'), 'author', $node->author, 60, 60, NULL, NULL, NULL); |
| 424 |
$output .= form_checkbox(t('Freeze'), 'freezed', 1, $node->freezed, t('If set, aggragator2 will not create new items, or update old ones, for this feed.')); |
$output .= form_checkbox(t('Freeze'), 'freezed', 1, $node->freezed, t('If set, aggragator2 will not create new items, or update old ones, for this feed.')); |
| 425 |
|
$output .= form_checkbox(t('Enable Block'), 'enable_block', 1, $node->enable_block, t('If set, aggragator2 will generate a Drupal block for this feed.')); |
| 426 |
if ($node->nid) { |
if ($node->nid) { |
| 427 |
// "change_existing_items" is not saved anywhere, it's temporary for the time of editing, and saving time |
// "change_existing_items" is not saved anywhere, it's temporary for the time of editing, and saving time |
| 428 |
$output .= form_checkbox(t('Apply changes to already existing items'), 'change_existing_items', 1, $node->change_existing_items, t('If set, changes to input format and item categories will be applied also to already existing items.')); |
$output .= form_checkbox(t('Apply changes to already existing items'), 'change_existing_items', 1, $node->change_existing_items, t('If set, changes to input format and item categories will be applied also to already existing items.')); |
| 429 |
} |
} |
| 430 |
} |
} |
| 431 |
else { |
else { |
| 432 |
|
$output .= form_hidden('refresh', $node->refresh); |
| 433 |
$output .= form_hidden('author', $node->author); |
$output .= form_hidden('author', $node->author); |
| 434 |
$output .= form_hidden('freezed', $node->freezed); |
$output .= form_hidden('freezed', $node->freezed); |
| 435 |
|
$output .= form_hidden('enable_block', $node->enable_block); |
| 436 |
} |
} |
| 437 |
|
|
| 438 |
if (user_access(AGGREGATOR2_PERM_EDIT_OWN_FEED_TAXONOMY) && function_exists('taxonomy_node_form')) { |
if (user_access(AGGREGATOR2_PERM_EDIT_OWN_FEED_TAXONOMY) && function_exists('taxonomy_node_form')) { |
| 439 |
$temp = module_invoke('taxonomy', 'node_form', $type, $node); |
// use hack (same as below for item categories) so we can hide specific vocabularies |
| 440 |
|
//$temp = module_invoke('taxonomy', 'node_form', $type, $node); |
| 441 |
|
/* |
| 442 |
|
** Taxonomy module doesn't add taxonomy terms at load time... so we have to do it by hand :(( |
| 443 |
|
*/ |
| 444 |
|
$terms = module_invoke('taxonomy', 'node_get_terms', $node->nid, 'tid'); |
| 445 |
|
$node->taxonomy = array(); |
| 446 |
|
foreach ($terms as $tid => $term) { |
| 447 |
|
if ($term->tid) { |
| 448 |
|
$node->taxonomy[] = $term->tid; |
| 449 |
|
} |
| 450 |
|
} |
| 451 |
|
$block = ''; |
| 452 |
|
// hide vocabularies |
| 453 |
|
if (!user_access(AGGREGATOR2_PERM_ACCESS_VOCABS)) { |
| 454 |
|
$hidden = variable_get('aggregator2_hidden_vocabs', array()); |
| 455 |
|
if (is_array($hidden) && count($hidden) > 0) { |
| 456 |
|
$block = ' AND v.vid NOT IN ('. implode(',', $hidden) .') '; |
| 457 |
|
} |
| 458 |
|
if (is_array($node->taxonomy) && count($node->taxonomy) > 0) { |
| 459 |
|
$c = db_query('SELECT tid FROM {term_data} WHERE vid IN ('. implode(',', $hidden) .') AND tid IN('. implode(',', $node->taxonomy) .')'); |
| 460 |
|
while ($tid = db_fetch_object($c)) { |
| 461 |
|
$output .= form_hidden('taxonomy][', $tid->tid); |
| 462 |
|
} |
| 463 |
|
} |
| 464 |
|
} |
| 465 |
|
$temp = NULL; |
| 466 |
|
$c = db_query("SELECT v.*, n.type FROM {vocabulary} v INNER JOIN {vocabulary_node_types} n ON v.vid = n.vid WHERE n.type = '%s' $block ORDER BY v.weight, v.name", 'aggregator2-feed'); |
| 467 |
|
while ($vocabulary = db_fetch_object($c)) { |
| 468 |
|
$temp[] = taxonomy_form($vocabulary->vid, $node->taxonomy, '', 'taxonomy'); |
| 469 |
|
} |
| 470 |
|
|
| 471 |
|
|
| 472 |
if (is_array($temp) && count($temp) > 0) { |
if (is_array($temp) && count($temp) > 0) { |
| 473 |
$output .= form_group(t('Categories'), implode('', $temp), t('Select categories to be associated with this feed')); |
$output .= form_group(t('Categories'), implode('', $temp), t('Select categories to be associated with this feed')); |
| 474 |
} |
} |
| 488 |
* so it always checks $node->taxonomy instead of $node->'name' :( |
* so it always checks $node->taxonomy instead of $node->'name' :( |
| 489 |
* so just copy part of taxonomy_node_form function here... |
* so just copy part of taxonomy_node_form function here... |
| 490 |
*/ |
*/ |
| 491 |
|
$block = ''; |
| 492 |
|
// hide vocabularies |
| 493 |
|
if (!user_access(AGGREGATOR2_PERM_ACCESS_VOCABS)) { |
| 494 |
|
$hidden = variable_get('aggregator2_hidden_vocabs', array()); |
| 495 |
|
if (is_array($hidden) && count($hidden) > 0) { |
| 496 |
|
$block = ' AND v.vid NOT IN ('. implode(',', $hidden) .') '; |
| 497 |
|
} |
| 498 |
|
if (is_array($node->feed_item_taxonomy) && count($node->feed_item_taxonomy) > 0) { |
| 499 |
|
$c = db_query('SELECT tid FROM {term_data} WHERE vid IN ('. implode(',', $hidden) .') AND tid IN('. implode(',', $node->feed_item_taxonomy) .')'); |
| 500 |
|
while ($tid = db_fetch_object($c)) { |
| 501 |
|
$output .= form_hidden('feed_item_taxonomy][', $tid->tid); |
| 502 |
|
} |
| 503 |
|
} |
| 504 |
|
} |
| 505 |
|
|
| 506 |
$temp = NULL; |
$temp = NULL; |
| 507 |
$c = db_query("SELECT v.*, n.type FROM {vocabulary} v INNER JOIN {vocabulary_node_types} n ON v.vid = n.vid WHERE n.type = '%s' ORDER BY v.weight, v.name", 'aggregator2-item'); |
$c = db_query("SELECT v.*, n.type FROM {vocabulary} v INNER JOIN {vocabulary_node_types} n ON v.vid = n.vid WHERE n.type = '%s' $block ORDER BY v.weight, v.name", 'aggregator2-item'); |
| 508 |
while ($vocabulary = db_fetch_object($c)) { |
while ($vocabulary = db_fetch_object($c)) { |
| 509 |
$temp[] = taxonomy_form($vocabulary->vid, $node->feed_item_taxonomy, '', 'feed_item_taxonomy'); |
$temp[] = taxonomy_form($vocabulary->vid, $node->feed_item_taxonomy, '', 'feed_item_taxonomy'); |
| 510 |
} |
} |
| 520 |
} |
} |
| 521 |
} |
} |
| 522 |
|
|
| 523 |
|
$output .= form_textfield(t('Image/Logo link'), 'image', $node->image, 60, 1024, t('Use only full URL (including "http://" part too) to image so it does not break RSS/ATOM feed compatibility.'), NULL, FALSE); |
| 524 |
if (user_access('administer nodes')) { |
if (user_access('administer nodes')) { |
| 525 |
$output .= form_textfield(t('Image link'), 'image', $node->image, 60, 1024, t('Use only full URL (including "http://" part too) to image so it does not break RSS/ATOM feed compatibility.'), NULL, FALSE); |
//$output .= form_textfield(t('Image link'), 'image', $node->image, 60, 1024, t('Use only full URL (including "http://" part too) to image so it does not break RSS/ATOM feed compatibility.'), NULL, FALSE); |
| 526 |
$output .= form_checkbox(t('Create GUID for items'), 'guid_items', 1, $node->guid_items, t('If enabled, aggragator2 will try to generate GUID for each item. Use this ONLY if aggregated items do not contain GUID tag and their LINK is not unique (ie. more than one item has the same link).')); |
$output .= form_checkbox(t('Create GUID for items'), 'guid_items', 1, $node->guid_items, t('If enabled, aggragator2 will try to generate GUID for each item. Use this ONLY if aggregated items do not contain GUID tag and their LINK is not unique (ie. more than one item has the same link).')); |
| 527 |
$output .= form_checkbox(t('Update existing items'), 'update_items', 1, $node->update_items, t('If enabled, aggragator2 will update already existing items, overwriting any changes done between cron runs.')); |
$output .= form_checkbox(t('Update existing items'), 'update_items', 1, $node->update_items, t('If enabled, aggragator2 will update already existing items, overwriting any changes done between cron runs.')); |
| 528 |
$output .= form_checkbox(t('Publish new items'), 'item_status', 1, $node->item_status, t('If enabled, aggragator2 will mark each new item as published.')); |
$output .= form_checkbox(t('Publish new items'), 'item_status', 1, $node->item_status, t('If enabled, aggragator2 will mark each new item as published.')); |
| 542 |
$output .= form_select(t('Show "full article"/"visit site" link'), 'item_show_link', $node->item_show_link, array(AGGREGATOR2_SHOW_LINK_ALWAYS => t('Always'), AGGREGATOR2_SHOW_LINK_NEVER => t('Do not display'), AGGREGATOR2_SHOW_LINK_TEASER_ONLY => t('Only with teaser'), AGGREGATOR2_SHOW_LINK_PAGE_ONLY => t('Only on full page')), t('Select place(s) where link to full article (for news items) or visit site (for news feeds) will be shown.')); |
$output .= form_select(t('Show "full article"/"visit site" link'), 'item_show_link', $node->item_show_link, array(AGGREGATOR2_SHOW_LINK_ALWAYS => t('Always'), AGGREGATOR2_SHOW_LINK_NEVER => t('Do not display'), AGGREGATOR2_SHOW_LINK_TEASER_ONLY => t('Only with teaser'), AGGREGATOR2_SHOW_LINK_PAGE_ONLY => t('Only on full page')), t('Select place(s) where link to full article (for news items) or visit site (for news feeds) will be shown.')); |
| 543 |
} |
} |
| 544 |
else { |
else { |
| 545 |
$output .= form_hidden('image', $node->image); |
//$output .= form_hidden('image', $node->image); |
| 546 |
$output .= form_hidden('guid_items', $node->guid_items); |
$output .= form_hidden('guid_items', $node->guid_items); |
| 547 |
$output .= form_hidden('update_items', $node->update_items); |
$output .= form_hidden('update_items', $node->update_items); |
| 548 |
$output .= form_hidden('item_status', $node->item_status); |
$output .= form_hidden('item_status', $node->item_status); |
| 574 |
$output .= form_checkbox(t('Create drupal blocks for each feed'), 'aggregator2_create_feed_blocks', 1, variable_get('aggregator2_create_feed_blocks', 0), t('If enabled, aggragator2 will create block for each feed. Such block still needs to be enabled on '. l('admin/block', 'admin/block') .' page.')); |
$output .= form_checkbox(t('Create drupal blocks for each feed'), 'aggregator2_create_feed_blocks', 1, variable_get('aggregator2_create_feed_blocks', 0), t('If enabled, aggragator2 will create block for each feed. Such block still needs to be enabled on '. l('admin/block', 'admin/block') .' page.')); |
| 575 |
$output .= form_checkbox(t('Show link to feed with each item'), 'aggregator2_show_feed_link', 1, variable_get('aggregator2_show_feed_link', 0), t('If enabled, aggragator2 will show "source" link with each item. It will point to item\'s feed node.')); |
$output .= form_checkbox(t('Show link to feed with each item'), 'aggregator2_show_feed_link', 1, variable_get('aggregator2_show_feed_link', 0), t('If enabled, aggragator2 will show "source" link with each item. It will point to item\'s feed node.')); |
| 576 |
$output .= form_checkbox(t('Show link to items with each feed'), 'aggregator2_show_item_link', 1, variable_get('aggregator2_show_item_link', 0), t('If enabled, aggragator2 will show "items" link with each feed. It will point to feed node list of all items.')); |
$output .= form_checkbox(t('Show link to items with each feed'), 'aggregator2_show_item_link', 1, variable_get('aggregator2_show_item_link', 0), t('If enabled, aggragator2 will show "items" link with each feed. It will point to feed node list of all items.')); |
| 577 |
|
$output .= form_checkbox(t('Use link to item source whenever possible'), 'agg2_original_links', 1, variable_get('agg2_original_links', 0), t('If enabled, aggragator2 will use data from "source" tags instead of "link" tags. That will make "full article" link point to site which first published article, instead to site from which article was aggregated. Unfortunetly many sites do not use "source" tags, so often links will still point to site from which feeed was aggregated.')); |
| 578 |
|
|
| 579 |
|
$output .= form_checkbox(t('Ignore RSS/ATOM teasers'), 'aggregator2_ignore_teasers', 1, variable_get('aggregator2_ignore_teasers', 0), t('If enabled, aggragator2 will ignore teasers set by RSS/ATOM data, and let Drupal auto-generate teasers.')); |
| 580 |
|
|
| 581 |
|
if (function_exists('taxonomy_node_form')) { |
| 582 |
|
// which categories will be blocked for users without "access all vocabs" permission |
| 583 |
|
$temp = NULL; |
| 584 |
|
$c = db_query("SELECT v.*, n.type FROM {vocabulary} v INNER JOIN {vocabulary_node_types} n ON v.vid = n.vid WHERE n.type = '%s' ORDER BY v.weight, v.name", 'aggregator2-item'); |
| 585 |
|
while ($vocabulary = db_fetch_object($c)) { |
| 586 |
|
$temp[$vocabulary->vid] = $vocabulary->name; |
| 587 |
|
} |
| 588 |
|
if (is_array($temp) && count($temp) > 0) { |
| 589 |
|
$output .= form_checkboxes(t('Hide vocabularies'), 'aggregator2_hidden_vocabs', variable_get('aggregator2_hidden_vocabs', array()), $temp, t('Users without the <em>see all vocabularies on edit page</em> permission will not be able to see selected vocabularies on feed and item edit pages.')); |
| 590 |
|
} |
| 591 |
|
} |
| 592 |
|
|
| 593 |
// how many feeds to update at one cron run |
// how many feeds to update at one cron run |
| 594 |
$feed_count = drupal_map_assoc(array(0, 1, 2, 3, 4, 5, 10, 15, 20, 25, 50, 100)); |
$feed_count = drupal_map_assoc(array(0, 1, 2, 3, 4, 5, 10, 15, 20, 25, 50, 100)); |
| 598 |
// how long intervals to use between node_save()/node_delete() calls |
// how long intervals to use between node_save()/node_delete() calls |
| 599 |
$sleep_interval = drupal_map_assoc(array(0, 1, 2, 3, 4, 5)); |
$sleep_interval = drupal_map_assoc(array(0, 1, 2, 3, 4, 5)); |
| 600 |
$output .= form_select(t('Interval between node updates'), 'aggregator2_sleep_interval', variable_get('aggregator2_sleep_interval', 3), $sleep_interval, t('Select how many seconds aggregator2 should wait before trying to save/delete next node.')); |
$output .= form_select(t('Interval between node updates'), 'aggregator2_sleep_interval', variable_get('aggregator2_sleep_interval', 3), $sleep_interval, t('Select how many seconds aggregator2 should wait before trying to save/delete next node.')); |
| 601 |
|
$output .= form_textarea(t('Blacklist URLs'), 'aggregator2_blacklist_url', variable_get('aggregator2_blacklist_url', ''), 60, 10, |
| 602 |
|
t('One entry per line. You can enter full URLs or domain names only. You can also enter regular expression (find out more about what it is at %link. more examples can be found also at %link2). For example "http://some.url.com/some/page.html" will blacklist that specific URL. ".url.com" will blacklist all URLs from url.com domain, and all it\'s subdomains. "some.url.com" will blacklist all URLs from "some" subdomain. "/^ftp\:\/\//" will blacklist any ftp:// URL. Feed which has URL which matches any of the rules on blacklist will be blocked. Items which have link pointing to URL which matches any of the rules from blacklist will not be created.', array('%link' => l('http://www.php.net/manual/en/reference.pcre.pattern.syntax.php', 'http://www.php.net/manual/en/reference.pcre.pattern.syntax.php'), '%link2' => l('http://www.php.net/manual/en/function.preg-match.php', 'http://www.php.net/manual/en/function.preg-match.php'))), |
| 603 |
|
NULL, NULL); |
| 604 |
|
|
| 605 |
// Globally change settings for all feeds - useful if one wants to change setting without need to edit each feed |
// Globally change settings for all feeds - useful if one wants to change setting without need to edit each feed |
| 606 |
if ($clear_items = variable_get('aggregator2_clear_items', 0)) { |
if ($clear_items = variable_get('aggregator2_clear_items', 0)) { |
| 612 |
$period['1000000000'] = t('Never'); |
$period['1000000000'] = t('Never'); |
| 613 |
$output .= form_group(t('Change all news feeds with one click'), form_select(t('Discard feed items older than'), 'aggregator2_clear_items', 0, $period, t('The time feed items should be kept. Older items will be automatically discarded. Requires crontab.'))); |
$output .= form_group(t('Change all news feeds with one click'), form_select(t('Discard feed items older than'), 'aggregator2_clear_items', 0, $period, t('The time feed items should be kept. Older items will be automatically discarded. Requires crontab.'))); |
| 614 |
|
|
| 615 |
|
$output .= form_checkbox(t('Time debugging'), 'agg2_dbg_time', 1, variable_get('agg2_dbg_time', 0), t('If enabled, aggragator2 will log beginning end ending of feed aggregation. This may slow down whole process, but also can give You information about which feeds are slow or even timing out.')); |
| 616 |
|
|
| 617 |
return $output; |
return $output; |
| 618 |
} |
} |
| 619 |
|
|
| 625 |
function aggregator2_block($op = 'list', $delta = 0) { |
function aggregator2_block($op = 'list', $delta = 0) { |
| 626 |
if (variable_get('aggregator2_create_feed_blocks', 0) == 1) { |
if (variable_get('aggregator2_create_feed_blocks', 0) == 1) { |
| 627 |
if ($op == 'list') { |
if ($op == 'list') { |
| 628 |
$result = db_query(db_rewrite_sql('SELECT n.nid, n.title FROM {node} n WHERE n.type = \'aggregator2-feed\' AND n.status = 1')); |
$result = db_query(db_rewrite_sql('SELECT n.nid, n.title, af.enable_block FROM {node} n INNER JOIN {aggregator2_feed} af ON n.nid = af.nid WHERE n.type = \'aggregator2-feed\' AND af.enable_block = 1')); |
| 629 |
|
|
| 630 |
while ($block = db_fetch_object($result)) { |
while ($block = db_fetch_object($result)) { |
| 631 |
$blocks[$block->nid]['info'] = $block->title; |
$blocks[$block->nid]['info'] = $block->title . ' (feed block)'; |
| 632 |
} |
} |
| 633 |
$blocks['sources']['info'] = t('Latest sources'); |
$blocks['sources']['info'] = t('Latest sources'); |
| 634 |
return $blocks; |
return $blocks; |
| 652 |
$block = array(); |
$block = array(); |
| 653 |
$items = array(); |
$items = array(); |
| 654 |
$block['subject'] = t('Latest sources'); |
$block['subject'] = t('Latest sources'); |
| 655 |
$result = db_query('SELECT n.nid, n.title FROM {node} n WHERE n.type = \'aggregator2-feed\' AND n.status = 1 ORDER BY n.changed DESC LIMIT 10'); |
$result = db_query('SELECT n.nid, n.title FROM {node} n INNER JOIN {aggregator2_feed} af ON n.nid = af.nid WHERE n.type = \'aggregator2-feed\' AND n.status = 1 AND af.enable_block = 1 ORDER BY n.changed DESC LIMIT 10'); |
| 656 |
while ($temp = db_fetch_object($result)) { |
while ($temp = db_fetch_object($result)) { |
| 657 |
$items[] = l($temp->title, 'aggregator2/sources/'.$temp->nid); |
$items[] = l($temp->title, 'aggregator2/sources/'.$temp->nid); |
| 658 |
} |
} |
| 672 |
switch ($op) { |
switch ($op) { |
| 673 |
case 'settings': |
case 'settings': |
| 674 |
if ($node->type == 'aggregator2-feed') { |
if ($node->type == 'aggregator2-feed') { |
| 675 |
$options = variable_get('aggregator2_feed_defs', array('freezed' => 0, 'update_items' => 1, 'item_status' => 1)); |
$options = variable_get('aggregator2_feed_defs', array('refresh' => 3600, 'freezed' => 0, 'enable_block' => 0, 'update_items' => 1, 'item_status' => 1)); |
| 676 |
$output = ''; |
$output = ''; |
| 677 |
|
|
| 678 |
$temp = form_checkbox(t('Freeze'), 'aggregator2_feed_defs][freezed', 1, $options['freezed']); |
$temp = form_checkbox(t('Freeze'), 'aggregator2_feed_defs][freezed', 1, $options['freezed']); |
| 679 |
|
$temp = form_checkbox(t('Enable Block'), 'aggregator2_feed_defs][enable_block', 1, $options['enable_block']); |
| 680 |
// "change_existing_items" is not saved anywhere, it's temporary for the time of editing, and saving time |
// "change_existing_items" is not saved anywhere, it's temporary for the time of editing, and saving time |
| 681 |
$temp .= form_checkbox(t('Apply changes to already existing items after feed is re-edited'), 'aggregator2_feed_defs][change_existing_items', 1, $options['change_existing_items']); |
$temp .= form_checkbox(t('Apply changes to already existing items after feed is re-edited'), 'aggregator2_feed_defs][change_existing_items', 1, $options['change_existing_items']); |
| 682 |
$temp .= form_checkbox(t('Create GUID for items'), 'aggregator2_feed_defs][guid_items', 1, $options['guid_items']); |
$temp .= form_checkbox(t('Create GUID for items'), 'aggregator2_feed_defs][guid_items', 1, $options['guid_items']); |
| 685 |
$temp .= form_checkbox(t('Discard only items not published currently'), 'aggregator2_feed_defs][item_delete_mode', 1, $options['item_delete_mode']); |
$temp .= form_checkbox(t('Discard only items not published currently'), 'aggregator2_feed_defs][item_delete_mode', 1, $options['item_delete_mode']); |
| 686 |
$output = form_item(t('Default feed options'), $temp); |
$output = form_item(t('Default feed options'), $temp); |
| 687 |
|
|
| 688 |
|
$period = drupal_map_assoc(array(900, 1800, 3600, 7200, 10800, 21600, 32400, 43200, 64800, 86400, 172800, 259200, 604800, 1209600, 2419200), 'format_interval'); |
| 689 |
|
$output .= form_select(t('Default update interval'), 'aggregator2_feed_defs][refresh', $options['refresh'], $period, t('The refresh interval indicating how often feed should be updated. Requires crontab.')); |
| 690 |
|
|
| 691 |
$promoted_count = drupal_map_assoc(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30)); |
$promoted_count = drupal_map_assoc(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30)); |
| 692 |
$promoted_count['0'] = t('None'); |
$promoted_count['0'] = t('None'); |
| 693 |
$promoted_count['1000000000'] = t('All'); |
$promoted_count['1000000000'] = t('All'); |
| 706 |
case 'rss item': |
case 'rss item': |
| 707 |
if ($node->type == 'aggregator2-item') { |
if ($node->type == 'aggregator2-item') { |
| 708 |
return array(array('key' => 'source', |
return array(array('key' => 'source', |
| 709 |
'attributes' => array('url' => ($node->source_link ? $node->source_link : $node->feed_url)), |
'attributes' => array('url' => ($node->source_xml ? $node->source_xml : $node->feed_url)), |
| 710 |
'value' => check_plain(($node->source_title ? $node->source_title : $node->feed_title)))); |
'value' => check_plain(($node->source_title ? $node->source_title : $node->feed_title))), |
| 711 |
|
array('key' => 'dc:source', |
| 712 |
|
'value' => ($node->source_link ? $node->source_link : $node->link))); |
| 713 |
} |
} |
| 714 |
if ($node->type == 'aggregator2-feed') { |
if ($node->type == 'aggregator2-feed') { |
| 715 |
return array(array('key' => 'source', |
return array(array('key' => 'source', |
| 716 |
'attributes' => array('url' => $node->link), |
'attributes' => array('url' => $node->url), |
| 717 |
'value' => check_plain($node->title))); |
'value' => check_plain($node->title)), |
| 718 |
|
array('key' => 'dc:source', |
| 719 |
|
'value' => $node->link)); |
| 720 |
} |
} |
| 721 |
break; |
break; |
| 722 |
} |
} |
| 743 |
$terms_refreshed = array(); |
$terms_refreshed = array(); |
| 744 |
foreach ($terms as $tid) { |
foreach ($terms as $tid) { |
| 745 |
if (!isset($cache_tids[$tid])) { |
if (!isset($cache_tids[$tid])) { |
| 746 |
$temp = db_query('SELECT vid, tid FROM {term_data} WHERE tid = '. $cat); |
$temp = db_query('SELECT vid, tid FROM {term_data} WHERE tid = '. $tid); |
| 747 |
if ($temp) { |
if ($temp) { |
| 748 |
$cache_tids[$tid] = db_fetch_object($temp); |
$cache_tids[$tid] = db_fetch_object($temp); |
| 749 |
} |
} |
| 777 |
|
|
| 778 |
// check how many feed nodew we can update at a time |
// check how many feed nodew we can update at a time |
| 779 |
$limit = variable_get('aggregator2_cron_feed_count', 10); |
$limit = variable_get('aggregator2_cron_feed_count', 10); |
| 780 |
if (is_numeric($limit) && $limit > -1) { |
if ($limit == 0) { |
| 781 |
|
return; |
| 782 |
|
} |
| 783 |
|
else if ($limit < 9999999) { |
| 784 |
$limit = 'LIMIT '. $limit; |
$limit = 'LIMIT '. $limit; |
| 785 |
} |
} |
| 786 |
else { |
else { |
| 880 |
} |
} |
| 881 |
} |
} |
| 882 |
|
|
| 883 |
|
|
| 884 |
|
echo '<html><head></head><body>'; |
| 885 |
|
echo 'refreshing items...<br />'; |
| 886 |
|
|
| 887 |
aggregator2_refresh($feed); |
aggregator2_refresh($feed); |
| 888 |
|
|
| 889 |
|
echo 'checking for too old items...<br />'; |
| 890 |
|
|
| 891 |
aggregator2_remove_old_items($feed->nid, $feed->clear_items, $feed->item_delete_mode); |
aggregator2_remove_old_items($feed->nid, $feed->clear_items, $feed->item_delete_mode); |
| 892 |
|
|
| 893 |
// If needed, back to "real" user |
// If needed, back to "real" user |
| 895 |
$user = $old_user; |
$user = $old_user; |
| 896 |
} |
} |
| 897 |
|
|
| 898 |
|
echo 'done.<br />'; |
| 899 |
|
echo 'You can go to <a href="/node/'. $nid .'">feed node</a> or <a href="/admin/aggregator2">admin/aggregator2</a>.<br />'; |
| 900 |
|
echo '<script type="text/javascript">document.write(\'You will be redirected to feed node page in 10 seconds\'); setTimeout("document.location=\'/node/'. $nid .'\'", 10000);</script>'; |
| 901 |
|
echo '</body></html>'; |
| 902 |
|
exit(); |
| 903 |
|
|
| 904 |
drupal_goto('node/'. $nid); |
drupal_goto('node/'. $nid); |
| 905 |
} |
} |
| 906 |
} |
} |
| 1031 |
print $output; |
print $output; |
| 1032 |
} |
} |
| 1033 |
|
|
| 1034 |
|
/** |
| 1035 |
|
* This function gives control of contents and functions on the link of 'full article'. |
| 1036 |
|
*/ |
| 1037 |
|
function theme_aggregator2_link_full_article($node) { |
| 1038 |
|
if (variable_get('agg2_original_links', 0)) { |
| 1039 |
|
return '<a href="'. ($node->source_link ? $node->source_link : $node->link) .'" title="'. t('Read original article.') .'">'. t('original article') .'</a>'; |
| 1040 |
|
} |
| 1041 |
|
else { |
| 1042 |
|
return '<a href="'. $node->link .'" title="'. t('Read original article.') .'">'. t('original article') .'</a>'; |
| 1043 |
|
} |
| 1044 |
|
} |
| 1045 |
|
|
| 1046 |
|
/** |
| 1047 |
|
* This function gives control of contents and functions on the link of 'visit site'. |
| 1048 |
|
*/ |
| 1049 |
|
function theme_aggregator2_link_visit_site($node) { |
| 1050 |
|
return '<a href="'. $node->link .'" title="'. t('Visit the site where this news was first published.') .'">'. t('visit site') .'</a>'; |
| 1051 |
|
} |
| 1052 |
|
|
| 1053 |
|
|
| 1054 |
|
|
| 1055 |
|
/** |
| 1056 |
|
* Private function; If URL is ok returns 1. If it's blacklisted returns 0. If expression contains error returns FALSE. |
| 1057 |
|
*/ |
| 1058 |
|
function aggregator2_is_valid_url($url) { |
| 1059 |
|
static $blacklist = NULL; |
| 1060 |
|
|
| 1061 |
|
// Prepare pattern string |
| 1062 |
|
if ($blacklist == NULL) { |
| 1063 |
|
$temp = variable_get('aggregator2_blacklist_url', ''); |
| 1064 |
|
if ($temp) { |
| 1065 |
|
$blacklist = array(); |
| 1066 |
|
$temp = explode("\n", $temp); |
| 1067 |
|
foreach ($temp as $line) { |
| 1068 |
|
// Simple comparision |
| 1069 |
|
if (preg_match('/^\w+:\/\//', $line)) { |
| 1070 |
|
$blacklist[] = '^'.preg_replace('/[^\w]/', '\\\$0', $line).'$'; |
| 1071 |
|
} |
| 1072 |
|
// Check by domain and subdomain |
| 1073 |
|
else if ($line[0] != '/') { |
| 1074 |
|
if ($line[0] == '.') { |
| 1075 |
|
$blacklist[] = '^\w+:\/\/(?:\w+\.|\.)*'.preg_replace('/[^\w]/', '\\\$0', substr($line, 1)).'.*?$'; |
| 1076 |
|
} |
| 1077 |
|
else { |
| 1078 |
|
$blacklist[] = '^\w+:\/\/'.preg_replace('/[^\w]/', '\\\$0', $line).'.*$'; |
| 1079 |
|
} |
| 1080 |
|
} |
| 1081 |
|
// Use pattern |
| 1082 |
|
else { |
| 1083 |
|
$blacklist[] = substr($line, 1, -1); |
| 1084 |
|
} |
| 1085 |
|
} |
| 1086 |
|
if (count($blacklist) > 0) { |
| 1087 |
|
$blacklist = '/'.implode('|', $blacklist).'/'; |
| 1088 |
|
} |
| 1089 |
|
else { |
| 1090 |
|
$blacklist = ''; |
| 1091 |
|
} |
| 1092 |
|
} |
| 1093 |
|
} |
| 1094 |
|
|
| 1095 |
|
if ($blacklist) { |
| 1096 |
|
return !preg_match($blacklist, $url, $matches); |
| 1097 |
|
} |
| 1098 |
|
|
| 1099 |
|
return 1; |
| 1100 |
|
} |
| 1101 |
|
|
| 1102 |
/** |
/** |
| 1103 |
* Private function; Create list of titles of nodes of given type |
* Private function; Create list of titles of nodes of given type |
| 1193 |
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0); |
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0); |
| 1194 |
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); |
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); |
| 1195 |
|
|
| 1196 |
$data = curl_exec($ch); |
$temp = curl_exec($ch); |
| 1197 |
$info = curl_getinfo($ch); |
if (($result->code = curl_errno($ch)) != 0) { |
| 1198 |
|
$result->error = curl_error($ch); |
| 1199 |
|
} |
| 1200 |
|
|
| 1201 |
|
// TODO: currently we don't use it to keep compatibility with drupal_http_request. |
| 1202 |
|
// We could use it and depend on cURL's handling of redirections, so we knew URL was redirected and still get data. |
| 1203 |
|
// cURL returns last redirected URL (if there were more than one :) while drupal's function returns 1st. |
| 1204 |
|
// $info = curl_getinfo($ch); |
| 1205 |
|
|
| 1206 |
curl_close($ch); |
curl_close($ch); |
| 1207 |
unset($ch); |
unset($ch); |
| 1208 |
|
|
| 1209 |
$response = parse_response($data); |
if ($result->code != 0) { |
| 1210 |
|
return $result; |
| 1211 |
|
} |
| 1212 |
|
|
| 1213 |
|
$response = parse_response($temp); |
| 1214 |
$result->code = $response[0]; |
$result->code = $response[0]; |
| 1215 |
$result->headers = $response[1]; |
$result->headers = $response[1]; |
| 1216 |
$result->data = $response[2]; |
$result->data = $response[2]; |
| 1217 |
$error = $response[3]; |
$error = $response[3]; |
| 1218 |
switch ($code) { |
switch ($result->code) { |
| 1219 |
case 200: // OK |
case 200: // OK |
| 1220 |
case 304: // Not modified |
case 304: // Not modified |
| 1221 |
break; |
break; |
| 1245 |
function aggregator2_refresh(&$feed) { |
function aggregator2_refresh(&$feed) { |
| 1246 |
global $AGGREGATOR2_REFRESH_FEED_RUNNING; |
global $AGGREGATOR2_REFRESH_FEED_RUNNING; |
| 1247 |
|
|
| 1248 |
|
// Debugging |
| 1249 |
|
if (variable_get('agg2_dbg_time', 0) == 1) { |
| 1250 |
|
watchdog('agg2-debug', t('Debug: start %title.', array('%title' => '<em>'. $feed->title .'</em>')), WATCHDOG_NOTICE, l(t('view'), 'node/'. $feed->nid)); |
| 1251 |
|
$dbg_time_start = microtime(); |
| 1252 |
|
} |
| 1253 |
|
|
| 1254 |
// Generate conditional GET headers. |
// Generate conditional GET headers. |
| 1255 |
$headers = array(); |
$headers = array(); |
| 1256 |
if ($feed->etag) { |
if ($feed->etag) { |
| 1293 |
break; |
break; |
| 1294 |
} |
} |
| 1295 |
else { |
else { |
| 1296 |
drupal_set_message('Parsing feed '. $feed->title .' took '. $xml_tree['parser_time'] .' seconds.'); |
drupal_set_message(t('Parsing feed %title took %time seconds.', array('%title' => $feed->title, '%time' => $xml_tree['parser_time']))); |
| 1297 |
} |
} |
| 1298 |
|
|
| 1299 |
$AGGREGATOR2_REFRESH_FEED_RUNNING = TRUE; |
$AGGREGATOR2_REFRESH_FEED_RUNNING = TRUE; |
| 1381 |
} |
} |
| 1382 |
$feed->image = '<a href="'. $image['LINK'][0]['VALUE'] .'" class="aggregator2_logo_link"><img src="'. $image['URL'][0]['VALUE'] .'" class="aggregator2_logo" alt="'. $image['TITLE'][0]['VALUE'] .'" /></a>'; |
$feed->image = '<a href="'. $image['LINK'][0]['VALUE'] .'" class="aggregator2_logo_link"><img src="'. $image['URL'][0]['VALUE'] .'" class="aggregator2_logo" alt="'. $image['TITLE'][0]['VALUE'] .'" /></a>'; |
| 1383 |
} |
} |
| 1384 |
|
else if (!$feed->image) { |
| 1385 |
|
$feed->image = ''; |
| 1386 |
|
} |
| 1387 |
|
|
| 1388 |
/* |
/* |
| 1389 |
** Update the feed data: |
** Update the feed data: |
| 1416 |
// probably best way would be to run refresh as admin user and just not forget to set item's user to feed owner :( |
// probably best way would be to run refresh as admin user and just not forget to set item's user to feed owner :( |
| 1417 |
// $feed = node_validate($feed); |
// $feed = node_validate($feed); |
| 1418 |
$feed->validated = TRUE; |
$feed->validated = TRUE; |
| 1419 |
if (!($errors = form_get_errors())) { |
if (!($errors = form_get_errors()) && aggregator2_is_valid_url($feed->url)) { |
| 1420 |
node_save($feed); |
node_save($feed); |
| 1421 |
flush(); |
flush(); |
| 1422 |
sleep(variable_get('aggregator2_sleep_interval', 3)); |
sleep(variable_get('aggregator2_sleep_interval', 3)); |
| 1437 |
watchdog('aggregator2', t('Failed to parse RSS feed %site: %error.', array('%site' => '<em>'. $feed->title .'</em>', '%error' => "<em>$result->code $result->error</em>")), WATCHDOG_ERROR, l(t('view'), 'node/'.$feed->nid)); |
watchdog('aggregator2', t('Failed to parse RSS feed %site: %error.', array('%site' => '<em>'. $feed->title .'</em>', '%error' => "<em>$result->code $result->error</em>")), WATCHDOG_ERROR, l(t('view'), 'node/'.$feed->nid)); |
| 1438 |
drupal_set_message(t('Failed to parse RSS feed %site: %error.', array('%site' => '<em>'. $feed->title .'</em>', '%error' => "<em>$result->code $result->error</em>"))); |
drupal_set_message(t('Failed to parse RSS feed %site: %error.', array('%site' => '<em>'. $feed->title .'</em>', '%error' => "<em>$result->code $result->error</em>"))); |
| 1439 |
} |
} |
| 1440 |
|
|
| 1441 |
|
// Debugging |
| 1442 |
|
if (variable_get('agg2_dbg_time', 0) == 1) { |
| 1443 |
|
$dbg_time_end = microtime(); |
| 1444 |
|
|
| 1445 |
|
list($sec, $usec) = explode(' ', $dbg_time_start); |
| 1446 |
|
$dbg_time_start = $sec + $usec; |
| 1447 |
|
list($sec, $usec) = explode(' ', $dbg_time_end); |
| 1448 |
|
$dbg_time = ($sec + $usec) - $dbg_time_start; |
| 1449 |
|
|
| 1450 |
|
watchdog('agg2-debug', t('Debug: end %title. Time: %time', array('%title' => '<em>'. $feed->title .'</em>', '%time' => $dbg_time)), WATCHDOG_NOTICE, l(t('view'), 'node/'. $feed->nid)); |
| 1451 |
|
} |
| 1452 |
} |
} |
| 1453 |
|
|
| 1454 |
/** |
/** |
| 1685 |
function aggregator2_clone($object) { |
function aggregator2_clone($object) { |
| 1686 |
return version_compare(phpversion(), '5.0') < 0 ? $object : clone($object); |
return version_compare(phpversion(), '5.0') < 0 ? $object : clone($object); |
| 1687 |
} |
} |
| 1688 |
|
|
| 1689 |
|
|
| 1690 |
/** |
/** |
| 1691 |
* Private function; Convert relative URLs |
* Private function; Convert relative URLs |
| 1692 |
*/ |
*/ |
| 1735 |
// TODO: maybe select just those which will not be deleted? so update at the end of this funtion would have less nodes to update :) |
// TODO: maybe select just those which will not be deleted? so update at the end of this funtion would have less nodes to update :) |
| 1736 |
$promote_items = $feed->promoted_items; |
$promote_items = $feed->promoted_items; |
| 1737 |
$promoted = array(); |
$promoted = array(); |
| 1738 |
if ($promote_items != 1000000000) { |
if ($promote_items != 1000000000 && $promote_items != 0) { |
| 1739 |
$result = db_query('SELECT ai.nid AS nid FROM {node} n, {aggregator2_item} ai WHERE ai.fid = %d AND ai.nid = n.nid AND n.status = 1 ORDER BY n.created ASC', $feed->nid); |
$result = db_query('SELECT ai.nid AS nid FROM {node} n, {aggregator2_item} ai WHERE ai.fid = %d AND ai.nid = n.nid AND n.status = 1 ORDER BY n.created ASC', $feed->nid); |
| 1740 |
while ($temp = db_fetch_array($result)) { |
while ($temp = db_fetch_array($result)) { |
| 1741 |
$promoted[] = $temp['nid']; |
$promoted[] = $temp['nid']; |
| 1763 |
|
|
| 1764 |
if ($item['CONTENT']) { // Atom 0.3, 1.0 |
if ($item['CONTENT']) { // Atom 0.3, 1.0 |
| 1765 |
if (strlen($body) < strlen($item['CONTENT'][0]['VALUE'])) { |
if (strlen($body) < strlen($item['CONTENT'][0]['VALUE'])) { |
| 1766 |
if ($body) { |
if ($body && !variable_get('aggregator2_ignore_teasers', 0)) { |
| 1767 |
$teaser = $body; |
$teaser = $body; |
| 1768 |
} |
} |
| 1769 |
$body = &$item['CONTENT'][0]['VALUE']; |
$body = &$item['CONTENT'][0]['VALUE']; |
| 1771 |
} |
} |
| 1772 |
else if ($item['CONTENT:ENCODED']) { // Don't know where it came from but it can be found in RSS 2.0 feeds |
else if ($item['CONTENT:ENCODED']) { // Don't know where it came from but it can be found in RSS 2.0 feeds |
| 1773 |
if (strlen($body) < strlen($item['CONTENT:ENCODED'][0]['VALUE'])) { |
if (strlen($body) < strlen($item['CONTENT:ENCODED'][0]['VALUE'])) { |
| 1774 |
if ($body) { |
if ($body && !variable_get('aggregator2_ignore_teasers', 0)) { |
| 1775 |
$teaser = $body; |
$teaser = $body; |
| 1776 |
} |
} |
| 1777 |
$body = &$item['CONTENT:ENCODED'][0]['VALUE']; |
$body = &$item['CONTENT:ENCODED'][0]['VALUE']; |
| 1818 |
$link = $feed->link; |
$link = $feed->link; |
| 1819 |
} |
} |
| 1820 |
|
|
| 1821 |
|
// Try to "sniff" real link from feeds like news.google.com which "hide" real link behind own url |
| 1822 |
|
if (strpos($link, 'http://news.google.com/news/url?') === 0) { |
| 1823 |
|
if (preg_match('/\&url=(.*)\&/U', $link, $matches) && $matches[1]) { |
| 1824 |
|
$link = rawurldecode($matches[1]); |
| 1825 |
|
} |
| 1826 |
|
} |
| 1827 |
|
else if (preg_match('/^\w+:\/\/(?:\w+\.|\.)*yahoo.com\/dailynews\/rss\/.*\*(.*)/', $link, $matches)) { |
| 1828 |
|
$link = rawurldecode($matches[1]); |
| 1829 |
|
} |
| 1830 |
|
|
| 1831 |
/* |
/* |
| 1832 |
** Resolve the items source. |
** Resolve the items source. |
| 1833 |
*/ |
*/ |
| 1834 |
|
// RSS 2.0 description of SOURCE is a bit different from ATOM and DC. |
| 1835 |
|
// It says link should point to XML data of source (so i guess to feed/channel??), |
| 1836 |
|
// while ATOM and DC say it just points to original data (and from examples on web |
| 1837 |
|
// it looks like it means link to original article on site, not in RSS/ATOM format). |
| 1838 |
if ($item['SOURCE'][0]['VALUE'] && $item['SOURCE'][0]['URL']) { // RSS 2.0 |
if ($item['SOURCE'][0]['VALUE'] && $item['SOURCE'][0]['URL']) { // RSS 2.0 |
| 1839 |
$source_title = &$item['SOURCE'][0]['VALUE']; |
$source_title = &$item['SOURCE'][0]['VALUE']; |
| 1840 |
$source_link = &$item['SOURCE'][0]['URL']; |
$source_xml = &$item['SOURCE'][0]['URL']; |
| 1841 |
|
} |
| 1842 |
|
if ($item['DC:SOURCE'][0]['VALUE'] || (!$source_xml && $item['SOURCE'][0]['VALUE'])) { // Dublin core |
| 1843 |
|
$source_link = &$item['DC:SOURCE'][0]['VALUE']; |
| 1844 |
} |
} |
| 1845 |
else if ($item['SOURCE'] || $item['ATOM:SOURCE']) { // ATOM 1.0 |
else if ($item['SOURCE'] || $item['ATOM:SOURCE']) { // ATOM 1.0 |
| 1846 |
if ($item['SOURCE'][0]['TITLE']) $source_title = &$item['SOURCE'][0]['TITLE'][0]['VALUE']; |
if ($item['SOURCE'][0]['TITLE']) $source_title = &$item['SOURCE'][0]['TITLE'][0]['VALUE']; |
| 1848 |
if ($item['SOURCE'][0]['LINK']) $source_link = &$item['SOURCE'][0]['LINK'][0]['VALUE']; |
if ($item['SOURCE'][0]['LINK']) $source_link = &$item['SOURCE'][0]['LINK'][0]['VALUE']; |
| 1849 |
else if ($item['SOURCE'][0]['ATOM:LINK']) $source_link = &$item['SOURCE'][0]['ATOM:LINK'][0]['VALUE']; |
else if ($item['SOURCE'][0]['ATOM:LINK']) $source_link = &$item['SOURCE'][0]['ATOM:LINK'][0]['VALUE']; |
| 1850 |
} |
} |
| 1851 |
else { |
|
| 1852 |
|
if (!$source_title) { |
| 1853 |
$source_title = ''; |
$source_title = ''; |
| 1854 |
|
} |
| 1855 |
|
if (!$source_link) { |
| 1856 |
$source_link = ''; |
$source_link = ''; |
| 1857 |
} |
} |
| 1858 |
|
if (!$source_xml) { |
| 1859 |
|
$source_xml = ''; |
| 1860 |
|
} |
| 1861 |
|
|
| 1862 |
/* |
/* |
| 1863 |
** Try to resolve and parse the item's publication date. If no |
** Try to resolve and parse the item's publication date. If no |
| 1994 |
$edit->link = $link; |
$edit->link = $link; |
| 1995 |
$edit->source_link = $source_link; |
$edit->source_link = $source_link; |
| 1996 |
$edit->source_title = $source_title; |
$edit->source_title = $source_title; |
| 1997 |
|
$edit->source_xml = $source_xml; |
| 1998 |
$edit->body = aggregator2_convert_relative_urls($body, $feed->link); |
$edit->body = aggregator2_convert_relative_urls($body, $feed->link); |
| 1999 |
$edit->rss_data = &$xml_tree; |
$edit->rss_data = &$xml_tree; |
| 2000 |
$edit->rss_item_data = &$item; |
$edit->rss_item_data = &$item; |
| 2053 |
} |
} |
| 2054 |
|
|
| 2055 |
// Now un-promote older items |
// Now un-promote older items |
| 2056 |
if ($promote_items != 1000000000) { |
if ($promote_items != 1000000000 && $promote_items != 0) { |
| 2057 |
$temp = array(); |
$temp = array(); |
| 2058 |
while (count($promoted) > $promote_items) { |
while (count($promoted) > $promote_items) { |
| 2059 |
$temp[] = array_shift($promoted); |
$temp[] = array_shift($promoted); |
| 2083 |
foreach ($xml_tree['OPML'][0]['BODY'][0]['OUTLINE'] as $item) { |
foreach ($xml_tree['OPML'][0]['BODY'][0]['OUTLINE'] as $item) { |
| 2084 |
$nid = _aggregator2_easyfeed_add($item['XMLURL'], &$u); |
$nid = _aggregator2_easyfeed_add($item['XMLURL'], &$u); |
| 2085 |
if ($nid && $nid > 0) { |
if ($nid && $nid > 0) { |
| 2086 |
db_query("INSERT INTO {aggregator2_item} (nid, fid, author, link, guid, source_link, source_title) VALUES (%d, %d, '%s', '%s', '%s', '%s', '%s')", $nid, $feed->nid, '', '', $item['XMLURL'], $feed->url, $feed->title); |
db_query("INSERT INTO {aggregator2_item} (nid, fid, author, link, guid, source_link, source_xml, source_title) VALUES (%d, %d, '%s', '%s', '%s', '%s', '%s', '%s')", $nid, $feed->nid, '', '', $item['XMLURL'], $feed->link, $feed->url, $feed->title); |
| 2087 |
} |
} |
| 2088 |
} |
} |
| 2089 |
} |
} |