? .bzr
? 503452-retool-export.patch
? 630194-plugin-option-definition.patch
? exposed-form-plugin-full.patch
? exposed-form-plugin.patch
? exposed-form-plugin2.patch
? hack-views-module-2.txt
? retool-export.patch
? views-option_definition.patch
? views-pluggable-exposed-forms_1.patch
? includes/group-by.patch
Index: handlers/views_handler_argument.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/handlers/views_handler_argument.inc,v
retrieving revision 1.7.2.3
diff -u -p -r1.7.2.3 views_handler_argument.inc
--- handlers/views_handler_argument.inc	10 Nov 2009 23:20:05 -0000	1.7.2.3
+++ handlers/views_handler_argument.inc	14 Nov 2009 00:59:02 -0000
@@ -96,15 +96,15 @@ class views_handler_argument extends vie
     $options = parent::option_definition();
 
     $options['default_action'] = array('default' => 'ignore');
-    $options['style_plugin'] = array('default' => 'default_summary');
-    $options['style_options'] = array('default' => array());
+    $options['style_plugin'] = array('default' => 'default_summary', 'export' => 'export_style');
+    $options['style_options'] = array('default' => array(), 'export' => FALSE);
     $options['wildcard'] = array('default' => 'all');
     $options['wildcard_substitution'] = array('default' => t('All'), 'translatable' => TRUE);
     $options['title'] = array('default' => '', 'translatable' => TRUE);
     $options['breadcrumb'] = array('default' => '', 'translatable' => TRUE);
-    $options['default_argument_type'] = array('default' => 'fixed');
+    $options['default_argument_type'] = array('default' => 'fixed', 'export' => 'export_plugin');
     $options['default_argument'] = array('default' => '');
-    $options['validate_type'] = array('default' => 'none');
+    $options['validate_type'] = array('default' => 'none', 'export' => 'export_plugin');
     $options['validate_fail'] = array('default' => 'not found');
 
     return $options;
@@ -742,6 +742,31 @@ class views_handler_argument extends vie
     unset($argument);
     return $value;
   }
