# This patch file was generated by NetBeans IDE
# This patch can be applied using context Tools: Apply Diff Patch action on respective folder.
# It uses platform neutral UTF-8 encoding.
# Above lines and this line are ignored by the patching process.
Index: contributions/modules/image/contrib/image_gallery/image_gallery.module
--- contributions/modules/image/contrib/image_gallery/image_gallery.module Base (1.31)
+++ contributions/modules/image/contrib/image_gallery/image_gallery.module Locally Modified (Based On 1.31)
@@ -374,6 +374,12 @@
     'image_gallery' => array(
       'arguments' => array('galleries' => NULL, 'images' => NULL),
     ),
+    'image_gallery_count' => array(
+      'arguments' => array('count' => 0),
+    ),
+    'image_gallery_updated' => array(
+      'arguments' => array('timestamp' => 0),
+    ),
     'image_gallery_img' => array(
       'arguments' => array('image' => NULL, 'size' => NULL),
     ),
@@ -450,6 +456,20 @@
 }
 
 /**
+ * Theme the count of gallery items on a gallery list.
+ */
+function theme_image_gallery_count($count) {
+  return "There are $count images in this gallery.";
+}
+
+/**
+ * Theme the gallery last updated time on a gallery list.
+ */
+function theme_image_gallery_updated($timestamp) {
+  return '<p class="last">'. t('%date', array('%date' => format_date($timestamp))) ."</p>\n";
+}
+
+/**
  * Returns (and possibly creates) a new vocabulary for Image galleries.
  */
 function _image_gallery_get_vid() {
@@ -467,3 +487,13 @@
 
   return $vid;
 }
+
+/**
+ * Implementation of hook_views_api().
+ */
+function image_gallery_views_api() {
+  return array(
+    'api' => 2,
+    'path' => drupal_get_path('module', 'image_gallery') .'/views',
+  );
+}
Index: contributions/modules/image/contrib/image_gallery/views/image_gallery.views.inc
--- contributions/modules/image/contrib/image_gallery/views/image_gallery.views.inc Base (1.1)
+++ contributions/modules/image/contrib/image_gallery/views/image_gallery.views.inc Locally Modified (Based On 1.1)
@@ -6,3 +6,327 @@
  * Image Gallery views integration.
  */
 
