Commit 118515fd authored by merlinofchaos's avatar merlinofchaos
Browse files

Syncing DRUPAL-5 from HEAD

parent d961ae4c
11/27/2005 added field 'handler' to view_tablefield
11/28/2005 added fields 'sortable' and 'defaultsort' to view_tablefield
11/28/2005 changed view_argument type from int(2) to varchar(25) for greater flexibility
11/30/2005 changed filter table and view table significantly. Probably sort table too.
12/5/2005 Add options varchar(255) to both sort and filter tables.
12/7/2005 Add menu_title to view_view and title to view_argument
12/8/2005 Added options varchar(255) to view_argument as well.
12/10/2005 Added block_more int(1) to view_view
12/21/2005 Renamed 'sql' to 'query' and 'countsql' to 'countquery' for consistency
1/2/2006 SCHEMA CHANGES SCHEMA CHANGES
Too drastic to easily deal with. Before you install this version of
Views, you should export all your old views as a backup, then drop the
views_view table and re-import. Sorry. I hope to not do something like
this ever again.
2/19/2006 allow a complete formsapi setting in any 'options' or 'value' setting for 'filter'.
Retooled the API to be less hackish.
3/2/2006 Added the ability to expose filters to end user. Requires running update.php.
3/16/2006 Basic user documentation written.
\ No newline at end of file
CHANGELOG for Views for Drupal 5
Views 1.0
o Initial release under drupal.org's new release system
Views 1.1-dev
Bugs fixed:
o 97228: Fatal error on the views help page.
o View Import was completely not working.
o 93873: Exposed filters were completely not working.
o 92305: Removed broken and unworkable 'distinct' profile filter.
o 93540: Don't use block title if no page title.
o 93493: Allow field labels to be turned off if item not sortable.
o 91665: Order By pretty much borked in PGSQL.
o 85290: Views generated invalid CSS with -- this could have an impact on
your theming!
o 90482: Validate that nodes per page is not 0 if pager is on.
o 89893: Multiple filters not showing up properly in RSS links
o 97462: More robust view export code.
o 82634: theme_imagebutton renamed to theme_views_imagebutton
o 77859: update module weight to 10 in update.php -- RUN UPDATE.PHP!!
o 97589: Add some sorting on plugins so that Views' default plugins are
always on top.
New features:
o New comment fields to allow more Views use of comments. [Egon Bianchet]
o Recent comments block default view.
o Add simple 'word search' to text field operators [gordonh]
o Early views_search.inc -- needs testing! [gordonh]
o 90643: Access-checking 'edit', 'delete' and 'view' links as fields
o Added uninstall function (accessible from the module administration page)
o 88849: new views_pre_query hook
o 97290: new $offset argument to views_build_view to allow views to to
skip the first N nodes [doesn't work if $ pager = true].
o 97290: New options for granularity on date sorts
......@@ -18,6 +18,58 @@ function comment_views_tables() {
'field' => 'nid'
),
),
'fields' => array(
'subject' => array(
'name' => t('Comment: Subject'),
'handler' => array(
'views_handler_field_commentlink' => t('Normal'),
'views_handler_field_commentlink_with_mark' => t('With updated mark')
),
'option' => array(
'#type' => 'select',
'#options' => array(
'link' => 'As link',
'nolink' => 'Without link'
),
),
'addlfields' => array('cid'),
'sortable' => TRUE,
),
'comment' => array(
'name' => t('Comment: Comment'),
'handler' => 'views_handler_field_comment',
'addlfields' => array('format'),
'help' => t('Display the content of a comment.'),
),
'cid' => array(
'name' => t('Comment: Comment ID'),
'sortable' => TRUE,
'help' => t('Display the CID of a comment.'),
),
'timestamp' => array(
'name' => t('Comment: Created Time'),
'sortable' => TRUE,
'handler' => views_handler_field_dates(),
'option' => 'string',
'help' => t('Display the post time of the comment.'),
),
'name' => array(
'name' => t('Comment: Author Name'),
'handler' => 'views_handler_field_username',
'sortable' => TRUE,
'uid' => 'uid',
'addlfields' => array('uid'),
'help' => t('This will display the author of the node.'),
),
),
'sorts' => array(
'timestamp' => array(
'name' => t('Comment: Created Time'),
'handler' => 'views_handler_sort_date',
'option' => views_handler_sort_date_options(),
'help' => t('Sort by the created time of comments.'),
),
),
);
$tables['node_comment_statistics'] = array(
......@@ -78,6 +130,8 @@ function comment_views_tables() {
'sorts' => array(
'last_comment_timestamp' => array(
'name' => t('Comment: Last Comment Date'),
'handler' => 'views_handler_sort_date',
'option' => views_handler_sort_date_options(),
'help' => t('This will allow you to sort by the date of the most recent comment on a node.')
),
'comment_count' => array(
......@@ -114,11 +168,108 @@ function views_handler_field_last_comment_name($fieldinfo, $fielddata, $value, $
}
/*
function comment_views_arguments() {
* Format a field as a link to a comment.
*/
function views_handler_field_commentlink($fieldinfo, $fielddata, $value, $data) {
if ($fielddata['options'] == 'nolink') {
return check_plain($value);
}
return l($value, "node/$data->nid", NULL, NULL, "comment-$data->comments_cid");
}
/*
* Format a field as a link to a 'mark', stating whether or not the comment has
* updated since it was last viewed by the user.
*/
function views_handler_field_commentlink_with_mark($fieldinfo, $fielddata, $value, $data) {
if ($fielddata['options'] == 'nolink') {
$link = check_plain($value);
}
else {
$link = l($value, "node/$data->nid", NULL, NULL, "comment-$data->comments_cid");
}
return $link .' '. theme('mark', node_mark($data->nid, $data->comments_timestamp));
}
function comment_views_default_views() {
/*
* Format a field as a comment
*/
function views_handler_field_comment($fieldinfo, $fielddata, $value, $data) {
$obj->comment = check_markup($data->comments_comment, $data->comments_format, FALSE);
comment_invoke_comment($obj, 'view');
return $obj->comment;
}
/*
function comment_views_arguments() {
}
*/
function comment_views_default_views() {
$view = new stdClass();
$view->name = 'comments_recent';
$view->description = t('Display recent comments block');
$view->access = array (
);
$view->view_args_php = '';
$view->block = TRUE;
$view->block_title = t('Recent comments');
$view->block_header = "";
$view->block_header_format = '1';
$view->block_footer = "";
$view->block_footer_format = '1';
$view->block_empty = "";
$view->block_empty_format = '1';
$view->block_type = 'list';
$view->nodes_per_block = '10';
$view->block_more = '0';
$view->block_use_page_header = FALSE;
$view->block_use_page_footer = FALSE;
$view->block_use_page_empty = FALSE;
$view->sort = array (
array (
'tablename' => 'comments',
'field' => 'timestamp',
'sortorder' => 'DESC',
'options' => '',
),
);
$view->argument = array (
);
$view->field = array (
array (
'tablename' => 'comments',
'field' => 'subject',
'label' => '',
'handler' => 'views_handler_field_commentlink',
'options' => 'link',
),
array (
'tablename' => 'comments',
'field' => 'name',
'label' => '',
),
array (
'tablename' => 'comments',
'field' => 'timestamp',
'label' => '',
'handler' => 'views_handler_field_date_small',
),
);
$view->filter = array (
array (
'tablename' => 'node_comment_statistics',
'field' => 'comment_count',
'operator' => '>',
'options' => '',
'value' => '1',
),
);
$view->exposed_filter = array (
);
$view->requires = array(comments, node_comment_statistics);
$views[$view->name] = $view;
return $views;
}
......@@ -28,7 +28,7 @@ function node_views_tables() {
'help' => t('Display the title of the node.'),
),
'nid' => array(
'name' => t('Node: Node ID'),
'name' => t('Node: ID'),
'sortable' => true,
'help' => t('Display the NID of a node.'),
),
......@@ -70,6 +70,29 @@ function node_views_tables() {
'notafield' => TRUE,
'help' => t('Display the Main Content.'),
),
'view' => array(
'name' => t('Node: View link'),
'handler' => 'views_handler_node_view',
'notafield' => TRUE,
'option' => 'string',
'help' => t('Display a link to view the node. Enter the text of this link into the option field; if blank the default "View" will be used.'),
),
'edit' => array(
'name' => t('Node: Edit link'),
'handler' => 'views_handler_node_edit',
'notafield' => TRUE,
'addlfields' => array('type', 'uid'),
'option' => 'string',
'help' => t('Display a link to edit the node. Enter the text of this link into the option field; if blank the default "Edit" will be used.'),
),
'delete' => array(
'name' => t('Node: Delete link'),
'handler' => 'views_handler_node_delete',
'notafield' => TRUE,
'addlfields' => array('type', 'uid'),
'option' => 'string',
'help' => t('Display a link to delete the node. Enter the text of this link into the option field; if blank the default "Delete" will be used.'),
),
),
'sorts' => array(
'nid' => array(
......@@ -78,10 +101,14 @@ function node_views_tables() {
),
'created' => array(
'name' => t('Node: Created Time'),
'handler' => 'views_handler_sort_date',
'option' => views_handler_sort_date_options(),
'help' => t('Sort by the submission date of the node.'),
),
'changed' => array(
'name' => t('Node: Last Updated Time'),
'name' => t('Node: Updated Time'),
'handler' => 'views_handler_sort_date',
'option' => views_handler_sort_date_options(),
'help' => t('Sort by the last update date of the node.'),
),
'sticky' => array(
......@@ -810,3 +837,37 @@ function views_post_view_make_args($view, $feed_id, $arg) {
return $args;
}
/**
* display a link to view a node
*/
function views_handler_node_view($fieldinfo, $fielddata, $value, $data) {
$link_text = $fielddata['options'] ? $fielddata['options'] : t('View');
return l($link_text, "node/$data->nid");
}
/**
* display a link to edit a node
*/
function views_handler_node_edit($fieldinfo, $fielddata, $value, $data) {
// try to build a fake node object
$data->type = $data->node_type;
$data->uid = $data->node_uid;
if (node_access('update', $data)) {
$link_text = $fielddata['options'] ? $fielddata['options'] : t('Edit');
return l($link_text, "node/$data->nid/edit");
}
}
/**
* display a link to delete a node
*/
function views_handler_node_delete($fieldinfo, $fielddata, $value, $data) {
// try to build a fake node object
$data->type = $data->node_type;
$data->uid = $data->node_uid;
if (node_access('delete', $data)) {
$link_text = $fielddata['options'] ? $fielddata['options'] : t('Delete');
return l($link_text, "node/$data->nid/delete");
}
}
......@@ -5,56 +5,6 @@
*/
function profile_views_tables() {
// provide a distinct filter so users are only displayed once.
$tables['profile_distinct'] = array(
'name' => 'users',
'provider' => 'internal', // won't show up in external list.
'join' => array(
'left' => array(
'table' => 'node',
'field' => 'uid'
),
'right' => array(
'field' => 'uid'
),
),
'fields' => array(
'mail' => array(
'name' => t('User: Email'),
'handler' => 'views_handler_field_email',
'sortable' => true,
'help' => t('This will display the email of the user.'),
),
),
'sorts' => array(
'uid' => array(
'name' => t('User: Uid'),
'help' => t('This allows you to sort by user id.'),
),
'mail' => array(
'name' => t('User: Email'),
'help' => t('This allows you to sort alphabetically by email.'),
),
),
'filters' => array(
'distinct' => array(
'name' => t('Profile: Distinct'),
'operator' => array('=' => 'is'),
'list' => array('distinct' => 'distinct'),
'handler' => 'views_handler_filter_profile_distinct',
'value-type' => 'array',
'help' => t('This filter ensures that each user profile may only be listed once, even if it matches multiple criteria.'),
),
'mail' => array(
'name' => t('User: Email'),
'operator' => 'views_handler_operator_like',
'handler' => 'views_handler_filter_like',
'help' => t('This allows you to filter by a particular email address.'),
),
),
);
// add all profile fields as possible display fields and filters
$profile_fields = profile_views_get_fields();
foreach ($profile_fields as $field) {
......@@ -340,16 +290,6 @@ function views_handler_filter_profile_selection($op, $filter) {
/* FILTER HANDLER FUNCTIONS */
/**
* Provide distince filter for user object. Note: this replaces the node
* distinct field and hence donflicts with it.
*/
function views_handler_filter_profile_distinct($op, $filter, $filterinfo, &$query) {
$field = 'users.uid';
$query->fields[0] = "DISTINCT($field)";
$query->count_field = "DISTINCT($field)";
}
/**
* Handle a profile date fild.
*
......
<?php
// $Id$
function search_views_tables() {
$tables['temp_search_results'] = array(
'name' => 'temp_search_results',
'join' => array(
'left' => array(
'table' => 'node',
'field' => 'nid',
),
'right' => array(
'field' => 'sid',
),
),
'filters' => array(
'word' => array(
'name' => t('Search: Index'),
'operator' => array('=' => t('Contains')),
'handler' => 'search_views_handler_search_index',
),
),
);
return $tables;
}
function search_views_handler_search_index($op, $filter, $filterdata, &$query) {
switch ($op) {
case 'handler':
$select2 = 'i.relevance AS score';
$search = search_parse_query($filter['value']);
if ($search === NULL || $search[0] == '' || $search[2] == '') {
$query->add_where("0");
return;
}
$conditions = '('. $search[2] .") AND i.type = 'node'";
$arguments = array_merge($search[3], array($search[4]));
$result = db_query_temporary("SELECT i.type, i.sid, SUM(i.score * t.count) AS relevance, COUNT(*) AS matches FROM {search_index} i INNER JOIN {search_total} t ON i.word = t.word $join1 WHERE $conditions GROUP BY i.type, i.sid HAVING COUNT(*) >= %d", $arguments, 'temp_search_sids');
// Calculate maximum relevance, to normalize it
$normalize = db_result(db_query('SELECT MAX(relevance) FROM temp_search_sids'));
if (!$normalize) {
$query->add_where("0");
return;
}
$select2 = str_replace('i.relevance', '('. (1.0 / $normalize) .' * i.relevance)', $select2);
// Second pass: only keep items that match the complicated keywords conditions (phrase search, negative keywords, ...)
$conditions = '('. $search[0] .')';
$arguments = $search[1];
$result = db_query_temporary("SELECT i.type, i.sid, $select2 FROM temp_search_sids i INNER JOIN {search_dataset} d ON i.sid = d.sid AND i.type = d.type $join2 WHERE $conditions $sort_parameters", $arguments, 'temp_search_results');
if (($count = db_result(db_query('SELECT COUNT(*) FROM temp_search_results'))) == 0) {
$query->add_where("0");
return;
}
$query->ensure_table('temp_search_results');
$query->add_where('temp_search_results.sid IS NOT NULL');
}
}
......@@ -48,6 +48,8 @@ function statistics_views_tables() {
),
'timestamp' => array(
'name' => t('Node: Last Hit Time'),
'handler' => 'views_handler_sort_date',
'option' => views_handler_sort_date_options(),
'help' => t('This allows you to sort by the time a node was last read.'),
),
),
......
......@@ -184,9 +184,14 @@ function user_views_query_substitutions($view) {
* specified in the field info.
*/
function views_handler_field_username($fieldinfo, $fielddata, $value, $data) {
$obj->name = $value;
$uidfield = $fielddata['tablename'] . "_" . $fieldinfo['uid'];
$obj->uid = $data->$uidfield;
if (!$value && $data->$uidfield) {
$obj = user_load(array('uid' => $data->$uidfield));
}
else {
$obj->name = $value;
$obj->uid = $data->$uidfield;
}
return theme('username', $obj);
}
......
This diff is collapsed.
......@@ -236,6 +236,15 @@
}
}
function views_uninstall() {
db_query("DROP TABLE IF EXISTS {view_view}");
db_query("DROP TABLE IF EXISTS {view_sort}");
db_query("DROP TABLE IF EXISTS {view_argument}");
db_query("DROP TABLE IF EXISTS {view_tablefield}");
db_query("DROP TABLE IF EXISTS {view_filter}");
db_query("DROP TABLE IF EXISTS {view_exposed_filter}");
}
/*
* update module for UTF.
*/
......@@ -337,3 +346,9 @@ function views_update_9() {
db_add_column($ret, 'view_argument', 'wildcard_substitution', 'varchar(32)');
return $ret;
}
function views_update_10() {
$ret = array();
$ret[] = update_sql("UPDATE {system} SET weight = 10 WHERE name = 'views'");
return $ret;
}
<?php
// $Id$
// $Name$
// ---------------------------------------------------------------------------
// Drupal Hooks
......@@ -337,9 +338,12 @@ function &views_get_current_view() {
* @param $page
* $use_pager is false, and $limit is !0, $page tells it what page to start
* on, in case for some reason a particular section of view is needed,
* @param $offset
* If $use_pager == false, skip the first $offset results. Does not work
* with pager.
* without paging on.
*/
function views_build_view($type, &$view, $args = array(), $use_pager = false, $limit = 0, $page = 0) {
function views_build_view($type, &$view, $args = array(), $use_pager = false, $limit = 0, $page = 0, $offset = 0) {
views_load_cache();
// Fix a number of annoying whines when NULL is passed in..
......@@ -361,6 +365,12 @@ function views_build_view($type, &$view, $args = array(), $use_pager = false, $l
ob_end_clean();
}
// 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';
$output .= $function($view);
}
$plugins = _views_get_style_plugins();
if ($view->query) {
$info['query'] = $view->query;
......@@ -400,7 +410,7 @@ function views_build_view($type, &$view, $args = array(), $use_pager = false, $l
$view->total_rows = $GLOBALS['pager_total_items'][$use_pager - 1];
}
else {
$result = ($limit ? db_query_range($query, $info['args'], $page * $limit, $limit) : db_query($query, $info['args']));
$result = ($limit ? db_query_range($query, $info['args'], $page * $limit + $offset, $limit) : db_query($query, $info['args']));
}
$view->num_rows = db_num_rows($result);
if ($type == 'result') {
......@@ -585,7 +595,7 @@ function views_get_title($view, $context = 'menu', $args = NULL) {
$title = $view->page_title;
}
if (!$title) {
if (!$title && $context == 'block') {
$title = $view->block_title;
}
......@@ -1058,9 +1068,8 @@ function _views_construct_header($view, $fields) {
$header = array();
$info = $fields[$field['fullname']];
$header['data'] = ($field['label'] ? $field['label'] : $info['name']);
if ($field['sortable']) {
$header['data'] = ($field['label'] ? $field['label'] : $info['name']);
if (function_exists($info['sort_handler'])) {
$header['field'] = $info['sort_handler']($field, $info);
}
......@@ -1068,12 +1077,16 @@ function _views_construct_header($view, $fields) {
$header['field'] = $field['fullname'];
}
}
else {
$header['data'] = $field['label'];
}
if ($field['defaultsort']) {
$header['sort'] = strtolower($field['defaultsort']);
}
// Add CSS id to table cell header cell.
$header['id'] = "view-field-$field[queryname]";
$header['id'] = views_css_safe('view-field-'. $field['queryname']);
$header['class'] = "view-cell-header";
$headers[] = $header;
}
......@@ -1081,11 +1094,10 @@ function _views_construct_header($view, $fields) {
}
function theme_views_display_filters($view) {
$form = views_filters_form($view);
return drupal_get_form("views_filters_$view->name", $form, 'views_filters');
return drupal_get_form("views_filters", $view);
}
function views_filters_form($view) {
function views_filters($view) {
$filters = _views_get_filters();
foreach ($view->exposed_filter as $count => $expose) {
$id = $expose['id'];
......@@ -1162,6 +1174,7 @@ function views_filters_form($view) {
function views_filters_process($form) {
unset($form['form_id']);
unset($form['form_token']);
return $form;
}
function theme_views_filters($form) {
......@@ -1189,12 +1202,12 @@ function theme_views_view_list($view, $nodes, $type) {
foreach ($view->field as $field) {
if ($fields[$field['id']]['visible'] !== FALSE) {
if ($field['label']) {
$item .= "<div class='view-label view-label-$field[queryname]'>" . $field['label'] . "</div>";
$item .= "<div class='view-label ". views_css_safe('view-label-'. $field['queryname']) ."'>" . $field['label'] . "</div>";