+
+  /**
+   * Special handling for the style export.
+   *
+   * Arguments can have styles for the summary view. This special export
+   * handler makes sure this works properly.
+   */
+  function export_style($indent, $prefix, $storage, $option, $definition, $parents) {
+    $output = '';
+    $name = $storage[$option];
+    $options = $storage['style_options'];
+
+    $plugin = views_get_plugin('style', $name);
+    if ($plugin) {
+      $plugin->init($this->view, $this->display, $options);
+      // Write which plugin to use.
+      $output .= $indent . $prefix . "['$option'] = '$name';\n";
+
+      // Pass off to the plugin to export itself.
+      $output .= $plugin->export_options($indent, $prefix . "['style_options']");
+    }
+
+    return $output;
+  }
+
 }
 
 /**
Index: includes/base.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/includes/base.inc,v
retrieving revision 1.2.2.1
diff -u -p -r1.2.2.1 base.inc
--- includes/base.inc	25 Jun 2009 22:15:36 -0000	1.2.2.1
+++ includes/base.inc	14 Nov 2009 00:59:02 -0000
@@ -125,4 +125,63 @@ class views_object {
       unset($this->query);
     }
   }
+
+  function export_options($indent, $prefix) {
+    $output = '';
+    foreach ($this->option_definition() as $option => $definition) {
+      $output .= $this->export_option($indent, $prefix, $this->options, $option, $definition, array());
+    }
+
+    return $output;
+  }
+
+  function export_option($indent, $prefix, $storage, $option, $definition, $parents) {
+    // Do not export options for which we have no settings.
+    if (!isset($storage[$option])) {
+      return;
+    }
+
+    if (isset($definition['export'])) {
+      if ($definition['export'] === FALSE) {
+        return;
+      }
+
+      // Special handling for some items
+      if (method_exists($this, $definition['export'])) {
+        return $this->{$definition['export']}($indent, $prefix, $storage, $option, $definition, $parents);
+      }
+    }
+
+    // Add the current option to the parents tree.
+    $parents[] = $option;
+    $output = '';
+
+    // If it has child items, export those separately.
+    if (isset($definition['contains'])) {
+      foreach ($definition['contains'] as $sub_option => $sub_definition) {
+        $output .= $this->export_option($indent, $prefix, $storage[$option], $sub_option, $sub_definition, $parents);
+      }
+    }
+    // Otherwise export just this item.
+    else {
+      $default = isset($definition['default']) ? $definition['default'] : NULL;
+      $value = $storage[$option];
+      if (isset($definition['bool'])) {
+        $value = (bool) $value;
+      }
+
+      if ($value !== $default) {
+        $output .= $indent . $prefix . "['" . implode("']['", $parents) . "'] = ";
+        if (isset($definition['bool'])) {
+          $output .= empty($storage[$option]) ? 'FALSE' : 'TRUE';
+        }
+        else {
+          $output .= views_var_export($storage[$option], $indent);
+        }
+
+        $output .= ";\n";
+      }
+    }
+    return $output;
+  }
 }
Index: includes/handlers.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/includes/handlers.inc,v
retrieving revision 1.109.2.11
diff -u -p -r1.109.2.11 handlers.inc
--- includes/handlers.inc	10 Nov 2009 23:20:05 -0000	1.109.2.11
+++ includes/handlers.inc	14 Nov 2009 00:59:04 -0000
@@ -278,6 +278,7 @@ class views_handler extends views_object
   function option_definition() {
     $options = parent::option_definition();
 
+    $options['relationship'] = array('default' => 'none');
     $options['group_type'] = array('default' => 'group');
 
     return $options;
Index: includes/view.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/includes/view.inc,v
retrieving revision 1.151.2.18
diff -u -p -r1.151.2.18 view.inc
--- includes/view.inc	11 Nov 2009 01:08:29 -0000	1.151.2.18
+++ includes/view.inc	14 Nov 2009 00:59:05 -0000
@@ -557,7 +557,7 @@ class view extends views_db_object {
     $this->_pre_query();
 
     if ($this->display_handler->uses_exposed()) {
-      $exposed_form = $this->display_handler->get_exposed_form_plugin();
+      $exposed_form = $this->display_handler->get_plugin('exposed_form');
       $this->exposed_widgets = $exposed_form->render_exposed_form();
       if (form_set_error() || !empty($this->build_info['abort'])) {
         $this->built = TRUE;
@@ -687,7 +687,7 @@ class view extends views_db_object {
       $cache = FALSE;
     }
     else {
-      $cache = $this->display_handler->get_cache_plugin();
+      $cache = $this->display_handler->get_plugin('cache');
     }
     if ($cache && $cache->cache_get('results')) {
       vpr('Used cached results');
@@ -720,7 +720,7 @@ class view extends views_db_object {
       $this->start_query_capture();
     }
 
-    $exposed_form = $this->display_handler->get_exposed_form_plugin();
+    $exposed_form = $this->display_handler->get_plugin('exposed_form');
     $exposed_form->pre_render();
 
     // Check for already-cached output.
@@ -728,7 +728,7 @@ class view extends views_db_object {
       $cache = FALSE;
     }
     else {
-      $cache = $this->display_handler->get_cache_plugin();
+      $cache = $this->display_handler->get_plugin('cache');
     }
     if ($cache && $cache->cache_get('output')) {
       vpr('Used cached output');
@@ -1373,6 +1373,8 @@ class view extends views_db_object {
         continue;
       }
 
+      $output .= $display->handler->export_options($indent, '$handler->options');
+/*
       foreach ($display->handler->option_definition() as $option => $definition) {
         // Special handling for some items
         switch ($option) {
@@ -1395,6 +1397,7 @@ class view extends views_db_object {
             }
         }
       }
+*/
     }
 
     return $output;