+/*
+ * strategy
+ * 
+ * two ways of getting the image gallery cover image
+ * - a plain field. This allows complex code like recursion (check the gallery itself, 
+ * if empty, check the child galleries, etc)
+ * Plain field also allows us to grab the sort order set on the gallery images 
+ * and get the first image from that order as the front.
+ * (combining the two options will be MONSTROUS!)
+ * - a relationship
+ * This gets us onto the node table, so any fields can be used for the cover.
+ * Depth should be possible too -- eg, "the newest image out of the gammery or its immediate children"
+ *
+ * so we want two families of handlers
+ * - field handlers
+ * - relationship handlers
+ *
+ * top-level classes should cover all the depth and recursion stuff.
+ */
+
+
+
+/**
+ * Implementation of hook_views_data_alter().
+ * Add fields for image gallery (ie vocabulary terms) to the term_data table.
+ */
+function image_gallery_views_data_alter(&$data) {
+  // ----------------------------------------------------------------------
+  // Relationships for cover node.
+  //
+  // These allow any node field to be used to create the gallery cover node.
+  // The limitation, however, is that either consider the immediate gallery,
+  // or a flat pool of the gallery and descendants.
+  // Note that a bug in Views -- http://drupal.org/node/380560 -- will cause
+  // an error message when adding node fields on these relationships.
+  $data['term_data']['gallery_cover_latest'] = array(
+    'group' => t('Image gallery'),    
+    'relationship' => array(
+      'title' => t('Latest image'),
+      'label'  => t('Cover image, latest'),
+      'help' => t('Relate an image gallery to its most recently updated node (does not consider child galleries).'),
+      'handler' => 'image_gallery_handler_relationship_gallery_cover',
+      'base'   => 'node',
+      'field'  => 'nid',
+      'correlated field' => 'tid',
+      'subquery order' => ' ORDER BY gallery_cover_node.created DESC ',
+      // TODO: standardize -- remove ORDER BY part!
+    ),
+  );
+  $data['term_data']['gallery_cover_oldest'] = array(
+    'group' => t('Image gallery'),
+    'relationship' => array(
+      'title' => t('Oldest image'),
+      'label'  => t('Cover image, oldest'),
+      'help' => t('Relate an image gallery to its oldest node (does not consider child galleries).'),
+      'handler' => 'image_gallery_handler_relationship_gallery_cover',
+      'base'   => 'node',
+      'field'  => 'nid',
+      'correlated field' => 'tid',
+      'subquery order' => ' ORDER BY gallery_cover_node.created ASC ',
+    ),
+  );
+  $data['term_data']['gallery_cover_node_title'] = array(
+    'group' => t('Image gallery'),
+    'relationship' => array(
+      'title' => t('First image by title'),
+      'label'  => t('Cover image, first by title'),
+      'help' => t('Relate an image gallery to its first node when sorted by title (does not consider child galleries).'),
+      'handler' => 'image_gallery_handler_relationship_gallery_cover',
+      'base'   => 'node',
+      'field'  => 'nid',
+      'correlated field' => 'tid',
+      'subquery order' => ' ORDER BY gallery_cover_node.title ASC ',
+    ),
+  );
+
+  // ----------------------------------------------------------------------
+  // Simple fields.
+
+  // Gallery count.
+  $data['term_data']['gallery_count'] = array(
+    'group' => t('Image gallery'),
+    'field' => array(
+      'title' => t('Count'),
+      'help' => t('Count of items in a gallery.'),
+      'handler' => 'image_gallery_handler_field_gallery_count',
+    ),
+  );
+  
+  // ----------------------------------------------------------------------
+  // Fields for cover image.
+  //
+  // These use a combination of code and separate queries to get a cover node.
+  // This makes them more powerful that using the relationship cover node,
+  // as we can consider child galleries recursively rather than just
+  // flattening all descendant galleries.
+  // We can also do complex things such as grab the top-most node from the
+  // gallery according to how the view for that gallery sorts them.
+  // The downside however is that without a relationship, the fields here are
+  // all you've got.
+  // To add more fields, define them on term_data and optionally add handlers.
+  // See image_gallery_handler_field_gallery_cover for more information.
+  $data['term_data']['gallery_latest_thumbnail'] = array(
+    'group' => t('Image gallery'),    
+    'field' => array(
+      'title' => t('Latest image'),
+      'help' => t('The most recently posted image in the gallery or its child galleries.'),
+      'handler' => 'image_gallery_handler_field_gallery_cover_thumbnail',
+      'order clause' => 'n.sticky DESC, n.created DESC',
+    ),
+  );
+  $data['term_data']['gallery_latest_time'] = array(
+    'group' => t('Image gallery'),    
+    'field' => array(
+      'title' => t('Last updated time'),
+      'help' => t('The time of the most recently posted image in the gallery or its child galleries.'),
+      'handler' => 'image_gallery_handler_field_gallery_cover_latest_time',
+      'order clause' => 'n.sticky DESC, n.created DESC',
+    ),
+  );
+  $data['term_data']['gallery_first_title'] = array(
+    'group' => t('Image gallery'),
+    'field' => array(
+      'title' => t('First image by title'),
+      'help' => t('The first posted image in the gallery or its child galleries.'),
+      'handler' => 'image_gallery_handler_field_gallery_cover_thumbnail',
+      'order clause' => 'n.sticky DESC, n.title ASC',
+    ),
+  );
+  $data['term_data']['gallery_oldest_thumbnail'] = array(
+    'group' => t('Image gallery'),
+    'field' => array(
+      'title' => t('Oldest image'),
+      'help' => t('The first posted image in the gallery or its child galleries.'),
+      'handler' => 'image_gallery_handler_field_gallery_cover_thumbnail',
+      'order clause' => 'n.sticky DESC, n.created ASC',
+    ),
+  );
+
+  // Cover from the gallery view sort order. TODO: better name!
+  $data['term_data']['gallery_cover_view_first_thumbnail'] = array(
+    'group' => t('Image gallery'),
+    'field' => array(
+      'title' => t('Cover image (view)'),
+      'help' => t('The cover thumbnail from the gallery, given by the gallery view sort order.'),
+      'handler' => 'image_gallery_handler_field_gallery_cover_gallery_view_first',
+    ),
+  );
+
+  // Add a parent term argument to the term_hierarchy table.
+  // We need this because the Views relationship won't work for top-level
+  // terms that have no parent. See http://drupal.org/node/408180 for details.
+  $data['term_hierarchy']['image_gallery_parent'] = array(
+     'real field' => 'parent',
+    'title' => t('Parent term'),
+    'help' => t('The parent term of the term. This can produce duplicate entries if you are using a vocabulary that allows multiple parents.'),
+    'argument' => array(
+      'handler' => 'views_handler_argument_numeric',
+    ),
+  );
+
+}
+
+/**
+ * Implementation of hook_views_handlers().
+ */
+function image_gallery_views_handlers() {
+  return array(
+    'info' => array(
+      'path' => drupal_get_path('module', 'image_gallery') . '/views',
+    ),
+    'handlers' => array(
+      'image_gallery_handler_field_gallery_count' => array(
+        'parent' => 'views_handler_field_taxonomy',
+      ),
+      'image_gallery_handler_field_gallery_cover' => array(
+        'parent' => 'views_handler_field_taxonomy',
+     ),
+      'image_gallery_handler_field_gallery_cover_thumbnail' => array(
+        'parent' => 'image_gallery_handler_field_gallery_cover',
+     ),
+      'image_gallery_handler_field_gallery_cover_latest_time' => array(
+        'parent' => 'image_gallery_handler_field_gallery_cover',
+      ),
+      // uses gallery view to get first
+      // slightly skewed inheritance so we don't have to repeat all the image code
+      'image_gallery_handler_field_gallery_cover_gallery_view_first' => array(
+        'parent' => 'image_gallery_handler_field_gallery_cover_thumbnail',
+      ),
+      // gallery cover relationship
+      'image_gallery_handler_relationship_gallery_cover' => array(
+        'parent' => 'views_handler_relationship',
+      ),
+      // plugins
+      'image_gallery_plugin_display_image_gallery' => array(
+         'parent' => 'views_plugin_display_page',
+      ),
+    ),
+  );
+}
+
+
+/**
+ * Implementation of hook_views_plugins().
+ */
+function image_gallery_views_plugins() {
+  return array(
+    'display' => array(
+      'image_gallery' => array(
+        'title' => t('Gallery'),
+        'help' => t('Display the view as a gallery of images, with a URL and menu links.'),
+        'handler' => 'image_gallery_plugin_display_image_gallery',
+        'theme' => 'views_view', // TODO ??
+        'uses hook menu' => TRUE,
+        'use ajax' => TRUE,
+        'use pager' => TRUE,
+        'accept attachments' => TRUE,
+        'admin' => t('Page'),
+        'help topic' => 'display-page', // TODO
+        'parent' => 'page',
+        'path' => drupal_get_path('module', 'image_gallery') . '/views',
+
+      ),
+    ),
+  );
+}
+
+
+/**
+ * Join handler for relationships that join with a subquery as the left field.
+ * To use this join, set 'left query' in the definition as a subquery to go on the
+ * left side of the JOIN condition, ie:
+ *   LEFT JOIN node node_term_data ON ([YOUR SUBQUERY HERE]) = node_term_data.nid
+ */
+class image_gallery_join_subquery extends views_join {
+  // PHP 4 doesn't call constructors of the base class automatically from a
+  // constructor of a derived class. It is your responsibility to propagate
+  // the call to constructors upstream where appropriate.
+  function construct($table = NULL, $left_table = NULL, $left_field = NULL, $field = NULL, $extra = array(), $type = 'LEFT') {
+    parent::construct($table, $left_table, $left_field, $field, $extra, $type);
+
+    $this->left_query = $this->definition['left query'];
+  }
+
+  /**
+   * Build the SQL for the join this object represents.
+   */
+  function join($table, &$query) {
+    $left = $query->get_table_info($this->left_table);
+    $output = " $this->type JOIN {" . $this->table . "} $table[alias] ON ($this->left_query) = $table[alias].$this->field";
+
+    // Tack on the extra.
+    if (isset($this->extra)) {
+      if (is_array($this->extra)) {
+        $extras = array();
+        foreach ($this->extra as $info) {
+          $extra = '';
+          // Figure out the table name. Remember, only use aliases provided
+          // if at all possible.
+          $join_table = '';
+          if (!array_key_exists('table', $info)) {
+            $join_table = $table['alias'] . '.';
+          }
+          elseif (isset($info['table'])) {
+            $join_table = $info['table'] . '.';
+          }
+
+          // And now deal with the value and the operator.  Set $q to
+          // a single-quote for non-numeric values and the
+          // empty-string for numeric values, then wrap all values in $q.
+          $raw_value = $this->db_safe($info['value']);
+          $q = (empty($info['numeric']) ? "'" : '');
+
+          if (is_array($raw_value)) {
+            $operator = !empty($info['operator']) ? $info['operator'] : 'IN';
+            // Transform from IN() notation to = notation if just one value.
+            if (count($raw_value) == 1) {
+              $value = $q . array_shift($raw_value) . $q;
+              $operator = $operator == 'NOT IN' ? '!=' : '=';
+            }
+            else {
+              $value = "($q" . implode("$q, $q", $raw_value) . "$q)";
+            }
+          }
+          else {
+            $operator = !empty($info['operator']) ? $info['operator'] : '=';
+            $value = "$q$raw_value$q";
+          }
+          $extras[] = "$join_table$info[field] $operator $value";
+        }
+
+        if ($extras) {
+          if (count($extras) == 1) {
+            $output .= ' AND ' . array_shift($extras);
+          }
+          else {
+            $output .= ' AND (' . implode(' ' . $this->extra_type . ' ', $extras) . ')';
+          }
+        }
+      }
+      else if ($this->extra && is_string($this->extra)) {
+        $output .= " AND ($this->extra)";
+      }
+    }
+    return $output;
+  }
+} // class image_gallery_join_subquery
+
+
+/**
+ * Gallery Display -- add the gallery view above the gallery image view
+ *
+ * also show, optionally, the gallery term description above its images
+ *
+ * IRC:: What's the best way to programatically insert code into a view header?
+ *  hook_views_pre_render() and append to $view->display['mydisplay']->display_options['header']
+ *
+ *
+ *
+ *
+ *
+ */
+
+// end
\ No newline at end of file
Index: contributions/modules/image/contrib/image_gallery/views/image_gallery_handler_field_gallery_count.inc
--- contributions/modules/image/contrib/image_gallery/views/image_gallery_handler_field_gallery_count.inc No Base Revision
+++ contributions/modules/image/contrib/image_gallery/views/image_gallery_handler_field_gallery_count.inc Locally New
@@ -0,0 +1,31 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Views handler for Image gallery count field.
+ */
+
+/**
+ * TODO
+ */
+class image_gallery_handler_field_gallery_count extends views_handler_field_taxonomy {  
+  /**
+   * Override query() so we don't query: fake field.
+   */
+  function query() {
+    $this->ensure_my_table();
+    $this->add_additional_fields();
+  }
+  
+  /**
+   * Returns field html.
+   */
+  function render($values) {
+    $count = taxonomy_term_count_nodes($values->tid, 'image');
+    $output = theme('image_gallery_count', $count);
+    return $this->render_link($output, $values);
+  }
+
+}
+
Index: contributions/modules/image/contrib/image_gallery/views/image_gallery_handler_field_gallery_cover.inc
--- contributions/modules/image/contrib/image_gallery/views/image_gallery_handler_field_gallery_cover.inc No Base Revision
+++ contributions/modules/image/contrib/image_gallery/views/image_gallery_handler_field_gallery_cover.inc Locally New
@@ -0,0 +1,213 @@
+<?php
+// $Id//
+
+/**
+ * Parent class for fields that gives us the cover.
+ *
+ * This takes care of defining the descendant and depth options, getting and
+ * storing a query, and running the query to get the cover nid.
+ *
+ * There are several ways to use this class:
+ * - Define the ordering in the field definition, with an 'order clause'.
+ *   This gets tacked onto the fairly simple node query defined in this handler.
+ * - Define your own query in the field definition with a 'basic query' key.
+ * - Subclass this handler and create your own query by overriding
+ *   get_cover_node_nid_query(). This allows some pretty complex stuff, such as
+ *   grabbing the query from another view.
+ */
+class image_gallery_handler_field_gallery_cover extends views_handler_field_taxonomy {
+  /**
+   * Constructor to provide additional fields to add.
+   */
+  function construct() {
+    parent::construct();
+
+    $this->additional_fields['tid'] = 'tid';
+  }
+
+  function init(&$view, $options) {
+    parent::init($view, $options);
+
+    $this->vid = _image_gallery_get_vid();
+
+    // The name of a key that is safe to use in $values to stash our nid.
+    // This is just a dummy that should be overridden.
+    // Groups of handlers that use the same query (eg, latest image and last
+    // update time) should override this to a safe key that they can share.
+    // This avoids running the query/ies to get the cover nid multiple times for
+    // each row of the view.
+    // TODO: doesn't work and probably can't ever.
+    if ($this->definition['cover group']) {
+      $this->cover_stash =  $this->definition['cover group'];
+    }
+    else {
+      $this->cover_stash =  'image_gallery_cover';
+    }
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['depth'] = array('default' => 0);
+    $options['descendants'] = array('default' => 'single');
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $form['descendants'] = array(
+      '#type' => 'radios',
+      '#title' => t('Descendant handling'),
+      '#description' => // COMING SOON theme('advanced_help_topic', 'image_gallery', 'descendants') .
+        t('How to handle images from subgalleries: either only choose a cover from this gallery itself, or consider subgalleries all together, or recurse into subgalleries if the gallery itself is empty.'),
+      '#options' => array(
+        'single'  => t('Only get a cover image from this gallery'),
+        'flat'    => t('Consider subgalleries, flattened.'),
+        'recurse' => t('Consider subgalleries, recursively. (Warning: this can produce many queries per row if your parent galleries are empty!).'),
+      ),
+      '#default_value' => $this->options['descendants'],
+    );
+
+    $form['depth'] = array(
+      '#type' => 'weight',
+      '#title' => t('Depth'),
+      '#default_value' => $this->options['depth'],
+      '#description' => t('How deeply to go into subgalleries if one of the descendant options is selected above.'),
+    );
+
+  }
+
+  /**
+   * Get the cover nid for the current tid.
+   *
+   * This makes up our query from the field definition and handler functions,
+   * and then runs it according to the descendant and depth options given
+   * for the field.
+   */
+  function get_cover_node_nid($values) {
+    // The term id of the current gallery.
+    // This comes straight from the database row so should be safe for
+    // inclusion in a query.
+    $tid = $values->tid;
+
+    // Get the basic query but only once for all rows of the view.
+    // This can be set in the handler definition, or in the handler class's
+    // get_cover_node_nid_query function for more complex cases.
+    // The handler definition takes priority over the function.
+    // This is stored in the handler object so we only have to get it
+    // once for the whole view.
+    if (!isset($this->basic_query)) {
+      if (isset($this->definition['basic query'])) {
+        $this->basic_query = $this->definition['basic query'];
+      }
+      else {
+        $this->basic_query = $this->get_cover_node_nid_query();
+      }
+    }
+    
+    // If we don't have a query, return NULL now to prevent SQL errors.
+    if (is_null($this->basic_query)) {
+      return NULL;
+    }
+
+    // Add the definition's ORDER clause, if there is one.
+    if ($this->definition['order clause']) {
+      $this->basic_query = str_replace('***ORDER_CLAUSE***', $this->definition['order clause'], $this->basic_query);
+    }
+
+    // Add our WHERE clause.
+    switch ($this->options['descendants']) {
+      // Plain: only consider this gallery.
+      // Recursive: only consider this gallery (we'll recurse later)
+      case 'single':
+      case 'recurse':
+        $where_clause = "tn.tid = $tid ";
+        $query = str_replace('***WHERE_CLAUSE***', $where_clause, $this->basic_query);
+        break;
+      // Flat: all descendant galleries considered for the cover query.
+      case 'flat':
+        $tree = taxonomy_get_tree($this->vid, $tid, -1, $this->options['depth']);
+        $descendant_tids = array_merge(array($tid), array_map('_taxonomy_get_tid_from_term', $tree));
+        // The values of $descendant_tids should be safe for raw inclusion in the
+        // SQL since they're all loaded from integer fields in the database.
+        $where_clause = 'tn.tid IN (' . implode(',', $descendant_tids) . ')';
+        $query = str_replace('***WHERE_CLAUSE***', $where_clause, $this->basic_query);
+        break;
+    }
+
+    #dsm($query);
+
+    // Run the query to get the cover nid.
+    if ($nid = db_result(db_query_range(db_rewrite_sql($query), '', 0, 1))) {
+      return $nid;
+    }
+
+    // We have no nid: the gallery is empty. Should we recurse?
+    if ($this->options['descendants'] == 'recurse' && $this->options['depth'] > 0) {
+      $nid = $this->get_cover_node_nid_recurse($tid, 1);
+      return $nid;
+    }
+  }
+
+  /**
+   * Recursively query descendant tids until we get a cover nid.
+   *
+   * Warning! This is probably quite intensive, as it drills down the term
+   * hierarchy doing a query on each term until it finds a node -- and this is
+   * done for EVERY row of the main gallery term view!
+   *
+   * @param $tid The tid whose children we should investigate for a cover nid.
+   * @param $recurse The current recursion depth.
+   */
+  function get_cover_node_nid_recurse($tid, $recurse) {
+    $tree = taxonomy_get_tree($this->vid, $tid, -1, 1);
+    foreach ($tree as $term) {
+      $where_clause = 'tn.tid = ' . $term->tid;
+      $query = str_replace('***WHERE_CLAUSE***', $where_clause, $this->basic_query);
+      if ($nid = db_result(db_query_range(db_rewrite_sql($query), '', 0, 1))) {
+        return $nid;
+      }
+
+      // Recurse into this gallery, if we may.
+      if ($this->options['depth'] > $recurse) {
+        if ($nid = $this->get_cover_node_nid_recurse($term->tid, $recurse + 1)) {
+          return $nid;
+        }
+      }
+    }
+  }
+
+  /**
+   * The query this handler should use to gets its cover node id, unless
+   * the field definition specifies one.
+   *
+   * The return string should include a placeholder for the WHERE clause
+   * as in this basic case. This is where the tid(s) will go.
+   * The order clause should be supplied by the handler definition.
+   * Warning: this is NOT sophisticated stuff. The WHERE clause inserted into
+   * this string will expect to find a row "tn.tid" in the query.
+   */
+  function get_cover_node_nid_query() {
+    return 'SELECT n.nid from {node} n INNER JOIN {term_node} tn ON n.nid = tn.nid ' .
+        "WHERE ***WHERE_CLAUSE*** AND n.type = 'image' AND n.status = 1 " .
+        'ORDER BY ***ORDER_CLAUSE***';
+  }
+
+  /**
+   * Override query() so we don't query: fake field.
+   */
+  function query() {
+    $this->ensure_my_table();
+    $this->add_additional_fields();
+  }
+
+  /**
+   * Returns field html. Just a dummy to inherit.
+   */
+  function render($values) {
+    $nid = $this->get_cover_node_nid($values);
+    return $nid;
+  }
+}
\ No newline at end of file
Index: contributions/modules/image/contrib/image_gallery/views/image_gallery_handler_field_gallery_cover_gallery_view_first.inc
--- contributions/modules/image/contrib/image_gallery/views/image_gallery_handler_field_gallery_cover_gallery_view_first.inc No Base Revision
+++ contributions/modules/image/contrib/image_gallery/views/image_gallery_handler_field_gallery_cover_gallery_view_first.inc Locally New
@@ -0,0 +1,97 @@
+<?php
+// $Id$
+
+/**
+ * Field handler to return the cover image according to the sort order of the
+ * gallery image view.
+ * WARNING: doing complex things to your gallery image view will break this!
+ * Slightly skewed inheritance so we don't have to repeat all the image code.
+ */
+class image_gallery_handler_field_gallery_cover_gallery_view_first extends image_gallery_handler_field_gallery_cover_thumbnail {
+
+  function get_cover_node_nid_query() {
+     $gallery_view = views_get_view('gallery'); // hardcoded view name.
+     // If the view doesn't exist, we're out of here.
+     if (!isset($gallery_view)) {
+       return NULL;
+     }
+
+     // do VIEW->preview stuff
+     $gallery_view->preview = TRUE;
+     $gallery_view->set_display('preview');
+
+     // must set $args
+     #$args = array($tid);
+
+/*
+ *
+ *
+ *     $preview = $view->preview($form_state['display_id'], $args);
+
+    // Get information from the preview for display.
+    if (!empty($view->build_info['query'])) {
+      $rows = array();
+      $query = db_prefix_tables($view->build_info['query']);
+
+ */
+
+      #dsm($gallery_view);
+     #$gallery_view->pre_execute($args);
+
+    // ugh!!!
+    //$gallery_view->display['default']->display_options['']
+
+     // calls DISPLAY->execute
+     $gallery_view->build('default'); // Build the query
+     // gets us a query obj.
+     // and builds up the query too! too much, can't alter it!
+
+
+
+
+     // can we add a WHERE here????
+     // $this->query->add_where(0, "$this->table_alias.$this->real_field IN ($subquery$where  )", $args);
+     $gallery_view->query->add_where(0, "45 = 45");
+     // nope!
+
+      // nicked from views admin.inc
+      $query = db_prefix_tables($gallery_view->build_info['query']);
+      if ($gallery_view->build_info['query_args']) {
+        _db_query_callback($gallery_view->build_info['query_args'], TRUE);
+        $query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query);
+      }
+
+
+    # dsm($gallery_view->build_info);
+     #dsm($gallery_view->build_info['query']);
+     #dsm($query);
+
+     ####!!! this gets us the query string!
+     ## stash it and play with it ;)
+
+     // override the set number of items per page to just get the first one.
+     $gallery_view->pager['items_per_page'] = 1;
+     // Some streamlining could be done here: execute does paging and allsorts.
+     $gallery_view->execute(); // Run the query
+     $gallery_view->post_execute();
+
+     //dsm($gallery_view->result);
+
+     $cover_nid = $gallery_view->result[0]->nid;
+
+     // We need to insert some placeholders
+     // Some assumptions:
+     // - the query already has a WHERE -- because image galleries
+     //   filter on node type at the very least!
+     // - the query has an ORDER BY clause -- because if your gallery has no
+     //   order why do you want to use its order here?
+     // - the query doesn't have a join to term_node -- the gallery view only
+     //   adds this when the argument is present.
+     $query = str_replace('WHERE', "INNER JOIN {term_node} tn ON node.nid = tn.nid \n WHERE", $query);
+     $query = str_replace('ORDER BY', " AND ***WHERE_CLAUSE***\n ORDER BY", $query);
+     
+     #dsm($query);
+
+     return $query;
+  }
+}
Index: contributions/modules/image/contrib/image_gallery/views/image_gallery_handler_field_gallery_cover_latest_time.inc
--- contributions/modules/image/contrib/image_gallery/views/image_gallery_handler_field_gallery_cover_latest_time.inc No Base Revision
+++ contributions/modules/image/contrib/image_gallery/views/image_gallery_handler_field_gallery_cover_latest_time.inc Locally New
@@ -0,0 +1,21 @@
+<?php
+// $Id$
+
+/**
+ * Field handler for the gallery's updated time.
+ */
+class image_gallery_handler_field_gallery_cover_latest_time extends image_gallery_handler_field_gallery_cover {
+
+  /**
+   * Returns field html.
+   */
+  function render($values) {
+    $nid = $this->get_cover_node_nid($values);
+
+    $latest_node = node_load($nid);
+    if ($latest_node->changed) {
+      $output = theme('image_gallery_updated', $latest_node->changed);
+      return $this->render_link($output, $values);
+    }
+  }
+}
Index: contributions/modules/image/contrib/image_gallery/views/image_gallery_handler_field_gallery_cover_thumbnail.inc
--- contributions/modules/image/contrib/image_gallery/views/image_gallery_handler_field_gallery_cover_thumbnail.inc No Base Revision
+++ contributions/modules/image/contrib/image_gallery/views/image_gallery_handler_field_gallery_cover_thumbnail.inc Locally New
@@ -0,0 +1,53 @@
+<?php
+// $Id$
+/**
+ * Field handler for gallery cover node image.
+ *
+ * Displays a thumbnail of the cover image node, at the chosen derivative size.
+ * This covers basic cases where the handler definition can specify the query
+ * and the order to get the cover node.
+ */
+class image_gallery_handler_field_gallery_cover_thumbnail extends image_gallery_handler_field_gallery_cover {
+  /**
+   * Defines default values for options.
+   */
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['image_derivative'] = array('default' => array(IMAGE_THUMBNAIL));
+
+    return $options;
+  }
+
+  /**
+   * Extends the field's basic options with more image specific
+   * options.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    foreach (image_get_sizes() as $key => $size) {
+      $sizes[$key] = $size['label'];
+    }
+    $form['image_derivative'] = array(
+      '#type' => 'select',
+      '#title' => t('Image size to show'),
+      '#options' => $sizes,
+      '#default_value' => $this->options['image_derivative'],
+      '#description' => t('Pick an image derivative to display.')
+    );
+  }
+
+  /**
+   * Returns field html.
+   */
+  function render($values) {
+    $nid = $this->get_cover_node_nid($values);
+
+    $latest_node = node_load($nid);
+    $output = image_display($latest_node, $this->options['image_derivative']);
+    return $nid . $this->render_link($output, $values);
+  }
+
+}
+
Index: contributions/modules/image/contrib/image_gallery/views/image_gallery_handler_relationship_gallery_cover.inc
--- contributions/modules/image/contrib/image_gallery/views/image_gallery_handler_relationship_gallery_cover.inc No Base Revision
+++ contributions/modules/image/contrib/image_gallery/views/image_gallery_handler_relationship_gallery_cover.inc Locally New
@@ -0,0 +1,196 @@
+<?php
+// $Id$
+/*
+ * @file
+ * Handlers for image gallery cover node.
+ *
+ * NOTE: a bug in Views -- http://drupal.org/node/380560 -- will cause
+ * errors when adding node fields on this relationship.
+ */
+
+/**
+ * Relationship handler for image gallery cover node.
+ *
+ * This joins to the node table from the term_data table, giving us a node
+ * based on the given term. This is the gallery's cover node, which supplies the
+ * image shown in the list of galleries.
+ * Using this relationship allows the user to add any node fields to the view.
+ * The downside is that while we can consider descendant galleries too, there is
+ * no recursion: setting a depth of 1 means "give me the (best) image out of
+ * the gallery and its immediate children" -- the images are considered
+ * as a flat pool from which to pick.
+ *
+ * This handler uses a special join object to create the relationship join on
+ * the value returned by a subquery.
+ * For example:
+ *  "given term tid 1, find the nid of the most recent node with that term"
+ *  in other words, the most recent image in this gallery.
+ *
+ * The main part of the query is provided in this handler.
+ * To use this, you need to give the subquery sort order, and the subquery's
+ * correlated field (the field from the main views query on which to link) --
+ * this is usually just 'tid'.
+ * 
+ * Define these as follows:
+ *  'relationship' => array(
+ *    'title' => t('Latest image'),
+ *    'label'  => t('Cover image, latest'),
+ *    'help' => t('Relate an image gallery to its most recently updated node (does not consider child galleries).'),
+ *    'handler' => 'image_gallery_handler_relationship_gallery_cover',
+ *    'base'   => 'node',
+ *    'field'  => 'nid',
+ *    'correlated field' => 'tid',
+ *    'subquery order' => ' ORDER BY gallery_cover_node.changed DESC ',
+ *  )
+ * This example gets you a cover image that is the latest changed node.
+ *
+ * If you need a different query, subclass this handler and override the
+ * left_query() method to return your own subquery on which to join.
+ */
+class image_gallery_handler_relationship_gallery_cover extends views_handler_relationship {
+  /**
+   * Defines default values for options.
+   */
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['depth'] = array('default' => array(1));
+
+    return $options;
+  }
+
+  /**
+   * Extends the field's basic options with more image specific
+   * options.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $form['depth'] = array(
+      '#type' => 'weight',
+      '#title' => t('Depth'),
+      '#default_value' => $this->options['depth'],
+      '#description' => t('The depth will determine how deep to look into descendant galleries to cover nodes.' .
+         'There is no recursion: so setting the depth to 1 will choose the best fitting node out of the pool of images in the gallery and its children taken all together.' .
+         'Setting this to 0 will only consider the gallery itself.'
+       ),
+    );
+  }
+
+  /**
+   * Return the subquery to use for the left side of the relationship join clause.
+   * 
+   */
+  function left_query() {
+    $order = $this->definition['subquery order'];
+    $field = $this->definition['correlated field'];
+    $where_tid = $this->table_alias . '.' . $field;
+
+
+    /*
+    // simple version
+    $subquery = 'SELECT gallery_cover_node.nid FROM ' .
+      '{term_node} gallery_cover_term_node INNER JOIN ' .
+      ' {node} gallery_cover_node ' .
+      'ON gallery_cover_term_node.nid = gallery_cover_node.nid ' .
+      'WHERE gallery_cover_node.status = 1 AND ' .
+      'gallery_cover_term_node.tid = ' . $where_tid . ' ' .
+      $order .
+      'LIMIT 1';
+    */
+    // now rip it up!
+
+    $subquery = "\nSELECT gallery_cover_node.nid FROM " .
+      "{term_node} gallery_cover_term_node INNER JOIN {node} gallery_cover_node \n" .
+      "ON gallery_cover_term_node.nid = gallery_cover_node.nid ";
+    $where = "  WHERE gallery_cover_node.status = 1 AND " .
+      "gallery_cover_term_node.tid = $where_tid ";
+
+    // Depth: this is shamelessly ripped from views_handler_argument_term_node_tid_depth
+    if ($this->options['depth'] > 0) {
+      $subquery .= "    LEFT JOIN {term_hierarchy} th ON th.tid = gallery_cover_term_node.tid\n";
+      $last = "th";
+      foreach (range(1, abs($this->options['depth'])) as $count) {
+        $subquery .= "    LEFT JOIN {term_hierarchy} th$count ON $last.parent = th$count.tid\n";
+        $where .= "\n OR th$count.tid = $where_tid\n";
+        $last = "th$count";
+      }
+    }
+    else if ($this->options['depth'] < 0) {
+      $last = "tn";
+      foreach (range(1, abs($this->options['depth'])) as $count) {
+        $subquery .= "    LEFT JOIN {term_hierarchy} th$count ON $last.tid = th$count.parent\n";
+        $where .= "\n OR th$count.tid = $where_tid\n";
+        $last = "th$count";
+      }
+    }
+    $subquery = "$subquery $where $order LIMIT 1";
+
+    dsm($subquery);
+
+    return $subquery;
+  }
+
+  /**
+   * Called to implement a relationship in a query.
+   */
+  function query() {
+    // Figure out what base table this relationship brings to the party.
+    $table_data = views_fetch_data($this->definition['base']);
+    $base_field = empty($this->definition['base field']) ? $table_data['table']['base']['field'] : $this->definition['base field'];
+
+    $this->ensure_my_table();
+
+    $def = $this->definition;
+    $def['table'] = $this->definition['base'];
+    $def['field'] = $base_field;
+    $def['left_table'] = $this->table_alias;
+    $def['left_field'] = $this->field;
+    if (!empty($this->options['required'])) {
+      $def['type'] = 'INNER';
+    }
+
+    if (!empty($this->definition['left query'])) {
+      $def['left query'] = $this->definition['left query'];
+    }
+    else {
+      $def['left query'] = $this->left_query();
+    }
+
+    if (!empty($def['join_handler']) && class_exists($def['join_handler'])) {
+      $join = new $def['join_handler'];
+    }
+    else {
+      $join = new image_gallery_join_subquery();
+    }
+
+    $join->definition = $def;
+    $join->construct();
+    $join->adjusted = TRUE;
+
+    // use a short alias for this:
+    $alias = $def['table'] . '_' . $this->table;
+
+    $this->alias = $this->query->add_relationship($alias, $join, $this->definition['base'], $this->relationship);
+  }
+}
+
+/**
+ * Subclass example.
+ */
+/*
+class image_gallery_handler_relationship_gallery_cover_example extends views_handler_relationship {
+  function left_query($field) {
+    $order = $this->definition['left query order'];
+    $sub_query = 'SELECT gallery_cover_node.nid FROM ' .
+      '{term_node} gallery_cover_term_node INNER JOIN ' .
+      ' {node} gallery_cover_node ' .
+      'ON gallery_cover_term_node.nid = gallery_cover_node.nid ' .
+      'WHERE gallery_cover_node.status = 1 AND ' .
+      'gallery_cover_term_node.tid = ' . $field . ' ' .
+      $order .
+      'LIMIT 1';
+
+    return $sub_query;
+  }
+*/
Index: contributions/modules/image/contrib/image_gallery/views/image_gallery_plugin_display_image_gallery.inc
--- contributions/modules/image/contrib/image_gallery/views/image_gallery_plugin_display_image_gallery.inc No Base Revision
+++ contributions/modules/image/contrib/image_gallery/views/image_gallery_plugin_display_image_gallery.inc Locally New
@@ -0,0 +1,24 @@
+<?php
+// $Id:$
+/**
+ * @file
+ * Contains the image gallery display plugin.
+ */
+
+/**
+ * The plugin that handles a full page.
+ *
+ * @ingroup views_display_plugins
+ */
+class image_gallery_plugin_display_image_gallery extends views_plugin_display_page {
+  /**
+   * Embed the gallery term view above the normal rendering of this view.
+   */
+  function render() {
+    $output = 'Show terms here. TODO.';
+
+    $output .= parent::render();
+
+    return $output;
+  }
+}
\ No newline at end of file

