diff -urN feedapi_itemfilter.orig/category_filter/feedapi_category_filter.info feedapi_itemfilter/category_filter/feedapi_category_filter.info --- feedapi_itemfilter.orig/category_filter/feedapi_category_filter.info 1970-01-01 01:00:00.000000000 +0100 +++ feedapi_itemfilter/category_filter/feedapi_category_filter.info 2009-10-15 15:20:56.000000000 +0100 @@ -0,0 +1,20 @@ +name = FeedAPI category filter +description = "Filters feed items based on keywords. Only these feed items, that have matched keyword(s) in the feed item description field will be saved." +core = 6.x +package = "FeedAPI Filter" +version = 6.x-1.0-beta +dependencies[] = feedapi +dependencies[] = feedapi_itemfilter + +; Information added by drupal.org packaging script on 2008-05-28 +version = "6.x-1.x-dev" +project = "feedapi_itemfilter" +datestamp = "1211933074" + + +; Information added by drupal.org packaging script on 2009-02-11 +version = "6.x-1.1" +core = "6.x" +project = "feedapi_itemfilter" +datestamp = "1234385434" + diff -urN feedapi_itemfilter.orig/category_filter/feedapi_category_filter.module feedapi_itemfilter/category_filter/feedapi_category_filter.module --- feedapi_itemfilter.orig/category_filter/feedapi_category_filter.module 1970-01-01 01:00:00.000000000 +0100 +++ feedapi_itemfilter/category_filter/feedapi_category_filter.module 2009-10-15 15:22:44.000000000 +0100 @@ -0,0 +1,133 @@ +items directly in your code (see line 116 below). + */ +function feedapi_category_filter_feedapi_itemfilter($op, &$feed, &$options) +{ + switch ($op) { + // Prepare settings for the filter. + case 'settings': + $form['info'] = array( + '#type' => 'item', + // '#title' => t('Information about filter'), + // '#value' => t('Keyword filter will check ...'), + '#description' => t('Category filter will check the <category> fields of feed items against a set of keyword(s) + immediately after parsing. Any item that has no matching keywords will not be saved with the feed.'), + '#weight' => -15, + ); + $form['categories'] = array( + '#type' => 'textarea', + '#title' => t('Include Tags'), + '#default_value' => $node_type_settings['feedapi']['itemfilter']['category'], + '#attributes' => '', + '#description' => t('Keywords that must be included in a feed item for it to be displayed - e.g. "iPhone, +battery, -problem". + Keywords that start with minus (-) will be used as negative keywords. + Please separate different keywords with comma (,). You can also use phrases - e.g. "top performance, -bad problems".'), + ); + return $form; + break; + + // Process the items. + case 'process': + // Is the filter enabled and do we have something to process? + if(!empty($options['categories'])) { // is_null? + + // Arrays for new feed item set and keywords is necessary + $newfeed = array(); + $words = explode(",", $options['categories']); + // If delimiter does not exist then there is only one keyword + if ($words == FALSE) { + $words = array($options['categories']); + } + + // There are two types of keywords -- negative and positive. + $wordlist = array('neg' => array(), 'pos' => array()); + + // So split the list into two sets. + foreach ($words as $word) { + $word = trim($word); + if(mb_substr($word, 0, 1) == '-') { + $wordlist['neg'][] = mb_substr($word, 1); + } + elseif(mb_substr($word, 0, 1) == '+') { + $wordlist['pos'][] = mb_substr($word, 1); + } + else { + $wordlist['pos'][] = $word; + } + } + + // Get through each feed item. + foreach ($feed->items as $key=>$item) { + // If negative keyword has been found then move directly to next item. + foreach ($wordlist['neg'] as $value) { + foreach ($item->options->tags as $tag) { + // Number 2 here means that we are stepping out from both foreach statement. + if (strcasecmp($tag, $value) == 0) continue 3; + } + } + + // And now we process positive keywords. + if(!empty($wordlist['pos'])) { + foreach ($wordlist['pos'] as $value) { + foreach ($item->options->tags as $tag) { + if (strcasecmp($tag, $value) == 0) { + // If keyword found then the item is worth saving. + $newfeed[] = $feed->items[$key]; + // And there is no reason to try out remaining keywords --> move to the next item. + continue 3; + } + } + } + } else { + // If no positive items are provided, pick the item by default + $newfeed[] = $feed->items[$key]; + } // End of positive items parsing + } // end of items parsing + + // Let our users know about the results. + drupal_set_message(t('The feed %name was filtered, based on the following categories: "%categories". Items kept after filtering: %new out of %old.', array('%name' => $feed->title, '%categories' => $options['categories'], '%new' => count($newfeed), '%old' => count($feed->items)))); + // And finally - let's replace the items with the ones that we need. + $feed->items = $newfeed; + } // endif + break; + } // end switch +} diff -urN feedapi_itemfilter.orig/category_filter/README.txt feedapi_itemfilter/category_filter/README.txt --- feedapi_itemfilter.orig/category_filter/README.txt 1970-01-01 01:00:00.000000000 +0100 +++ feedapi_itemfilter/category_filter/README.txt 2009-10-15 15:20:56.000000000 +0100 @@ -0,0 +1,21 @@ +================================================================================== +Category Filter +================================================================================== + +Category filter will check the fields (tags) of feed items against a set of +keyword(s) immediately after parsing. Any item that has no matching keywords will +not be saved with the feed. Items matching a negative keyword will also be discarded. + +Keywords should be separated by comma e.g. "iPhone, +battery, -problem". + +You can use plus sign (+) in front of positive keywords if you want, but this +is not required. + +If you define more than one keyword then the feed item will be included if +any of the keywords is found. + +The negative keywords dominate over positive ones. So if the negative keyword is +found the feed item will be always dropped. + +The search is case insensitive. The keyword 'iPhone' is just as good as the +keyword 'IPHONE' or 'iphone'. diff -urN feedapi_itemfilter.orig/feedapi_itemfilter.module~ feedapi_itemfilter/feedapi_itemfilter.module~ --- feedapi_itemfilter.orig/feedapi_itemfilter.module~ 1970-01-01 01:00:00.000000000 +0100 +++ feedapi_itemfilter/feedapi_itemfilter.module~ 2009-10-15 15:20:56.000000000 +0100 @@ -0,0 +1,159 @@ + 'fieldset', + '#title' => t('Item filters'), + '#description' => t('Feedapi item filters will check feed items against filter critera -- any item, that does not fulfill criteria will not be included in the feed.'), + '#tree' => TRUE, + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + + // Collect filters' settings trough hook + $filters = module_implements('feedapi_itemfilter', TRUE); + rsort($filters); + foreach ($filters as $module) { + $func = $module .'_feedapi_itemfilter'; + // Get additional settings from filters + $form['feedapi']['itemfilter'][$module] = array( + '#type' => 'fieldset', + '#title' => feedapi_itemfilter_get_natural_name($module), + '#tree' => TRUE, + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + //$form_additional = $func('settings', $df=array(), $tr=array()); + $form['feedapi']['itemfilter'][$module] = array_merge_recursive($form['feedapi']['itemfilter'][$module], $func('settings', $df=array(), $tr=array())); + $form['feedapi']['itemfilter'][$module]['#weight'] = $node_type_settings['itemfilter'][$module]['weight']; + $form['feedapi']['itemfilter'][$module]['enabled'] = array( + '#type' => 'checkbox', + '#title' => t('Enable filter'), + '#description' => t('Check if you want to use this filter.'), + '#default_value' => $node_type_settings['itemfilter'][$module]['enabled'], + '#weight' => -14, + ); + $form['feedapi']['itemfilter'][$module]['weight'] = array( + '#type' => 'weight', + '#delta' => 15, + '#title' => t('Weight'), + '#description' => t('Control the execution order. Filters with lower weights are called before filters with higher weights.'), + '#default_value' => $node_type_settings['itemfilter'][$module]['weight'], + '#weight' => -13, + ); + } + + return $form; + } +} + +/** + * Implementation of FeedAPI's feedapi_after_parse call + * + * @param &$feed + * Array of parsed feed + */ +function feedapi_itemfilter_feedapi_after_parse(&$feed) +{ + // First, we have to find out keyword filter settings. + + // When the node is refreshed, then the settings are available from $feed->settings. + if (!empty($feed->settings['feedapi']['itemfilter'])) { + $options = $feed->settings['feedapi']['itemfilter']; + } + // But when the node is inserted then the $feed->settings is not available + // and we have to obatin them from $_POST. + elseif (!empty($_POST['feedapi']['feedapi']['itemfilter'])) { + $options = $_POST['feedapi']['feedapi']['itemfilter']; + } + // When the refresh is called from cron.php neither of the above + // may not work, but fortunatelly we have $feed->nid present. + elseif ($feed->nid > 0) { + $node = node_load($feed->nid); + $options = $node->feed->settings['feedapi']['itemfilter']; + } + // This is last try - when the node is updated then the none of above will work and the only way + // to recover the settings is obataining nid from http address arguments. + // + // @todo Is this REALLY the only option here? The relyable results are not guaranteed, especially + // when user has played around with the path. + elseif (is_numeric(arg(1))) { + $node = node_load(arg(1)); + $options = $node->feed->settings['feedapi']['itemfilter']; + } + // Anyway, if none of above worked then we are skrewed. Let the user know about it. + else { + drupal_set_message(t('Feedapi filter could not detect the feed. Filtering was not carried out. You may need to remove the feed items and try to refresh the feed manually.'), 'error'); + return; + } + + // Provide hook so we can have extendable filtering system. + + // Find filters. + $filters = module_implements('feedapi_itemfilter', TRUE); + $modules = array(); + + // Set filter order. + foreach ($filters as $module) { + if ($options[$module]['enabled']) { + $modules[$options[$module]['weight']] = $module; + } + } + arsort($modules); + + // Run enabled filters. + foreach ($modules as $weight => $module) { + $func = $module . '_feedapi_itemfilter'; + $func('process', $feed, $options[$module]); + } +} + +/** + * Get the module-defined natural name of FeedAPI filter + * Define this name in hook_help(): + * + * function hook_help($section) { + * switch ($section) { + * case 'feedapi/itemfilter/full_name': + * return t('Natural name'); + * break; + * } + * } + */ +function feedapi_itemfilter_get_natural_name($module) { + $help = $module .'_help'; + $module_natural = function_exists($help) ? $help('feedapi/itemfilter/full_name') : t($module); + return empty($module_natural) ? t($module) : $module_natural; +}