From 02c45ad9bab0f2a24b8dae0991d8b2157bc7b151 Mon Sep 17 00:00:00 2001
From: Greg Brandysiewicz <tinker@200883.no-reply.drupal.org>
Date: Mon, 25 Mar 2013 11:03:29 -0700
Subject: [PATCH] Issue #982382 by tinker: Modified relation handler to properly select all transalted nodes in queues where option i18n is 1

---
 includes/views/nodequeue.views.inc                 |   81 ++++++++++++++++++++
 .../nodequeue_handler_relationship_nodequeue.inc   |   59 ++++++++++++++-
 2 files changed, 139 insertions(+), 1 deletions(-)

diff --git a/includes/views/nodequeue.views.inc b/includes/views/nodequeue.views.inc
index 5142cbf..679fd7b 100644
--- a/includes/views/nodequeue.views.inc
+++ b/includes/views/nodequeue.views.inc
@@ -319,3 +319,84 @@ function nodequeue_views_data_alter(&$data) {
     ),
   );
 }
+
+class views_join_nodequeue extends views_join {
+  /**
+   * Build the SQL for the join this object represents.
+   */
+  function join($table, &$query) {
+    if (empty($this->definition['table formula'])) {
+      $right_table = "{" . $this->table . "}";
+    } else {
+      $right_table = $this->definition['table formula'];
+    }
+
+    if ($this->left_table) {
+      $left = $query->get_table_info($this->left_table);
+      $left_field = "$left[alias].$this->left_field";
+    } else {
+      // This can be used if left_field is a formula or something. It should be used only *very* rarely.
+      $left_field = $this->left_field;
+    }
+
+    if (!empty($this->definition['i18n'])) {
+      $output = " $this->type JOIN $right_table $table[alias] ON ($left_field = $table[alias].$this->field OR $left[alias].tnid = $table[alias].$this->field)";
+    } else {
+      $output = " $this->type JOIN $right_table $table[alias] ON $left_field = $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)) {
+        $extra_type = 'AND';
+        if (!empty($this->extra_type)) {
+          $extra_type = $this->extra_type;
+        }
+        $output .= ' ' . $extra_type . " ($this->extra)";
+      }
+    }
+    return $output;
+  }
+}
\ No newline at end of file
diff --git a/includes/views/nodequeue_handler_relationship_nodequeue.inc b/includes/views/nodequeue_handler_relationship_nodequeue.inc
index d3cc185..0f6a3bd 100644
--- a/includes/views/nodequeue_handler_relationship_nodequeue.inc
+++ b/includes/views/nodequeue_handler_relationship_nodequeue.inc
@@ -29,9 +29,11 @@ class nodequeue_handler_relationship_nodequeue extends views_handler_relationshi
     );
 
     $options = array();
+    $i18n = array();
     $queues = nodequeue_load_queues(nodequeue_get_all_qids(NULL));
     foreach ($queues as $queue) {
       $options[$queue->qid] = $queue->title;
+      $i18n[$queue->qid] = (isset($queue->i18n)) ? $queue->i18n : FALSE;
     }
 
     $form['qids'] = array(
@@ -44,6 +46,47 @@ class nodequeue_handler_relationship_nodequeue extends views_handler_relationshi
       '#process' => array('expand_checkboxes', 'views_process_dependency'),
       '#dependency' => array('edit-options-limit' => array(TRUE)),
     );
+
+    $form['i18n'] = array(
+      '#type' => 'hidden',
+      '#value' => $i18n
+    );
+  }
+
+  /**
+   * Validate the options form.
+   */
+  function options_validate($form, &$form_state) {
+    $opt_qids = array_filter($form_state['values']['options']['qids']);
+
+    if (isset($form_state['values']['options']['i18n'])) {
+      $opt_i18n = $form_state['values']['options']['i18n'];
+      $opt_labels = $form['qids']['#options'];
+      if (count($opt_qids)) {
+        $i18n_on = array();
+        $i18n_off = array();
+
+        foreach($opt_qids as $id) {
+          if ($opt_i18n[$id]) {
+            $i18n_on[] = $opt_labels[$id];
+          } else {
+            $i18n_off[] = $opt_labels[$id];
+          }
+        }
+        if (count($i18n_on) && count($i18n_off)) {
+          // Mix of language negotiation which will cause problems
+          $message = t('Selected nodqueues use different language negotiation
+            methods and cannot be combined. Please modify your selection to only
+            include nodequeues using one method. The following treat translation
+            nodes as a single node: !i18n_on_str. The following manually manage
+            translated nodes: !i18n_off_str', array(
+              '!i18n_on_str' => implode(', ', $i18n_on),
+              '!i18n_off_str' => implode(', ', $i18n_off),
+              ));
+          form_set_error('qids', $message);
+        }
+      }
+    }
   }
 
   /**
@@ -51,12 +94,26 @@ class nodequeue_handler_relationship_nodequeue extends views_handler_relationshi
    */
   function query() {
     // Figure out what base table this relationship brings to the party.
-    $join = new views_join();
+    $join = new views_join_nodequeue();
+    $i18n = FALSE;
+    $opt_qids = array_filter($this->options['qids']);
+    if (count($opt_qids)) {
+      if (isset($this->options['i18n']) && count($this->options['i18n'])) {
+        foreach ($opt_qids as $id) {
+          if (isset($this->options['i18n'][$id]) && $this->options['i18n'][$id]) {
+            $i18n = TRUE;
+            break;
+          }
+        }
+      }
+    }
+
     $join->definition = array(
       'table' => 'nodequeue_nodes',
       'field' => 'nid',
       'left_table' => 'node',
       'left_field' => 'nid',
+      'i18n' => $i18n,
     );
 
     if (!empty($this->options['required'])) {
-- 
1.7.0.4

