Commit 9bdf7f2e authored by merlinofchaos's avatar merlinofchaos
Browse files

Sync from HEAD to DRUPAL-5

parent db6bb601
......@@ -3,7 +3,7 @@ CHANGELOG for Views for Drupal 5
Views 1.0
o Initial release under drupal.org's new release system
Views 1.1-dev
Views 5.x-1.1-beta-1
Bugs fixed:
o 97228: Fatal error on the views help page.
......@@ -34,3 +34,33 @@ Views 1.1-dev
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
o Provide a proper 'action' for exposed filters so they always go to the
view, not just the current page.
o 76601: New 'all files' field to display all files on a node as a single
field
Views 5.x-1.2-beta-1
Bugs fixed:
o 100394: Fix to t() call in 'new comments'.
o 100164: alias prefixing fix.
o 100109: Incorrect caching of 'is new' filter.
o 99849: DISTINCT could break summary views.
o 99783: Comment count didn't take into account pages. Also moved handler
out of node where it didn't belong.
o Use drupal_add_feed() for RSS icons so they can be themed.
o 99323: fix link in argument handling help
o Temporary fix for cache not being loaded for menu item creation
o 100317: exported view gets improperly formed value fields on filters
o 98441: Fixed 'optional' setting on exposed filters.
o 100997: Clarified use of $arg in help text
o 100769: Getting book parents didn't require parents to be current
o 98492: Recent comments block needed to filter out moderated comments
New features:
o 99225: CSS generator for views theme wizard
o 88067: theme_view much more useful now.
o 98492: Comment moderation status filter
o 101025: Sort by node type
Views --dev
......@@ -128,7 +128,7 @@ function views_handler_field_book_parent_title_nl($fieldinfo, $fielddata, $value
function views_handler_filter_book_parent_zero() {
$parents = array();
$result = db_query("SELECT DISTINCT parent FROM {book} ORDER BY parent");
$result = db_query("SELECT DISTINCT parent FROM {book} INNER JOIN {node} n ON book.vid = n.vid ORDER BY parent");
while ($obj = db_fetch_object($result)) {
$parents[$obj->parent] = "$obj->parent";
}
......
......@@ -62,6 +62,14 @@ function comment_views_tables() {
'help' => t('This will display the author of the node.'),
),
),
'filters' => array(
'status' => array(
'name' => t('Comment: Pending approval'),
'operator' => array('=' => t('Equals')),
'list' => 'views_handler_operator_yesno',
'list-type' => 'select',
),
),
'sorts' => array(
'timestamp' => array(
'name' => t('Comment: Created Time'),
......@@ -177,6 +185,18 @@ function views_handler_field_commentlink($fieldinfo, $fielddata, $value, $data)
return l($value, "node/$data->nid", NULL, NULL, "comment-$data->comments_cid");
}
/*
* Format a field as a number of comments, plus the number of unread comments.
*/
function views_handler_comments_with_new($fieldinfo, $fielddata, $value, $data) {
$comments = intval($value);
if ($comments && $new = comment_num_new($data->nid)) {
$comments .= '<br />';
$comments .= l(t('@num new', array('@num' => $new)), "node/$data->nid", NULL, comment_page_new_query($data->nid), 'new');
}
return $comments;
}
/*
* 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.
......@@ -264,6 +284,13 @@ function comment_views_default_views() {
'options' => '',
'value' => '1',
),
array (
'tablename' => 'comments',
'field' => 'status',
'operator' => '=',
'options' => '',
'value' => '0',
),
);
$view->exposed_filter = array (
);
......
......@@ -119,6 +119,10 @@ function node_views_tables() {
'name' => t('Node: Title'),
'help' => t('Sort by the node title, alphabetically'),
),
'type' => array(
'name' => t('Node: Type'),
'help' => t('Sort by the node type, alphabetically'),
),
'random' => array(
'name' => t('Random'),
'handler' => 'views_handler_sort_random',
......@@ -416,18 +420,6 @@ function views_handler_nodetype($fieldinfo, $fielddata, $value, $data) {
return node_get_types('name', $value);
}
/*
* Format a field as a number of comments, plus the number of unread comments.
*/
function views_handler_comments_with_new($fieldinfo, $fielddata, $value, $data) {
$comments = intval($value);
if (module_exists('comment') && $comments && $new = comment_num_new($data->nid)) {
$comments .= '<br />';
$comments .= l(t('%num new', array('%num' => $new)), "node/$data->nid", NULL, NULL, 'new');
}
return $comments;
}
/*
* Format a field as the Body of a node.
*/
......@@ -684,19 +676,19 @@ function views_handler_filter_isnew($op, $filter, $filterinfo, &$query) {
// Hey, Drupal kills old history, so nodes that haven't been updated
// since NODE_NEW_LIMIT are bzzzzzzzt outta here!
$limit = NODE_NEW_LIMIT;
$limit = time() - NODE_NEW_LIMIT;
$query->ensure_table('history');
if (module_exists('comment')) {
$query->ensure_table('node_comment_statistics');
$clause = "OR node_comment_statistics.last_comment_timestamp > $limit";
$clause = ("OR node_comment_statistics.last_comment_timestamp > (***CURRENT_TIME*** - $limit)");
$clause2 = "OR history.timestamp < node_comment_statistics.last_comment_timestamp";
}
// NULL means a history record doesn't exist. That's clearly new content.
// Unless it's very very old content. Everything in the query is already
// type safe cause none of it is coming from outside here.
$query->add_where("(history.timestamp IS NULL AND (node.changed > $limit $clause)) OR history.timestamp < node.changed $clause2");
$query->add_where("(history.timestamp IS NULL AND (node.changed > (***CURRENT_TIME***-$limit) $clause)) OR history.timestamp < node.changed $clause2");
}
/*
......@@ -751,10 +743,10 @@ function views_handler_sort_random($action, &$query, $sortinfo, $sort) {
switch ($GLOBALS['db_type']) {
case 'mysql':
case 'mysqli':
$query->add_orderby('', "rand()", "ASC");
$query->add_orderby('', "rand()", "ASC", 'random_sort');
break;
case 'pgsql':
$query->add_orderby('', "random()", "ASC");
$query->add_orderby('', "random()", "ASC", 'random_sort');
break;
}
}
......
; $Id$
name = Views
description = The views module creates customized views of node lists.
version = 1.1
version = $Name$
package = Views
......@@ -97,6 +97,7 @@ function views_menu($may_cache) {
* Helper function to add a menu item for a view.
*/
function _views_create_menu_item(&$items, $view, $path, $local_task_type = MENU_NORMAL_ITEM, $args = array()) {
views_load_cache();
static $roles = NULL;
if ($roles == NULL) {
global $user;
......@@ -1157,13 +1158,14 @@ function views_filters($view) {
}
$form['#method'] = 'get';
$form['#process'] = array('views_filters_process' => array());
$form['#action'] = url($view->real_url ? $view->real_url : $view->url, NULL, NULL, true);
$form['view'] = array('#type' => 'value', '#value' => $view);
$form['submit'] = array('#type' => 'button', '#name' => '', '#value' => t('Submit'));
// clean URL get forms breaks if we don't give it a 'q'.
if (!(bool)variable_get('clean_url', '0')) {
$form['q'] = array(
'#type' => 'hidden',
'#value' => $_GET['q'],
'#value' => $view->real_url ? $view->real_url : $view->url,
'#name' => 'q',
);
}
......@@ -1609,6 +1611,22 @@ function views_handler_operator_yesno() {
return array('1' => t('Yes'), '0' => t('No'));
}
/*
* Break x,y,z and x+y+z into an array. Numeric only.
*/
function _views_break_phrase($str) {
if (preg_match('/^([0-9]+[+ ])+[0-9]+$/', $str)) {
// The '+' character in a query string may be parsed as ' '.
return array('or', preg_split('/[+ ]/', $str));
}
else if (preg_match('/^([0-9]+,)*[0-9]+$/', $str)) {
return array('and', explode(',', $str));
}
else {
return NULL;
}
}
/**
* Default Views style plugins. Implementation of hook_views_style_plugins()
*/
......@@ -1683,19 +1701,20 @@ function views_handler_filter_like($op, $filter, $filterinfo, &$query) {
$words = trim($match[2], ',?!();:-');
$words = $phrase ? array($words) : preg_split('/ /', $words, -1, PREG_SPLIT_NO_EMPTY);
foreach ($words as $word) {
$q[] = "UPPER(%s) LIKE UPPER('%%%s%%')";
$v[] = $field;
$v[] = trim($word, " ,!?");
$where[] = "UPPER(%s) LIKE UPPER('%%%s%%')";
$values[] = $field;
$values[] = trim($word, " ,!?");
}
}
if ($filter['operator'] == 'word') {
$q = '('. implode(' OR ', $q) .')';
$where = '('. implode(' OR ', $where) .')';
}
else {
$q = implode(' AND ', $q);
$where = implode(' AND ', $where);
}
array_unshift($v, $q);
call_user_func_array(array($query, 'add_where'), $v);
// previously this was a call_user_func_array but that's unnecessary
// as views will unpack an array that is a single arg.
$query->add_where($where, $values);
break;
case 'starts':
$query->add_where("UPPER(%s) LIKE UPPER('%s%%')",
......@@ -1763,14 +1782,15 @@ function views_views_query_substitutions($view) {
* @param $view_name
* The name of the view.
* @param $limit
* Required if $use_pager is set; if $limit is set and $use_pager is
* Maximum number of nodes displayed on one page. if $limit is set and $use_pager is
* not, this will be the maximum number of records returned. This is ignored
* if using a view set to return a random result. If $use_pager is set and
* this field is not, you'll get a SQL error. Don't do that!
* if using a view set to return a random result.
* If NULL, the setting defined for the $view will be used.
* @param $use_pager
* If set, use a pager. Set this to the pager id you want it to use if you
* plan on using multiple pagers on a page. Note that the pager element id
* will be decremented in order to have the IDs start at 0.
* If NULL, the setting defined for the $view will be used.
* @param $type
* 'page' -- Produce output as a page, sent through theme.
* The only real difference between this and block is that
......@@ -1778,9 +1798,15 @@ function views_views_query_substitutions($view) {
* 'block' -- Produce output as a block, sent through theme.
* 'embed' -- Use this if you want to embed a view onto another page,
* and don't want any block or page specific things to happen to it.
* @param $view_args
* An array containing the arguments for the view
*/
function theme_view( $view_name, $limit = 0, $use_pager = false, $type = 'embed' ) {
function theme_view($view_name, $limit = NULL, $use_pager = NULL, $type = 'embed', $view_args = array()) {
if ($view = views_get_view($view_name)) {
$use_pager = isset($use_pager) ? $use_pager : $view->use_pager;
$limit_default = ($type == 'block') ? $view->nodes_per_block : $view->nodes_per_page;
$limit = isset($limit) ? $limit : $limit_default;
return views_build_view($type, $view, $view_args, $use_pager, $limit);
}
}
......@@ -101,7 +101,7 @@ function _views_view_build_filters(&$query, &$view) {
}
if ($expose['optional']) {
if (!isset($_GET["filter$count"]) && !$expose['is_default']) {
if ((!isset($_GET["filter$count"]) || $_GET["filter$count"] == '') && !$expose['is_default']) {
continue 2; // skip
}
if ($_GET["filter$count"] == '**ALL**' ||
......@@ -110,7 +110,7 @@ function _views_view_build_filters(&$query, &$view) {
continue 2; // skip this filter entirely.
}
}
if (isset($_GET["filter$count"])) {
if (isset($_GET["filter$count"]) && $_GET["filter$count"] != '') {
$value = $_GET["filter$count"];
if ($filterinfo['value-type'] == 'array' && !is_array($value)) {
$value = array($value);
......@@ -249,7 +249,7 @@ function _views_build_summary(&$query, $argtype, $option, $self_sort) {
if (!function_exists($arginfo[$argtype]['handler'])) {
return false;
}
$primary_field = $query->fields[0];
$query->clear_fields();
$fieldinfo = $arginfo[$argtype]['handler']('summary', $query, $argtype, $option);
......@@ -257,7 +257,7 @@ function _views_build_summary(&$query, $argtype, $option, $self_sort) {
if ($fieldinfo['fieldname']) {
$query->add_field($fieldinfo[field], '', $fieldinfo[fieldname]);
}
$query->add_field('count(node.nid)', '', 'num_nodes');
$query->add_field("count($primary_field)", '', 'num_nodes');
$query->add_groupby($fieldinfo['field']);
$query->set_count_field("DISTINCT($fieldinfo[field])");
if ($self_sort) {
......@@ -362,6 +362,8 @@ class _views_query {
* Add multiple an orderby's. Right now I'm not sure why this function
* is separate from add_orderby above; I don't think it needs to
* be.
*
* NOTE: $alias doesn't work when adding multiple orderbys.
*/
function add_orderby($table, $field, $order, $alias = '') {
if (!$alias && $table) {
......@@ -380,7 +382,14 @@ class _views_query {
}
foreach($field as $f) {
$as = $alias . '_' . $f;
// Only fill out this aliasing if there is a table;
// otherwise we assume it is a formula.
if ($table) {
$as = $alias . '_' . $f;
}
else {
$as = $alias;
}
$this->add_field($f, $table, $as);
$this->orderby[] = "$as $order";
}
......@@ -443,7 +452,7 @@ class _views_query {
if ($joininfo) {
$this->joins[$table][$i] = $joininfo;
}
$this->tablequeue[] = array('table' => $table, 'num' => $i);
$this->tablequeue[] = array('table' => $table, 'num' => $i, 'alias_prefix' => $this->use_alias_prefix);
}
return $this->tables[$table];
}
......@@ -522,7 +531,10 @@ class _views_query {
* @param $alias_prefix
* An optional prefix for the table alias.
*/
function get_table_name($table, $table_num, $alias_prefix = '') {
function get_table_name($table, $table_num, $alias_prefix = null) {
if (is_null($alias_prefix)) {
$alias_prefix = $this->use_alias_prefix;
}
return ($table_num < 2 ? $alias_prefix . $table : $alias_prefix . $table . $table_num);
}
......
; $Id$
name = Views RSS
description = RSS plugin for the views feed selector argument.
version = 1.1
version = $Name$
package = Views
dependencies = views
......@@ -82,13 +82,7 @@ function views_rss_views_feed_argument($op, &$view, $arg) {
$filters = drupal_query_string_encode($view->used_filters);
}
drupal_add_link(array('rel' => 'alternate',
'type' => 'application/rss+xml',
'title' => check_plain($title),
'href' => url($url, $filters, NULL, TRUE)));
if ($view->build_type != 'block') {
return theme('feed_icon', url($url, $filters));
}
drupal_add_feed($title, $filters);
}
}
......
; $Id$
name = Views Theme Wizard
description = The views theme wizard helps create stub theming for views.
version = 1.1
version = $Name$
package = Views
dependencies = views
......@@ -55,6 +55,12 @@ function views_theme_wizard_form($views) {
'#type' => 'markup',
'#value' => '',
);
$form['code3'] = array(
'#type' => 'markup',
'#value' => '',
);
$form['submit'] = array(
'#type' => 'button',
......@@ -90,6 +96,11 @@ function views_theme_wizard_generate($form, $form_values) {
$form['code2']['#value'] = views_theme_wizard_generate_list_template_code($view);
$form['code2']['#title'] = t('This code goes in a file named views-list-%s.tpl.php', array('%s' => $view->name));
$form['code2']['#rows'] = 20;
$form['code3']['#type'] = 'textarea';
$form['code3']['#value'] = views_theme_wizard_generate_list_stylesheet_code($view);
$form['code3']['#title'] = t('This code goes in a file named views-list-%s.css', array('%s' => $view->name));
$form['code3']['#rows'] = 20;
}
if ($op == t('List Theme Fields')) {
......@@ -102,6 +113,7 @@ function views_theme_wizard_generate($form, $form_values) {
$form['code2']['#value'] = views_theme_wizard_example_field($view);
$form['code2']['#title'] = t('This is a basic theme function', array('%s' => $view->name));
$form['code2']['#rows'] = 20;
}
return $form;
}
......@@ -202,7 +214,9 @@ EOT;
* generate a template file for a list theme
*/
function views_theme_wizard_generate_list_template_code($view) {
$header = <<<EOT
$header = <<<EOT
<?php
/**
* views template to output one 'row' of a view.
......@@ -220,7 +234,6 @@ function views_theme_wizard_generate_list_template_code($view) {
* \$count -- the current row in the view (not TOTAL but for this page) starting
* from 0.
* \$stripe -- 'odd' or 'even', alternating.
EOT;
$fields = _views_get_fields();
......@@ -251,7 +264,12 @@ EOT;
*
* This function goes in your views-list-{$view->name}.tpl.php file
*/
?>
//now we add the stylesheet...
drupal_add_css(path_to_theme() .'/views-list-{$view->name}.css');
?>
EOT;
......@@ -259,3 +277,55 @@ EOT;
return $header .$output;
}
/**
* generate a stylesheet file for a list theme
*/
function views_theme_wizard_generate_list_stylesheet_code($view) {
$header = <<<EOT
/* *
* views template to output the stylesheet to customize a view.
* This code was generated by the views theming wizard
* Date: $now
* View: $view->name
*
* The class selectors are filled with a single comment line.
* You should complete each selector according to your liking.
*/
\n
EOT;
$fields = _views_get_fields();
$taken = array();
$output .= <<<EOT
.view-label {
/* insert your css code for this element here */
}
.view-field {
/* insert your css code for this element here */
}
EOT;
// Set up the selectors in nicely named chunks.
foreach ($view->field as $id => $field) {
$field_name = views_css_safe($field['field']);
if (isset($taken[$field_name])) {
$field_name = views_css_safe($field['queryname']);
}
$taken[$field_name] = true;
$output .= <<<EOT
.view-field-{$field_name} {
/* insert your css code for this element here */
}
.view-data-{$field_name} {
/* insert your css code for this element here */
}
EOT;
}
return $header .$output;
}
; $Id$
name = Views UI
description = The Views UI module allows you to create and edit views.
version = 1.1
version = $Name$
package = Views
dependencies = views
......@@ -761,7 +761,7 @@ function views_edit_view($view, $op = '') {
'#default_value' => $view->url,
'#size' => 60,
'#maxlength' => 255,
'#description' => t('Enter the URL to use for this view in the form of \'dir/dir\'. Do not begin or end the URL with a /. Example: \'view/tracker\'. This is required if providing a page view. You can also add $arg as a placeholder for arguments passed in the URL, for example \'user/$arg/tracker\' or \'view/taxonomy/$arg\'.'),
'#description' => t('Enter the URL to use for this view in the form of \'dir/dir\'. Do not begin or end the URL with a /. Example: \'view/tracker\'. This is required if providing a page view. You can also add $arg as a placeholder for arguments passed in the URL, for example \'user/$arg/tracker\' or \'view/taxonomy/$arg\'. Note that any arguments listed here will be required, even if they are listed as optional below. You do not need to list arguments at the end of the path.'),
);
$form['page-info']['page_type'] = array(
......@@ -803,7 +803,6 @@ function views_edit_view($view, $op = '') {
'#maxlength' => 5,
'#description' => t('The number of nodes to display per page. If 0, all nodes will be displayed. If not using a pager, this will be the maximum number of nodes in the list.'),
'#attributes' => NULL,
'#required' => true,
);
$form['page-info']['page_header_fieldset'] = array(
'#type' => 'fieldset',
......@@ -1044,7 +1043,7 @@ function views_edit_view($view, $op = '') {
'#cols' => 60,
'#rows' => 6,
'#description' => '<p>'. t('Advanced Usage Only: PHP code that returns a custom array of arguments for the view. Should not include &lt;?php ?&gt; delimiters.') .'</p>' .
'<p>'. t('For more information, please see the <a href="%arg">Argument Handling Code documentation</a> in the Drupal handbook.', array('%arg' => 'http://drupal.org/node/70145')) .'</p>',
'<p>'. t('For more information, please see the <a href="!arg">Argument Handling Code documentation</a> in the Drupal handbook.', array('%arg' => 'http://drupal.org/node/70145')) .'</p>',
);
} else {
$form['view_args_php_fieldset']['view_args_php'] = array(
......@@ -1872,9 +1871,8 @@ function views_create_view_code($vid) {
$output .= " 'tablename' => " . var_export($fieldbits[0], true) . ",\n";
$output .= " 'field' => " . var_export($fieldbits[1], true) . ",\n";
$output .= " 'operator' => " . var_export($filter['operator'], true) . ",\n";
$value = var_export($filter['value'], true);
$output .= " 'options' => " . var_export($filter['options'], true) . ",\n";
$output .= " 'value' => " . var_export($value, true) . ",\n";
$output .= " 'value' => " . var_export($filter['value'], true) . ",\n";
$output .= " ),\n";
$requires[$fieldbits[0]] = 1;
}
......
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