Commit 58e4ed44 authored by merlinofchaos's avatar merlinofchaos

Checkpoint checkin

parent 5a781272
......@@ -120,7 +120,7 @@ function _views_discover_default_views() {
views_include_default_views();
$defaults = module_invoke_all('views_default_views');
$cache = array();
dsm('..');
foreach ($defaults as $name => $view) {
$cache[$name] = $view;
}
......@@ -178,3 +178,94 @@ function views_cache_get($cid, $use_language = FALSE) {
return cache_get($cid, 'cache_views');
}
/**
* @defgroup views_object_cache Non-volatile cache storage
* @{
* The non-volatile object cache is used to store an object while it is
* being edited, so that we don't have to save until we're completely
* done. The cache should be 'cleaned' on a regular basis, meaning to
* remove old objects from the cache, but otherwise the data in this
* cache must remain stable, as it includes unsaved changes.
*/
/**
* Get an object from the non-volatile Views cache.
*
* This function caches in memory as well, so that multiple calls to this
* will not result in multiple database reads.
*
* @param $obj
* A 32 character or less string to define what kind of object is being
* stored; primarily this is used to prevent collisions.
* @param $name
* The name of the view (or other object) being stored.
* @param $skip_cache
* Skip the memory cache, meaning this must be read from the db again.
*
* @return
* The data that was cached.
*/
function views_object_cache_get($obj, $name, $skip_cache = FALSE) {
static $cache = array();
$key = "$obj:$name";
if ($skip_cache) {
unset($cache[$key]);
}
if (!array_key_exists($key, $cache)) {
$data = db_fetch_object(db_query("SELECT * FROM {views_object_cache} WHERE sid = '%s' AND obj = '%s' AND name = %d", session_id(), $obj, $name));
if ($data) {
$cache[$key] = unserialize($data->data);
}
}
return isset($cache[$key]) ? $cache[$key] : NULL;
}
/**
* Store an object in the non-volatile Views cache.
*
* @param $obj
* A 32 character or less string to define what kind of object is being
* stored; primarily this is used to prevent collisions.
* @param $name
* The name of the view (or other object) being stored.
* @param $cache
* The object to be cached. This will be serialized prior to writing.
*/
function views_object_cache_set($obj, $name, $cache) {
views_object_cache_clear($obj, $name);
db_query("INSERT INTO {views_object_cache} (sid, obj, name, data, updated) VALUES ('%s', '%s', '%s', '%s', %d)", session_id(), $obj, $name, serialize($cache), time());
}
/**
* Remove an object from the non-volatile Views cache
*
* @param $obj
* A 32 character or less string to define what kind of object is being
* stored; primarily this is used to prevent collisions.
* @param $name
* The name of the view (or other object) being stored.
*/
function views_object_cache_clear($obj, $name) {
db_query("DELETE FROM {views_object_cache} WHERE sid = '%s' AND obj = '%s' AND name = %d", session_id(), $obj, $name);
}
/**
* Remove all objects in the object cache that are older than the
* specified age.
*
* @param $age
* The minimum age of objects to remove, in seconds. For example, 86400 is
* one day. Defaults to 7 days.
*/
function views_object_cache_clean($age = NULL) {
if (empty($age)) {
$age = 86400 * 7; // 7 days
}
db_query("DELETE FROM {views_object_cache} WHERE updated < %d", time() - $age);
}
/**
* @}
*/
......@@ -7,8 +7,6 @@
/**
* Instantiate and construct a new handler
*
* @todo: move to handlers.inc
*/
function _views_create_handler($definition) {
// dpr('Instantiating handler ' . $definition['handler']);
......@@ -23,8 +21,6 @@ function _views_create_handler($definition) {
/**
* Prepare a handler's data by checking defaults and such.
*
* @todo: move to handlers.inc
*/
function _views_prepare_handler($definition, $data, $field) {
foreach (array('group', 'title', 'help') as $key) {
......@@ -43,8 +39,6 @@ function _views_prepare_handler($definition, $data, $field) {
/**
* Fetch a handler to join one table to a primary table from the data cache
*
* @todo: move to cache.inc (maybe)
*/
function views_get_table_join($table, $primary_table) {
$data = views_fetch_data($table);
......
......@@ -496,11 +496,6 @@ class view extends views_db_object {
}
}
// If the view is not defined in the database, check the default_views hook.
if (is_null($cache[$arg]) && !is_numeric($arg)) {
$cache[$arg] = views_get_default_view($arg);
}
return $cache[$arg];
}
......@@ -567,7 +562,8 @@ class view extends views_db_object {
* A vid will be assigned to the view and also returned from this function.
*/
function save() {
if (!empty($this->vid)) {
// If we have no vid or our vid is a string, this is a new view.
if (!empty($this->vid) || !is_numeric($this->vid)) {
// remove existing table entries
foreach ($this->objects_all() as $key) {
db_query("DELETE from {views_" . $key . "} WHERE vid = %d", $this->vid);
......@@ -657,6 +653,7 @@ class views_db_object {
}
$schema = drupal_get_schema($this->db_table);
// Go through our schema and build correlations.
foreach ($schema['fields'] as $field => $info) {
if ($info['type'] == 'serial') {
......@@ -810,6 +807,48 @@ class views_db_object {
}
return $output;
}
/**
* Add a new display handler to the view, automatically creating an id.
*
* @param $type
* The plugin type from the views plugin data. Defaults to 'page'.
* @param $style
* The style plugin from the views plugin data. Defaults to 'default'.
*
* @return
* The key to the display in $view->display, so that the new display
* can be easily located.
*/
function add_display($type = 'page', $style = 'default') {
// Get all existing IDs so we can feel confident that we have a unique
// one for the new display.
foreach ($this->display as $d) {
$ids[$d->id] = TRUE;
}
$id = $type;
$count = 0;
// Loop through IDs based upon our style plugin name until
// we find one that is unused.
while (!empty($ids[$id])) {
$id = $type . '_' . ++$count;
}
// Create the new display object
$display = new views_display;
$display->display_plugin = $type;
$display->style_plugin = $style;
$display->id = $id;
// @todo Should the display plugin have some kind of constructor
// to fill in default values here? That seems very logical.
// Add the new display object to the view.
$this->display[] = $display;
return max(array_keys($this->display));
}
}
/**
......
This diff is collapsed.
......@@ -247,6 +247,16 @@ function views_include($file) {
$used[$file] = TRUE;
}
/**
* Prepare the specified string for use as a CSS identifier.
*/
function views_css_safe($string) {
return str_replace('_', '-', $string);
}
// -----------------------------------------------------------------------
// Views handler functions
/**
* Load views files on behalf of modules.
*/
......@@ -302,6 +312,29 @@ function views_fetch_data($table = NULL) {
return _views_fetch_data($table);
}
/**
* Fetch a list of all base tables available
*
* @return
* A keyed array of in the form of 'base_table' => 'Description'.
*/
function views_fetch_base_table_names() {
static $base_tables = array();
if (empty($base_tables)) {
$data = views_fetch_data();
foreach ($data as $table => $info) {
if (!empty($info['table']['base'])) {
$base_tables[$table] = $info['table']['base']['title'];
}
}
}
return $base_tables;
}
// -----------------------------------------------------------------------
// Views plugin functions
/**
* Fetch the plugin data from cache.
*/
......@@ -321,18 +354,44 @@ function views_get_plugin($type, $plugin) {
}
/**
* Prepare the specified string for use as a CSS identifier.
* Fetch a list of all base tables available
*
* @return
* A keyed array of in the form of 'base_table' => 'Description'.
*/
function views_css_safe($string) {
return str_replace('_', '-', $string);
function views_fetch_plugin_names($type) {
static $plugins = array();
if (empty($plugins)) {
$data = views_fetch_plugin_data();
foreach ($data as $plugin_type => $plugs) {
// Skip some info data
if (!is_array($plugs)) {
continue;
}
foreach ($plugs as $id => $plugin) {
$plugins[$plugin_type][$id] = $plugin['title'];
}
}
}
if (!empty($plugins[$type])) {
return $plugins[$type];
}
// fall-through
return array();
}
// -----------------------------------------------------------------------
// Views database functions
/**
* Get a view from the database or from default views.
*
* This function is just a static wrapper around views::load().
* This function is just a static wrapper around views::load(). This function
* isn't called 'views_load()' primarily because it might get a view
* from the default views which aren't technically loaded from the database.
*
* @todo LG: Shouldn't this be called views_load() to parallel node_load() et al?
* @param $name
* The name of the view.
* @param $reset
......@@ -343,7 +402,13 @@ function views_css_safe($string) {
*/
function &views_get_view($name, $reset = FALSE) {
views_include('view');
return view::load($name, $reset);
$view = view::load($name, $reset);
if (empty($view)) {
$view = views_get_default_view($name);
}
return $view;
}
/**
......@@ -353,15 +418,33 @@ function &views_get_view($name, $reset = FALSE) {
* 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.
* 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) {
$null = NULL;
$cache = views_discover_default_views();
if (isset($cache[$view_name])) {
return $cache[$view_name];
}
return $null;
}
/**
* Create an empty view to work with.
*
* @return
* 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';
return $view;
}
/**
......@@ -391,6 +474,7 @@ function views_discover_default_views() {
* array($view, $display_id),
* array($view, $display_id),
* );
* @endcode
*/
function views_get_page_views() {
return views_get_applicable_views('uses_hook_menu');
......@@ -408,6 +492,7 @@ function views_get_page_views() {
* array($view, $display_id),
* array($view, $display_id),
* );
* @endcode
*/
function views_get_block_views() {
return views_get_applicable_views('uses_hook_block');
......@@ -423,6 +508,7 @@ function views_get_block_views() {
* array($view, $display_id),
* array($view, $display_id),
* );
* @endcode
*/
function views_get_applicable_views($type) {
$result = array();
......
......@@ -163,6 +163,72 @@ function views_ui_list_views() {
* Page callback to add a new view.
*/
function views_ui_add_page() {
$output = 'foo';
return $output;
$view = views_new_view();
return drupal_get_form('views_ui_add_form', $view);
}
/**
* Form constructor callback to create the views Add Form, phase 1.
*/
function views_ui_add_form(&$form_state, $view) {
$form = array();
$form['name'] = array(
'#type' => 'textfield',
'#title' => t('View name'),
'#description' => t('This is the unique name of the view. It must contain only alphanumeric characters and underscores; it is used to identify the view internally and to generate unique theming template names for this view. If overriding a module provided view, the name must not be changed or instead a new view will be created.'),
'#default_value' => $view->name,
'#required' => TRUE,
);
$form['description'] = array(
'#type' => 'textfield',
'#title' => t('View description'),
'#description' => t('This description will appear on the Views administrative UI to tell you what the view is about.'),
'#default_value' => $view->description,
);
$form['tag'] = array(
'#type' => 'textfield',
'#title' => t('View tag'),
'#description' => t('Enter an optional tag for this view; it is used only to help sort views on the administrative page.'),
'#default_value' => $view->tag,
// TODO: This should be an autocomplete field.
);
$form['base_table'] = array(
'#type' => 'select',
'#title' => t('Base table'),
'#description' => t('The base table is the primary table for which information is being retrieved. The base table controls what arguments, fields, sort criteria and filters are available, so once this is set it cannot be changed.'),
'#options' => views_fetch_base_table_names(),
'#default_value' => $view->base_table,
'#disabled' => !empty($view->vid) && $view->vid != 'new',
);
if (empty($view->vid) || $view->vid == 'new') {
$form['displays'] = array(
'#type' => 'checkboxes',
'#title' => t('Initial displays'),
'#description' => t('Select which displays you would like to have automatically created with this view.'),
'#options' => views_fetch_plugin_names('display'),
'#required' => TRUE,
);
}
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Next'),
'#submit' => array('views_ui_add_form_submit'),
);
$form_state['view'] = $view;
return $form;
}
/**
* Submit handler for the ui add form
*/
function views_ui_add_form_submit($form, &$form_state) {
views_include('cache');
views_object_cache_set('view', $view->name, $view);
}
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment