Index: includes/filter.inc
===================================================================
RCS file: includes/filter.inc
diff -N includes/filter.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ includes/filter.inc 1 May 2009 16:45:22 -0000
@@ -0,0 +1,270 @@
+name = $name;
+ if (!isset($_SESSION['filter'][$name])) {
+ $_SESSION['filter'][$name] = array();
+ }
+ $this->filter =& $_SESSION['filter'][$name];
+ $this->elements = module_invoke_all('filter_elements_' . $name, $this);
+ $this->addTag('filter_' . $name);
+ $this->addMetaData('filter', $this->filter);
+ $this->addMetaData('elements', $this->elements);
+
+ // Add simple conditions of the currently active filters to the query.
+ // @todo: Implement additional simple filter configurations.
+ foreach ($this->filter as $name => $values) {
+ foreach ($values as $value) {
+ if (isset($this->elements[$name]['field'])) {
+ $this->condition($this->elements[$name]['field'], $value);
+ }
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Return the defined filter name.
+ *
+ * @return
+ * The previously defined filter.
+ */
+ public function getFilterName() {
+ return $this->name;
+ }
+
+ /**
+ * Return the loaded, currently active filters for that query.
+ *
+ * @return
+ * Array with active filters.
+ */
+ public function getFilter() {
+ return $this->filter;
+ }
+
+ /**
+ * Get the form definition of the active filter.
+ *
+ * @see filter_extender_form
+ *
+ * @param $title
+ * @return
+ */
+ public function getForm($title = NULL) {
+ if ($title == NULL) {
+ $title = t('Only display items where');
+ }
+
+ // Note: #query is a workaround becase we can't directly call a object
+ // method for the form submit.
+ $form = array(
+ '#title' => $title,
+ '#type' => 'fieldset',
+ '#weight' => -50,
+ '#theme' => 'filter_form',
+ '#query' => $this,
+ );
+
+ $i = 0;
+ foreach ($this->filter as $name => $values) {
+ $options = $this->elements[$name]['options'];
+ if (count(array_filter($this->elements[$name]['options'], 'is_array')) > 0) {
+ $options = call_user_func_array('array_merge', $this->elements[$name]['options']);
+ }
+ $params = array(
+ '%property' => $this->elements[$name]['title'],
+ '%value' => join(t(' and '), array_intersect_key($options, $values)
+ ));
+ if ($i++ > 0) {
+ $form['current'][] = array('#markup' => t('and where %property is %value', $params));
+ }
+ else {
+ $form['current'][] = array('#markup' => t('%property is %value', $params));
+ }
+ }
+
+ // Create a select for each filter element.
+ // @todo: Allow different fields, for example text, autocomplete, radios.
+ foreach ($this->elements as $name => $element) {
+ $names[$name] = $element['title'];
+ $form['status'][$name] = array(
+ '#type' => 'select',
+ '#options' => $element['options'],
+ );
+ }
+
+ // Create list of filter elements.
+ $form['filter'] = array(
+ '#type' => 'radios',
+ '#options' => $names,
+ );
+
+ $form['buttons']['submit'] = array(
+ '#type' => 'submit',
+ '#value' => (count($this->filter) ? t('Refine') : t('Filter')),
+ '#submit' => array('filter_extender_form_submit'),
+ );
+ if (count($this->filter)) {
+ $form['buttons']['undo'] = array(
+ '#type' => 'submit',
+ '#value' => t('Undo'),
+ '#submit' => array('filter_extender_form_submit'),
+ );
+ $form['buttons']['reset'] = array(
+ '#type' => 'submit',
+ '#value' => t('Reset'),
+ '#submit' => array('filter_extender_form_submit'),
+ );
+ }
+
+ drupal_add_js('misc/form.js');
+ return $form;
+ }
+
+ /**
+ * Handle the filter form submit.
+ *
+ * Because this can't be called directly, it's called by the helper function
+ * filter_extender_form_submit.
+ *
+ * @see filter_extender_form_submit()
+ */
+ function submitForm($form, &$form_state) {
+ $op = $form_state['values']['op'];
+ switch ($op) {
+ case t('Filter'):
+ case t('Refine'):
+ if (!empty($form_state['values']['filter'])) {
+ $filter = $form_state['values']['filter'];
+ // Merge an array of arrays into one if necessary.
+ $options = $this->elements[$filter]['options'];
+ if (is_array(current($this->elements[$filter]['options']))) {
+ $options = call_user_func_array('array_merge', $this->elements[$filter]['options']);
+ }
+ $value = $form_state['values'][$filter];
+ if (isset($options[$value])) {
+ // Only add the new filter of multiple is enabled, override the
+ // current value if not.
+ if (isset($this->elements[$filter]['multiple']) && $this->elements[$filter]['multiple']) {
+ $this->filter[$filter][$value] = $value;
+ }
+ else {
+ $this->filter[$filter] = array($value => $value);
+ }
+ }
+ }
+ break;
+ case t('Undo'):
+ array_pop($this->filter);
+ break;
+ case t('Reset'):
+ $this->filter = array();
+ break;
+ }
+
+ $form_state['redirect'] = $_GET['q'];
+ }
+}
+
+/**
+ * Theme filter selector form.
+ *
+ * @ingroup themeable
+ */
+function theme_filter_form($form) {
+ $output = '';
+ if (!empty($form['current'])) {
+ $output .= '';
+ foreach (element_children($form['current']) as $key) {
+ $output .= '' . drupal_render($form['current'][$key]) . '
';
+ }
+ $output .= '
';
+ }
+
+ $output .= '' . (!empty($form['current']) ? '- ' . t('and') . ' ' . t('where') . '
' : '') . '- ';
+ foreach (element_children($form['filter']) as $key) {
+ $output .= drupal_render($form['filter'][$key]);
+ }
+ $output .= '
- ' . t('is') . '
- ';
+
+ foreach (element_children($form['status']) as $key) {
+ $output .= drupal_render($form['status'][$key]);
+ }
+ $output .= '
';
+ $output .= '' . drupal_render($form['buttons']) . '
';
+ return $output;
+}
+
+/**
+ * Form for the filter of the passed in $query object.
+ *
+ * This is a helper function because we can't directly call a object method with
+ * drupal_get_form(). Only use this if you don't already have a $form object
+ * that could be extended.
+ *
+ * @param $query
+ * SelectQuery object that is already extend with Filter.
+ * @return
+ */
+function filter_extender_form($query) {
+ return $query->getForm();
+}
+
+/**
+ * Helper function for submitting the filter form.
+ *
+ * @see filter_extender_form()
+ */
+function filter_extender_form_submit($form, &$form_state) {
+ $form['filter']['#query']->submitForm($form, $form_state);
+}
\ No newline at end of file
Index: modules/user/user.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.admin.inc,v
retrieving revision 1.45
diff -u -p -r1.45 user.admin.inc
--- modules/user/user.admin.inc 30 Apr 2009 16:10:10 -0000 1.45
+++ modules/user/user.admin.inc 1 May 2009 16:45:22 -0000
@@ -19,112 +19,13 @@ function user_admin($callback_arg = '')
$output = drupal_get_form('user_multiple_cancel_confirm');
}
else {
- $output = drupal_get_form('user_filter_form');
- $output .= drupal_get_form('user_admin_account');
+ $output = drupal_get_form('user_admin_account');
}
}
return $output;
}
/**
- * Form builder; Return form for user administration filters.
- *
- * @ingroup forms
- * @see user_filter_form_submit()
- */
-function user_filter_form() {
- if (!isset($_SESSION['user_overview_filter'])) {
- drupal_set_session('user_overview_filter', array());
- }
- $session = &$_SESSION['user_overview_filter'];
- $filters = user_filters();
-
- $i = 0;
- $form['filters'] = array(
- '#type' => 'fieldset',
- '#title' => t('Show only users where'),
- '#theme' => 'user_filters',
- );
- foreach ($session as $filter) {
- list($type, $value) = $filter;
- // Merge an array of arrays into one if necessary.
- $options = $type == 'permission' ? call_user_func_array('array_merge', $filters[$type]['options']) : $filters[$type]['options'];
- $params = array('%property' => $filters[$type]['title'] , '%value' => $options[$value]);
- if ($i++ > 0) {
- $form['filters']['current'][] = array('#markup' => t('and where %property is %value', $params));
- }
- else {
- $form['filters']['current'][] = array('#markup' => t('%property is %value', $params));
- }
- }
-
- foreach ($filters as $key => $filter) {
- $names[$key] = $filter['title'];
- $form['filters']['status'][$key] = array(
- '#type' => 'select',
- '#options' => $filter['options'],
- );
- }
-
- $form['filters']['filter'] = array(
- '#type' => 'radios',
- '#options' => $names,
- );
- $form['filters']['buttons']['submit'] = array(
- '#type' => 'submit',
- '#value' => (count($session) ? t('Refine') : t('Filter')),
- );
- if (count($session)) {
- $form['filters']['buttons']['undo'] = array(
- '#type' => 'submit',
- '#value' => t('Undo'),
- );
- $form['filters']['buttons']['reset'] = array(
- '#type' => 'submit',
- '#value' => t('Reset'),
- );
- }
-
- drupal_add_js('misc/form.js');
-
- return $form;
-}
-
-/**
- * Process result from user administration filter form.
- */
-function user_filter_form_submit($form, &$form_state) {
- $op = $form_state['values']['op'];
- $filters = user_filters();
- switch ($op) {
- case t('Filter'): case t('Refine'):
- if (isset($form_state['values']['filter'])) {
- $filter = $form_state['values']['filter'];
- // Merge an array of arrays into one if necessary.
- $options = $filter == 'permission' ? call_user_func_array('array_merge', $filters[$filter]['options']) : $filters[$filter]['options'];
- if (isset($options[$form_state['values'][$filter]])) {
- if (!isset($_SESSION['user_overview_filter'])) {
- drupal_set_session('user_overview_filter', array());
- }
- $_SESSION['user_overview_filter'][] = array($filter, $form_state['values'][$filter]);
- }
- }
- break;
- case t('Undo'):
- array_pop($_SESSION['user_overview_filter']);
- break;
- case t('Reset'):
- drupal_set_session('user_overview_filter', array());
- break;
- case t('Update'):
- return;
- }
-
- $form_state['redirect'] = 'admin/user/user';
- return;
-}
-
-/**
* Form builder; User administration page.
*
* @ingroup forms
@@ -143,14 +44,16 @@ function user_admin_account() {
t('Operations')
);
- $query = db_select('users', 'u');
- $query->leftJoin('users_roles', 'ur', 'u.uid = ur.uid');
- $query->condition('u.uid', 0, '<>');
- user_build_filter_query($query);
+ // Extend with Filter early so that the count query gets the same filters applied.
+ $query = db_select('users', 'u')->extend('Filter');
+ $query
+ ->filterName('user_admin')
+ ->condition('u.uid', 0, '<>');
$count_query = clone $query;
$count_query->addExpression('COUNT(DISTINCT u.uid)');
+ // Extend with PagerDefault and Tablesort now, as the count query doesn't need them.
$query = $query->extend('PagerDefault')->extend('TableSort');
$query
->fields('u', array('uid', 'name', 'status', 'created', 'access'))
@@ -158,6 +61,8 @@ function user_admin_account() {
->setHeader($header)
->setCountQuery($count_query);
$result = $query->execute();
+ // Load filter form.
+ $form['filter'] = $query->getForm();
$form['options'] = array(
'#type' => 'fieldset',
@@ -177,6 +82,9 @@ function user_admin_account() {
$form['options']['submit'] = array(
'#type' => 'submit',
'#value' => t('Update'),
+ // Only run the update validate and submit function for the Update button.
+ '#submit' => array('user_admin_account_update'),
+ '#validate' => array('user_admin_account_update_validate'),
);
$destination = drupal_get_destination();
@@ -211,7 +119,7 @@ function user_admin_account() {
/**
* Submit the user administration update form.
*/
-function user_admin_account_submit($form, &$form_state) {
+function user_admin_account_update($form, &$form_state) {
$operations = module_invoke_all('user_operations', $form_state);
$operation = $operations[$form_state['values']['operation']];
// Filter out unchecked accounts.
@@ -230,7 +138,10 @@ function user_admin_account_submit($form
}
}
-function user_admin_account_validate($form, &$form_state) {
+/**
+ * Validate the user administration update form.
+ */
+function user_admin_account_update_validate($form, &$form_state) {
$form_state['values']['accounts'] = array_filter($form_state['values']['accounts']);
if (count($form_state['values']['accounts']) == 0) {
form_set_error('', t('No users selected.'));
@@ -797,7 +708,8 @@ function theme_user_admin_account($form)
t('Operations')
);
- $output = drupal_render($form['options']);
+ $output = drupal_render($form['filter']);
+ $output .= drupal_render($form['options']);
if (isset($form['name']) && is_array($form['name'])) {
foreach (element_children($form['name']) as $key) {
$rows[] = array(
@@ -848,49 +760,3 @@ function theme_user_admin_new_role($form
return $output;
}
-
-/**
- * Theme user administration filter form.
- *
- * @ingroup themeable
- */
-function theme_user_filter_form($form) {
- $output = '';
- $output .= drupal_render($form['filters']);
- $output .= '
';
- $output .= drupal_render_children($form);
- return $output;
-}
-
-/**
- * Theme user administration filter selector.
- *
- * @ingroup themeable
- */
-function theme_user_filters($form) {
- $output = '';
-
- return $output;
-}
Index: modules/user/user.css
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.css,v
retrieving revision 1.10
diff -u -p -r1.10 user.css
--- modules/user/user.css 9 Oct 2008 04:19:44 -0000 1.10
+++ modules/user/user.css 1 May 2009 16:45:23 -0000
@@ -12,12 +12,6 @@
#user-login-form {
text-align: center;
}
-#user-admin-filter ul {
- list-style-type: none;
- padding: 0;
- margin: 0;
- width: 100%;
-}
#user-admin-buttons {
float: left; /* LTR */
margin-left: 0.5em; /* LTR */
Index: modules/user/user.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.module,v
retrieving revision 1.982
diff -u -p -r1.982 user.module
--- modules/user/user.module 30 Apr 2009 16:10:10 -0000 1.982
+++ modules/user/user.module 1 May 2009 16:45:23 -0000
@@ -69,14 +69,6 @@ function user_theme() {
'arguments' => array('form' => NULL),
'file' => 'user.admin.inc',
),
- 'user_filter_form' => array(
- 'arguments' => array('form' => NULL),
- 'file' => 'user.admin.inc',
- ),
- 'user_filters' => array(
- 'arguments' => array('form' => NULL),
- 'file' => 'user.admin.inc',
- ),
'user_signature' => array(
'arguments' => array('signature' => NULL),
),
@@ -2423,9 +2415,9 @@ function _user_sort($a, $b) {
}
/**
- * List user administration filters that can be applied.
+ * Implementation of hook_filter_elements_filtername().
*/
-function user_filters() {
+function user_filter_elements_user_admin() {
// Regular filters
$filters = array();
$roles = user_roles(TRUE);
@@ -2433,8 +2425,8 @@ function user_filters() {
if (count($roles)) {
$filters['role'] = array(
'title' => t('role'),
- 'field' => 'ur.rid',
'options' => $roles,
+ 'multiple' => TRUE,
);
}
@@ -2452,6 +2444,7 @@ function user_filters() {
$filters['permission'] = array(
'title' => t('permission'),
'options' => $options,
+ 'multiple' => TRUE,
);
$filters['status'] = array(
@@ -2463,32 +2456,36 @@ function user_filters() {
}
/**
- * Extends a query object for user administration filters based on session.
+ * Extends a query object for user permission filters.
*
* @param $query
* Query object that should be filtered.
*/
-function user_build_filter_query(SelectQuery $query) {
- $filters = user_filters();
-
- // Extend Query with filter conditions.
- foreach ($_SESSION['user_overview_filter'] 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
- // skip adding it to the filter query.
- if ($key == 'permission') {
+function user_query_filter_user_admin_alter($query) {
+ // Extend Query with permission conditions.
+ $filter = $query->getMetaData('filter');
+ if (isset($filter['permission'])) {
+ $i = 0;
+ $query->leftJoin('users_roles', 'ur', 'u.uid = ur.uid');
+ foreach ($filter['permission'] as $value) {
$account = new stdClass();
$account->uid = 'user_filter';
$account->roles = array(DRUPAL_AUTHENTICATED_RID => 1);
if (user_access($value, $account)) {
continue;
}
- $query->leftJoin('role_permission', 'p', 'ur.rid = p.rid');
- $query->condition(db_or()->condition('u.uid', 1)->condition('p.permission', $value));
+ $query->leftjoin('role_permission', "p$i", "ur.rid = p$i.rid");
+ $query->condition(db_or()->condition("u.uid", 1)->condition("p$i.permission", $value));
+ $i++;
}
- else {
- $query->condition($filters[$key]['field'], $value);
+ }
+
+ if (isset($filter['role'])) {
+ $i = 0;
+ foreach ($filter['role'] as $value) {
+ $table = $query->leftJoin('users_roles', "ur$i", "ur$i.uid = u.uid");
+ $query->condition("ur$i.rid", $value);
+ $i++;
}
}
}