/[drupal]/contributions/modules/aggregator2/aggregator2.module
ViewVC logotype

Diff of /contributions/modules/aggregator2/aggregator2.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph | View Patch Patch

revision 1.31.2.2, Fri Feb 3 10:02:15 2006 UTC revision 1.31.2.3, Thu Jul 20 11:16:44 2006 UTC
# Line 1  Line 1 
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
# Line 32  define("AGGREGATOR2_PERM_REFRESH_OWN_FEE Line 32  define("AGGREGATOR2_PERM_REFRESH_OWN_FEE
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");
# Line 99  For the feed to update automatically you Line 100  For the feed to update automatically you
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  /**  /**
# Line 168  function aggregator2_link($type, $node = Line 169  function aggregator2_link($type, $node =
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;
# Line 212  function aggregator2_validate(&$node) { Line 213  function aggregator2_validate(&$node) {
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
# Line 232  function aggregator2_validate(&$node) { Line 236  function aggregator2_validate(&$node) {
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  /**  /**
# Line 259  function aggregator2_insert($node) { Line 270  function aggregator2_insert($node) {
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    
# Line 280  function aggregator2_update($node) { Line 291  function aggregator2_update($node) {
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])
# Line 335  function aggregator2_load($node) { Line 346  function aggregator2_load($node) {
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  }  }
# Line 402  function aggregator2_form(&$node) { Line 413  function aggregator2_form(&$node) {
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      }      }
# Line 445  function aggregator2_form(&$node) { Line 488  function aggregator2_form(&$node) {
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        }        }
# Line 462  function aggregator2_form(&$node) { Line 520  function aggregator2_form(&$node) {
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.'));
# Line 483  function aggregator2_form(&$node) { Line 542  function aggregator2_form(&$node) {
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);
# Line 515  function aggregator2_settings() { Line 574  function aggregator2_settings() {
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));
# Line 524  function aggregator2_settings() { Line 598  function aggregator2_settings() {
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)) {
# Line 535  function aggregator2_settings() { Line 612  function aggregator2_settings() {
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    
# Line 546  function aggregator2_settings() { Line 625  function aggregator2_settings() {
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;
# Line 572  function aggregator2_block($op = 'list', Line 652  function aggregator2_block($op = 'list',
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          }          }
# Line 592  function aggregator2_nodeapi(&$node, $op Line 672  function aggregator2_nodeapi(&$node, $op
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']);
# Line 604  function aggregator2_nodeapi(&$node, $op Line 685  function aggregator2_nodeapi(&$node, $op
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');
# Line 622  function aggregator2_nodeapi(&$node, $op Line 706  function aggregator2_nodeapi(&$node, $op
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    }    }
# Line 655  function aggregator2_taxonomy($op, $type Line 743  function aggregator2_taxonomy($op, $type
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          }          }
# Line 689  function aggregator2_cron() { Line 777  function aggregator2_cron() {
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 {
# Line 789  function aggregator2_admin_refresh_feed( Line 880  function aggregator2_admin_refresh_feed(
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
# Line 797  function aggregator2_admin_refresh_feed( Line 895  function aggregator2_admin_refresh_feed(
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  }  }
# Line 927  function aggregator2_page_opml() { Line 1031  function aggregator2_page_opml() {
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
# Line 1022  function aggregator2_http_request($url, Line 1193  function aggregator2_http_request($url,
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;
# Line 1063  function aggregator2_http_request($url, Line 1245  function aggregator2_http_request($url,
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) {
# Line 1105  function aggregator2_refresh(&$feed) { Line 1293  function aggregator2_refresh(&$feed) {
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;
# Line 1193  function aggregator2_refresh(&$feed) { Line 1381  function aggregator2_refresh(&$feed) {
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:
# Line 1225  function aggregator2_refresh(&$feed) { Line 1416  function aggregator2_refresh(&$feed) {
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));
# Line 1246  function aggregator2_refresh(&$feed) { Line 1437  function aggregator2_refresh(&$feed) {
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  /**  /**
# Line 1482  function aggregator2_replace_entities(&$ Line 1685  function aggregator2_replace_entities(&$
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   */   */
# Line 1531  function aggregator2_parse_items(&$xml_t Line 1735  function aggregator2_parse_items(&$xml_t
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'];
# Line 1559  function aggregator2_parse_items(&$xml_t Line 1763  function aggregator2_parse_items(&$xml_t
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'];
# Line 1567  function aggregator2_parse_items(&$xml_t Line 1771  function aggregator2_parse_items(&$xml_t
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'];
# Line 1614  function aggregator2_parse_items(&$xml_t Line 1818  function aggregator2_parse_items(&$xml_t
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'];
# Line 1627  function aggregator2_parse_items(&$xml_t Line 1848  function aggregator2_parse_items(&$xml_t
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
# Line 1767  function aggregator2_parse_items(&$xml_t Line 1994  function aggregator2_parse_items(&$xml_t
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;
# Line 1825  function aggregator2_parse_items(&$xml_t Line 2053  function aggregator2_parse_items(&$xml_t
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);
# Line 1855  function aggregator2_parse_opml($xml_tre Line 2083  function aggregator2_parse_opml($xml_tre
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  }  }

Legend:
Removed from v.1.31.2.2  
changed lines
  Added in v.1.31.2.3

  ViewVC Help
Powered by ViewVC 1.1.2