Newer
Older
Earl Miles
committed
<?php
// $Id$
Earl Miles
committed
/**
Earl Miles
committed
* @file view.inc
* Provides the view object type and associated methods.
*/
* @defgroup views_objects Objects that represent a View or part of a view.
* @{
* These objects are the core of Views do the bulk of the direction and
* storing of data. All database activity is in these objects.
*/
/**
* An object to contain all of the data to generate a view, plus the member
* functions to build the view query, execute the query and render the output.
*/
class view extends views_db_object {
var $db_table = 'views_view';
Earl Miles
committed
var $base_table = 'node';
// State variables
var $built = FALSE;
var $executed = FALSE;
Earl Miles
committed
Earl Miles
committed
var $args = array();
Earl Miles
committed
var $use_ajax = FALSE;
var $pager = array(
'use_pager' => FALSE,
'items_per_page' => 10,
'element' => 0,
'offset' => 0,
'current_page' => 0,
);
// Places to put attached renderings:
var $attachment_before = '';
var $attachment_after = '';
Earl Miles
committed
// Exposed widget input
var $exposed_data = array();
var $exposed_input = array();
Earl Miles
committed
// Used to store views that were previously running if we recurse.
var $old_view = array();
/**
* Constructor
*/
function view() {
parent::init();
// Make sure all of our sub objects are arrays.
foreach ($this->db_objects() as $object) {
Earl Miles
committed
$this->query = new stdClass();
* Returns a list of the sub-object types used by this view. These types are
* stored on the display, and are used in the build process.
return array('argument', 'field', 'sort', 'filter', 'relationship');
}
/**
* Returns the complete list of dependent objects in a view, for the purpose
* of initialization and loading/saving to/from the database.
Earl Miles
committed
*
* Note: In PHP5 this should be static, but PHP4 doesn't support static
* methods.
function db_objects() {
return array('display');
}
/**
* Set the arguments that come to this view. Usually from the URL
* but possibly from elsewhere.
*/
Earl Miles
committed
function set_arguments($args) {
Earl Miles
committed
$this->args = $args;
}
/**
* Set the page size for ranged or pager queries
*/
function set_items_per_page($items_per_page) {
$this->pager['items_per_page'] = $items_per_page;
if (empty($items_per_page)) {
$this->pager['use_pager'] = FALSE;
}
}
/**
* Whether or not the pager should be used.
*/
Earl Miles
committed
function set_use_pager($use_pager) {
Earl Miles
committed
}
/**
* The pager element id to use if use_apger is on
*/
function set_pager_element($pager_element) {
}
/**
* How many records to skip. This does not function if use_pager is
* set.
*/
Earl Miles
committed
function set_offset($offset) {
Earl Miles
committed
}
/**
* Whether or not AJAX should be used. If AJAX is used, paging,
* tablesorting and exposed filters will be fetched via an AJAX call
* rather than a page refresh.
*/
function set_use_ajax($use_ajax) {
$this->use_ajax = $use_ajax;
}
/**
* Set the exposed filters input to an array. If unset they will be taken
* from $_GET when the time comes.
*/
function set_exposed_input($filters) {
$this->exposed_input = $filters;
Earl Miles
committed
}
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/**
* Figure out what the exposed input for this view is.
*/
function get_exposed_input() {
// Fill our input either from $_GET or from something previously set on the
// view.
if (empty($this->exposed_input)) {
$this->exposed_input = $_GET;
// unset items that are definitely not our input:
foreach (array('page', 'q') as $key) {
if (isset($this->exposed_input[$key])) {
unset($this->exposed_input[$key]);
}
}
// If we have no input at all, check for remembered input via session.
// If filters are not overridden, store the 'remember' settings on the
// default display. If they are, store them on this display. This way,
// multiple displays in the same view can share the same filters and
// remember settings.
$display_id = ($this->display_handler->is_defaulted('filters')) ? 'default' : $this->current_display;
if (empty($this->exposed_input) && !empty($_SESSION['views'][$this->name][$display_id])) {
$this->exposed_input = $_SESSION['views'][$this->name][$display_id];
}
}
return $this->exposed_input;
}
* Set the display for this view and initialize the display handler.
function init_display($reset = FALSE) {
// The default display is always the first one in the list.
if (isset($this->current_display)) {
return TRUE;
Earl Miles
committed
// Instantiate all displays
foreach (array_keys($this->display) as $id) {
// Correct for shallow cloning
// Often we'll have a cloned view so we don't mess up each other's
// displays, but the clone is pretty shallow and doesn't necessarily
// clone the displays. We can tell this by looking to see if a handler
// has already been set; if it has, but $this->current_display is not
// set, then something is dreadfully wrong.
if (!empty($this->display[$id]->handler)) {
$this->display[$id] = drupal_clone($this->display[$id]);
unset($this->display[$id]->handler);
}
$this->display[$id]->handler = views_get_plugin('display', $this->display[$id]->display_plugin);
if (!empty($this->display[$id]->handler)) {
Earl Miles
committed
// Initialize the new display handler with data.
$this->display[$id]->handler->init($this, $this->display[$id]);
Earl Miles
committed
// If this is NOT the default display handler, let it know which is
// since it may well utilize some data from the default.
// This assumes that the 'default' handler is always first. It always
// is. Make sure of it.
if ($id != 'default') {
$this->display[$id]->handler->default_display = &$this->display['default']->handler;
Earl Miles
committed
}
}
}
$this->current_display = 'default';
$this->display_handler = &$this->display['default']->handler;
Earl Miles
committed
/**
* Get the first display that is accessible to the user.
*
* @param $displays
* Either a single display id or an array of display ids.
*/
function choose_display($displays) {
if (!is_array($displays)) {
return $displays;
}
Earl Miles
committed
$this->init_display();
Earl Miles
committed
foreach ($displays as $display_id) {
if ($this->display[$display_id]->handler->access()) {
Earl Miles
committed
return $display_id;
}
}
Earl Miles
committed
Earl Miles
committed
return 'default';
}
/**
* Set the display as current.
*
* @param $display_id
* The id of the display to mark as current.
*/
Earl Miles
committed
function set_display($display_id = NULL) {
// If we have not already initialized the display, do so. But be careful.
if (empty($this->current_display)) {
$this->init_display();
Earl Miles
committed
// If handlers were not initialized, and no argument was sent, set up
// to the default display.
if (empty($display_id)) {
$display_id = 'default';
}
}
Earl Miles
committed
$display_id = $this->choose_display($display_id);
Earl Miles
committed
// If no display id sent in and one wasn't chosen above, we're finished.
if (empty($display_id)) {
return TRUE;
}
// Ensure the requested display exists.
if (empty($this->display[$display_id])) {
$display_id = 'default';
if (empty($this->display[$display_id])) {
vpr(t('set_display() called with invalid display id @display.', array('@display' => $display_id)));
Earl Miles
committed
// Set the current display.
Earl Miles
committed
// Ensure requested display has a working handler.
if (empty($this->display[$display_id]->handler)) {
$this->display_handler = &$this->display[$display_id]->handler;
Earl Miles
committed
return TRUE;
}
/**
* Find and initialize the style plugin.
*
* Note that arguments may have changed which style plugin we use, so
* check the view object first, then ask the display handler.
*/
function init_style() {
if (isset($this->style_plugin)) {
return is_object($this->style_plugin);
Earl Miles
committed
$this->plugin_name = $this->display_handler->get_option('style_plugin');
$this->style_options = $this->display_handler->get_option('style_options');
Earl Miles
committed
$this->style_plugin = views_get_plugin('style', $this->plugin_name);
if (empty($this->style_plugin)) {
Earl Miles
committed
// init the new display handler with data.
$this->style_plugin->init($this, $this->display[$this->current_display], $this->style_options);
}
/**
* Acquire and attach all of the handlers.
*/
function init_handlers() {
if (empty($this->inited)) {
foreach (views_object_types() as $key => $info) {
$this->_init_handler($key, $info);
}
$this->inited = TRUE;
}
}
/**
* Create a list of base tables eligible for this view. Used primarily
* for the UI. Display must be already initialized.
*/
function get_base_tables() {
$base_tables = array(
$this->base_table => TRUE,
'#global' => TRUE,
);
foreach ($this->display_handler->get_handlers('relationship') as $handler) {
$base_tables[$handler->definition['base']] = TRUE;
}
return $base_tables;
}
/**
* Run the pre_query() on all active handlers.
*/
function _pre_query() {
foreach (views_object_types() as $key => $info) {
$handlers = &$this->$key;
Earl Miles
committed
$position = 0;
foreach ($handlers as $id => $handler) {
$handlers[$id]->position = $position;
$handlers[$id]->pre_query();
Earl Miles
committed
$position++;
/**
* Attach all of the handlers for each type.
*
* @param $key
* One of 'argument', 'field', 'sort', 'filter', 'relationship'
* @param $info
* The $info from views_object_types for this object.
*/
function _init_handler($key, $info) {
// Load the requested items from the display onto the object.
$this->$key = $this->display_handler->get_handlers($key);
Earl Miles
committed
// This reference deals with difficult PHP indirection.
$handlers = &$this->$key;
// Run through and test for accessibility.
foreach ($handlers as $id => $handler) {
if (!$handler->access()) {
unset($handlers[$id]);
Earl Miles
committed
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
/**
* Render the exposed filter form.
*
* This actually does more than that; because it's using FAPI, the form will
* also assign data to the appropriate handlers for use in building the
* query.
*/
function render_exposed_form($block = FALSE) {
// Deal with any exposed filters we may have, before building.
$form_state = array(
'view' => &$this,
'display' => &$this->display_handler->display,
'method' => 'get',
'rerender' => TRUE,
'no_redirect' => TRUE,
);
// Some types of displays (eg. attachments) may wish to use the exposed
// filters of their parent displays instead of showing an additional
// exposed filter form for the attachment as well as that for the parent.
if (!$this->display_handler->displays_exposed() || (!$block && $this->display_handler->get_option('exposed_block'))) {
unset($form_state['rerender']);
}
if (!empty($this->ajax)) {
$form_state['ajax'] = TRUE;
}
$output = drupal_build_form('views_exposed_form', $form_state);
if (!empty($form_state['js settings'])) {
$this->js_settings = $form_state['js settings'];
}
return $output;
}
Earl Miles
committed
// Initially, we want to build sorts and fields. This can change, though,
// if we get a summary view.
// build arguments.
// Create a title for use in the breadcrumb trail.
$title = $this->display_handler->get_option('title');
$this->build_info['breadcrumb'] = array();
$breadcrumb_args = array();
$substitutions = array();
Earl Miles
committed
$status = TRUE;
// Iterate through each argument and process.
foreach ($this->argument as $id => $arg) {
$argument = &$this->argument[$id];
if ($argument->broken()) {
$argument->set_relationship();
$arg = isset($this->args[$position]) ? $this->args[$position] : NULL;
$argument->position = $position;
Earl Miles
committed
if (isset($arg) || $argument->has_default_argument()) {
if (!isset($arg)) {
$arg = $argument->get_default_argument();
// make sure default args get put back.
if (isset($arg)) {
$this->args[$position] = $arg;
}
}
Earl Miles
committed
// Set the argument, which will also validate that the argument can be set.
if (!$argument->set_argument($arg)) {
$status = $argument->validate_fail($arg);
Earl Miles
committed
break;
}
if ($argument->is_wildcard()) {
$arg_title = $argument->wildcard_title();
Earl Miles
committed
}
else {
$arg_title = $argument->get_title();
$argument->query();
Earl Miles
committed
}
// Since we're really generating the breadcrumb for the item above us,
// check the default action of this argument.
if ($this->display_handler->uses_breadcrumb() && $argument->uses_breadcrumb()) {
if (strpos($path, '%') === FALSE) {
$this->build_info['breadcrumb'][$path] = str_replace(array_keys($substitutions), $substitutions, $title);
}
}
// Allow the argument to muck with this breadcrumb.
$argument->set_breadcrumb($this->build_info['breadcrumb']);
// Test to see if we should use this argument's title
if (!empty($argument->options['title'])) {
$title = $argument->options['title'];
Earl Miles
committed
$substitutions['%' . ($position + 1)] = $arg_title;
Earl Miles
committed
$breadcrumb_args[] = $arg;
}
else {
// determine default condition and handle.
$status = $argument->default_action();
Earl Miles
committed
break;
// Be safe with references and loops:
unset($argument);
if (!empty($title)) {
$this->build_info['title'] = str_replace(array_keys($substitutions), $substitutions, $title);
}
Earl Miles
committed
// Store the arguments for later use.
$this->build_info['substitutions'] = $substitutions;
Earl Miles
committed
return $status;
Earl Miles
committed
/**
* Do some common building initialization.
*/
function init_query() {
// Create and initialize the query object.
$views_data = views_fetch_data($this->base_table);
$this->base_field = $views_data['table']['base']['field'];
if (!empty($views_data['table']['base']['database'])) {
$this->base_database = $views_data['table']['base']['database'];
}
views_include('query');
$this->query = new views_query($this->base_table, $this->base_field);
}
/**
* Build the query for the view.
*/
function build($display_id = NULL) {
if (!empty($this->built)) {
return;
}
if (empty($this->current_display) || $display_id) {
if (!$this->set_display($display_id)) {
return FALSE;
}
// Let modules modify the view just prior to executing it.
foreach (module_implements('views_pre_build') as $module) {
$function = $module . '_views_pre_build';
$function($this);
}
// Attempt to load from cache.
// @todo Load a build_info from cache.
$start = views_microtime();
// If that fails, let's build!
$this->build_info = array();
Earl Miles
committed
$this->init_query();
// Call a module hook and see if it wants to present us with a
// pre-built query or instruct us not to build the query for
// some reason.
// @todo: Implement this. Use the same mechanism Panels uses.
// Run through our handlers and ensure they have necessary information.
$this->init_handlers();
// Let the handlers interact with each other if they really want.
$this->_pre_query();
if ($this->display_handler->uses_exposed()) {
Earl Miles
committed
$this->exposed_widgets = $this->render_exposed_form();
Earl Miles
committed
// Build all the relationships first thing.
$this->_build('relationship');
// Build all the filters.
$this->_build('filter');
$this->build_sort = TRUE;
// Arguments can, in fact, cause this whole thing to abort.
if (!$this->_build_arguments()) {
$this->build_time = views_microtime() - $start;
Earl Miles
committed
// Initialize the style; arguments may have changed which style we use,
// so waiting as long as possible is important. But we need to know
// about the style when we go to build fields.
if (!$this->init_style()) {
$this->build_info['fail'] = TRUE;
return FALSE;
}
if ($this->style_plugin->uses_fields()) {
$this->_build('field');
}
// Build our sort criteria if we were instructed to do so.
if (!empty($this->build_sort)) {
// Allow the style handler to deal with sorting.
if ($this->style_plugin->build_sort()) {
$this->_build('sort');
}
}
// Allow display handler to affect the query:
$this->display_handler->query();
// Allow style handler to affect the query:
$this->style_plugin->query();
if (variable_get('views_sql_signature', FALSE)) {
$this->query->add_field(NULL, "'" . $this->name . ':' . $this->current_display . "'", 'view_name');
}
// Let modules modify the query just prior to finalizing it.
foreach (module_implements('views_query_alter') as $module) {
$function = $module . '_views_query_alter';
$function($this, $this->query);
}
$this->build_info['query'] = $this->query->query();
$this->build_info['count_query'] = $this->query->query(TRUE);
$this->build_info['query_args'] = $this->query->get_where_args();
$this->built = TRUE;
$this->build_time = views_microtime() - $start;
// Attach displays
$this->attach_displays();
}
/**
* Internal method to build an individual set of handlers.
*/
function _build($key) {
$handlers = &$this->$key;
foreach ($handlers as $id => $data) {
if (!empty($handlers[$id]) && is_object($handlers[$id])) {
// Give this handler access to the exposed filter input.
Earl Miles
committed
if (!empty($this->exposed_data)) {
Earl Miles
committed
$rc = $handlers[$id]->accept_exposed_input($this->exposed_data);
$handlers[$id]->store_exposed_input($this->exposed_data, $rc);
if (!$rc) {
$handlers[$id]->set_relationship();
$handlers[$id]->query();
/**
* Execute the view's query.
*/
function execute($display_id = NULL) {
if (empty($this->built)) {
if (!$this->build($display_id)) {
return FALSE;
}
}
// Let modules modify the view just prior to executing it.
foreach (module_implements('views_pre_execute') as $module) {
$function = $module . '_views_pre_execute';
$function($this);
}
Earl Miles
committed
$query = db_rewrite_sql($this->build_info['query'], $this->base_table, $this->base_field, array('view' => &$this));
$count_query = db_rewrite_sql($this->build_info['count_query'], $this->base_table, $this->base_field, array('view' => &$this));
Earl Miles
committed
$args = $this->build_info['query_args'];
$items = array();
if ($query) {
Earl Miles
committed
$replacements = module_invoke_all('views_query_substitutions', $this);
Earl Miles
committed
$query = str_replace(array_keys($replacements), $replacements, $query);
Earl Miles
committed
$count_query = 'SELECT COUNT(*) FROM (' . str_replace(array_keys($replacements), $replacements, $count_query) . ') count_alias';
Earl Miles
committed
Earl Miles
committed
if (is_array($args)) {
foreach ($args as $id => $arg) {
$args[$id] = str_replace(array_keys($replacements), $replacements, $arg);
Earl Miles
committed
}
}
Earl Miles
committed
// Allow for a view to query an external database.
if (isset($this->base_database)) {
db_set_active($this->base_database);
$external = TRUE;
}
$start = views_microtime();
if (!empty($this->pager['items_per_page'])) {
// We no longer use pager_query() here because pager_query() does not
// support an offset. This is fine as we don't actually need pager
// query; we've already been doing most of what it does, and we
// just need to do a little more playing with globals.
if (!empty($this->pager['use_pager']) || !empty($this->get_total_rows)) {
$this->total_rows = db_result(db_query($count_query, $args)) - $this->pager['offset'];
if (!empty($this->pager['use_pager'])) {
// dump information about what we already know into the globals
global $pager_page_array, $pager_total, $pager_total_items;
// total rows in query
$pager_total_items[$this->pager['element']] = $this->total_rows;
// total pages
$pager_total[$this->pager['element']] = ceil($pager_total_items[$this->pager['element']] / $this->pager['items_per_page']);
// What page was requested:
$pager_page_array = isset($_GET['page']) ? explode(',', $_GET['page']) : array();
// If the requested page was within range. $this->pager['current_page']
// defaults to 0 so we don't need to set it in an out-of-range condition.
if (!empty($pager_page_array[$this->pager['element']])) {
$page = intval($pager_page_array[$this->pager['element']]);
Earl Miles
committed
if ($page > 0 && $page < $pager_total[$this->pager['element']]) {
$this->pager['current_page'] = $page;
}
}
$pager_page_array[$this->pager['element']] = $this->pager['current_page'];
}
$offset = $this->pager['current_page'] * $this->pager['items_per_page'] + $this->pager['offset'];
$result = db_query_range($query, $args, $offset, $this->pager['items_per_page']);
$result = db_query($query, $args);
}
$this->result = array();
while ($item = db_fetch_object($result)) {
$this->result[] = $item;
if (!empty($external)) {
Earl Miles
committed
db_set_active();
}
$this->execute_time = views_microtime() - $start;
$this->executed = TRUE;
}
/**
* Render this view for display.
*/
function render($display_id = NULL) {
Earl Miles
committed
// Check for cached output.
// @todo: Implement this
$this->execute($display_id);
// Check to see if the build failed.
$start = views_microtime();
Earl Miles
committed
if (!empty($this->live_preview) && variable_get('views_show_additional_queries', FALSE)) {
$this->start_query_capture();
}
Earl Miles
committed
// Initialize the style plugin.
$this->init_style();
$this->style_plugin->pre_render($this->result);
// Let modules modify the view just prior to executing it.
foreach (module_implements('views_pre_render') as $module) {
$function = $module . '_views_pre_render';
// Give field handlers the opportunity to perform additional queries
// using the entire resultset prior to rendering.
if ($this->style_plugin->uses_fields()) {
foreach ($this->field as $id => $handler) {
if (!empty($this->field[$id])) {
$this->field[$id]->pre_render($this->result);
}
$output = $this->display_handler->render();
Earl Miles
committed
if (!empty($this->live_preview) && variable_get('views_show_additional_queries', FALSE)) {
$this->end_query_capture();
}
$this->render_time = views_microtime() - $start;
return $output;
Earl Miles
committed
Earl Miles
committed
/**
* Render a specific field via the field ID and the row #.
*/
function render_field($field, $row) {
if (isset($this->field[$field]) && isset($this->result[$row])) {
return $this->field[$field]->advanced_render($this->result[$row]);
}
}
Earl Miles
committed
/**
Earl Miles
committed
* Execute the given display, with the given arguments.
* To be called externally by whatever mechanism invokes the view,
* such as a page callback, hook_block, etc.
*
* This function should NOT be used by anything external as this
* returns data in the format specified by the display. It can also
* have other side effects that are only intended for the 'proper'
* use of the display, such as setting page titles and breadcrumbs.
*
* If you simply want to view the display, use view::preview() instead.
Earl Miles
committed
*/
function execute_display($display_id = NULL, $args = array()) {
Earl Miles
committed
if (empty($this->current_display) || $this->current_display != $this->choose_display($display_id)) {
if (!$this->set_display($display_id)) {
return FALSE;
}
Earl Miles
committed
Earl Miles
committed
$this->pre_execute($args);
Earl Miles
committed
// Execute the view
$output = $this->display_handler->execute();
Earl Miles
committed
$this->post_execute();
return $output;
Earl Miles
committed
}
Earl Miles
committed
/**
* Preview the given display, with the given arguments.
Earl Miles
committed
*
* To be called externally, probably by an AJAX handler of some flavor.
* Can also be called when views are embedded, as this guarantees
* normalized output.
Earl Miles
committed
*/
function preview($display_id = NULL, $args = array()) {
if (empty($this->current_display) || $this->current_display != $display_id) {
if (!$this->set_display($display_id)) {
return FALSE;
}
}
Earl Miles
committed
$this->pre_execute($args);
// Preview the view.
$output = $this->display_handler->preview();
$this->post_execute();
return $output;
}
/**
* Run attachments and let the display do what it needs to do prior
* to running.
*/
function pre_execute($args = array()) {
$this->old_view[] = views_get_current_view();
Earl Miles
committed
views_set_current_view($this);
$display_id = $this->current_display;
Earl Miles
committed
// Let modules modify the view just prior to executing it.
foreach (module_implements('views_pre_view') as $module) {
$function = $module . '_views_pre_view';
$function($this, $display_id, $args);
}
// Prepare the view with the information we have, but only if we were
// passed arguments, as they may have been set previously.
if ($args) {
$this->set_arguments($args);
}
Earl Miles
committed
// $this->attach_displays();
Earl Miles
committed
// Allow the display handler to set up for execution
$this->display_handler->pre_execute();
Earl Miles
committed
}
Earl Miles
committed
Earl Miles
committed
/**
* Unset the current view, mostly.
*/
function post_execute() {
// unset current view so we can be properly destructed later on.
Earl Miles
committed
// Return the previous value in case we're an attachment.
Earl Miles
committed
if ($this->old_view) {
$old_view = array_pop($this->old_view);
}
Earl Miles
committed
views_set_current_view(isset($old_view) ? $old_view : FALSE);
Earl Miles
committed
}
/**
* Run attachment displays for the view.
*/
function attach_displays() {
if (!empty($this->is_attachment)) {
return;
}
if (!$this->display_handler->accept_attachments()) {
return;
}
$this->is_attachment = TRUE;
// Give other displays an opportunity to attach to the view.
foreach ($this->display as $id => $display) {
if (!empty($this->display[$id]->handler)) {
$this->display[$id]->handler->attach_to($this->current_display);
}
}
$this->is_attachment = FALSE;
}
Earl Miles
committed
/**
* Called to get hook_menu information from the view and the
* named display handler.
*/
function execute_hook_menu($display_id = NULL) {
// Prepare the view with the information we have.
// This was probably already called, but it's good to be safe.
if (!$this->set_display($display_id)) {
Earl Miles
committed
// Execute the view
if (isset($this->display_handler)) {
return $this->display_handler->execute_hook_menu();
}
}
Earl Miles
committed
/**
* Called to get hook_block information from the view and the
* named display handler.
*/
function execute_hook_block($display_id = NULL) {
// Prepare the view with the information we have.
// This was probably already called, but it's good to be safe.
if (!$this->set_display($display_id)) {
return FALSE;
}
// Execute the view
if (isset($this->display_handler)) {
return $this->display_handler->execute_hook_block();
}
}
Earl Miles
committed
/**
* Determine if the given user has access to the view. Note that
* this sets the display handler if it hasn't been.
*/
Earl Miles
committed
function access($displays = NULL, $account = NULL) {
if (!isset($this->current_display)) {
$this->init_display();
Earl Miles
committed
}
if (!$account) {
$account = $GLOBALS['user'];
}
Earl Miles
committed
// We can't use choose_display() here because that function
// calls this one.
$displays = (array)$displays;
foreach ($displays as $display_id) {
if (!empty($this->display[$display_id]->handler)) {
if ($this->display[$display_id]->handler->access($account)) {
return TRUE;
}
}
Earl Miles
committed
return FALSE;
Earl Miles
committed
}
/**
* Get the view's current title. This can change depending upon how it
* was built.
*/
function get_title() {
if (empty($this->display_handler)) {
if (!$this->set_display('default')) {
return FALSE;
}
}
// During building, we might find a title override. If so, use it.
if (!empty($this->build_info['title'])) {
$title = $this->build_info['title'];
}
else {
$title = $this->display_handler->get_option('title');