Index: node_breadcrumb.features.inc
===================================================================
RCS file: node_breadcrumb.features.inc
diff -N node_breadcrumb.features.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ node_breadcrumb.features.inc	13 Jan 2011 02:12:38 -0000
@@ -0,0 +1,175 @@
+<?php
+/**
+ * @file Support for features.
+ * Import and export the rules.
+ * 
+ * Menu items being exported (normally identified by menu link id) are converted
+ * back to drupal paths when exporting, and when importing, that path is
+ * retrieved and the appropriate menu link id on the local site is used. This is
+ * because mlids are highly volatile, paths are expected to be more consistent
+ * and portable between sites.
+ * 
+ * 
+ * @author dman dan@coders.co.nz
+ */
+
+/**
+ * CRUD to load all rules
+ */
+function node_breadcrumb_rule_load_all() {
+  $result = db_query("SELECT * FROM {node_breadcrumb_rule} ORDER BY weight, rid");
+  $rules = array();
+  while ($rule = db_fetch_array($result)) {
+    $rules[$rule['rid']] = $rule;
+  }
+  return $rules;
+}
+
+/**
+ * CRUD to load save/update rules
+ */
+function node_breadcrumb_rule_save($rule) {
+  $rule = node_breadcrumb_rule_localize($rule);
+  // This would be easier if the module used db_schema
+  db_query("DELETE FROM {node_breadcrumb_rule} WHERE rid=%d", $rule['rid']);
+  db_query('INSERT INTO {node_breadcrumb_rule} (rid, node_type, tid1, tid2, mid, weight, `condition`) VALUES (%d, "%s", %d, %d, %d, %d, "%s")', $rule['rid'], $rule['node_type'], $rule['tid1'], $rule['tid2'], $rule['mid'], $rule['weight'], $rule['condition']);
+}
+
+/**
+ * Implementation of hook_features_export_options().
+ * 
+ * Provide a selector to define which of the configurations to use.
+ */
+function node_breadcrumb_rule_features_export_options() {
+  $options = array();
+  foreach ((array)node_breadcrumb_rule_load_all() as $rule) {
+    $options[$rule['rid']] = $rule['rid'];
+  }
+  return $options;
+}
+
+/**
+ * Convert nonportable data into something that can be serialized
+ */
+function node_breadcrumb_rule_sanitize($rule) {
+  // Saving the mlid is not very portable. 
+  // Export based on menu item PATH
+  // will be more likely to be useful.
+  if (!empty($rule['mid'])) {
+    $menu_item = menu_link_load($rule['mid']);
+    if ($menu_item) {
+      $rule['menu_path'] = drupal_get_path_alias($menu_item['link_path']);
+    }
+  }
+  return $rule;  
+}
+
+/**
+ * Convert portable data into something that may fit into this site.
+ * The inverse of sanitize
+ */
+function node_breadcrumb_rule_localize($rule) {
+  // If the menu link defined a path, 
+  // find that path on this site and figure out its menu id.
+  if (!empty($rule['menu_path'])) {
+    $mlid = db_result(db_query('SELECT mlid FROM {menu_links} WHERE link_path="%s"', drupal_get_normal_path($rule['menu_path'])));
+    if (!empty($mlid)) {
+      $rule['mid'] = $mlid;
+    }
+  }
+  return $rule;  
+}
+
+/**
+ * Implementation of hook_features_export().
+ *
+ * Sets info-file options for exporting a rule settings array.
+ * 
+ * @param array $data   
+ * An array of machine names for the component in question
+ * to be exported.
+ * @param array &$export
+ * By reference. An array of all components to be exported with a given
+ * feature. Component objects that should be exported should be added to   this
+ * array.
+ */
+function node_breadcrumb_rule_features_export($data, &$export) {
+  $rules = node_breadcrumb_rule_load_all();
+  $export['dependencies']['node_breadcrumb'] = 'node_breadcrumb';
+
+  // Dump all rules if not defined
+  if (empty($data)) {
+    $data = array_keys($rules);
+  }
+  foreach ($data as $component_id => $rule) {
+    $export['features']['node_breadcrumb_rule'][$component_id] = $component_id;
+  }
+  return array();
+}
+
+/**
+ * Implementation of hook_features_export_render().
+ * 
+ * Generates the PHP dump representing the settings
+ * 
+ * @param array $data   
+ * An array of machine names for the component in question
+ * to be exported.
+ */
+function node_breadcrumb_rule_features_export_render($module, $data, $export = NULL) {
+  $code = array();
+  $code[] = '  $node_breadcrumb_rules = array();';
+  $code[] = '';
+
+  $rules = node_breadcrumb_rule_load_all();
+  // Dump all profiles if not defined
+  if (empty($data)) {
+    $data = array_keys($rules);
+  }
+
+  foreach ($data as $rule_id) {
+    $rule = $rules[$rule_id];
+    $rule = node_breadcrumb_rule_sanitize($rule);
+    $setting_identifier = features_var_export($rule_id);
+    $setting_export = features_var_export($rule, '  ');
+    $code[] = "  // Exported rule: {$setting_name}";
+    $code[] = "  \$node_breadcrumb_rules[{$setting_identifier}] = {$setting_export};";
+    $code[] = "";
+  }
+
+  $code[] = '  return $node_breadcrumb_rules;';
+  $code = implode("\n", $code);
+
+  return array('node_breadcrumb_rule_defaults' => $code);
+}
+
+
+/**
+ * Implementation of hook_features_revert().
+ */
+function node_breadcrumb_rule_features_revert($module_name) {
+  node_breadcrumb_rule_features_rebuild($module_name);
+}
+
+/**
+ * Rebuild all component objects for a given feature module. That is, re-
+ * import the exported feature settings as defined in
+ * node_breadcrumb_rule_features_export_render
+ * 
+ * 
+ * @param string $module_name
+ *   The name of the feature module whose components should be rebuilt.
+ */
+function node_breadcrumb_rule_features_rebuild($module_name) {
+  $component_type = 'node_breadcrumb_rule';
+  // This call will return the data structure serialized in the feature module
+  $mycomponents = features_get_default($component_type, $module_name);
+  
+  // Merge the imported named settings into the array of settings
+  if (!empty($mycomponents)) {
+    foreach ($mycomponents as $component_id => $mycomponent) {
+      node_breadcrumb_rule_save($mycomponent);
+      drupal_set_message("Updated $component_id as a $module setting");
+    }
+  }
+}
\ No newline at end of file
Index: node_breadcrumb.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/node_breadcrumb/node_breadcrumb.module,v
retrieving revision 1.26
diff -u -p -r1.26 node_breadcrumb.module
--- node_breadcrumb.module	22 Oct 2009 11:27:09 -0000	1.26
+++ node_breadcrumb.module	13 Jan 2011 02:12:38 -0000
@@ -4,6 +4,16 @@
 function _node_breadcrumb_set_location($mid, $last_path, $last_title) {
   $add_active_class = variable_get('node_breadcrumb_add_active_class', FALSE);
   $menu_item = menu_link_load($mid);
+
+  if (empty($menu_item)) {
+    // Setting a node breadcrumb rule with a non-existent or deleted menu id causes
+    // strange errors (the rule removes all navigation) so the import will fail if
+    // the mlid is invalid.
+    // Ensure that doesn't happen
+    watchdog('node_breadcrumb', 'Node breadcrumb rule refers to a non-existent menu link id. Ignoring', array(), WATCHDOG_ERROR);
+    return;
+  }      
+  
   menu_local_tasks(0);
   menu_local_tasks(1);
   menu_set_item($_GET['q'], $menu_item);