Index: plugins/views_plugin_display.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_display.inc,v
retrieving revision 1.20.2.14
diff -u -p -r1.20.2.14 views_plugin_display.inc
--- plugins/views_plugin_display.inc	13 Nov 2009 22:07:54 -0000	1.20.2.14
+++ plugins/views_plugin_display.inc	14 Nov 2009 00:59:07 -0000
@@ -278,7 +278,10 @@ class views_plugin_display extends views
           'arguments' => TRUE,
           'filters' => TRUE,
         ),
+        'export' => FALSE,
       ),
+
+      // These are the 5 handler types.
       'relationships' => array(
         'default' => array(),
         'export' => 'export_item',
@@ -299,16 +302,7 @@ class views_plugin_display extends views
         'default' => array(),
         'export' => 'export_item',
       ),
-      'access' => array(
-        'contains' => array(
-          'type' => array('default' => 'none'),
-         ),
-      ),
-      'cache' => array(
-        'contains' => array(
-          'type' => array('default' => 'none'),
-         ),
-      ),
+
       'title' => array(
         'default' => '',
         'translatable' => TRUE,
@@ -342,6 +336,7 @@ class views_plugin_display extends views
       ),
       'use_ajax' => array(
         'default' => FALSE,
+        'bool' => TRUE,
       ),
       'items_per_page' => array(
         'default' => 10,
@@ -351,15 +346,18 @@ class views_plugin_display extends views
       ),
       'use_pager' => array(
         'default' => FALSE,
+        'bool' => TRUE,
       ),
       'pager_element' => array(
         'default' => 0,
       ),
       'use_more' => array(
         'default' => FALSE,
+        'bool' => TRUE,
       ),
       'use_more_always' => array(
         'default' => FALSE,
+        'bool' => TRUE,
       ),
       'use_more_text' => array(
         'default' => 'more',
@@ -370,33 +368,61 @@ class views_plugin_display extends views
       ),
       'distinct' => array(
         'default' => FALSE,
+        'bool' => TRUE,
       ),
       'group_by' => array(
         'default' => FALSE,
+        'bool' => TRUE,
+      ),
+
+      // These types are all plugins that can have individual settings
+      // and therefore need special handling.
+      'access' => array(
+        'contains' => array(
+          'type' => array('default' => 'none', 'export' => 'export_plugin'),
+         ),
+      ),
+      'cache' => array(
+        'contains' => array(
+          'type' => array('default' => 'none', 'export' => 'export_plugin'),
+         ),
+      ),
+      // Note that exposed_form plugin has options in a separate array,
+      // while access and cache do not. access and cache are legacy and
+      // that pattern should not be repeated, but it is left as is to
+      // reduce the need to modify older views. Let's consider the
+      // pattern used here to be the template from which future plugins
+      // should be copied.
+      'exposed_form' => array(
+        'contains' => array(
+          'type' => array('default' => 'basic', 'export' => 'export_plugin'),
+          'options' => array('default' => array(), 'export' => FALSE),
+         ),
       ),
 
+      // Note that the styles have their options completely independent.
+      // Like access and cache above, this is a legacy pattern and
+      // should not be repeated.
       'style_plugin' => array(
         'default' => 'default',
+        'export' => 'export_style',
       ),
       'style_options' => array(
         'default' => array(),
+        'export' => FALSE,
       ),
       'row_plugin' => array(
         'default' => 'fields',
+        'export' => 'export_style',
       ),
       'row_options' => array(
         'default' => array(),
+        'export' => FALSE,
       ),
 
       'exposed_block' => array(
         'default' => FALSE,
       ),
