Commit f4f02cb1 authored by merlinofchaos's avatar merlinofchaos
Browse files

Breaking the caching stuff into its own .inc file, reducing the frequency with...

Breaking the caching stuff into its own .inc file, reducing the frequency with which views includes are loaded.
parent 91ec26c2
<?php
// $Id$
function views_init() {
// hook init is called even on cached pages, but we don't want to
// actually do anything in that case.
if (!function_exists('drupal_get_path')) {
return;
}
// Load all our module 'on behalfs'.
$path = drupal_get_path('module', 'views') . '/modules';
$files = system_listing('views_.*\.inc$', $path, 'name', 0);
foreach($files as $file) {
// The filename format is very specific. It must be views_MODULENAME.inc
$module = substr_replace($file->name, '', 0, 6);
if (module_exists($module)) {
require_once("./$file->filename");
}
}
}
// ---------------------------------------------------------------------------
// Acquire Views Data
/**
* Return the arguments array; construct one if we haven't already. The
* array is cached in a global, safely named variable so that arguments
* are only constructed once per run.
*/
function _views_get_arguments($titles = false) {
static $views_arguments;
global $locale;
if (!$views_arguments) {
$data = cache_get("views_arguments:$locale", 'cache');
$cache = unserialize($data->data);
if (is_array($cache)) {
$views_arguments = $cache;
}
else {
$arguments = module_invoke_all('views_arguments');
foreach ($arguments as $name => $arg) {
if ($arg['option'] && !is_array($arg['option'])) {
if ($arg['option'] == 'string' || $arg['option'] == 'integer') {
$arg['option'] = array('#type' => 'textfield', '#size' => 10, '#maxlength' => 255);
}
else {
$arg['option'] = array('#type' => 'select', '#options' => $arg['option']);
}
}
$views_arguments['base'][$name] = $arg['name'];
$views_arguments['title'][$name] = $arg;
}
$cache = $views_arguments;
cache_set("views_arguments:$locale", 'cache', serialize($cache));
}
}
return ($titles ? $views_arguments['base'] : $views_arguments['title']);
}
/**
* Constructs the full table information array. Caches it into a global array
* so that it will only be called once per run.
*/
function _views_get_tables($full = false) {
static $views_tables;
global $locale;
if (!$views_tables) {
$data = cache_get("views_tables:$locale", 'cache');
$cache = unserialize($data->data);
if (is_array($cache)) {
$views_tables = $cache;
}
else {
$table_data = module_invoke_all('views_tables');
$views_tables['tables'] = $table_data;
foreach ($table_data as $name => $table) {
if (is_array($table['filters'])) {
foreach ($table['filters'] as $filter => $data) {
$data['table'] = $name;
// translate for deprecated APIs...
if ($data['option'] && !is_array($data['option'])) {
if ($data['option'] == 'string' || $data['option'] == 'integer') {
$data['option'] = array('#type' => 'textfield', '#size' => 10, '#maxlength' => 255);
}
else {
$data['option'] = array('#type' => 'select', '#options' => $data['option']);
}
}
if ($data['list']) {
$data['value'] = array('#type' => 'select', '#options' => $data['list']);
if ($data['list-type'] != 'select') {
$data['value']['#multiple'] = TRUE;
}
}
else if (!$data['value']) {
$data['value'] = array('#type' => 'textfield', '#size' => 10, '#maxlength' => 255);
}
$views_tables['filters']['titles']["$name.$filter"] = $data['name'];
$views_tables['filters']['base']["$name.$filter"] = $data;
}
}
if (is_array($table['fields'])) {
foreach ($table['fields'] as $field => $data) {
if ($data['option'] && !is_array($data['option'])) {
if ($data['option'] == 'string' || $data['option'] == 'integer') {
$data['option'] = array('#type' => 'textfield', '#size' => 10, '#maxlength' => 255);
}
else {
$data['option'] = array('#type' => 'select', '#options' => $data['option']);
}
}
$data['table'] = $name;
$views_tables['fields']['titles']["$name.$field"] = $data['name'];
$views_tables['fields']['base']["$name.$field"] = $data;
}
}
if (is_array($table['sorts'])) {
foreach ($table['sorts'] as $field => $data) {
$data['table'] = $name;
if ($data['option'] && !is_array($data['option'])) {
if ($data['option'] == 'string' || $data['option'] == 'integer') {
$data['option'] = array('#type' => 'textfield', '#size' => 10, '#maxlength' => 255);
}
else {
$data['option'] = array('#type' => 'select', '#options' => $data['option']);
}
}
$views_tables['sorts']['titles']["$name.$field"] = $data['name'];
$views_tables['sorts']['base']["$name.$field"] = $data;
}
}
}
cache_set("views_tables:$locale", 'cache', serialize($views_tables));
}
}
return ($full ? $views_tables : $views_tables['tables']);
}
/**
* Gets the filter information; if it doesn't exist, call the function
* that constructs all that.
*/
function _views_get_filters($titles = false) {
$table_data = _views_get_tables(true);
return ($titles ? $table_data['filters']['titles'] : $table_data['filters']['base']);
}
/**
* Gets the field information; if it doesn't exist, call the function
* that constructs all that.
*/
function _views_get_fields($titles = false) {
$table_data = _views_get_tables(true);
return ($titles ? $table_data['fields']['titles'] : $table_data['fields']['base']);
}
/**
* Gets the sort information; if it doesn't exist, call the function
* that constructs all that.
*/
function _views_get_sorts($titles = false) {
$table_data = _views_get_tables(true);
return ($titles ? $table_data['sorts']['titles'] : $table_data['sorts']['base']);
}
/**
* Invalidate the views cache, forcing a rebuild on the next grab of table data.
*/
function views_invalidate_cache() {
cache_clear_all('views_', 'cache', true);
}
/**
* Ensures that views have legitimate information; a bit more is stored on
* the $view object than is in the database, and this isn't necessarily
* set when a view is constructed externally.
*/
function views_sanitize_view(&$view) {
_views_check_arrays($view); // so reference works.
foreach ($view->field as $i => $field) {
if (!isset($view->field[$i]['id'])) {
$view->field[$i]['id'] = $view->field[$i]['fullname'] = "$field[tablename].$field[field]";
$view->field[$i]['queryname'] = "$field[tablename]_$field[field]";
}
}
foreach ($view->filter as $i => $filter) {
if (!isset($view->filter[$i]['id'])) {
$view->filter[$i]['id'] = $view->filter[$i]['field'] = "$filter[tablename].$filter[field]";
}
}
foreach ($view->exposed_filter as $i => $exposed_filter) {
if (!isset($view->exposed_filter[$i]['id'])) {
$view->exposed_filter[$i]['id'] = $view->exposed_filter[$i]['field'] = "$exposed_filter[tablename].$exposed_filter[field]";
}
}
foreach ($view->sort as $i => $sort) {
if (!isset($view->sort[$i]['id'])) {
$view->sort[$i]['id'] = $view->sort[$i]['field'] = "$sort[tablename].$sort[field]";
}
}
foreach ($view->argument as $i => $argument) {
if (!isset($view->argument[$i]['id'])) {
$view->argument[$i]['id'] = $view->argument[$i]['type'];
}
}
}
/**
* Build default view information from all modules and cache it.
*/
function _views_get_default_views() {
static $views_default_views;
global $locale;
if (!$views_default_views) {
$data = cache_get("views_default_views:$locale", 'cache');
$cache = unserialize($data->data);
if (is_array($cache)) {
$views_default_views = $cache;
}
else {
// We have to make sure table data is built in order to be sure about providers.
$tables = array_keys(_views_get_tables());
$views = module_invoke_all('views_default_views');
$views_default_views = array();
foreach ($views as $i => $view) {
if (!is_array($view->requires) || !array_diff($view->requires, $tables)) {
views_sanitize_view($view);
$views_default_views[$i] = $view;
}
}
cache_set("views_default_views:$locale", 'cache', serialize($views_default_views));
}
}
return $views_default_views;
}
/**
* Return the style plugins; construct one if we haven't already. The
* array is cached in a static variable so that arguments
* are only constructed once per run.
*/
function _views_get_style_plugins($titles = false) {
static $views_style_plugins;
global $locale;
if (!$views_style_plugins) {
$data = cache_get("views_style_plugins:$locale", 'cache');
$cache = unserialize($data->data);
if (is_array($cache)) {
$views_style_plugins = $cache;
}
else {
$arguments = module_invoke_all('views_style_plugins');
foreach ($arguments as $name => $arg) {
if (!isset($arg['summary_theme'])) {
$arg['summary_theme'] = 'views_summary';
}
$views_style_plugins['title'][$name] = $arg['name'];
$views_style_plugins['base'][$name] = $arg;
}
$cache = $views_style_plugins;
cache_set("views_style_plugins:$locale", 'cache', serialize($cache));
}
}
return ($titles ? $views_style_plugins['title'] : $views_style_plugins['base']);
}
// ---------------------------------------------------------------------------
// Drupal Hooks
......@@ -286,7 +10,7 @@ function _views_get_style_plugins($titles = false) {
function views_help($section) {
switch ($section) {
case 'admin/help#views':
return t('The views module creates customized views of node lists.');
return t('The views module creates customized views of node lists. You may need to activate the Views UI module to get to the user administration pages.');
}
}
......@@ -298,6 +22,7 @@ function views_menu($may_cache) {
global $locale;
if ($may_cache) {
views_load_cache();
// Invalidate the views cache to ensure that views data gets rebuilt.
// This is the best way to tell that module configuration has changed.
if (arg(0) == 'admin' && arg(2) == 'modules') {
......@@ -434,6 +159,7 @@ function _views_menu_type($view) {
function views_block($op = 'list', $delta = 0) {
$block = array();
if ($op == 'list') {
views_load_cache();
// Grab views from the database and provide them as blocks.
$result = db_query("SELECT vid, block_title, page_title, name FROM {view_view} WHERE block = 1");
while ($view = db_fetch_object($result)) {
......@@ -479,6 +205,7 @@ function _views_check_arrays(&$view) {
* for a default view by that name.
*/
function views_get_view($view_name) {
views_load_cache();
$view = _views_load_view($view_name);
if ($view) {
return $view;
......@@ -529,6 +256,7 @@ function views_view_page() {
* This views a view by block. Can be used as a callback or programmatically.
*/
function views_view_block($vid) {
views_load_cache();
$view = views_get_view($vid);
if (!$view || !$view->block) {
......@@ -556,6 +284,21 @@ function views_view_block($vid) {
}
}
function &views_set_current_view($view = NULL) {
static $current_view = NULL;
if ($view !== NULL) {
unset($current_view);
$current_view = &$view;
unset($GLOBALS['current_view']);
$GLOBALS['current_view'] = &$view;
}
return $current_view;
}
function &views_get_current_view() {
return views_set_current_view();
}
/**
* This builds the basic view.
* @param $type
......@@ -596,12 +339,14 @@ function views_view_block($vid) {
* without paging on.
*/
function views_build_view($type, &$view, $args = array(), $use_pager = false, $limit = 0, $page = 0) {
views_load_cache();
// Fix a number of annoying whines when NULL is passed in..
if ($args == NULL) {
$args = array();
}
$GLOBALS['current_view'] = &$view;
views_set_current_view($view);
$view->build_type = $type;
$view->type = ($type == 'block' ? $view->block_type : $view->page_type);
......@@ -625,8 +370,7 @@ function views_build_view($type, &$view, $args = array(), $use_pager = false, $l
}
}
else {
$path = drupal_get_path('module', 'views');
require_once("./$path/views_query.inc");
views_load_query();
$info = _views_build_query($view, $args);
if ($info['fail']) {
......@@ -697,6 +441,22 @@ function views_build_view($type, &$view, $args = array(), $use_pager = false, $l
// ---------------------------------------------------------------------------
// Utility
/**
* Load the cache sub-module
*/
function views_load_cache() {
$path = drupal_get_path('module', 'views');
require_once("./$path/views_cache.inc");
}
/**
* Load the query sub-module
*/
function views_load_query() {
$path = drupal_get_path('module', 'views');
require_once("./$path/views_query.inc");
}
/**
* Easily theme any item to a view.
* @param $function
......@@ -878,6 +638,13 @@ function _views_is_cacheable(&$view) {
return true;
}
/**
* Invalidate the views cache, forcing a rebuild on the next grab of table data.
*/
function views_invalidate_cache() {
cache_clear_all('views_', 'cache', true);
}
// ---------------------------------------------------------------------------
// Database functions
......@@ -1008,8 +775,7 @@ function _views_save_view($view) {
// cache the query
if (_views_is_cacheable($view)) {
$path = drupal_get_path('module', 'views');
require_once("./$path/views_query.inc");
views_load_query();
$info = _views_build_query($view);
$view->query = _views_replace_args($info['query'], $info['args']);
......
<?php
// $Id$
// Load all our module 'on behalfs'.
// Whenever we decide we need this, load our module 'on behalfs'.
$path = drupal_get_path('module', 'views') . '/modules';
$files = system_listing('views_.*\.inc$', $path, 'name', 0);
foreach($files as $file) {
// The filename format is very specific. It must be views_MODULENAME.inc
$module = substr_replace($file->name, '', 0, 6);
if (module_exists($module)) {
require_once("./$file->filename");
}
}
// ---------------------------------------------------------------------------
// Acquire Views Data
/**
* Return the arguments array; construct one if we haven't already. The
* array is cached in a global, safely named variable so that arguments
* are only constructed once per run.
*/
function _views_get_arguments($titles = false) {
static $views_arguments;
global $locale;
if (!$views_arguments) {
$data = cache_get("views_arguments:$locale", 'cache');
$cache = unserialize($data->data);
if (is_array($cache)) {
$views_arguments = $cache;
}
else {
$arguments = module_invoke_all('views_arguments');
foreach ($arguments as $name => $arg) {
if ($arg['option'] && !is_array($arg['option'])) {
if ($arg['option'] == 'string' || $arg['option'] == 'integer') {
$arg['option'] = array('#type' => 'textfield', '#size' => 10, '#maxlength' => 255);
}
else {
$arg['option'] = array('#type' => 'select', '#options' => $arg['option']);
}
}
$views_arguments['base'][$name] = $arg['name'];
$views_arguments['title'][$name] = $arg;
}
$cache = $views_arguments;
cache_set("views_arguments:$locale", 'cache', serialize($cache));
}
}
return ($titles ? $views_arguments['base'] : $views_arguments['title']);
}
/**
* Constructs the full table information array. Caches it into a global array
* so that it will only be called once per run.
*/
function _views_get_tables($full = false) {
static $views_tables;
global $locale;
if (!$views_tables) {
$data = cache_get("views_tables:$locale", 'cache');
$cache = unserialize($data->data);
if (is_array($cache)) {
$views_tables = $cache;
}
else {
$table_data = module_invoke_all('views_tables');
$views_tables['tables'] = $table_data;
foreach ($table_data as $name => $table) {
if (is_array($table['filters'])) {
foreach ($table['filters'] as $filter => $data) {
$data['table'] = $name;
// translate for deprecated APIs...
if ($data['option'] && !is_array($data['option'])) {
if ($data['option'] == 'string' || $data['option'] == 'integer') {
$data['option'] = array('#type' => 'textfield', '#size' => 10, '#maxlength' => 255);
}
else {
$data['option'] = array('#type' => 'select', '#options' => $data['option']);
}
}
if ($data['list']) {
$data['value'] = array('#type' => 'select', '#options' => $data['list']);
if ($data['list-type'] != 'select') {
$data['value']['#multiple'] = TRUE;
}
}
else if (!$data['value']) {
$data['value'] = array('#type' => 'textfield', '#size' => 10, '#maxlength' => 255);
}
$views_tables['filters']['titles']["$name.$filter"] = $data['name'];
$views_tables['filters']['base']["$name.$filter"] = $data;
}
}
if (is_array($table['fields'])) {
foreach ($table['fields'] as $field => $data) {
if ($data['option'] && !is_array($data['option'])) {
if ($data['option'] == 'string' || $data['option'] == 'integer') {
$data['option'] = array('#type' => 'textfield', '#size' => 10, '#maxlength' => 255);
}
else {
$data['option'] = array('#type' => 'select', '#options' => $data['option']);
}
}
$data['table'] = $name;
$views_tables['fields']['titles']["$name.$field"] = $data['name'];
$views_tables['fields']['base']["$name.$field"] = $data;
}
}
if (is_array($table['sorts'])) {
foreach ($table['sorts'] as $field => $data) {
$data['table'] = $name;
if ($data['option'] && !is_array($data['option'])) {
if ($data['option'] == 'string' || $data['option'] == 'integer') {
$data['option'] = array('#type' => 'textfield', '#size' => 10, '#maxlength' => 255);
}
else {
$data['option'] = array('#type' => 'select', '#options' => $data['option']);
}
}
$views_tables['sorts']['titles']["$name.$field"] = $data['name'];
$views_tables['sorts']['base']["$name.$field"] = $data;
}
}
}
cache_set("views_tables:$locale", 'cache', serialize($views_tables));
}
}
return ($full ? $views_tables : $views_tables['tables']);
}
/**
* Gets the filter information; if it doesn't exist, call the function
* that constructs all that.
*/
function _views_get_filters($titles = false) {
$table_data = _views_get_tables(true);
return ($titles ? $table_data['filters']['titles'] : $table_data['filters']['base']);
}
/**
* Gets the field information; if it doesn't exist, call the function
* that constructs all that.
*/
function _views_get_fields($titles = false) {
$table_data = _views_get_tables(true);
return ($titles ? $table_data['fields']['titles'] : $table_data['fields']['base']);
}
/**
* Gets the sort information; if it doesn't exist, call the function
* that constructs all that.
*/
function _views_get_sorts($titles = false) {
$table_data = _views_get_tables(true);
return ($titles ? $table_data['sorts']['titles'] : $table_data['sorts']['base']);
}
/**
* Ensures that views have legitimate information; a bit more is stored on
* the $view object than is in the database, and this isn't necessarily
* set when a view is constructed externally.
*/
function views_sanitize_view(&$view) {
_views_check_arrays($view); // so reference works.
foreach ($view->field as $i => $field) {
if (!isset($view->field[$i]['id'])) {
$view->field[$i]['id'] = $view->field[$i]['fullname'] = "$field[tablename].$field[field]";
$view->field[$i]['queryname'] = "$field[tablename]_$field[field]";
}
}
foreach ($view->filter as $i => $filter) {
if (!isset($view->filter[$i]['id'])) {
$view->filter[$i]['id'] = $view->filter[$i]['field'] = "$filter[tablename].$filter[field]";
}
}
foreach ($view->exposed_filter as $i => $exposed_filter) {
if (!isset($view->exposed_filter[$i]['id'])) {
$view->exposed_filter[$i]['id'] = $view->exposed_filter[$i]['field'] = "$exposed_filter[tablename].$exposed_filter[field]";
}
}
foreach ($view->sort as $i => $sort) {
if (!isset($view->sort[$i]['id'])) {
$view->sort[$i]['id'] = $view->sort[$i]['field'] = "$sort[tablename].$sort[field]";
}
}
foreach ($view->argument as $i => $argument) {
if (!isset($view->argument[$i]['id'])) {
$view->argument[$i]['id'] = $view->argument[$i]['type'];
}
}
}
/**
* Build default view information from all modules and cache it.
*/
function _views_get_default_views() {
static $views_default_views;