From 5256422d31aad511f948c70928daa62d638eda12 Mon Sep 17 00:00:00 2001
From: jucallme <jucallme@gmail.com>
Date: Thu, 3 May 2012 22:30:54 -0300
Subject: [PATCH] expose the pager and move to a cookie handling instead of
 session to help with varnish handling

---
 handlers/views_handler_filter.inc     |   25 ++++++-----
 includes/view.inc                     |   12 ++++-
 plugins/views_plugin_exposed_form.inc |   10 +++-
 plugins/views_plugin_pager_full.inc   |   76 ++++++++++++++++++++++++++++++++-
 4 files changed, 105 insertions(+), 18 deletions(-)

diff --git a/handlers/views_handler_filter.inc b/handlers/views_handler_filter.inc
index 70da0d8..a2baf1c 100644
--- a/handlers/views_handler_filter.inc
+++ b/handlers/views_handler_filter.inc
@@ -622,36 +622,37 @@ class views_handler_filter extends views_handler {
     // Figure out which display id is responsible for the filters, so we
     // know where to look for session stored values.
     $display_id = ($this->view->display_handler->is_defaulted('filters')) ? 'default' : $this->view->current_display;
+    //$display_id = $this->view->current_display;
 
     // shortcut test.
     $operator = !empty($this->options['expose']['use_operator']) && !empty($this->options['expose']['operator_id']);
 
+    $exposed = isset($_COOKIE['views_exposed']) ? unserialize($_COOKIE['views_exposed']) : array();
     // false means that we got a setting that means to recuse ourselves,
     // so we should erase whatever happened to be there.
-    if (!$status && isset($_SESSION['views'][$this->view->name][$display_id])) {
-      $session = &$_SESSION['views'][$this->view->name][$display_id];
-      if ($operator && isset($session[$this->options['expose']['operator_id']])) {
-        unset($session[$this->options['expose']['operator_id']]);
+    if (!$status && isset($exposed[$this->view->name][$display_id])) {
+      if ($operator && isset($exposed[$this->options['expose']['operator_id']])) {
+        unset($exposed[$this->options['expose']['operator_id']]);
       }
 
-      if (isset($session[$this->options['expose']['identifier']])) {
-        unset($session[$this->options['expose']['identifier']]);
+      if (isset($exposed[$this->options['expose']['identifier']])) {
+        unset($exposed[$this->options['expose']['identifier']]);
       }
     }
 
     if ($status) {
-      if (!isset($_SESSION['views'][$this->view->name][$display_id])) {
-        $_SESSION['views'][$this->view->name][$display_id] = array();
+      if (!isset($exposed[$this->view->name][$display_id])) {
+        $exposed[$this->view->name][$display_id] = array();
       }
 
-      $session = &$_SESSION['views'][$this->view->name][$display_id];
-
       if ($operator && isset($input[$this->options['expose']['operator_id']])) {
-        $session[$this->options['expose']['operator_id']] = $input[$this->options['expose']['operator_id']];
+        $exposed[$this->view->name][$display_id][$this->options['expose']['operator_id']] = $input[$this->options['expose']['operator_id']];
       }
 
-      $session[$this->options['expose']['identifier']] = $input[$this->options['expose']['identifier']];
+      $exposed[$this->view->name][$display_id][$this->options['expose']['identifier']] = $input[$this->options['expose']['identifier']];
     }
+    // this cookie will expire at the end of the session.
+    setcookie('views_exposed', serialize($exposed), 0, '/');
   }
 
   /**
diff --git a/includes/view.inc b/includes/view.inc
index 349084e..20369ee 100644
--- a/includes/view.inc
+++ b/includes/view.inc
@@ -403,8 +403,16 @@ class view extends views_db_object {
       // remember settings.
       $display_id = ($this->display_handler->is_defaulted('filters')) ? 'default' : $this->current_display;
 
-      if (empty($this->exposed_input) && !empty($_SESSION['views'][$this->name][$display_id])) {
-        $this->exposed_input = $_SESSION['views'][$this->name][$display_id];
+      if (isset($_COOKIE['views_exposed'])) {
+        // get the cookie
+        $exposed = unserialize($_COOKIE['views_exposed']);
+      }
+      else {
+        $exposed = array();
+      }
+
+      if (empty($this->exposed_input) && !empty($exposed[$this->name][$display_id])) {
+        $this->exposed_input = $exposed[$this->name][$display_id];
       }
     }
 
diff --git a/plugins/views_plugin_exposed_form.inc b/plugins/views_plugin_exposed_form.inc
index 287dd89..fb3c30f 100644
--- a/plugins/views_plugin_exposed_form.inc
+++ b/plugins/views_plugin_exposed_form.inc
@@ -291,7 +291,7 @@ class views_plugin_exposed_form extends views_plugin {
   }
 
   function reset_form(&$form, &$form_state) {
-    // _SESSION is not defined for users who are not logged in.
+    // _COOKIE is not defined for users who are not logged in.
 
     // If filters are not overridden, store the 'remember' settings on the
     // default display. If they are, store them on this display. This way,
@@ -299,9 +299,13 @@ class views_plugin_exposed_form extends views_plugin {
     // remember settings.
     $display_id = ($this->view->display_handler->is_defaulted('filters')) ? 'default' : $this->view->current_display;
 
-    if (isset($_SESSION['views'][$this->view->name][$display_id])) {
-      unset($_SESSION['views'][$this->view->name][$display_id]);
+    $exposed = isset($_COOKIE['views_exposed']) ? unserialize($_COOKIE['views_exposed']) : array();
+
+    if (isset($exposed[$this->view->name][$display_id])) {
+      unset($exposed[$this->view->name][$display_id]);
     }
+    // this cookie will expire at the end of the session.
+    setcookie('views_exposed', serialize($exposed), 0, '/');
 
     // Set the form to allow redirect.
     if (empty($this->view->live_preview)) {
diff --git a/plugins/views_plugin_pager_full.inc b/plugins/views_plugin_pager_full.inc
index d4c2203..0559874 100644
--- a/plugins/views_plugin_pager_full.inc
+++ b/plugins/views_plugin_pager_full.inc
@@ -33,6 +33,8 @@ class views_plugin_pager_full extends views_plugin_pager {
         'items_per_page_options' => array('default' => '5, 10, 20, 40, 60'),
         'items_per_page_options_all' => array('default' => FALSE, 'bool' => TRUE),
         'items_per_page_options_all_label' => array('default' => '- All -', 'translatable' => TRUE),
+        'items_per_page_remember' => array('default' => FALSE, 'bool' => TRUE),
+        'offset_remember' => array('default' => FALSE, 'bool' => TRUE),
 
         'offset' => array('default' => FALSE, 'bool' => TRUE),
         'offset_label' => array('default' => 'Offset', 'translatable' => TRUE),
@@ -167,6 +169,15 @@ class views_plugin_pager_full extends views_plugin_pager {
       ),
     );
 
+    $form['expose']['items_per_page_remember'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Remember selected items per page'),
+      '#description' => t('Enable to remember the last selection made by the user.'),
+      '#default_value' => $this->options['expose']['items_per_page_remember'],
+      '#dependency' => array(
+        'edit-pager-options-expose-items-per-page' => array(1),
+      ),
+    );
 
     $form['expose']['items_per_page_options_all'] = array(
       '#type' => 'checkbox',
@@ -202,6 +213,16 @@ class views_plugin_pager_full extends views_plugin_pager {
         'edit-pager-options-expose-offset' => array(1)
       ),
     );
+
+    $form['expose']['offset_remember'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Remember selected offset'),
+      '#description' => t('Enable to remember the last selection made by the user.'),
+      '#default_value' => $this->options['expose']['offset_remember'],
+      '#dependency' => array(
+        'edit-pager-options-expose-offset' => array(1),
+      ),
+    );
   }
 
   function options_validate(&$form, &$form_state) {
@@ -252,8 +273,10 @@ class views_plugin_pager_full extends views_plugin_pager {
       }
     }
 
+    $this->get_exposed_input();
     $limit = $this->options['items_per_page'];
     $offset = $this->current_page * $this->options['items_per_page'] + $this->options['offset'];
+
     if (!empty($this->options['total_pages'])) {
       if ($this->current_page >= $this->options['total_pages']) {
         $limit = $this->options['items_per_page'];
@@ -383,6 +406,7 @@ class views_plugin_pager_full extends views_plugin_pager {
 
   function exposed_form_alter(&$form, &$form_state) {
     if ($this->items_per_page_exposed()) {
+      $this->get_exposed_input();
       $options = explode(',', $this->options['expose']['items_per_page_options']);
       $sanitized_options = array();
       if (is_array($options)) {
@@ -402,6 +426,7 @@ class views_plugin_pager_full extends views_plugin_pager {
     }
 
     if ($this->offset_exposed()) {
+      $this->get_exposed_input();
       $form['offset'] = array(
         '#type' => 'textfield',
         '#size' => 10,
@@ -415,8 +440,57 @@ class views_plugin_pager_full extends views_plugin_pager {
   function exposed_form_validate(&$form, &$form_state) {
     if (!empty($form_state['values']['offset']) && trim($form_state['values']['offset'])) {
       if (!is_numeric($form_state['values']['offset']) || $form_state['values']['offset'] < 0) {
-        form_set_error('offset', t('Offset must be an number greather or equal than 0.'));
+        form_set_error('offset', t('Offset must be an number greater or equal than 0.'));
       }
     }
   }
+
+  /**
+   * Saves the stored input to the form state.
+   */
+  function exposed_form_submit(&$form, &$form_state, &$exclude) {
+    if (empty($this->options['expose']['offset_remember']) && empty($this->options['expose']['items_per_page_remember'])) {
+      return;
+    }
+
+    $display_id = ($this->view->display_handler->is_defaulted('filters')) ? 'default' : $this->view->current_display;
+
+    $exposed = isset($_COOKIE['views_pager']) ? unserialize($_COOKIE['views_pager']) : array();
+
+    if ($this->items_per_page_exposed()) {
+      $exposed[$this->view->name][$display_id]['items_per_page'] = $form_state['values']['items_per_page'];
+    }
+    if ($this->offset_exposed()) {
+      $exposed[$this->view->name][$display_id]['offset'] = $form_state['values']['offset'];
+    }
+
+    // this cookie will expire at the end of the session.
+    setcookie('views_pager', serialize($exposed), 0, '/');
+  }
+
+  /**
+   * Allows input from the exposed pager to change the behavior of the pager.
+   */
+  function get_exposed_input() {
+    if (empty($this->options['expose']['offset_remember']) && empty($this->options['expose']['items_per_page_remember'])) {
+      return FALSE;
+    }
+
+    $display_id = ($this->view->display_handler->is_defaulted('filters')) ? 'default' : $this->view->current_display;
+
+    $exposed = isset($_COOKIE['views_pager']) ? unserialize($_COOKIE['views_pager']) : array();
+
+    if (!isset($exposed[$this->view->name][$display_id])) {
+      $exposed[$this->view->name][$display_id] = array();
+    }
+
+    if (!empty($exposed[$this->view->name][$display_id]['items_per_page'])) {
+      $this->options['items_per_page'] = ($exposed[$this->view->name][$display_id]['items_per_page'] != 'All') ? $exposed[$this->view->name][$display_id]['items_per_page'] : 0;
+    }
+    if (!empty($exposed[$this->view->name][$display_id]['offset'])) {
+      $this->options['offset'] = $exposed[$this->view->name][$display_id]['offset'];
+    }
+
+    return TRUE;
+  }
 }
-- 
1.7.5.4

