<?php
-// $Id$
-// $Name$
// ---------------------------------------------------------------------------
// Drupal Hooks
if (arg(0) == 'admin' && arg(2) == 'modules') {
views_invalidate_cache();
}
-
+
views_menu_standard_items($items);
}
else {
}
/**
+ * Implementation of hook_views_tabs().
+ */
+function views_views_tabs($op) {
+ switch ($op) {
+ case 'names':
+ return array('edit', 'view', 'clone', 'export', 'add');
+ break;
+ }
+}
+
+/**
* Add the adminstrative items to a view.
*/
function views_menu_admin_items(&$items, $view_name, $view_args, $args) {
+ // Remove args that are tabs from $args.
+ $tabs = array();
+ foreach (module_implements('views_tabs') as $module) {
+ $function = $module .'_views_tabs';
+ $tabs = array_merge($tabs, (array) $function('names'));
+ }
// See what the last arg is.
$last_arg = array_pop($args);
- if (in_array($last_arg, array('edit', 'view', 'clone', 'export'))) {
+ if (in_array($last_arg, $tabs)) {
array_pop($view_args);
}
else {
$args[] = $last_arg;
}
-
- $path = implode('/', $args);
$view = views_get_view($view_name);
+ $path = implode('/', $args);
views_ui_add_menu_items($items, $view, $path, $path != $_GET['q'] && !empty($view_args), $view_args);
}
if ($cache == 0) {
$views = array();
$used = array();
- $result = db_query("SELECT name, url FROM {view_view} WHERE page = 1");
+ // avoid creating empty path items by requiring an URL to be set
+ $result = db_query("SELECT name, url FROM {view_view} WHERE page = 1 AND LENGTH(url) > 0");
while ($view = db_fetch_object($result)) {
$used[$view->name] = TRUE;
foreach ($default_views as $name => $view) {
if ($view->page && !$used[$name] && ($views_status[$name] == 'enabled' || (!$view->disabled && $views_status[$name] != 'disabled'))) {
- if ($view->url{0} == '$' || strpos($view->url, '/$') !== FALSE) {
$views[$view->name] = $view->url;
- }
}
}
cache_set("views_urls", 'cache_views', serialize($views));
$items[] = _views_menu_item($path, $title, $view, $args, $access, $type, $weight);
if ($type == MENU_DEFAULT_LOCAL_TASK) {
- $items[] = _views_menu_item(dirname($path), $title, $view, $args, $access, $local_task_type, $weight);
+ switch ($view->menu_tab_default_parent_type) {
+ case 'tab':
+ $parent_type = MENU_LOCAL_TASK;
+ break;
+ case 'normal':
+ $parent_type = MENU_NORMAL_ITEM;
+ break;
+ case 'existing':
+ $parent_type = 0;
+ break;
+ }
+ if ($parent_type) {
+ $title = filter_xss_admin(views_get_title($view, 'menu-parent'));
+ $weight = $view->menu_parent_tab_weight;
+ $items[] = _views_menu_item(dirname($path), $title, $view, $args, $access, $parent_type, $weight);
+ }
}
}
}
// All views with an empty access setting are available to all roles.
- if (!$view->access) {
+ if (!$view->access) {
return TRUE;
}
if ($args == NULL) {
$args = array();
}
-
+
// if no filter values are passed in, get them from the $_GET array
if ($filters == NULL) {
- $filters = _views_get_filter_values();
+ $filters = views_get_filter_values();
}
views_set_current_view($view);
ob_end_clean();
}
+ $view->use_pager = $use_pager;
+ $view->pager_limit = $limit;
+ $view->current_page = $page;
+ $view->offset = $offset;
+
// Call a hook that'll let modules modify the view query before it is created
foreach (module_implements('views_pre_query') as $module) {
$function = $module .'_views_pre_query';
return $info;
}
- $query = db_rewrite_sql($info['query'], 'node');
-
$items = array();
- if ($query) {
- if ($use_pager) {
+ if ($info['query']) {
+ $query = db_rewrite_sql($info['query'], 'node');
+
+ if ($view->use_pager) {
$cquery = db_rewrite_sql($info['countquery'], 'node', 'nid', $info['rewrite_args']);
- $result = pager_query($query, $limit, $use_pager - 1, $cquery, $info['args']);
- $view->total_rows = $GLOBALS['pager_total_items'][$use_pager - 1];
+ $result = pager_query($query, $view->pager_limit, $view->use_pager - 1, $cquery, $info['args']);
+ $view->total_rows = $GLOBALS['pager_total_items'][$view->use_pager - 1];
}
else {
- $result = ($limit ? db_query_range($query, $info['args'], $page * $limit + $offset, $limit) : db_query($query, $info['args']));
+ $result = ($view->pager_limit ? db_query_range($query, $info['args'], $view->current_page * $view->pager_limit + $view->offset, $view->pager_limit) : db_query($query, $info['args']));
}
$view->num_rows = db_num_rows($result);
if ($type == 'result') {
$view->real_url = views_get_url($view, $args);
- $view->use_pager = $use_pager;
- $view->pager_limit = $limit;
$output .= views_theme('views_view', $view, $type, $items, $info['level'], $args);
// Call a hook that'll let modules modify the view just after it is displayed.
if (!$already_set) {
if ($GLOBALS['db_type'] == 'mysqli' || version_compare(mysql_get_server_info(), '4.1.3', '>=')) {
db_query("SET @@session.time_zone = '+00:00'");
- }
+ }
$already_set = true;
}
}
* Figure out what the title of a view should be.
*/
function views_get_title($view, $context = 'menu', $args = NULL) {
- if (($context == 'menu' || $context == 'admin') && $view->menu_title)
+ if ($context == 'menu-parent' && $view->menu_parent_title) {
+ return $view->menu_parent_title;
+ }
+ if (($context == 'menu' || $context == 'menu-parent' || $context == 'admin') && $view->menu_title) {
return $view->menu_title;
+ }
if ($context == 'block-info') {
return $view->description ? $view->description : $view->name;
}
}
- if (!$title && ($context == 'menu' || $context == 'page' || $context == 'admin')) {
+ if (!$title && ($context == 'menu' || $context == 'menu-parent' || $context == 'page' || $context == 'admin')) {
$title = $view->page_title;
}
* Provide all the fields in a view.
*/
function _views_view_fields() {
- return array('vid', 'name', 'description', 'access', 'page', 'page_title', 'page_header', 'page_header_format', 'page_footer', 'page_footer_format', 'page_empty', 'page_empty_format', 'page_type', 'use_pager', 'nodes_per_page', 'url', 'menu', 'menu_tab', 'menu_tab_default', 'menu_tab_weight', 'menu_title', 'block', 'block_title', 'block_use_page_header', 'block_header', 'block_header_format', 'block_use_page_footer', 'block_footer', 'block_footer_format', 'block_use_page_empty', 'block_empty', 'block_empty_format', 'block_type', 'nodes_per_block', 'block_more', 'url', 'breadcrumb_no_home', 'changed', 'view_args_php', 'is_cacheable');
+ return array(
+ 'vid' => '%d',
+ 'name' => "'%s'",
+ 'description' => "'%s'",
+ 'access' => "'%s'",
+ 'page' => '%d',
+ 'page_title' => "'%s'",
+ 'page_header' => "'%s'",
+ 'page_header_format' => '%d',
+ 'page_footer' => "'%s'",
+ 'page_footer_format' => '%d',
+ 'page_empty' => "'%s'",
+ 'page_empty_format' => '%d',
+ 'page_type' => "'%s'",
+ 'use_pager' => '%d',
+ 'nodes_per_page' => '%d',
+ 'url' => "'%s'",
+ 'menu' => '%d',
+ 'menu_tab' => '%d',
+ 'menu_tab_default' => '%d',
+ 'menu_tab_weight' => '%d',
+ 'menu_title' => "'%s'",
+ 'menu_tab_default_parent_type' => "'%s'",
+ 'menu_parent_title' => "'%s'",
+ 'menu_parent_tab_weight' => '%d',
+ 'block' => '%d',
+ 'block_title' => "'%s'",
+ 'block_use_page_header' => '%d',
+ 'block_header' => "'%s'",
+ 'block_header_format' => '%d',
+ 'block_use_page_footer' => '%d',
+ 'block_footer' => "'%s'",
+ 'block_footer_format' => '%d',
+ 'block_use_page_empty' => '%d',
+ 'block_empty' => "'%s'",
+ 'block_empty_format' => '%d',
+ 'block_type' => "'%s'",
+ 'nodes_per_block' => '%d',
+ 'block_more' => '%d',
+ 'breadcrumb_no_home' => '%d',
+ 'changed' => '%d',
+ 'view_args_php' => "'%s'",
+ 'is_cacheable' => '%d',
+ );
}
/**
db_query("DELETE FROM {view_sort} where vid=%d", $view->vid);
db_query("DELETE FROM {view_argument} where vid=%d", $view->vid);
db_query("DELETE FROM {view_tablefield} where vid=%d", $view->vid);
+ db_query("DELETE FROM {view_filter} where vid=%d", $view->vid);
+ db_query("DELETE FROM {view_exposed_filter} where vid=%d", $view->vid);
cache_clear_all('views_query:' . $view->name, 'cache_views');
cache_clear_all(); // In Drupal 5.0 and later this clears the page cache only.
// update
// Prepare the query:
foreach ($view as $key => $value) {
- if (in_array($key, $fields)) {
- $q[] = db_escape_string($key) ." = '%s'";
+ if (array_key_exists($key, $fields)) {
+ $q[] = db_escape_string($key) ." = $fields[$key]";
$v[] = $value;
}
}
// Prepare the query:
foreach ($view as $key => $value) {
- if (in_array((string) $key, $fields)) {
+ if (array_key_exists((string) $key, $fields)) {
$k[] = db_escape_string($key);
$v[] = $value;
- $s[] = is_numeric($value) ? '%d' : "'%s'";
+ $s[] = $fields[$key];
}
}
}
cache_clear_all('views_urls', 'cache_views');
cache_clear_all(); // clear the page cache as well.
+ return $view->vid;
}
// ---------------------------------------------------------------------------
function views_filters($view) {
$form = _views_build_filters_form($view);
+ $form['#view_name'] = $view->name;
$form['#method'] = 'get';
$form['#process'] = array('views_filters_process' => array());
$form['#action'] = url($view->real_url ? $view->real_url : $view->url, NULL, NULL, true);
$form['view'] = array('#type' => 'value', '#value' => $view);
$form['submit'] = array('#type' => 'button', '#name' => '', '#value' => t('Submit'));
-
+
// clean URL get forms breaks if we don't give it a 'q'.
if (!(bool)variable_get('clean_url', '0')) {
$form['q'] = array(
}
function _views_build_filters_form($view) {
+ // When the form is retrieved through an AJAX callback, the cache hasn't
+ // been loaded yet. The cache is necesssary for _views_get_filters().
+ views_load_cache();
+
$filters = _views_get_filters();
foreach ($view->exposed_filter as $count => $expose) {
$id = $expose['id'];
}
if ($expose['single']) {
- unset($item['#multiple']);\r
- // On multi-select categories the #size element is in the form by default. We remove it to allow the single-select drop-down filter to work.\r
+ unset($item['#multiple']);
+ // On multi-select categories the #size element is in the form by default. We remove it to allow the single-select drop-down filter to work.
unset($item['#size']);
}
if ($expose['optional'] && is_array($item['#options'])) {
}
$form["filter$count"] = $item;
}
-
+
return $form;
}
foreach ($nodes as $node) {
$item = '';
foreach ($view->field as $field) {
- if ($fields[$field['id']]['visible'] !== FALSE) {
+ if (!isset($fields[$field['id']]['visible']) && $fields[$field['id']]['visible'] !== FALSE) {
if ($field['label']) {
$item .= "<div class='view-label ". views_css_safe('view-label-'. $field['queryname']) ."'>" . $field['label'] . "</div>";
}
// For next round.
}
$args[] = $arg;
- if ($where && $where = strpos('$arg', $url)) {
+ if ($where && $where = strpos($url, '$arg')) {
$url = substr_replace($url, $arg, $where, 4);
}
else {
}
function views_handler_sort_date($op, &$query, $sortinfo, $sort) {
+ $timezone = _views_get_timezone();
switch($sort['options']) {
case 'normal':
default:
$field = $sortinfo['field'];
break;
case 'minute':
- $field = "DATE_FORMAT(FROM_UNIXTIME($sortinfo[table].$sortinfo[field]), '%Y%m%%d%H%m')";
+ $field = "DATE_FORMAT(FROM_UNIXTIME($sortinfo[table].$sortinfo[field]), '%Y%m%%d%H%i')";
break;
case 'hour':
$field = "DATE_FORMAT(FROM_UNIXTIME($sortinfo[table].$sortinfo[field]), '%Y%m%%d%H')";
break;
case 'day':
- $field = "DATE_FORMAT(FROM_UNIXTIME($sortinfo[table].$sortinfo[field]), '%Y%m%%d')";
+ $field = "DATE_FORMAT(FROM_UNIXTIME($sortinfo[table].$sortinfo[field]+$timezone), '%Y%m%%d')";
break;
case 'month':
- $field = "DATE_FORMAT(FROM_UNIXTIME($sortinfo[table].$sortinfo[field]), '%Y%m%)";
+ $field = "DATE_FORMAT(FROM_UNIXTIME($sortinfo[table].$sortinfo[field]+$timezone), '%Y%m')";
break;
case 'year':
- $field = "DATE_FORMAT(FROM_UNIXTIME($sortinfo[table].$sortinfo[field]), '%Y%')";
+ $field = "DATE_FORMAT(FROM_UNIXTIME($sortinfo[table].$sortinfo[field]+$timezone), '%Y')";
break;
}
$alias = $as = $sortinfo['table'] . '_' . $sortinfo['field'];
if (!$node) {
return FALSE;
}
-
+
if ($argument && $node->type != $argument) {
return FALSE;
}
}
/**
+ * Custom filter for IS NULL and IS NOT NULL operations
+ * Operator must be 'IS' or 'IS NOT'
+ */
+function views_handler_filter_null($op, $filter, $filterinfo, &$query) {
+ switch($op) {
+ case 'handler':
+ $table = $filterinfo['table'];
+ $column = $filterinfo['field'];
+ $field = "$table.$column";
+ $query->ensure_table($table);
+ $operator = $filter['operator'];
+ $query->add_where("$field $operator NULL");
+ break;
+ }
+}
+
+/**
* Format a field as file size.
*/
function views_handler_field_filesize($fieldinfo, $fielddata, $value, $data) {
}
}
-
/**
* This function is used as a central place to manage some translatable text strings
* that are used in different places.
/**
* This function fetches filter values from the $_GET object
*/
-function _views_get_filter_values() {
+function views_get_filter_values($input = NULL) {
+ if (!isset($input)) {
+ $input = $_GET;
+ }
$values = array();
- foreach($_GET as $key => $value) {
+ foreach($input as $key => $value) {
if(strpos($key, 'op') === 0) { // starts with op
$values[substr($key, 2)]['op'] = $value; // two letters in op
} elseif (strpos($key, 'filter') === 0) { // starts with op
}
}
return $values;
+}
+
+/**
+ * Invalidate the views cache when taxonomy vocabulary changes.
+ */
+function views_taxonomy($op, $type, $object = NULL) {
+ if ($type == 'vocabulary' && $op == 'delete' || $op == 'insert' || $op == 'update') {
+ views_invalidate_cache();
+ }
+}
+
+function views_form_alter($form_id, &$form) {
+ if ($form_id == 'profile_field_form') {
+ views_invalidate_cache();
+ }
+}
+
+// An implementation of hook_devel_caches() from devel.module. Must be in views.module so it always is included.
+function views_devel_caches() {
+ return array('cache_views');
}
\ No newline at end of file