Newer
Older
* Primarily Drupal hooks and global API functions to manipulate views.
*
* This is the main module file for Views. The main entry points into
* this module are views_page() and views_block(), where it handles
* incoming page and block requests.
Earl Miles
committed
/**
* Advertise the current views api version
*/
function views_api_version() {
Earl Miles
committed
}
/**
* Implements hook_forms().
*
* To provide distinct form IDs for Views forms, the View name and
* specific display name are appended to the base ID,
* views_form_views_form. When such a form is built or submitted, this
* function will return the proper callback function to use for the given form.
*/
function views_forms($form_id, $args) {
if (strpos($form_id, 'views_form_') === 0) {
return array(
$form_id => array(
'callback' => 'views_form',
),
);
}
}
/**
* Returns a form ID for a Views form using the name and display of the View.
*/
function views_form_id($view) {
$parts = array(
'views_form',
$view->name,
$view->current_display,
);
return implode('_', $parts);
}
Earl Miles
committed
/**
* Views will not load plugins advertising a version older than this.
*/
function views_api_minimum_version() {
return '2';
Earl Miles
committed
}
Earl Miles
committed
/**
* Implementation of hook_init().
*/
function views_init() {
drupal_add_css(drupal_get_path('module', 'views') . '/css/views.css');
}
* Implementation of hook_theme(). Register views theming functions.
Earl Miles
committed
function views_theme($existing, $type, $theme, $path) {
$path = drupal_get_path('module', 'views');
require_once "./$path/theme/theme.inc";
Earl Miles
committed
// Some quasi clever array merging here.
// Our extra version of pager from pager.inc
$hooks['views_mini_pager'] = $base + array(
'arguments' => array('tags' => array(), 'limit' => 10, 'element' => 0, 'parameters' => array()),
'pattern' => 'views_mini_pager__',
);
$arguments = array(
'display' => array('view' => NULL),
'style' => array('view' => NULL, 'options' => NULL, 'rows' => NULL, 'title' => NULL),
'row' => array('view' => NULL, 'options' => NULL, 'row' => NULL, 'field_alias' => NULL),
'exposed_form' => array('view' => NULL, 'options' => NULL),
'pager' => array(
'view' => NULL, 'options' => NULL,
'tags' => array(), 'quantity' => 10, 'element' => 0, 'parameters' => array()
),
);
// Default view themes
$hooks['views_view_field'] = $base + array(
'pattern' => 'views_view_field__',
'arguments' => array('view' => NULL, 'field' => NULL, 'row' => NULL),
$plugins = views_fetch_plugin_data();
// Register theme functions for all style plugins
foreach ($plugins as $type => $info) {
foreach ($info as $plugin => $def) {
if (isset($def['theme'])) {
$hooks[$def['theme']] = array(
'pattern' => $def['theme'] . '__',
Earl Miles
committed
'file' => $def['theme file'],
'path' => $def['theme path'],
'arguments' => $arguments[$type],
);
Earl Miles
committed
$include = './' . $def['theme path'] . '/' . $def['theme file'];
if (file_exists($include)) {
require_once $include;
}
if (!function_exists('theme_' . $def['theme'])) {
$hooks[$def['theme']]['template'] = views_css_safe($def['theme']);
if (isset($def['additional themes'])) {
foreach ($def['additional themes'] as $theme => $theme_type) {
if (empty($theme_type)) {
$theme = $theme_type;
$theme_type = $type;
}
$hooks[$theme] = array(
'pattern' => $theme . '__',
Earl Miles
committed
'file' => $def['theme file'],
'path' => $def['theme path'],
Earl Miles
committed
if (!function_exists('theme_' . $theme)) {
$hooks[$theme]['template'] = views_css_safe($theme);
}
}
}
Earl Miles
committed
$hooks['views_form_views_form'] = $base;
Earl Miles
committed
$hooks['views_exposed_form'] = $base + array(
'template' => 'views-exposed-form',
'pattern' => 'views_exposed_form__',
'arguments' => array('form' => NULL),
);
$hooks['views_more'] = $base + array(
'template' => 'views-more',
'pattern' => 'views_more__',
'arguments' => array('more_url' => NULL, 'link_text' => 'more'),
Earl Miles
committed
// Add theme suggestions which are part of modules.
foreach (views_get_module_apis() as $info) {
if (isset($info['template path'])) {
$hooks += _views_find_module_templates($hooks, $info['template path']);
}
}
Earl Miles
committed
}
Earl Miles
committed
/**
* Scans a directory of a module for template files.
*
* @param $cache
* The existing cache of theme hooks to test against.
* @param $path
* The path to search.
*
Earl Miles
committed
* @see drupal_find_theme_templates
*/
function _views_find_module_templates($cache, $path) {
$templates = array();
Earl Miles
committed
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
$regex = '\.tpl\.php' . '$';
// Because drupal_system_listing works the way it does, we check for real
// templates separately from checking for patterns.
$files = drupal_system_listing($regex, $path, 'name', 0);
foreach ($files as $template => $file) {
// Chop off the remaining extensions if there are any. $template already
// has the rightmost extension removed, but there might still be more,
// such as with .tpl.php, which still has .tpl in $template at this point.
if (($pos = strpos($template, '.')) !== FALSE) {
$template = substr($template, 0, $pos);
}
// Transform - in filenames to _ to match function naming scheme
// for the purposes of searching.
$hook = strtr($template, '-', '_');
if (isset($cache[$hook])) {
$templates[$hook] = array(
'template' => $template,
'path' => dirname($file->filename),
'include files' => $cache[$hook]['include files'],
);
}
// Ensure that the pattern is maintained from base themes to its sub-themes.
// Each sub-theme will have their templates scanned so the pattern must be
// held for subsequent runs.
if (isset($cache[$hook]['pattern'])) {
$templates[$hook]['pattern'] = $cache[$hook]['pattern'];
}
}
$patterns = array_keys($files);
foreach ($cache as $hook => $info) {
if (!empty($info['pattern'])) {
// Transform _ in pattern to - to match file naming scheme
// for the purposes of searching.
$pattern = strtr($info['pattern'], '_', '-');
$matches = preg_grep('/^'. $pattern .'/', $patterns);
if ($matches) {
foreach ($matches as $match) {
$file = substr($match, 0, strpos($match, '.'));
// Put the underscores back in for the hook name and register this pattern.
$templates[strtr($file, '-', '_')] = array(
'template' => $file,
'path' => dirname($files[$match]->filename),
'arguments' => $info['arguments'],
'original hook' => $hook,
'include files' => $info['include files'],
);
}
}
}
}
return $templates;
}
Earl Miles
committed
/**
* A theme preprocess function to automatically allow view-based node
* templates if called from a view.
*
* The 'modules/node.views.inc' file is a better place for this, but
* we haven't got a chance to load that file before Drupal builds the
* node portion of the theme registry.
*/
function views_preprocess_node(&$vars) {
// The 'view' attribute of the node is added in template_preprocess_views_view_row_node()
if (!empty($vars['node']->view) && !empty($vars['node']->view->name)) {
$vars['view'] = &$vars['node']->view;
Earl Miles
committed
$vars['template_files'][] = 'node-view-' . $vars['node']->view->name;
if(!empty($vars['node']->view->current_display)) {
$vars['template_files'][] = 'node-view-' . $vars['node']->view->name . '-' . $vars['node']->view->current_display;
Earl Miles
committed
}
}
}
/**
* A theme preprocess function to automatically allow view-based node
* templates if called from a view.
*/
function views_preprocess_comment(&$vars) {
// The 'view' attribute of the node is added in template_preprocess_views_view_row_comment()
if (!empty($vars['node']->view) && !empty($vars['node']->view->name)) {
$vars['view'] = &$vars['node']->view;
$vars['template_files'][] = 'comment-view-' . $vars['node']->view->name;
if(!empty($vars['node']->view->current_display)) {
$vars['template_files'][] = 'comment-view-' . $vars['node']->view->name . '-' . $vars['node']->view->current_display;
}
}
}
/**
* A theme preprocess function to automatically allow blocks with view-based
* block templates if called from a view.
*/
function views_preprocess_block($vars) {
if (!empty($vars['block']->view)) {
$vars['view'] = &$vars['block']->view;
$vars['template_files'][] = 'block-view-' . $vars['view']->name;
if(!empty($vars['view']->current_display)) {
$vars['template_files'][] = 'block-view-' . $vars['view']->name . '-' . $vars['view']->current_display;
}
}
}
/*
* Implementation of hook_perm()
*/
function views_perm() {
Earl Miles
committed
return array('access all views', 'administer views');
Earl Miles
committed
/**
* Implementation of hook_menu().
Earl Miles
committed
*/
function views_menu() {
Earl Miles
committed
// Any event which causes a menu_rebuild could potentially mean that the
// Views data is updated -- module changes, profile changes, etc.
views_invalidate_cache();
Earl Miles
committed
$items = array();
$items['views/ajax'] = array(
'title' => 'Views',
'page callback' => 'views_ajax',
'access callback' => TRUE,
'description' => 'Ajax callback for view loading.',
'file' => 'includes/ajax.inc',
'type' => MENU_CALLBACK,
);
Earl Miles
committed
// Path is not admin/build/views due to menu complications with the wildcards from
// the generic ajax callback.
$items['admin/views/ajax/autocomplete/user'] = array(
'page callback' => 'views_ajax_autocomplete_user',
'access callback' => 'user_access',
'access arguments' => array('access content'),
'file' => 'includes/ajax.inc',
'type' => MENU_CALLBACK,
);
Earl Miles
committed
return $items;
}
Earl Miles
committed
/**
* Implementation of hook_menu_alter().
*/
function views_menu_alter(&$callbacks) {
$our_paths = array();
$views = views_get_applicable_views('uses hook menu');
foreach ($views as $data) {
Earl Miles
committed
list($view, $display_id) = $data;
Earl Miles
committed
$result = $view->execute_hook_menu($display_id, $callbacks);
Earl Miles
committed
if (is_array($result)) {
// The menu system doesn't support having two otherwise
// identical paths with different placeholders. So we
// want to remove the existing items from the menu whose
// paths would conflict with ours.
// First, we must find any existing menu items that may
// conflict. We use a regular expression because we don't
// know what placeholders they might use. Note that we
// first construct the regex itself by replacing %views_arg
// in the display path, then we use this constructed regex
// (which will be something like '#^(foo/%[^/]*/bar)$#') to
// search through the existing paths.
$regex = '#^(' . preg_replace('#%views_arg#', '%[^/]*', implode('|', array_keys($result))) . ')$#';
Earl Miles
committed
$matches = preg_grep($regex, array_keys($callbacks));
// Remove any conflicting items that were found.
Earl Miles
committed
foreach ($matches as $path) {
// Don't remove the paths we just added!
if (!isset($our_paths[$path])) {
Earl Miles
committed
unset($callbacks[$path]);
}
}
foreach ($result as $path => $item) {
if (!isset($callbacks[$path])) {
// Add a new item, possibly replacing (and thus effectively
// overriding) one that we removed above.
$callbacks[$path] = $item;
}
else {
// This item already exists, so it must be one that we added.
// We change the various callback arguments to pass an array
// of possible display IDs instead of a single ID.
Earl Miles
committed
$callbacks[$path]['page arguments'][1] = (array)$callbacks[$path]['page arguments'][1];
$callbacks[$path]['page arguments'][1][] = $display_id;
Earl Miles
committed
$callbacks[$path]['access arguments'][] = $item['access arguments'][0];
Earl Miles
committed
$callbacks[$path]['load arguments'][1] = (array)$callbacks[$path]['load arguments'][1];
$callbacks[$path]['load arguments'][1][] = $display_id;
}
$our_paths[$path] = TRUE;
Earl Miles
committed
}
}
}
// Save memory: Destroy those views.
foreach ($views as $data) {
list($view, $display_id) = $data;
$view->destroy();
}
Earl Miles
committed
}
Earl Miles
committed
/**
Earl Miles
committed
* Helper function for menu loading. This will automatically be
Earl Miles
committed
* called in order to 'load' a views argument; primarily it
* will be used to perform validation.
*
* @param $value
* The actual value passed.
* @param $name
* The name of the view. This needs to be specified in the 'load function'
* of the menu entry.
Earl Miles
committed
* @param $display_id
* The display id that will be loaded for this menu item.
Earl Miles
committed
* @param $index
Earl Miles
committed
* The menu argument index. This counts from 1.
Earl Miles
committed
*/
function views_arg_load($value, $name, $display_id, $index) {
Earl Miles
committed
static $views = array();
// Make sure we haven't already loaded this views argument for a similar menu
// item elsewhere.
$key = $name . ':' . $display_id . ':' . $value . ':' . $index;
if (isset($views[$key])) {
return $views[$key];
}
Earl Miles
committed
if ($view = views_get_view($name)) {
Earl Miles
committed
$view->init_handlers();
$ids = array_keys($view->argument);
$indexes = array();
Earl Miles
committed
$path = explode('/', $view->get_path());
foreach ($path as $id => $piece) {
if ($piece == '%' && !empty($ids)) {
$indexes[$id] = array_shift($ids);
}
}
if (isset($indexes[$index])) {
if (isset($view->argument[$indexes[$index]])) {
$arg = $view->argument[$indexes[$index]]->validate_argument($value) ? $value : FALSE;
$view->destroy();
Earl Miles
committed
// Store the output in case we load this same menu item again.
$views[$key] = $arg;
return $arg;
Earl Miles
committed
}
$view->destroy();
Earl Miles
committed
}
}
/**
* Page callback entry point; requires a view and a display id, then
* passes control to the display handler.
*/
function views_page() {
$args = func_get_args();
$name = array_shift($args);
$display_id = array_shift($args);
// Load the view
Earl Miles
committed
if ($view = views_get_view($name)) {
Earl Miles
committed
return $view->execute_display($display_id, $args);
}
// Fallback; if we get here no view was found or handler was not valid.
return drupal_not_found();
}
/**
* Implementation of hook_block
*/
function views_block($op = 'list', $delta = 0, $edit = array()) {
switch ($op) {
case 'list':
Earl Miles
committed
// Try to avoid instantiating all the views just to get the blocks info.
views_include('cache');
$cache = views_cache_get('views_block_items', TRUE);
if ($cache && is_array($cache->data)) {
return $cache->data;
}
Earl Miles
committed
$items = array();
Earl Miles
committed
$views = views_get_all_views();
foreach ($views as $view) {
// disabled views get nothing.
if (!empty($view->disabled)) {
continue;
}
Earl Miles
committed
$view->init_display();
foreach ($view->display as $display_id => $display) {
Earl Miles
committed
if (isset($display->handler) && !empty($display->handler->definition['uses hook block'])) {
$result = $display->handler->execute_hook_block();
if (is_array($result)) {
$items = array_merge($items, $result);
}
}
if (isset($display->handler) && $display->handler->get_option('exposed_block')) {
$result = $display->handler->get_special_blocks();
if (is_array($result)) {
$items = array_merge($items, $result);
}
}
Earl Miles
committed
}
Earl Miles
committed
}
Earl Miles
committed
// block.module has a delta length limit of 32, but our deltas can
// unfortunately be longer because view names can be 32 and display IDs
// can also be 32. So for very long deltas, change to md5 hashes.
$hashes = array();
// get the keys because we're modifying the array and we don't want to
// confuse PHP too much.
$keys = array_keys($items);
foreach ($keys as $delta) {
if (strlen($delta) >= 32) {
$hash = md5($delta);
$hashes[$hash] = $delta;
$items[$hash] = $items[$delta];
unset($items[$delta]);
}
}
Earl Miles
committed
// Only save hashes if they have changed.
$old_hashes = variable_get('views_block_hashes', array());
if ($hashes != $old_hashes) {
variable_set('views_block_hashes', $hashes);
}
// Save memory: Destroy those views.
Earl Miles
committed
foreach ($views as $view) {
$view->destroy();
}
Earl Miles
committed
views_cache_set('views_block_items', $items, TRUE);
Earl Miles
committed
return $items;
case 'view':
Earl Miles
committed
// if this is 32, this should be an md5 hash.
if (strlen($delta) == 32) {
$hashes = variable_get('views_block_hashes', array());
if (!empty($hashes[$delta])) {
$delta = $hashes[$delta];
}
}
Earl Miles
committed
// This indicates it's a special one.
if (substr($delta, 0, 1) == '-') {
list($nothing, $type, $name, $display_id) = explode('-', $delta);
// Put the - back on.
$type = '-' . $type;
Earl Miles
committed
if ($view = views_get_view($name)) {
if ($view->access($display_id)) {
$view->set_display($display_id);
if (isset($view->display_handler)) {
$output = $view->display_handler->view_special_blocks($type);
Earl Miles
committed
return $output;
}
}
Earl Miles
committed
}
}
Earl Miles
committed
list($name, $display_id) = explode('-', $delta);
// Load the view
Earl Miles
committed
if ($view = views_get_view($name)) {
if ($view->access($display_id)) {
Earl Miles
committed
$output = $view->execute_display($display_id);
$view->destroy();
Earl Miles
committed
return $output;
Earl Miles
committed
}
break;
}
}
Daniel Wehner
committed
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
/**
+ * Returns an array of language names.
+ *
+ * This is a one to one copy of locale_language_list because we can't rely on enabled locale module.
+ *
+ * @param $field
+ * 'name' => names in current language, localized
+ * 'native' => native names
+ * @param $all
+ * Boolean to return all languages or only enabled ones
+ *
+ * @see locale_language_list
+ */
function views_language_list($field = 'name', $all = FALSE) {
if ($all) {
$languages = language_list();
}
else {
$languages = language_list('enabled');
$languages = $languages[1];
}
$list = array();
foreach ($languages as $language) {
$list[$language->language] = ($field == 'name') ? t($language->name) : $language->$field;
}
return $list;
}
* Implementation of hook_flush_caches().
Earl Miles
committed
return array('cache_views', 'cache_views_data');
/**
* Invalidate the views cache, forcing a rebuild on the next grab of table data.
*/
function views_invalidate_cache() {
cache_clear_all('*', 'cache_views', true);
}
/**
* Access callback to determine if the user can import Views.
*
* View imports require an additional access check because they are PHP
* code and PHP is more locked down than administer views.
*/
function views_import_access() {
return user_access('administer views') && user_access('use PHP for block visibility');
}
Earl Miles
committed
/**
Earl Miles
committed
* Determine if the logged in user has access to a view.
Earl Miles
committed
* This function should only be called from a menu hook or some other
* embedded source. Each argument is the result of a call to
* views_plugin_access::get_access_callback() which is then used
* to determine if that display is accessible. If *any* argument
* is accessible, then the view is accessible.
Earl Miles
committed
*/
Earl Miles
committed
function views_access() {
$args = func_get_args();
foreach ($args as $arg) {
if ($arg === TRUE) {
return TRUE;
}
if (!is_array($arg)) {
continue;
}
list($callback, $arguments) = $arg;
$arguments = $arguments ? $arguments : array();
// Bring dynamic arguments to the access callback.
foreach ($arguments as $key => $value) {
if (is_int($value) && isset($args[$value])) {
$arguments[$key] = $args[$value];
}
}
Earl Miles
committed
if (function_exists($callback) && call_user_func_array($callback, $arguments)) {
return TRUE;
Earl Miles
committed
}
}
Earl Miles
committed
return FALSE;
Earl Miles
committed
}
Earl Miles
committed
/**
Earl Miles
committed
* Access callback for the views_plugin_access_perm access plugin.
Earl Miles
committed
*
Earl Miles
committed
* Determine if the specified user has access to a view on the basis of
* permissions. If the $account argument is omitted, the current user
* is used.
*/
function views_check_perm($perm, $account = NULL) {
return user_access($perm, $account) || user_access('access all views', $account);
}
/**
* Access callback for the views_plugin_access_role access plugin.
* Determine if the specified user has access to a view on the basis of any of
* the requested roles. If the $account argument is omitted, the current user
* is used.
Earl Miles
committed
*/
Earl Miles
committed
function views_check_roles($rids, $account = NULL) {
Earl Miles
committed
global $user;
Earl Miles
committed
$account = isset($account) ? $account : $user;
$roles = array_keys($account->roles);
$roles[] = $account->uid ? DRUPAL_AUTHENTICATED_RID : DRUPAL_ANONYMOUS_RID;
return user_access('access all views', $account) || array_intersect(array_filter($rids), $roles);
Earl Miles
committed
}
// ------------------------------------------------------------------
// Functions to help identify views that are running or ran
Earl Miles
committed
/**
* Set the current 'page view' that is being displayed so that it is easy
* for other modules or the theme to identify.
*/
function &views_set_page_view($view = NULL) {
static $cache = NULL;
if (isset($view)) {
$cache = $view;
}
return $cache;
}
/**
* Find out what, if any, page view is currently in use. Please note that
* this returns a reference, so be careful! You can unintentionally modify the
* $view object.
*/
function &views_get_page_view() {
return views_set_page_view();
}
/**
* Set the current 'current view' that is being built/rendered so that it is
* easy for other modules or items in drupal_eval to identify
*/
Earl Miles
committed
function &views_set_current_view($view = NULL) {
static $cache = NULL;
if (isset($view)) {
Earl Miles
committed
$cache = $view;
}
return $cache;
}
/**
* Find out what, if any, current view is currently in use. Please note that
* this returns a reference, so be careful! You can unintentionally modify the
* $view object.
*/
function &views_get_current_view() {
return views_set_current_view();
}
// ------------------------------------------------------------------
// Include file helpers
/**
* Include views .inc files as necessary.
*/
function views_include($file) {
static $used = array();
if (!isset($used[$file])) {
require_once './' . drupal_get_path('module', 'views') . "/includes/$file.inc";
}
$used[$file] = TRUE;
/**
* Load views files on behalf of modules.
*/
function views_module_include($file, $reset = FALSE) {
foreach (views_get_module_apis($reset) as $module => $info) {
Earl Miles
committed
if (file_exists("./$info[path]/$module.$file")) {
require_once "./$info[path]/$module.$file";
}
Earl Miles
committed
}
}
/**
* Get a list of modules that support the current views API.
*/
function views_get_module_apis($reset = FALSE) {
Earl Miles
committed
static $cache = NULL;
if (!isset($cache) || $reset) {
Earl Miles
committed
$cache = array();
foreach (module_implements('views_api') as $module) {
$function = $module . '_views_api';
$info = $function();
Earl Miles
committed
if (version_compare($info['api'], views_api_minimum_version(), '>=') &&
version_compare($info['api'], views_api_version(), '<=')) {
Earl Miles
committed
if (!isset($info['path'])) {
$info['path'] = drupal_get_path('module', $module);
}
$cache[$module] = $info;
}
}
}
Earl Miles
committed
return $cache;
}
/**
* Include views .css files.
*/
function views_add_css($file) {
// We set preprocess to FALSE because we are adding the files conditionally,
// and we don't want to generate duplicate cache files.
// TODO: at some point investigate adding some files unconditionally and
// allowing preprocess.
drupal_add_css(drupal_get_path('module', 'views') . "/css/$file.css", 'module', 'all', FALSE);
}
/**
* Include views .js files.
*/
function views_add_js($file) {
// If javascript has been disabled by the user, never add js files.
if (variable_get('views_no_javascript', FALSE)) {
return;
}
static $base = TRUE;
if ($base) {
drupal_add_js(drupal_get_path('module', 'views') . "/js/base.js");
}
drupal_add_js(drupal_get_path('module', 'views') . "/js/$file.js");
}
/**
* Load views files on behalf of modules.
*/
function views_include_handlers($reset = FALSE) {
static $finished = FALSE;
// Ensure this only gets run once.
if ($finished && !$reset) {
Earl Miles
committed
views_include('base');
views_include('cache');
Daniel Wehner
committed
_views_include_handlers($reset);
/**
* Load default views files on behalf of modules.
*/
function views_include_default_views($reset = FALSE) {
static $finished = FALSE;
// Ensure this only gets run once.
if ($finished && !$reset) {
return;
}
// Default views hooks may be in the normal handler file,
// or in a separate views_default file at the discretion of
Earl Miles
committed
// the module author.
views_include_handlers($reset);
Earl Miles
committed
_views_include_default_views($reset);
$finished = TRUE;
}
// -----------------------------------------------------------------------
// Views handler functions
/**
* Fetch a handler from the data cache.
Earl Miles
committed
*
* @param $table
* The name of the table this handler is from.
* @param $field
* The name of the field this handler is from.
* @param $key
* The type of handler. i.e, sort, field, argument, filter, relationship
Earl Miles
committed
* @param $override
* Override the actual handler object with this class. Used for
* aggregation when the handler is redirected to the aggregation
* handler.
Earl Miles
committed
*
Earl Miles
committed
* An instance of a handler object. May be views_handler_broken.
Earl Miles
committed
function views_get_handler($table, $field, $key, $override = NULL) {
$data = views_fetch_data($table);
Earl Miles
committed
$handler = NULL;
if (isset($data[$field][$key])) {
Earl Miles
committed
// Set up a default handler:
if (empty($data[$field][$key]['handler'])) {
$data[$field][$key]['handler'] = 'views_handler_' . $key;
}
Earl Miles
committed
if ($override) {
$data[$field][$key]['override handler'] = $override;
}
$handler = _views_prepare_handler($data[$field][$key], $data, $field, $key);
Earl Miles
committed
}
if ($handler) {
return $handler;
Earl Miles
committed
Earl Miles
committed
vpr("Missing handler: $table $field $key");
Earl Miles
committed
$broken = array(
'title' => t('Broken handler @table.@field', array('@table' => $table, '@field' => $field)),
'handler' => 'views_handler_' . $key . '_broken',
'table' => $table,
'field' => $field,
);
return _views_create_handler($broken, 'handler', $key);
/**
* Fetch Views' data from the cache
*/
function views_fetch_data($table = NULL, $reset = FALSE) {
views_include('cache');
return _views_fetch_data($table, $reset);
// -----------------------------------------------------------------------
// Views plugin functions
/**
* Fetch the plugin data from cache.
*/
function views_fetch_plugin_data($type = NULL, $plugin = NULL, $reset = FALSE) {
views_include('cache');
return _views_fetch_plugin_data($type, $plugin, $reset);
* Get a handler for a plugin
*
* @return views_plugin
*
* The created plugin object.
function views_get_plugin($type, $plugin, $reset = FALSE) {
$definition = views_fetch_plugin_data($type, $plugin, $reset);
Earl Miles
committed
return _views_create_handler($definition, $type);
Daniel Wehner
committed
/**
* Load the current enabled localization plugin.
*
* @return The name of the localization plugin.
*/
function views_get_localization_plugin() {
$plugin = variable_get('views_localization_plugin', '');
// Provide sane default values for the localization plugin.
if (empty($plugin)) {
if (module_exists('locale')) {
$plugin = 'core';
}
else {
$plugin = 'none';
}
}
return $plugin;
}
// -----------------------------------------------------------------------
// Views database functions
/**
* Get a view from the default views defined by modules.
Earl Miles
committed
*
* Default views are cached per-language. This function will rescan the
* default_views hook if necessary.
*
* @param $view_name
* The name of the view to load.
* @return
* A view object or NULL if it is not available.
*/
function &views_get_default_view($view_name, $reset = FALSE) {
Earl Miles
committed
// Attempt to load individually cached view from cache.
views_include('cache');
if (!$reset) {
$data = views_cache_get("views_default:{$view_name}", TRUE);
if (isset($data->data) && is_object($data->data)) {
return $data->data;
}
}
// Otherwise, allow entire cache to be rebuilt.
$cache = views_discover_default_views($reset);
if (isset($cache[$view_name])) {
return $cache[$view_name];
}
return $null;
}
/**
* Create an empty view to work with.
*
* A fully formed, empty $view object. This object must be populated before
* it can be successfully saved.
*/
function views_new_view() {
views_include('view');
$view = new view();
$view->vid = 'new';
}
/**
* Scan all modules for default views and rebuild the default views cache.
*
* @return An associative array of all known default views.
*/
function views_discover_default_views($reset = FALSE) {
Earl Miles
committed
static $cache = array();
Earl Miles
committed
if (empty($cache) || $reset) {
views_include('cache');