From 595a41735e1d6433cccfa052527bee0975110784 Mon Sep 17 00:00:00 2001
From: Bradley M. Froehle <bfroehle@math.berkeley.edu>
Date: Sun, 13 Feb 2011 15:01:15 -0800
Subject: [PATCH] 527430 - Add hook_user_filters()

---
 modules/user/user.admin.inc |   23 ++++++++++++++++++++---
 modules/user/user.api.php   |   34 ++++++++++++++++++++++++++++++++++
 modules/user/user.module    |   19 +++++++++++++------
 3 files changed, 67 insertions(+), 9 deletions(-)

diff --git modules/user/user.admin.inc modules/user/user.admin.inc
index effc964..99a5d6a 100644
--- modules/user/user.admin.inc
+++ modules/user/user.admin.inc
@@ -34,7 +34,7 @@ function user_admin($callback_arg = '') {
  */
 function user_filter_form() {
   $session = isset($_SESSION['user_overview_filter']) ? $_SESSION['user_overview_filter'] : array();
-  $filters = user_filters();
+  $filters = module_invoke_all('user_filters');
 
   $i = 0;
   $form['filters'] = array(
@@ -109,7 +109,7 @@ function user_filter_form() {
  */
 function user_filter_form_submit($form, &$form_state) {
   $op = $form_state['values']['op'];
-  $filters = user_filters();
+  $filters = module_invoke_all('user_filters');
   switch ($op) {
     case t('Filter'):
     case t('Refine'):
@@ -159,7 +159,24 @@ function user_admin_account() {
 
   $query = db_select('users', 'u');
   $query->condition('u.uid', 0, '<>');
-  user_build_filter_query($query);
+
+  // Build a list of all user filters and all applied user filters.
+  $filters = module_invoke_all('user_filters');
+  $applied_filters = isset($_SESSION['user_overview_filter']) ? $_SESSION['user_overview_filter'] : array();
+  foreach ($applied_filters as $applied_filter) {
+    // Call the callback function for each applied filter.
+    list($key, $value) = $applied_filter;
+    if ($function = $filters[$key]['callback']) {
+      // Add in callback arguments if present.
+      if (isset($filters[$key]['callback arguments'])) {
+        $args = array_merge(array($query, array($applied_filter)), $filters[$key]['callback arguments']);
+      }
+      else {
+        $args = array($query, array($applied_filter));
+      }
+      call_user_func_array($function, $args);
+    }
+  }
 
   $count_query = clone $query;
   $count_query->addExpression('COUNT(u.uid)');
diff --git modules/user/user.api.php modules/user/user.api.php
index 17618e1..2181b0a 100644
--- modules/user/user.api.php
+++ modules/user/user.api.php
@@ -185,6 +185,40 @@ function hook_user_operations() {
 }
 
 /**
+ * Add user filtering options.
+ *
+ * This hook enables modules to allow custom filtering methods at admin/people.
+ * The module must also implement hook_user_filter_query_alter() to do implement
+ * the actual filtering.
+ *
+ * @return
+ *  An array of filters. Each filter is an associative array that contains the
+ *  following key-value pairs:
+ *  - "title": Required. The label for the filter, displayed next to the
+ *    dropdown menu.
+ *  - "field": Optional. If set, the table will be sortable on this field.
+ *  - "options": An associative array of filter options, displayed in a
+ *    dropdown menu. No filtering will occur for an item keyed as '[any]'.
+ *  - "callback": Required. The function to call for the filtering.
+ *  - "callback arguments": Optional. An array of additional arguments, beyond
+ *    the SelectQuery and filter, to pass to the callback function.
+ */
+function hook_user_filters() {
+  $filters = array();
+  $filters['status'] = array(
+    'title' => t('status'),
+    'field' => 'u.status',
+    'options' => array(
+      '[any]' => t('any'),
+      1 => t('active'),
+      0 => t('blocked'),
+    ),
+    'callback' => 'user_user_filters_status',
+  );
+  return $filters;
+}
+
+/**
  * Retrieve a list of user setting or profile information categories.
  *
  * @return
diff --git modules/user/user.module modules/user/user.module
index 80a9eaf..5c5f133 100644
--- modules/user/user.module
+++ modules/user/user.module
@@ -3241,9 +3241,11 @@ function _user_sort($a, $b) {
 }
 
 /**
+ * Implements hook_user_filters().
+ *
  * List user administration filters that can be applied.
  */
-function user_filters() {
+function user_user_filters() {
   // Regular filters
   $filters = array();
   $roles = user_roles(TRUE);
@@ -3255,6 +3257,7 @@ function user_filters() {
       'options' => array(
         '[any]' => t('any'),
       ) + $roles,
+      'callback' => 'user_build_filter_query',
     );
   }
 
@@ -3274,6 +3277,7 @@ function user_filters() {
     'options' => array(
       '[any]' => t('any'),
     ) + $options,
+    'callback' => 'user_build_filter_query',
   );
 
   $filters['status'] = array(
@@ -3284,6 +3288,7 @@ function user_filters() {
       1 => t('active'),
       0 => t('blocked'),
     ),
+    'callback' => 'user_build_filter_query',
   );
   return $filters;
 }
@@ -3293,11 +3298,13 @@ function user_filters() {
  *
  * @param $query
  *   Query object that should be filtered.
+ * @param $filters
+ *   An array of user filters. Each filter is an array with two elements, the
+ *   first being the key and the second the value.
  */
-function user_build_filter_query(SelectQuery $query) {
-  $filters = user_filters();
+function user_build_filter_query(SelectQuery $query, $filters) {
   // Extend Query with filter conditions.
-  foreach (isset($_SESSION['user_overview_filter']) ? $_SESSION['user_overview_filter'] : array() as $filter) {
+  foreach ($filters as $filter) {
     list($key, $value) = $filter;
     // This checks to see if this permission filter is an enabled permission for
     // the authenticated role. If so, then all users would be listed, and we can
@@ -3317,8 +3324,8 @@ function user_build_filter_query(SelectQuery $query) {
       $users_roles_alias = $query->join('users_roles', 'ur', '%alias.uid = u.uid');
       $query->condition($users_roles_alias . '.rid' , $value);
     }
-    else {
-      $query->condition($filters[$key]['field'], $value);
+    elseif ($key == 'status') {
+      $query->condition('u.status', $value);
     }
   }
 }
-- 
1.7.3.5

