Index: feeds.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feeds/feeds.module,v
retrieving revision 1.55.2.3
diff -u -p -r1.55.2.3 feeds.module
--- feeds.module	28 Oct 2010 19:58:22 -0000	1.55.2.3
+++ feeds.module	30 Dec 2010 10:51:15 -0000
@@ -907,6 +907,33 @@ function feeds_library_exists($file, $li
   }
   return FALSE;
 }
+/**
+ * @}
+ */
+
+/**
+ * @defgroup rules hooks
+ * @{
+ */
+function feeds_feeds_after_import(FeedsImporter $importer, FeedsSource $source) {
+  _feeds_rules_helper('feeds_after_import', $importer, $source);
+}
+
+function feeds_feeds_after_parse(FeedsImporter $importer, FeedsSource $source) {
+  _feeds_rules_helper('feeds_after_parse', $importer, $source);
+}
+
+function feeds_feeds_after_clear(FeedsImporter $importer, FeedsSource $source) {
+  _feeds_rules_helper('feeds_after_clear', $importer, $source);
+}
+
+function _feeds_rules_helper($event, $importer, $source) {
+  if (module_exists('rules')) {
+    $node = node_load($source->feed_nid);
+    $user = user_load($node->uid);
+    rules_invoke_event($event, $importer, $source, $node, $user);
+  }
+}
 
 /**
  * @}
Index: feeds.rules.inc
===================================================================
RCS file: feeds.rules.inc
diff -N feeds.rules.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ feeds.rules.inc	30 Dec 2010 10:51:16 -0000
@@ -0,0 +1,426 @@
+<?php
+// $Id$
+
+/**
+ * Implementation of hook_rules_event_info().
+ * @ingroup rules
+ */
+function feeds_rules_event_info() {
+  return array(
+    'feeds_after_import' => array(
+      'label' => t('An import has been performed.'),
+      'module' => 'Feeds',
+      'arguments' => array(
+        'feeds_importer' => array(
+          'type' => 'feeds_importer',
+          'label' => t('The feeds importer that was updated.')
+        ),
+        'feeds_source' => array(
+          'type' => 'feeds_source',
+          'label' => t('The feeds source that was updated.')
+        ),
+        'node' => array(
+          'type' => 'node',
+          'label' => t('The node attached to the feeds source.')
+        ),
+        'user' => array(
+          'type' => 'user',
+          'label' => t('The user who created the feed.')
+        ),
+      ),
+    ),
+    'feeds_after_parse' => array(
+      'label' => t('A feed has been parsed.'),
+      'module' => 'Feeds',
+      'arguments' => array(
+        'feeds_importer' => array(
+          'type' => 'feeds_importer',
+          'label' => t('The feeds importer that was parsed.')
+        ),
+        'feeds_source' => array(
+          'type' => 'feeds_source',
+          'label' => t('The feeds source that was parsed.')
+        ),
+        'node' => array(
+          'type' => 'node',
+          'label' => t('The node attached to the feeds source.')
+        ),
+        'user' => array(
+          'type' => 'user',
+          'label' => t('The user who created the feed.')
+        ),
+      ),
+    ),
+    'feeds_after_clear' => array(
+      'label' => t('A feed has been cleared.'),
+      'module' => 'Feeds',
+      'arguments' => array(
+        'feeds_importer' => array(
+          'type' => 'feeds_importer',
+          'label' => t('The feeds importer that was cleared.')
+        ),
+        'feeds_source' => array(
+          'type' => 'feeds_source',
+          'label' => t('The feeds source that was cleared.')
+        ),
+        'node' => array(
+          'type' => 'node',
+          'label' => t('The node attached to the feeds source.')
+        ),
+        'user' => array(
+          'type' => 'user',
+          'label' => t('The user who created the feed.')
+        ),
+      ),
+    ),
+  );
+}
+
+/**
+ * Implementation of hook_rules_condition_info().
+ * @ingroup rules
+ */
+function feeds_rules_condition_info() {
+  return array(
+    'feeds_importer_is' => array(
+      'label' => t('Importer is'),
+      'arguments' => array(
+        'importer_1' => array('type' => 'feeds_importer', 'label' => t('First importer')),
+        'importer_2' => array('type' => 'feeds_importer', 'label' => t('Second importer'))
+      ),
+      'module' => 'Feeds',
+    ),
+    'feeds_source_has_importer' => array(
+      'label' => t('Source has importer'),
+      'arguments' => array(
+        'feeds_source' => array('type' => 'feeds_source', 'label' => t('Feeds source')),
+        'feeds_importer' => array('type' => 'feeds_importer', 'label' => t('Feeds importer'))
+      ),
+      'module' => 'Feeds',
+    ),
+    'feeds_source_is_standalone' => array(
+      'label' => t('Source is standalone'),
+      'arguments' => array(
+        'feeds_source' => array('type' => 'feeds_source', 'label' => t('Feeds source')),
+      ),
+      'module' => 'Feeds',
+    ),
+    'feeds_importer_has_fetcher' => array(
+      'label' => t('Importer has fetcher'),
+      'arguments' => array(
+        'feeds_importer' => array('type' => 'feeds_importer', 'label' => t('Feeds importer')),
+      ),
+      'module' => 'Feeds',
+    ),
+    'feeds_importer_has_parser' => array(
+      'label' => t('Importer has parser'),
+      'arguments' => array(
+        'feeds_importer' => array('type' => 'feeds_importer', 'label' => t('Feeds importer')),
+      ),
+      'module' => 'Feeds',
+    ),
+    'feeds_importer_has_processor' => array(
+      'label' => t('Importer has processor'),
+      'arguments' => array(
+        'feeds_importer' => array('type' => 'feeds_importer', 'label' => t('Feeds importer')),
+      ),
+      'module' => 'Feeds',
+    ),
+  );
+}
+
+function feeds_importer_is($importer, $settings) {
+  return in_array($importer->id, $settings['id']);
+}
+
+/**
+ * Condition: Check for content types - Configuration form
+ */
+function feeds_importer_is_form($settings, &$form) {
+  $form['settings']['id'] = array(
+    '#type' => 'select',
+    '#title' => t('Importers'),
+    '#options' => feeds_enabled_importers(),
+    '#multiple' => TRUE,
+    '#default_value' => isset($settings['id']) ? $settings['id'] : array(),
+    '#required' => TRUE,
+  );
+}
+
+function feeds_source_has_importer($source, $settings) {
+  return in_array($source->importer->id, $settings['id']);
+}
+
+function feeds_source_has_importer_form($settings, &$form) {
+  feeds_importer_is_form($settings, $form);
+}
+
+function feeds_source_is_standalone($source) {
+  return $source->nid == 0;
+}
+
+function feeds_importer_has_fetcher($importer, $settings) {
+  return $importer->config['fetcher']['plugin_key'] == $settings['plugin'];
+}
+
+function feeds_importer_has_fetcher_form($settings, &$form) {
+  _feeds_importer_has_helper('fetcher', $settings, $form);
+}
+
+function feeds_importer_has_parser($importer, $settings) {
+  return $importer->config['parser']['plugin_key'] == $settings['plugin'];
+}
+
+function feeds_importer_has_parser_form($settings, &$form) {
+  _feeds_importer_has_helper('parser', $settings, $form);
+}
+
+function feeds_importer_has_processor($importer, $settings) {
+  return $importer->config['processor']['plugin_key'] == $settings['plugin'];
+}
+
+function feeds_importer_has_processor_form($settings, &$form) {
+  _feeds_importer_has_helper('processor', $settings, $form);
+}
+
+function _feeds_importer_has_helper($type, $settings, &$form) {
+  $form['settings']['fetcher'] = array(
+    '#type' => 'select',
+    '#title' => t('Fetchers'),
+    '#options' => array_keys(feeds_get_plugins_by_type($type)),
+    '#multiple' => TRUE,
+    '#default_value' => isset($settings['plugin']) ? $settings['plugin'] : array(),
+    '#required' => TRUE,
+  );
+}
+
+/**
+ * Implementation of hook_rules_action_info().
+ * @ingroup rules
+ */
+function feeds_rules_action_info() {
+  return array(
+    'feeds_rules_action_import' => array(
+      'label' => t('Import a feed'),
+      'arguments' => array(
+        'feed_source' => array(
+          'type' => 'feeds_source',
+          'label' => t('Feeds source'),
+        ),
+      ),
+      'module' => 'Feeds',
+    ),
+
+    'feeds_rules_action_set_url' => array(
+      'label' => t('Set the url of a feeds source'),
+      'arguments' => array(
+        'feeds_source' => array('type' => 'feeds_source', 'label' => t('Feeds source')),
+        'feeds_url' => array('type' => 'string', 'label' => t('Url')),
+      ),
+      'module' => 'Feeds',
+    ),
+
+    'feeds_rules_action_set_path' => array(
+      'label' => t('Set the filepath of a feeds source'),
+      'arguments' => array(
+        'feeds_source' => array('type' => 'feeds_source', 'label' => t('Feeds source')),
+        'feeds_url' => array('type' => 'string', 'label' => t('Url')),
+      ),
+      'module' => 'Feeds',
+    ),
+
+    'feeds_rules_action_load_source' => array(
+      'label' => t('Load a feeds source by importer and optionally node id'),
+      'arguments' => array(
+        'feeds_importer' => array(
+          'type' => 'string',
+          'label' => t('Importer name')
+        ),
+        'feeds_nid' => array(
+          'type' => 'number',
+          'label' => t('Node id of source if importer is attached to a node'),
+          'required' => FALSE,
+        ),
+      ),
+      'new variables' => array(
+        'feeds_source' => array(
+          'type' => 'feeds_source',
+          'label' => t('Loaded feeds source'),
+        ),
+      ),
+      'module' => 'Feeds',
+    ),
+
+    'feeds_rules_action_clear' => array(
+      'label' => t('Clear a feeds source'),
+      'arguments' => array(
+        'feeds_source' => array('type' => 'feeds_source', 'label' => t('Feeds source')),
+      ),
+      'module' => 'Feeds',
+    ),
+
+    'feeds_rules_action_load_from_node' => array(
+      'label' => t('Load a feeds source from a node'),
+      'arguments' => array(
+        'node' => array('type' => 'node', 'label' => t('Node to load feeds source from')),
+      ),
+      'new variables' => array(
+        'feeds_source_from_node' => array(
+          'type' => 'feeds_source',
+          'label' => t('Feeds source loaded from node'),
+        ),
+      ),
+      'module' => 'Feeds',
+    ),
+  );
+}
+
+/**
+ * Callabck for the action feeds_rules_action_import.
+ *
+ * TODO: Add option to use batch?  Combine this function with the next, similar
+ * to _feeds_rules_action_set_path.
+ */
+function feeds_rules_action_import($source) {
+  _feeds_rules_action_helper($source, 'import');
+}
+
+/**
+ * Callabck for the action feeds_rules_action_clear.
+ *
+ * TODO: Add option to use batch?
+ */
+function feeds_rules_action_clear($source) {
+  _feeds_rules_action_helper($source, 'clear');
+}
+
+/**
+ * Helper function for feeds_rules_action_clear and feeds_rules_action_import.
+ */
+function _feeds_rules_action_helper($source, $action, $action) {
+  try {
+    while ($state != $source->$action());
+  }
+  catch (Exception $e) {
+    /**
+     * TODO: Determine if $souce is attached to a node and use node title.
+     */
+    drupal_set_message(t("There was an eror {$action}ing: %importer",
+      array('%importer' => $source->importer->config['name']))
+    );
+    return FALSE;
+  }
+}
+
+/**
+ * Loads a feed.
+ */
+function feeds_rules_action_load_source($importer, $nid) {
+  return array('feeds_source' => feeds_source($importer, $nid));
+}
+
+/**
+ * Set the url of a feed source that uses the FeedsHTTPFetcher.
+ */
+function feeds_rules_action_set_url($source, $url) {
+  _feeds_rules_action_set_path($source, $url, 'FeedsHTTPFetcher');
+}
+
+/**
+ * Set the path of a feed source that uses the FeedsFileFetcher.
+ */
+function feeds_rules_action_set_path($source, $path) {
+  _feeds_rules_action_set_path($source, $path, 'FeedsFileFetcher');
+}
+
+/**
+ * Helper function for the previous two functions.
+ *
+ * TODO: Validation of path.
+ */
+function _feeds_rules_action_set_path($source, $path, $type) {
+  $config = $source->getConfig();
+  if (isset($config[$type])) {
+    $config[$type]['source'] = $path;
+    $source->setConfig($config);
+  }
+  return array('feeds_source' => $source);
+}
+
+/**
+ * Loads a feed source based on the node provided.
+ * Currently will only find the first importer bound to the node type.
+ */
+function feeds_rules_action_load_from_node($node) {
+  foreach (feeds_enabled_importers() as $feed_id) {
+    $feed = feeds_importer($feed_id);
+    if ($feed->config['content_type'] == $node->type) {
+      return array('feeds_source_from_node' => feeds_source($feed_id, $node->nid));
+    }
+  }
+}
+
+/**
+ * Implementation of hook_rules_data_type_info().
+ */
+function feeds_rules_data_type_info() {
+  $info = array(
+    'feeds_source' => array(
+      'label' => t('Feeds Source'),
+      'class' => 'feeds_source_rules_data_type',
+      'savable' => TRUE,
+      'identifiable' => TRUE,
+      'uses_input_form' => FALSE,
+      'module' => 'Feeds',
+    ),
+
+    'feeds_importer' => array(
+      'label' => t('Feeds Importer'),
+      'class' => 'feeds_importer_rules_data_type',
+      'saveable' => TRUE,
+      'identifiable' => TRUE,
+      'uses_input_form' => FALSE,
+      'module' => 'Feeds',
+    ),
+  );
+}
+
+/**
+ * Provides a data type of feeds_source to rules. Allows for intelligent saving.
+ */
+class feeds_source_rules_data_type extends rules_data_type {
+  function save() {
+    $source = &$this->get();
+    $source->save();
+    return TRUE;
+  }
+
+  function load($source_id) {
+    return feeds_source($source_id['importer'], $source_id['nid']);
+  }
+
+  function get_identifier() {
+    $source = &$this->get();
+    return array('importer' => $source->importer->id, 'nid' => $source->feed_nid);
+  }
+}
+
+/**
+ * Provides a data type of feed_importer to rules. Allows for intelligent saving.
+ */
+class feeds_importer_rules_data_type extends rules_data_type {
+  function save() {
+    $importer = &$this->get();
+    $importer->save();
+    return TRUE;
+  }
+
+  function load($importer_id) {
+    return feeds_importer($importer_id);
+  }
+
+  function get_identifier() {
+    $importer = &$this->get();
+    return $importer->id;
+  }
+}
