5.x-1.x branch
Provides named versions of exposed views filters.
Example, instead of using http://example.com/myview?filter0=123456 you could use http://example.com/myview?timestamp=123456
| Name | Description |
|---|---|
| views_bonus_named_filters_admin_page | |
| views_bonus_named_filters_edit | Page callback for modifying named filter settings for a view. |
| views_bonus_named_filters_edit_submit | Submit handler for views_bonus_named_filters form. |
| views_bonus_named_filters_menu | Implementation of hook_menu(). |
| views_bonus_named_filters_views_query_alter | Implementation of hook_views_query_alter(). |
| _views_bonus_named_filters_build_filters | Re-written version of _views_view_build_filters that doesn't add normal filters. |
| _views_bonus_named_filters_get_filters | Get a list of filter names for a given view. |
| _views_bonus_named_filters_named_filters_list | Builds a list of exposed filter names. |
| _views_bonus_named_filters_provides |
- <?php
- /**
- * @file
- * Provides named versions of exposed views filters.
- *
- * Example, instead of using http://example.com/myview?filter0=123456 you could
- * use http://example.com/myview?timestamp=123456
- */
-
- /**
- * Implementation of hook_menu().
- */
- function views_bonus_named_filters_menu($may_cache) {
- $items[] = array();
- if ($may_cache) {
- $items[] = array(
- 'path' => 'admin/build/views/defaultnamedfilters',
- 'title' => t('Named Filters'),
- 'callback' => 'views_bonus_named_filters_admin_page',
- 'access' => user_access('administer views'),
- 'type' => MENU_LOCAL_TASK,
- );
- }
- else {
- if (user_access('administer views') &&
- arg(0) == 'admin' &&
- arg(1) == 'build' &&
- arg(2) == 'views') {
-
- $view_name = arg(3);
- $default_view = false;
- if ($view_name && !($view = views_load_view($view_name))) {
- $view = views_get_view($view_name);
- $default_view = true;
- }
- if ($view && !empty($view->exposed_filter)) {
- $items[] = array(
- 'path' => "admin/build/views/$view->name/namedfilters",
- 'title' => t('Name Filters'),
- 'callback' => 'drupal_get_form',
- 'callback arguments' => array('views_bonus_named_filters_edit', $view->name),
- 'access' => user_access('administer views'),
- 'weight' => 10,
- 'type' => ($default_view ? MENU_CALLBACK : MENU_LOCAL_TASK),
- );
- }
- }
- }
-
- return $items;
- }
-
- /**
- *
- * @return unknown_type
- */
- function views_bonus_named_filters_admin_page() {
- views_load_cache();
-
- $numViews = 25;
-
- drupal_set_title(t('Administer views'));
-
- $result = pager_query("SELECT vid, name, description, menu_title, page_title, block_title, url, page, menu, block FROM {view_view} ORDER BY name", $numViews);
-
- while ($view = db_fetch_object($result)) {
- $url = ($view->page ? l($view->url, $view->url) : t('No Page View'));
- $provides = _views_bonus_named_filters_provides($view);
-
- $result2 = db_query("SELECT * FROM {view_exposed_filter} WHERE vid = $view->vid ORDER BY position ASC");
-
- $view->exposed_filter = array();
- while ($arg = db_fetch_array($result2)) {
- $arg['id'] = $arg['field'];
- $view->exposed_filter[] = $arg;
- }
-
- $items[] = array(
- $view->name,
- filter_xss_admin(views_get_title($view, 'admin')),
- $view->description,
- implode(', ', $provides),
- $url,
- _views_bonus_named_filters_named_filters_list($view),
- theme('links', array(
- array(
- 'title' => t('Manage Named Filters'),
- 'href' => "admin/build/views/$view->name/namedfilters",
- 'query' => drupal_get_destination(),
- ),
- )),
- );
- }
-
- if ($items) {
- $output = theme('table', array(t('View'), t('Title'), t('Description'), t('Provides'), t('URL'), t('Filters'), t('Actions')), $items, array("cellpadding" => "4"), t('Existing Views'));
- $output .= theme('pager', NULL, $numViews);
- }
- else {
- $output .= t('<p>No views have currently been defined.</p>');
- }
-
- $result = db_query("SELECT name FROM {view_view}");
- while ($view = db_fetch_object($result)) {
- $used[$view->name] = true;
- }
-
- $output .= t('<p>Below are system default views; if you edit one of these, a view will be created that will override any system use of the view.</p>');
- $items = array();
- $default_views = _views_get_default_views();
-
- $views_status = variable_get('views_defaults', array());
-
- foreach ($default_views as $view) {
- $url = ($view->page ? l($view->url, $view->url) : t('No Page View'));
-
- if ($used[$view->name]) {
- $status = t('Overridden');
- }
- else if (isset($views_status[$view->name])) {
- if ($views_status[$view->name] == 'enabled') {
- $status = t('Enabled');
- }
- else {
- $status = t('Disabled');
- }
- }
- else if ($view->disabled) {
- $status = t('Disabled');
- }
- else {
- $status = t('Enabled');
- }
-
- $provides = _views_bonus_named_filters_provides($view);
-
- $links = array(
- array(
- 'title' => t('Manage Named Filters'),
- 'href' => "admin/build/views/$view->name/namedfilters",
- 'query' => drupal_get_destination(),
- ),
- );
-
- $items[] = array(
- $view->name,
- filter_xss_admin(views_get_title($view, 'menu')),
- $view->description,
- implode(', ', $provides),
- $url,
- $status,
- _views_bonus_named_filters_named_filters_list($view),
- theme('links', $links),
- );
- }
-
- if ($items) {
- $output .= theme('table', array(t('Default view'), t('Title'), t('Description'), t('Provides'), t('URL'), t('Status'), t('Filters'), t('Named Filters')), $items, array("cellpadding" => "4"), t('Default Views'));
- }
- else {
- $output .= t('<p>No views have currently been defined.</p>');
- }
-
- return $output;
- }
-
- function _views_bonus_named_filters_provides(&$view) {
- $provides = array();
- if ($view->page) {
- $provides[] = t('Page');
- }
- if ($view->block) {
- $provides[] = t('Block');
- }
- if ($view->menu) {
- $provides[] = t('Menu');
- }
- return $provides;
- }
-
- /**
- * Builds a list of exposed filter names.
- *
- * @param $view
- * View to build a list of filters for.
- * @return
- * A themed table of exposed filter names.
- */
- function _views_bonus_named_filters_named_filters_list(&$view) {
- $named_filters = _views_bonus_named_filters_get_filters($view->name);
-
- $rows = array();
-
- foreach ($view->exposed_filter as $position => $filter) {
- $row = array();
- $row[] = "filter$position";
- foreach ($named_filters as $named_position => $named_filter) {
- if ($named_position == $position) {
- $row[] = $named_filter->filter_name;
- break;
- }
- }
- if (sizeof($row) == 1) {
- $row[] = '';
- }
- $rows[] = $row;
- }
-
- if (!empty($rows[0])) {
- return theme('table', array(t('Exposed'), t('Named')), $rows);
- }
- }
-
- /**
- * Page callback for modifying named filter settings for a view.
- *
- * @param $view_name
- * The name of a view to add named filter settings for.
- * @return
- * FAPI array.
- */
- function views_bonus_named_filters_edit($view_name) {
- $form = array();
- $view = views_get_view($view_name);
- $filters = _views_get_filters();
- $named_filters = _views_bonus_named_filters_get_filters($view->name);
-
- $form['view'] = array(
- '#type' => 'value',
- '#value' => $view,
- );
-
- $form['filters']['#tree'] = TRUE;
-
- foreach ($view->exposed_filter as $position => $field) {
- $section = array();
-
- $filtername = $field['id'];
- $filterinfo = $filters[$filtername];
-
- $section['name'] = array(
- '#type' => 'textfield',
- '#title' => t('Name'),
- '#size' => 25,
- '#default_value' => $named_filters[$position]->filter_name,
- );
-
- if (!isset($form['filters'][$filtername])) {
- $form['filters'][$filtername] = array(
- '#type' => 'fieldset',
- '#title' => $filterinfo['name'],
- '#tree' => true,
- );
- }
-
- $form['filters'][$filtername][$position] = $section;
- }
-
- $form['submit'] = array(
- '#type' => 'submit',
- '#value' => 'Submit',
- );
-
- return $form;
- }
-
- /**
- * Submit handler for views_bonus_named_filters form.
- *
- * Save named filter choices into the database.
- * @return
- * We don't care about where the redirect goes so no return value.
- */
- function views_bonus_named_filters_edit_submit($form_id, $form_values) {
- db_query("DELETE FROM {views_bonus_named_filters} WHERE view_name = '%s'", $form_values['view']->name);
-
- foreach ($form_values['filters'] as $id => $filters) {
- foreach ($filters as $position => $filter) {
- if ($filter['name']) {
- db_query("INSERT INTO {views_bonus_named_filters} (filter_name, filter_id, view_name, position) VALUES ('%s', '%s', '%s', %d)",
- $filter['name'], $id, $form_values['view']->name, $position);
- }
- }
- }
- cache_clear_all('views_filter_names:' . $form_values['view']->name, 'cache_views');
- }
-
- /**
- * Implementation of hook_views_query_alter().
- */
- function views_bonus_named_filters_views_query_alter(&$query, &$view, $summary, $level) {
- // See if this view has any named filters
- $named_filters = _views_bonus_named_filters_get_filters($view->name);
- if (!empty($named_filters)) {
- $values = array();
- // Look through our named filters.
- foreach ($named_filters as $position => $filter) {
- if ($value = $_GET[$filter->filter_name]) {
- // So, we found a filter. Add it to the running list to pass to views.
- $values[$position]['filter'] = $value;
- }
- }
-
- // If we found exposed arguments, tell views to update the filters.
- if (!empty($values)) {
- _views_bonus_named_filters_build_filters($query, $view, $values);
- }
- }
- }
-
- /**
- * Re-written version of _views_view_build_filters that doesn't add normal filters.
- *
- * Supports handling multiple exposed arguments of the same type a little bit
- * better than _views_view_build_filters does as well.
- */
- function _views_bonus_named_filters_build_filters(&$query, &$view, $exposed_filter_values) {
- $filters = _views_get_filters();
- $view->used_filters = array();
- $exposed_filters = $view->exposed_filter;
-
- foreach ($view->filter as $i => $filter) {
- $filterinfo = $filters[$filter['field']]; // shortcut
- if (!$filterinfo['field']) {
- $fieldbits = explode('.', $filter['field']);
- $filterinfo['field'] = $fieldbits[1];
- }
-
- foreach($exposed_filters as $position => $expose) {
- if ($filter['id'] == $expose['id'] && empty($exposed_filters[$position]['filterinfo'])) {
- $id = $expose['id'];
-
- /**
- * This is the part that's different from views. Instead of breaking
- * executing the following code for all views, we just execute it here.
- */
- $replace = array('>' => '>', '<' => '<');
- $filter['operator'] = strtr($filter['operator'], $replace);
-
- // Stash values for later.
- $exposed_filters[$position]['filterinfo'] = $filterinfo;
- $exposed_filters[$position]['filter'] = $filter;
-
- // We found an exposed filter and setup the values so now we drop out
- // to the normal filter loop so we can find the next one.
- break;
- }
- }
- }
-
- foreach ($exposed_filters as $position => $expose) {
- /**
- * No op support yet.
- *
- if (!$expose['operator'] && $exposed_filter_values[$count]['op']) {
- $filter['operator'] = check_plain($exposed_filter_values[$count]['op']);
- $view->used_filters["op$count"] = $exposed_filter_values[$count]['op'];
- }
- */
-
- // Pull values back out of exposed array.
- $filter = $expose['filter'];
- $filterinfo = $expose['filterinfo'];
-
- // If its optional there's a little bit different logic. Skip processing
- // in a couple cases.
- if ($expose['optional']) {
- if ((!isset($exposed_filter_values[$position]['filter']) || $exposed_filter_values[$position]['filter'] == '') && !$expose['is_default']) {
- continue; // skip
- }
- if ($exposed_filter_values[$position]['filter'] == '**ALL**' ||
- (is_array($exposed_filter_values[$position]['filter']) && in_array('**ALL**', $exposed_filter_values[$position]['filter']))) {
- $view->used_filters["filter$position"] = $exposed_filter_values[$position]['filter'];
- continue; // skip this filter entirely.
- }
- }
-
- // If there's an exposed value, for the given filter, set it up.
- if (isset($exposed_filter_values[$position]['filter']) && $exposed_filter_values[$position]['filter'] != '') {
- $value = $exposed_filter_values[$position]['filter'];
- if ($filterinfo['value-type'] == 'array' && !is_array($value)) {
- $value = array($value);
- }
- $filter['value'] = $value;
- $view->used_filters["filter$position"] = $exposed_filter_values[$position]['filter'];
- }
-
- // Double check that we've got a valid handler and fall back on the default.
- if (!function_exists($filterinfo['handler'])) {
- $filterinfo['handler'] = 'views_handler_filter_default';
- }
-
- // Fire of our handler to take care of the rest.
- $filterinfo['handler']('handler', $filter, $filterinfo, $query);
- }
- }
-
- /**
- * Get a list of filter names for a given view.
- *
- * This gets called for every view so we cache the views to limit the impact
- * on views loading.
- *
- * @param $view_name
- * The name of the view to get a list for.
- * @return
- * An array of named filters for a view. Empty if non found.
- */
- function _views_bonus_named_filters_get_filters($view_name) {
- $filters = array();
-
- if ($cached = cache_get('views_filter_names:' . $view_name, 'cache_views')) {
- $filters = $cached->data;
- }
- elseif ($result = db_query("SELECT filter_id, filter_name, position FROM {views_bonus_named_filters} WHERE view_name = '%s'", $view_name)) {
- while ($row = db_fetch_object($result)) {
- $filters[$row->position] = $row;
- }
- cache_set('views_filter_names:' . $view_name, 'cache_views', $filters);
- }
-
- return $filters;
- }
-