-      'exposed_form' => array(
-        'contains' => array(
-          'type' => array('default' => 'basic'),
-          'options' => array('default' => array()),
-         ),
-      ),
     );
 
     if ($this->is_default_display()) {
@@ -508,67 +534,38 @@ class views_plugin_display extends views
    * Get the display or row plugin, if it exists.
    */
   function get_plugin($type = 'style', $name = NULL) {
-    if (!$name) {
-      $name = $this->get_option($type . '_plugin');
+    switch ($type) {
+      case 'style':
+      case 'row':
+        $option_name = $type . '_plugin';
+        $options = $this->get_option($type . '_options');
+        if (!$name) {
+          $name = $this->get_option($option_name);
+        }
+
+        break;
+      default:
+        $option_name = $type;
+        $options = $this->get_option($type);
+        if (!$name) {
+          $name = $options['type'];
+        }
+
+        // access & cache store their options as siblings with the
+        // type; all others use an 'options' array.
+        if ($type != 'access' && $type != 'cache') {
+          $options = $options['options'];
+        }
     }
 
     $plugin = views_get_plugin($type, $name);
     if ($plugin) {
-      $options = $this->get_option($type . '_options');
       $plugin->init($this->view, $this->display, $options);
       return $plugin;
     }
   }
 
   /**
-   * Get the access plugin
-   */
-  function get_access_plugin($name = NULL) {
-    if (!$name) {
-      $access = $this->get_option('access');
-      $name = $access['type'];
-    }
-
-    $plugin = views_get_plugin('access', $name);
-    if ($plugin) {
-      $plugin->init($this->view, $this->display);
-      return $plugin;
-    }
-  }
-
-  /**
-   * Get the cache plugin
-   */
-  function get_cache_plugin($name = NULL) {
-    if (!$name) {
-      $cache = $this->get_option('cache');
-      $name = $cache['type'];
-    }
-
-    $plugin = views_get_plugin('cache', $name);
-    if ($plugin) {
-      $plugin->init($this->view, $this->display);
-      return $plugin;
-    }
-  }
-
-  /**
-   * Get the exposed form plugin
-   */
-  function get_exposed_form_plugin($name = NULL) {
-    if (!$name) {
-      $exposed_form = $this->get_option('exposed_form');
-      $name = $exposed_form['type'];
-    }
-
-    $plugin = views_get_plugin('exposed_form', $name);
-    if ($plugin) {
-      $plugin->init($this->view, $this->display);
-      return $plugin;
-    }
-  }
-
-  /**
    * Get the handler object for a single handler.
    */
   function &get_handler($type, $id) {
@@ -790,7 +787,7 @@ class views_plugin_display extends views
       );
     }
 
-    $access_plugin = $this->get_access_plugin();
+    $access_plugin = $this->get_plugin('access');
     if (!$access_plugin) {
       // default to the no access control plugin.
       $access_plugin = views_get_plugin('access', 'none');
@@ -809,7 +806,7 @@ class views_plugin_display extends views
       $options['access']['links']['access_options'] = t('Change settings for this access type.');
     }
 
-    $cache_plugin = $this->get_cache_plugin();
+    $cache_plugin = $this->get_plugin('cache');
     if (!$cache_plugin) {
       // default to the no cache control plugin.
       $cache_plugin = views_get_plugin('cache', 'none');
@@ -859,7 +856,7 @@ class views_plugin_display extends views
       'desc' => t('Allow the exposed form to appear in a block instead of the view.'),
     );
 
-    $exposed_form_plugin = $this->get_exposed_form_plugin();
+    $exposed_form_plugin = $this->get_plugin('exposed_form');
     if (!$exposed_form_plugin) {
       // default to the no cache control plugin.
       $exposed_form_plugin = views_get_plugin('exposed_form', 'basic');
@@ -1060,7 +1057,7 @@ class views_plugin_display extends views
         break;
       case 'access_options':
         $access = $this->get_option('access');
-        $plugin = $this->get_access_plugin();
+        $plugin = $this->get_plugin('access');
         $form['#title'] .= t('Access options');
         if ($plugin) {
           $form['#help_topic'] = $plugin->definition['help topic'];
@@ -1101,7 +1098,7 @@ class views_plugin_display extends views
         break;
       case 'cache_options':
         $cache = $this->get_option('cache');
-        $plugin = $this->get_cache_plugin();
+        $plugin = $this->get_plugin('cache');
         $form['#title'] .= t('Caching options');
         if ($plugin) {
           $form['#help_topic'] = $plugin->definition['help topic'];
@@ -1487,8 +1484,7 @@ class views_plugin_display extends views
         }
         break;
       case 'exposed_form_options':
-        $exposed_form = $this->get_option('exposed_form');
-        $plugin = $this->get_exposed_form_plugin();
+        $plugin = $this->get_plugin('exposed_form');
         $form['#title'] .= t('Exposed form options');
         if ($plugin) {
           $form['#help_topic'] = $plugin->definition['help topic'];
@@ -1554,19 +1550,19 @@ class views_plugin_display extends views
         }
         break;
       case 'access_options':
-        $plugin = $this->get_access_plugin();
+        $plugin = $this->get_plugin('access');
         if ($plugin) {
           $plugin->options_validate($form['access_options'], $form_state);
         }
         break;
       case 'cache_options':
-        $plugin = $this->get_cache_plugin();
+        $plugin = $this->get_plugin('cache');
         if ($plugin) {
           $plugin->options_validate($form['cache_options'], $form_state);
         }
         break;
       case 'exposed_form_options':
-        $plugin = $this->get_exposed_form_plugin();
+        $plugin = $this->get_plugin('exposed_form');
         if ($plugin) {
           $plugin->options_validate($form['exposed_form_options'], $form_state);
         }
@@ -1580,7 +1576,7 @@ class views_plugin_display extends views
    */
   function options_submit(&$form, &$form_state) {
     // Not sure I like this being here, but it seems (?) like a logical place.
-    $cache_plugin = $this->get_cache_plugin();
+    $cache_plugin = $this->get_plugin('cache');
     if ($cache_plugin) {
       $cache_plugin->cache_flush();
     }
@@ -1725,7 +1721,7 @@ class views_plugin_display extends views
 
         break;
       case 'exposed_form_options':
-        $plugin = $this->get_exposed_form_plugin();
+        $plugin = $this->get_plugin('exposed_form');
         if ($plugin) {
           $exposed_form = $this->get_option('exposed_form');
           $plugin->options_submit($form['exposed_form_options'], $form_state);
@@ -1928,7 +1924,7 @@ class views_plugin_display extends views
       return TRUE;
     }
 
-    $plugin = $this->get_access_plugin();
+    $plugin = $this->get_plugin('access');
     if ($plugin) {
       return $plugin->access($account);
     }
@@ -2071,6 +2067,131 @@ class views_plugin_display extends views
     }
   }
 
+  /**
+   * Override of export_option()
+   *
+   * Because displays do not want to export options that are NOT overridden from the
+   * default display, we need some special handling during the export process.
+   */
+  function export_option($indent, $prefix, $storage, $option, $definition, $parents) {
+    // The $prefix is wrong because we store our actual options a little differently:
+    $prefix = '$handler->display->display_options';
+    $output = '';
+    if (!$parents && !$this->is_default_display()) {
+      // Do not export items that are not overridden.
+      if ($this->is_defaulted($option)) {
+        return;
+      }
+
+      // If this is not defaulted and is overrideable, flip the switch to say this
+      // is overridden.
+      if ($this->defaultable_sections($option)) {
+        $output .= $indent . $prefix . "['defaults']['$option'] = FALSE;\n";
+      }
+    }
+
+    $output .= parent::export_option($indent, $prefix, $storage, $option, $definition, $parents);
+    return $output;
+  }
+
+  /**
+   * Special method to export items that have handlers.
+   *
+   * This method was specified in the option_definition() as the method to utilize to
+   * export fields, filters, sort criteria, relationships and arguments. This passes
+   * the export off to the individual handlers so that they can export themselves
+   * properly.
+   */
+  function export_item($indent, $prefix, $storage, $option, $definition, $parents) {
+    $output = '';
+
+    // cut the 's' off because the data is stored as the plural form but we need
+    // the singular form. Who designed that anyway? Oh yeah, I did. :(
+    $type = substr($option, 0, -1);
+    foreach ($storage[$option] as $id => $info) {
+      $handler = views_get_handler($info['table'], $info['field'], $type);
+      if ($handler) {
+        $handler->init($this->view, $info);
+        $output .= $indent . $prefix . "['$option']['$id']['id'] = '$id';\n";
+        $output .= $indent . $prefix . "['$option']['$id']['table'] = '$info[table]';\n";
+        $output .= $indent . $prefix . "['$option']['$id']['field'] = '$info[field]';\n";
+        $output .= $handler->export_options($indent, $prefix . "['$option']['$id']");
+      }
+
+      // Prevent reference problems.
+      unset($handler);
+    }
+
+    return $output;
+  }
+
+  /**
+   * Special handling for the style export.
+   *
+   * Styles are stored as style_plugin and style_options or row_plugin and
+   * row_options accordingly. The options are told not to export, and the
+   * export for the plugin should export both.
+   */
+  function export_style($indent, $prefix, $storage, $option, $definition, $parents) {
+    $output = '';
+    $style_plugin = $this->get_plugin();
+    if ($option == 'style_plugin') {
+      $type = 'style';
+      $options_field = 'style_options';
+      $plugin = $style_plugin;
+    }
+    else {
+      if (!$style_plugin || !$style_plugin->uses_row_plugin()) {
+        return;
+      }
+
+      $type = 'row';
+      $options_field = 'row_options';
+      $plugin = $this->get_plugin('row');
+      // If the style plugin doesn't use row plugins, don't even bother.
+    }
+
+    if ($plugin) {
+      // Write which plugin to use.
+      $value = $this->get_option($option);
+      $output .= $indent . $prefix . "['$option'] = '$value';\n";
+
+      // Pass off to the plugin to export itself.
+      $output .= $plugin->export_options($indent, $prefix . "['$options_field']");
+    }
+
+    return $output;
+  }
+
+  /**
+   * Special handling for plugin export
+   *
+   * Plugins other than styles are stored in array with 'type' being the key
+   * to the plugin. For modern plugins, the options are stored in the 'options'
+   * array, but for legacy plugins (access and cache) options are stored as
+   * siblings to the type.
+   */
+  function export_plugin($indent, $prefix, $storage, $option, $definition, $parents) {
+    $output = '';
+    $plugin_type = end($parents);
+    $plugin = $this->get_plugin($plugin_type);
+    if ($plugin) {
+      // Write which plugin to use.
+      $value = $storage[$option];
+      $new_prefix = $prefix . "['$plugin_type']";
+
+      $output .= $indent . $new_prefix . "['$option'] = '$value';\n";
+
+      if ($plugin_type != 'access' && $plugin_type!= 'cache') {
+        $new_prefix .= "['options']";
+      }
+
+      // Pass off to the plugin to export itself.
+      $output .= $plugin->export_options($indent, $new_prefix);
+    }
+
+    return $output;
+  }
 }
 
 
Index: plugins/views_plugin_display_page.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_display_page.inc,v
retrieving revision 1.5.2.3
diff -u -p -r1.5.2.3 views_plugin_display_page.inc
--- plugins/views_plugin_display_page.inc	26 Jun 2009 00:23:37 -0000	1.5.2.3
+++ plugins/views_plugin_display_page.inc	14 Nov 2009 00:59:07 -0000
@@ -66,7 +66,7 @@ class views_plugin_display_page extends 
 
     $path = implode('/', $bits);
 
-    $access_plugin = $this->get_access_plugin();
+    $access_plugin = $this->get_plugin('access');
 
     if ($path) {
       $items[$path] = array(
Index: plugins/views_plugin_style_summary.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_style_summary.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_plugin_style_summary.inc
--- plugins/views_plugin_style_summary.inc	3 Sep 2008 19:21:30 -0000	1.1
+++ plugins/views_plugin_style_summary.inc	14 Nov 2009 00:59:07 -0000
@@ -14,8 +14,8 @@ class views_plugin_style_summary extends
   function option_definition() {
     $options = parent::option_definition();
 
-    $options['count'] = array('default' => TRUE);
-    $options['override'] = array('default' => FALSE);
+    $options['count'] = array('default' => TRUE, 'bool' => TRUE);
+    $options['override'] = array('default' => FALSE, 'bool' => TRUE);
     $options['items_per_page'] = array('default' => 25);
 
     return $options;
