Source for file _class_itemlist.php
Documentation is available at _class_itemlist.php
* This file implements item/post/article lists
* b2evolution - {@link http://b2evolution.net/}
* Released under GNU GPL License - {@link http://b2evolution.net/about/license.html}
* @copyright (c)2003-2005 by Francois PLANQUE - {@link http://fplanque.net/}
if( !defined('DB_USER') ) die( 'Please, do not access this page directly.' );
require_once( dirname(__FILE__
).
'/_class_dataobjectlist.php' );
require_once( dirname(__FILE__
).
'/_class_item.php' );
function cat_req( $parent_cat_ID, $level )
// echo "[$parent_cat_ID] ";
if( ! in_array( $parent_cat_ID, $cat_array ) )
$cat_array[] =
$parent_cat_ID;
// echo "STOP! ALREADY VISITED THIS ONE!";
return -
1; // STOP going through that branch
var $max_paged; // Max page number for paged display
var $last_displayed_date =
'';
* {@internal ItemList::ItemList(-)}}
* @param array show_statuses
* @param mixed Specific post number to display
* @param mixed YearMonth(Day) to display
* @param mixed Week number. Note: uses mySQL's week numbering and mySQL default if applicable.
* In mySQL < 4.0, WEEK() uses mode 0: Week starts on Sunday;
* Value range is 0 to 53; week 1 is the first week that starts in this year
* @param mixed List of cats to restrict to
* @param array Array of cats to restrict to
* @param mixed List of authors to restrict to
* @param string sort order can be either ASC or DESC
* @param string space separated list of fields to order by. Possible list elements are:
* author issue_date mod_date status locale content title urltitle url ctageory
* @param mixed # of posts to display on the page
* @param mixed List page number in paged display
* @param mixed Start results at this position
* @param mixed End results at this position
* @param string Search string
* @param mixed Search for sentence or for words
* @param mixed Require exact match of title or contents
* @param boolean Is this preview
* @param mixed Do not show posts before this timestamp, can be 'now'
* @param mixed Do not show posts after this timestamp, can be 'now'
* @param string urltitle of post to display
$show_statuses =
array(),
$p =
'', // Specific post number to display
$m =
'', // YearMonth(Day) to display
$cat =
'', // List of cats to restrict to
$catsel =
array(), // Array of cats to restrict to
$author =
'', // List of authors to restrict to
$order =
'', // ASC or DESC
$orderby =
'', // list of fields to order by
$posts =
'', // # of posts to display on the page
$paged =
'', // List page number in paged display
$poststart =
'', // Start results at this position
$postend =
'', // End results at this position
$s =
'', // Search string
$sentence =
'', // Search for sentence or for words
$exact =
'', // Require exact match of title or contents
$preview =
0, // Is this preview
$default_posts_per_page =
'',
$timestamp_min =
'', // Do not show posts before this timestamp
$timestamp_max =
'now', // Do not show posts after this timestamp
$title =
'' ) // urltitle of post to display
global $tableposts, $tablepostcats, $tablecategories;
global $cache_categories;
global $cat_array; // communication with recursive callback funcs
// Call parent constructor:
$posts_per_page =
$posts;
elseif( !empty($default_posts_per_page) )
$posts_per_page =
$default_posts_per_page;
$posts_per_page =
$Settings->get('posts_per_page');
$this->posts_per_page =
$posts_per_page;
$what_to_show =
(empty($init_what_to_show)) ?
$Settings->get('what_to_show') :
$init_what_to_show;
// First let's clear some variables
// WE ARE GOING TO CONSTRUCT THE "AND" CLOSE
// THIS IS GOING TO LAST FOR MANY MANY LINES...
// if a month is specified in the querystring, load that month
$where .=
' AND YEAR(post_issue_date)=' .
substr($m,0,4);
$where .=
' AND MONTH(post_issue_date)=' .
substr($m,4,2);
$where .=
' AND DAYOFMONTH(post_issue_date)=' .
substr($m,6,2);
$where .=
' AND HOUR(post_issue_date)=' .
substr($m,8,2);
$where .=
' AND MINUTE(post_issue_date)=' .
substr($m,10,2);
$where .=
' AND SECOND(post_issue_date)=' .
substr($m,12,2);
// If a week number is specified
if( !empty($w) &&
($w>=
0) ) // Note: week # can be 0
$where .=
' AND WEEK(post_issue_date)='.
intval($w);
// if a post number is specified, load that post
if( ($p !=
'') &&
($p !=
'all') )
$where .=
' AND ID = '.
$p;
// if a post urltitle is specified, load that post
$where .=
' AND post_urltitle = '.
$DB->quote($title);
* ----------------------------------------------------
* ----------------------------------------------------
if( $exact ) // We want exact match of title or contents
else // The words/sentence are/is to be included in in the title or the contents
if( ($sentence ==
'1') or ($sentence ==
'sentence') )
$s =
$DB->escape(trim($s));
$search .=
'(post_title LIKE \''.
$n.
$s.
$n.
'\') OR (post_content LIKE \''.
$n.
$s.
$n.
'\')';
// puts spaces instead of commas
for ( $i =
0; $i <
count($s_array); $i++
)
$search .=
' '.
$join.
' ( (post_title LIKE \''.
$n.
$DB->escape($s_array[$i]).
$n.
'\') OR (post_content LIKE \''.
$n.
$DB->escape($s_array[$i]).
$n.
'\') ) ';
* ----------------------------------------------------
* ----------------------------------------------------
$cat_array =
array(); // this is a global var
// Check for cat string (which will be handled recursively)
if( ! ((empty($cat)) ||
($cat ==
'all') ||
($cat ==
'0')) )
{ // specified a category string:
{ // We want to exclude cats
$req_cat_array =
explode(' ', $cats[1]);
{ // We want to include cats
$req_cat_array =
explode(' ', $cat);
// Getting required sub-categories:
// and add everything to cat array
// ----------------- START RECURSIVE CAT LIST ----------------
cat_query(); // make sure the caches are loaded
foreach( $req_cat_array as $cat_ID )
{ // run recursively through the cats
settype( $cat_ID, 'integer' ); // make sure
cat_children( $cache_categories, ($blog==
1)?
0:
$blog, $cat_ID, 'cat_req_dummy', 'cat_req',
'cat_req_dummy', 'cat_req_dummy', 1 );
// ----------------- END RECURSIVE CAT LIST ----------------
// Add explicit selections:
// echo "Explicit selections!<br />";
$whichcat .=
' AND postcat_cat_ID '.
$eq.
' ('.
implode(",", $cat_array).
') ';
* ----------------------------------------------------
* ----------------------------------------------------
if((empty($author)) ||
($author ==
'all'))
$author_array =
explode(' ', $author);
$whichauthor .=
' AND post_author '.
$eq.
' '.
$author_array[0];
for ($i =
1; $i <
(count($author_array)); $i =
$i +
1) {
$whichauthor .=
' '.
$andor.
' post_author '.
$eq.
' '.
$author_array[$i];
$where .=
$search.
$whichcat .
$whichauthor;
* ----------------------------------------------------
* ----------------------------------------------------
$orderby =
'issue_date '.
$order;
$orderby_array =
explode(' ',$orderby);
$orderby =
$orderby_array[0].
' '.
$order;
if (count($orderby_array)>
1)
for($i =
1; $i <
(count($orderby_array)); $i++
)
$orderby .=
', post_'.
$orderby_array[$i].
' '.
$order;
* ----------------------------------------------------
* ----------------------------------------------------
{ // When in backoffice: always paged
// echo 'POSTSTART-POSTEND ';
if( $postend <
$poststart )
$postend =
$poststart +
$posts_per_page -
1;
if ($what_to_show ==
'posts' ||
$what_to_show ==
'paged')
$posts =
$postend -
$poststart +
1;
$limits =
' LIMIT '.
($poststart-
1).
','.
$posts;
elseif ($what_to_show ==
'days')
$posts =
$postend -
$poststart +
1;
$lastpostdate =
get_lastpostdate( $blog, $show_statuses, $cat, $catsel, $timestamp_min, $timestamp_max );
$lastpostdate =
mysql2date('Y-m-d 23:59:59',$lastpostdate);
$this->limitdate_end =
$lastpostdate -
(($poststart -
1) *
86400);
{ // no restriction if we request a month... some permalinks may point to the archive!
// echo 'ARCHIVE - no limits';
elseif ($what_to_show ==
'posts')
$limits =
' LIMIT '.
$posts_per_page;
elseif( $what_to_show ==
'paged' )
$pgstrt =
(intval($paged) -
1) *
$posts_per_page.
', ';
$limits =
'LIMIT '.
$pgstrt.
$posts_per_page;
elseif( $what_to_show ==
'days' )
if( !empty($p) ||
!empty($title) ||
!empty($s) ||
!empty($cat) ||
!empty($author) )
{ // We are in DAYS mode but we can't restrict on these!
$lastpostdate =
get_lastpostdate( $blog, $show_statuses, $cat, $catsel, $timestamp_min, $timestamp_max );
$lastpostdate =
mysql2date('Y-m-d 00:00:00',$lastpostdate);
$otherdate =
date('Y-m-d H:i:s', ($lastpostdate -
(($posts_per_page-
1) *
86400)));
$where .=
' AND post_issue_date > \''.
$otherdate.
'\'';
echo 'DEFAULT - NO LIMIT';
* ----------------------------------------------------
* Restrict to the statuses we want to show:
* ----------------------------------------------------
* ----------------------------------------------------
* ----------------------------------------------------
if( $timestamp_min ==
'now' )
if( !empty($timestamp_min) )
// echo 'hide before '.$timestamp_min;
$date_min =
date('Y-m-d H:i:s', $timestamp_min +
($Settings->get('time_difference') *
3600) );
$where .=
' AND post_issue_date >= \''.
$date_min.
'\'';
if( $timestamp_max ==
'now' )
if( !empty($timestamp_max) )
$date_max =
date('Y-m-d H:i:s', $timestamp_max +
($Settings->get('time_difference') *
3600) );
$where .=
' AND post_issue_date <= \''.
$date_max.
'\'';
// LIMIT TO SPECIFIC BLOG?
{ // Special case: we aggregate all cats from all blogs
$where =
'WHERE 1 '.
$where;
$where =
'WHERE cat_blog_ID = '.
$blog.
$where;
// We are going to proceed in two steps (we simulate a subquery)
// 1) we get the IDs we need
// 2) we get all the other fields matching these IDs
// This is more efficient than manipulating all fields at once.
$step1_sql =
"SELECT DISTINCT ID
FROM ($tableposts INNER JOIN $tablepostcats ON ID = postcat_post_ID)
INNER JOIN $tablecategories ON postcat_cat_ID = cat_ID ";
$step1_sql .=
' ORDER BY post_'.
$orderby;
$step1_sql .=
' '.
$limits;
// Get list of the IDs we need:
$ID_list =
$DB->get_list( $step1_sql, 0, 'Get ID list for Item List (Main|Lastpostdate) Query' );
$this->request =
'SELECT ID, post_author, post_issue_date, post_mod_date,
post_status, post_locale, post_content, post_title,
post_urltitle, post_url, post_category,
post_autobr, post_flags, post_wordcount, post_comments,
post_renderers, post_karma
$this->request .=
' WHERE ID IN ('.
$ID_list.
')
ORDER BY post_'.
$orderby;
$this->request .=
' WHERE 0';
$this->count_request =
"SELECT COUNT(ID)
FROM ($tableposts INNER JOIN $tablepostcats ON ID = postcat_post_ID)
INNER JOIN $tablecategories ON postcat_cat_ID = cat_ID
$this->result_rows =
$DB->get_results( $this->request, OBJECT, 'Get data for Item List (Main|Lastpostdate) Query' );
// echo $this->result_num_rows, ' items';
// Make a list of posts for future queries!
if( count( $this->result_rows ) ) foreach( $this->result_rows as $myrow )
// echo "postlist:". $this->postIDlist;
// Initialize loop stuff:
// dummy mysql query for the preview
// we need globals for the param function
global $preview_userid, $preview_date, $post_status, $post_locale, $content,
$post_title, $post_url, $post_category, $post_autobr, $edit_date,
$aa, $mm, $jj, $hh, $mn, $ss, $renderers;
global $DB, $localtimenow;
param( 'preview_userid', 'integer', true );
param( 'post_status', 'string', true );
param( 'post_locale', 'string', true );
param( 'content', 'html', true );
param( 'post_title', 'html', true );
param( 'post_url', 'string', true );
param( 'post_category', 'integer', true );
param( 'post_autobr', 'integer', 0 );
param( 'renderers', 'array', array() );
$post_renderers =
implode( '.', $renderers );
param( 'aa', 'integer', 2000 );
param( 'mm', 'integer', 1 );
param( 'jj', 'integer', 1 );
param( 'hh', 'integer', 20 );
param( 'mn', 'integer', 30 );
param( 'ss', 'integer', 0 );
$jj =
($jj >
31) ?
31 :
$jj;
$hh =
($hh >
23) ?
$hh -
24 :
$hh;
$mn =
($mn >
59) ?
$mn -
60 :
$mn;
$ss =
($ss >
59) ?
$ss -
60 :
$ss;
$post_date =
date('Y-m-d H:i:s', mktime( $hh, $mn, $ss, $mm, $jj, $aa ) );
if( $errcontent =
errors_display( T_('Invalid post, please correct these errors:'), '', false ) )
// little funky fix for IEwin, rawk on that code
if (($is_winIE) &&
(!isset
($IEWin_bookmarklet_fix)))
$content =
preg_replace('/\%u([0-9A-F]{4,4})/e', "'&#'.base_convert('\\1',16,10). ';'", $content);
$preview_userid AS post_author,
'$post_date' AS post_issue_date,
'$post_date' AS post_mod_date,
'".
$DB->escape($post_status).
"' AS post_status,
'".
$DB->escape($post_locale).
"' AS post_locale,
'".
$DB->escape($content).
"' AS post_content,
'".
$DB->escape($post_title).
"' AS post_title,
'".
$DB->escape($post_url).
"' AS post_url,
$post_category AS post_category,
$post_autobr AS post_autobr,
'".
$DB->escape( $post_renderers ).
"' AS post_renderers,
// Set variables for future:
global $previousday; // Should be a member var
* ItemList->get_max_paged(-)
* return maximum page number for paged display
//echo 'max paged= ', $this->max_paged;
* Template function: display last mod date (datetime) of Item
* {@internal ItemList::mod_date(-) }}
* @param string date/time format: leave empty to use locale default date format
* @param boolean true if you want GMT
function mod_date( $format =
'', $useGM =
false )
foreach( $this->result_rows as $loop_row )
{ // Go through whole list
$m =
$loop_row->post_mod_date;
$loop_mod_date =
mktime(substr($m,11,2),substr($m,14,2),substr($m,17,2),substr($m,5,2),substr($m,8,2),substr($m,0,4));
if( $loop_mod_date >
$mod_date_timestamp )
$mod_date_timestamp =
$loop_mod_date;
echo
date_i18n( $format, $mod_date_timestamp, $useGM );
* ItemList->get_total_num_posts(-)
* return total number of posts
* Private ItemList->calc_max(-)
return 1; // 1 row in preview mode
$this->total_num_posts =
$DB->get_var( $this->count_request, 0, 0, 'Get result count' );
* {@internal ItemList::get_category_group()}}
{ // We are at the the end!
{ // We need to initialize
$this->row =
& $this->result_rows[0];
// Go back now so that the fetch row doesn't skip one!
$this->last_Item =
new Item( $this->row ); // COPY !
* {@internal ItemList::get_item()}}
{ // We would pass the end!
$this->row =
& $this->result_rows[$this->row_num];
// echo '<p>accessing row['. $this->row_num. ']:',$this->row->post_title,'</p>';
// echo '<p>CAT CHANGE!</p>';
$this->last_Item =
new Item( $this->row ); // COPY !
* {@internal ItemList::get_postdata(-)}}
global $id, $postdata, $authordata, $day, $page, $pages, $multipage, $more, $numpages;
global $pagenow, $current_User;
if( empty($row->post_issue_date) )
die('ItemList::get_postdata(-) => No post data available!');
// echo 'starting ',$row->post_title;
'Author_ID' =>
$row->post_author,
'Date' =>
$row->post_issue_date,
'Status' =>
$row->post_status,
'Locale' =>
$row->post_locale,
'Content' =>
$row->post_content,
'Title' =>
$row->post_title,
'Category' =>
$row->post_category,
'AutoBR' =>
$row->post_autobr,
'Flags' =>
explode( ',', $row->post_flags ),
'Wordcount' =>
$row->post_wordcount,
'comments' =>
$row->post_comments,
'Karma' =>
$row->post_karma // this isn't used yet
// echo ' title: ',$postdata['Title'];
$currentmonth =
mysql2date('m',$postdata['Date']);
$content =
$postdata['Content'];
if( preg_match('/<!--nextpage-->/', $postdata['Content']) )
$content =
$postdata['Content'];
$content =
str_replace("\n<!--nextpage-->\n", '<!--nextpage-->', $content);
$content =
str_replace("\n<!--nextpage-->", '<!--nextpage-->', $content);
$content =
str_replace("<!--nextpage-->\n", '<!--nextpage-->', $content);
$pages =
explode('<!--nextpage-->', $content);
$numpages =
count($pages);
$pages[0] =
$postdata['Content'];
* Template function: Display the date if it has changed since last call
* {@internal ItemList::date_if_changed(-) }}
* @param string string to display before the date (if changed)
* @param string string to display after the date (if changed)
* @param string date/time format: leave empty to use locale default time format
$current_item_date =
$this->last_Item->get( 'issue_date' );
$current_item_date =
mysql2date( $format, $current_item_date );
if( $current_item_date !=
$this->last_displayed_date )
$this->last_displayed_date =
$current_item_date;
* Template function: display message if list is empty
* {@internal ItemList::display_if_empty(-) }}
* @param string String to display if list is empty
$message =
T_('Sorry, there is no post to display...');