Source for file _class_item.php
Documentation is available at _class_item.php
* This file implements items
* 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_dataobject.php';
* locale code for the Item content
* examples: en-US, zh-CN-utf-8
* Derived from $main_cat_ID
* {@internal Item::Item(-)}}
function Item( $db_row =
NULL )
// Call parent constructor:
$this->mod_date =
$db_row->post_mod_date;
$this->status =
$db_row->post_status;
$this->locale =
$db_row->post_locale;
$this->title =
$db_row->post_title;
$this->urltitle =
$db_row->post_urltitle;
$this->content =
$db_row->post_content;
$this->flags =
$db_row->post_flags;
$this->comments =
$db_row->post_comments; // Comments status
// echo 'renderers=', $db_row->post_renderers;
$this->url =
$db_row->post_url; // Should move
$this->autobr =
$db_row->post_autobr; // Should move
* generate permalink for item
* {@internal Item::gen_permalink(-)}}
* @todo archives modes in clean mode
* @param string 'urltitle', 'pid', 'archive#id' or 'archive#title'
* @param string url to use
* @param boolean true to force single post on destination page
* @param string glue between url params
function gen_permalink( $mode =
'', $blogurl =
'', $force_single =
false, $glue =
'&' )
global $DB, $BlogCache, $cacheweekly, $Settings;
$mode =
$Settings->get( 'permalink_type' );
if( $force_single &&
(strpos( $mode, 'archive' ) !==
false) )
{ // Comments cannot be displayed in archive mode
$current_Blog =
$BlogCache->get_by_ID( $this->blog_ID );
$blogurl =
$current_Blog->gen_blogurl();
// Link to an archive page:
$dest_type =
$Settings->get('archive_mode');
$urltail =
'p'.
$this->ID;
// Link to an archive page:
$dest_type =
$Settings->get('archive_mode');
$urltail =
'p'.
$this->ID;
// Link to individual post:
$dest_type =
'postbypost';
$urlparam =
'p='.
$this->ID;
$urltail =
'p'.
$this->ID;
// Link to individual post:
$dest_type =
'postbypost';
$urlparam =
'p='.
$this->ID;
$urltail =
'p'.
$this->ID;
if( ! $Settings->get('links_extrapath') )
{ // We reference by Query: Dirty but explicit permalinks
if((!isset
($cacheweekly)) ||
(empty($cacheweekly[$post_date])))
$cacheweekly[$post_date] =
$DB->get_var( "SELECT WEEK('".
$post_date.
"')" );
$permalink =
url_add_param( $blogurl, 'm='.
substr($post_date,0,4).
$glue.
'w='.
$cacheweekly[$post_date], $glue ).
'#'.
$anchor;
$permalink =
url_add_param( $blogurl, $urlparam.
$glue.
'more=1'.
$glue.
'c=1'.
$glue.
'tb=1'.
$glue.
'pb=1', $glue );
{ // We reference by path (CLEAN permalinks!)
if((!isset
($cacheweekly)) ||
(empty($cacheweekly[$post_date])))
$cacheweekly[$post_date] =
$DB->get_var( "SELECT WEEK('".
$post_date.
"')" );
$permalink =
url_add_tail( $blogurl, mysql2date("/Y/", $post_date).
'w'.
$cacheweekly[$post_date] ).
'#'.
$anchor;
// This is THE CLEANEST available: RECOMMENDED!
* Template function: display anchor for permalinks to refer to
* {@internal Item::anchor(-) }}
* @todo archives modes in clean mode
* @param string 'id' or 'title'
$mode =
$Settings->get( 'permalink_type' );
case 'archive#title':
// permalink_type
case 'title':
// explicit choice
echo
'<a name="'.
$title.
'"></a>';
case 'archive#id':
// permalink_type
case 'id':
// explicit choice
echo
'<a name="'.
$this->ID.
'"></a>';
case 'pid':
// permalink type where we need no ID
case 'urltitle':
// permalink type where we need no ID
* Template function: list all the category names
* {@internal Item::categories(-) }}
* @param string link title, '#' for default, false if you want no links
* @param string string fo display before the MAIN category, 'hide' to ignore main cat
* @param string string fo display after the MAIN category, 'hide' to ignore main cat
* @param string string fo display before OTHER categories, 'hide' to ignore other cats
* @param string string fo display after OTHER categories, 'hide' to ignore other cats
* @param string string fo display before EXTERNAL categories, 'hide' to ignore external cats
* @param string string fo display after EXTERNAL categories, 'hide' to ignore external cats
* @param string separator string
* @param string Output format for each cat, see {@link format_to_output()}
$before_main=
'<strong>', $after_main=
'</strong>',
$before_other=
'', $after_other=
'',
$before_external=
'<em>', $after_external=
'</em>',
{ /* TRANS: When the categories for a specific post are displayed, the user can click
on these cats to browse them, this is the default href title displayed there */
$link_title =
T_('Browse category');
$categoryIDs =
$cache_postcats[$this->ID];
$categoryNames =
array();
foreach( $categoryIDs as $cat_ID )
{ // we want to display links
$cat_name =
'<a href="'.
url_add_param( get_bloginfo('blogurl', $curr_blogparams), 'cat='.
$cat_ID ).
'" title="'.
$link_title.
'">'.
$cat_name.
'</a>';
{ // We are displaying the main cat!
if( $before_main ==
'hide' )
$cat_name =
$before_main.
$cat_name.
$after_main;
elseif( $cat['cat_blog_ID'] ==
$this->blog_ID )
{ // We are displaying another cat in the same blog
if( $before_other ==
'hide' )
$cat_name =
$before_other.
$cat_name.
$after_other;
{ // We are displaying an external cat (in another blog)
if( $before_external ==
'hide' )
$cat_name =
$before_external.
$cat_name.
$after_external;
$categoryNames[] =
$cat_name;
echo
implode( $separator, $categoryNames );
* Template function: display main category name
* {@internal Item::main_category(-) }}
* @param string Output format, see {@link format_to_output()}
* Check if user can see comments on this post
* {@internal Item::can_see_comments(-) }}
{ // Comments are disabled on this post
return true; // OK, user can see comments
* Template function: Check if user can leave comment on this post or display error
* {@internal Item::can_comment(-) }}
* @param string string to display before any error message
* @param string string to display after any error message
* @param string error message for non published posts, '#' for default
* @param string error message for closed comments posts, '#' for default
* @return boolean true if user can post
$before_error =
'<p><em>',
$after_error =
'</em></p>',
$non_published_msg =
'#',
{ // Comments are disabled on this post
{ // Comments are closed on this post
$closed_msg =
T_( 'Comments are closed for this post.' );
if( ($this->status ==
'draft') ||
($this->status ==
'deprecated' ) )
{ // Post is not published
if( $non_published_msg ==
'#' )
$non_published_msg =
T_( 'This post is not published. You cannot leave comments.' );
return true; // OK, user can comment!
* Template function: display content of item
* WARNING: parameter order is different from deprecated the_content(...)
* {@internal Item::content(-) }}
* @todo Param order and cleanup
* @param mixed page number to display specific page, # for url parameter
* @param mixed true to display 'more' text, false not to display, # for url parameter
* @param string text to display as the more link
* @param string text to display as the more anchor (once the more link has been clicked)
* @param string string to display before more link/anchor
* @param string string to display after more link/anchor
* @param string Output format, see {@link format_to_output()}
* @param integer max number of words
* @param boolean true if you don't want to repeat teaser after more link was pressed
* @param string filename to use to display more
// echo $format,'-',$cut,'-',$dispmore,'-',$disppage;
if( $more_link_text ==
'#' )
{ // TRANS: this is the default text for the extended post "more" link
$more_link_text =
'=> '.
T_('Read more!');
if( $more_anchor ==
'#' )
{ // TRANS: this is the default text displayed once the more link has been activated
$more_anchor =
'['.
T_('More:').
']';
if( $before_more ==
'#' )
$before_more =
'<p class="bMore">';
{ // We want to display more if requested by user:
{ // This is a multipage post
$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);
{ // We want to display the page requested by the user:
if( $disppage >
$numpages )
$content =
$pages[$disppage-
1];
if($disppage >
1) $dispmore=
1;
$content_parts =
explode('<!--more-->', $content);
if( count($content_parts)>
1 )
{ // This is an extended post (has a more section):
{ // Viewer has already asked for more
if( $stripteaser ||
preg_match('/<!--noteaser-->/', $content ) )
{ // We want to strip the teaser:
$output =
$content_parts[0];
if( !empty($more_anchor) ) $output .=
$before_more;
$output .=
'<a id="more'.
$this->ID.
'" name="more'.
$this->ID.
'"></a>'.
$more_anchor;
if( !empty($more_anchor) ) $output .=
$after_more;
if( count($content_parts) >
2 )
{ // we have additional <!--more--> tags somewhere
$output .=
implode('', $content_parts);
else $output .=
$content_parts[1];
{ // We are offering to read more
$output =
$content_parts[0];
$output .=
$before_more .
'<a href="'.
$this->gen_permalink( 'pid', $more_file ).
'#more'.
$this->ID.
'">'.
$output =
$content_parts[0];
$post_renderers =
$Renderer->validate_list( $this->renderers );
$output =
$Renderer->render( $output, $post_renderers, $format );
if( ($format ==
'xml') &&
$cut )
{ // Let's cut this down...
for ($i=
0; $i<
$cut; $i++
)
$excerpt .=
$blah[$i].
' ';
$output =
$excerpt .
'...';
* Template function: display issue date (datetime) of Item
* {@internal Item::issue_date(-) }}
* @param string date/time format: leave empty to use locale default date format
* @param boolean true if you want GMT
function issue_date( $format =
'', $useGM =
false )
* Template function: display issue time (datetime) of Item
* {@internal Item::issue_time(-) }}
* @param string date/time format: leave empty to use locale default time format
* @param boolean true if you want GMT
function issue_time( $format =
'', $useGM =
false )
* Template function: display locale for item
* {@internal Item::lang(-) }}
$this->disp( 'locale', 'raw' );
* Template function: display locale for item
* {@internal Item::locale(-) }}
$this->disp( 'locale', 'raw' );
* Template function: display language name for item
* {@internal Item::language(-) }}
* @param string Output format, see {@link format_to_output()}
function language( $format =
'htmlbody' )
$locale =
$locales[ $this->locale ];
* Template function: display last mod date (datetime) of Item
* {@internal Item::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 )
* Template function: display last mod time (datetime) of Item
* {@internal Item::mod_time(-) }}
* @param string date/time format: leave empty to use locale default time format
* @param boolean true if you want GMT
function mod_time( $format =
'', $useGM =
false )
* Template function: display permalink for item
* {@internal Item::permalink(-)}}
* @param string 'post', 'archive#id' or 'archive#title'
* @param string url to use
function permalink( $mode =
'', $blogurl=
'' )
* Template function: Displays link to feedback page (under some conditions)
* {@internal Item::feedback_link(-)}}
* @param string Type of feedback to link to (feedbacks (all)/comments/trackbacks/pingbacks)
* @param string String to display before the link (if comments are to be displayed)
* @param string String to display after the link (if comments are to be displayed)
* @param string Link text to display when there are 0 comments
* @param string Link text to display when there is 1 comment
* @param string Link text to display when there are >1 comments (include %d for # of comments)
* @param string Link title
* @param boolean true to use a popup windows ('#' to use if comments_popup_windows() is there)
* @param boolean true to hide if no feedback ('#' for default)
* @param string 'pid' or 'title'
* @param string url to use
function feedback_link( $type =
'feedbacks', $before =
'', $after =
'',
$zero=
'#', $one=
'#', $more=
'#', $title=
'#',
$use_popup =
'#', $hideifnone =
'#', $mode =
'', $blogurl=
'' )
global $b2commentsjavascript, $BlogCache;
if( $hideifnone ==
'#' ) $hideifnone =
false;
if( $title ==
'#' ) $title =
T_('Display feedback / Leave a comment');
if( $zero ==
'#' ) $zero =
T_('Send feedback');
if( $one ==
'#' ) $one =
T_('1 feedback');
if( $more ==
'#' ) $more =
T_('%d feedbacks');
if( $title ==
'#' ) $title =
T_('Display comments / Leave a comment');
if( $zero ==
'#' ) $zero =
T_('Leave a comment');
if( $one ==
'#' ) $one =
T_('1 comment');
if( $more ==
'#' ) $more =
T_('%d comments');
$current_Blog =
$BlogCache->get_by_ID( $this->blog_ID );
if( ! $current_Blog->get( 'allowtrackbacks' ) )
{ // Trackbacks not allowed on this blog:
if( $hideifnone ==
'#' ) $hideifnone =
false;
if( $title ==
'#' ) $title =
T_('Display trackbacks / Get trackback address for this post');
if( $zero ==
'#' ) $zero =
T_('Trackback (0)');
if( $one ==
'#' ) $one =
T_('Trackback (1)');
if( $more ==
'#' ) $more =
T_('Trackbacks (%d)');
$current_Blog =
$BlogCache->get_by_ID( $this->blog_ID );
if( ! $current_Blog->get( 'allowpingbacks' ) )
{ // Pingbacks not allowed on this blog:
if( $hideifnone ==
'#' ) $hideifnone =
true;
if( $title ==
'#' ) $title =
T_('Display pingbacks');
if( $zero ==
'#' ) $zero =
T_('Pingback (0)');
if( $one ==
'#' ) $one =
T_('Pingback (1)');
if( $more ==
'#' ) $more =
T_('Pingbacks (%d)');
die( "Unkown feedback type [$type]" );
{ // Use popups if javascript is included in page
$use_popup =
$b2commentsjavascript;
if( ($number ==
0) &&
$hideifnone )
{ // We need to tell b2evo to use the popup template
echo
'#', $type, '" '; // Position on feedback
echo
'title="', $title, '"';
if( $use_popup ) echo
' onclick="b2open(this.href); return false"';
* Displays button for deleting the Item if user has proper rights
* {@internal Item::delete_link(-)}}
* @param string to display before link
* @param string to display after link
* @param string link text
* @param string link title
* @param string class name
* @param boolean true to make this a button instead of a link
* @param string glue between url params
function delete_link( $before =
' ', $after =
' ', $text =
'#', $title =
'#', $class =
'', $button =
false, $glue =
'&' )
global $current_User, $admin_url;
if( ! $current_User->check_perm( 'blog_del_post', 'any', false, $this->blog_ID ) )
{ // User has right to delete this post
if( $text ==
'#' ) $text =
T_('Delete');
if( $title ==
'#' ) $title =
T_('Delete this post');
$url =
$admin_url.
'/edit_actions.php?action=delete'.
$glue.
'post='.
$this->ID;
echo
'<input type="button"';
echo
' value="'.
$text.
'" title="'.
$title.
'" onclick="if ( confirm(\'';
/* TRANS: Warning this is a javascript string */
echo
T_('You are about to delete this post!\\n\\\'Cancel\\\' to stop, \\\'OK\\\' to delete.');
echo
'\') ) { document.location.href=\''.
$url.
'\' }"';
if( !empty( $class ) ) echo
' class="'.
$class.
'"';
echo
'<a href="'.
$url.
'" title="'.
$title.
'" onclick="return confirm(\'';
/* TRANS: Warning this is a javascript string */
echo
T_('You are about to delete this post!\\n\\\'Cancel\\\' to stop, \\\'OK\\\' to delete.');
if( !empty( $class ) ) echo
' class="'.
$class.
'"';
* Provide link to edit a post if user has edit rights
* {@internal Item::edit_link(-)}}
* @param string to display before link
* @param string to display after link
* @param string link text
* @param string link title
* @param string class name
* @param string glue between url params
function edit_link( $before =
' ', $after =
' ', $text =
'#', $title =
'#', $class =
'', $glue =
'&' )
global $current_User, $admin_url;
if( ! $current_User->check_perm( 'blog_post_statuses', $this->status, false,
{ // User has no right to edit this post
if( $text ==
'#' ) $text =
T_('Edit');
if( $title ==
'#' ) $title =
T_('Edit this post');
echo
'<a href="'.
$admin_url.
'/b2edit.php?action=edit'.
$glue.
'post='.
$this->ID;
echo
'" title="'.
$title.
'"';
if( !empty( $class ) ) echo
' class="'.
$class.
'"';
* Provide link to publish a post if user has edit rights
* Note: publishing date will be updated
* {@internal Item::publish_link(-)}}
* @param string to display before link
* @param string to display after link
* @param string link text
* @param string link title
* @param string class name
* @param string glue between url params
function publish_link( $before =
' ', $after =
' ', $text =
'#', $title =
'#', $class =
'', $glue =
'&' )
global $current_User, $admin_url;
if( ($this->status ==
'published') // Already published!
||
! ($current_User->check_perm( 'blog_post_statuses', 'published', false, $this->blog_ID ))
||
! ($current_User->check_perm( 'edit_timestamp' ) ) )
{ // User has no right to publish this post now:
if( $text ==
'#' ) $text =
T_('Publish NOW!');
if( $title ==
'#' ) $title =
T_('Publish now using current date and time.');
echo
'<a href="'.
$admin_url.
'/edit_actions.php?action=publish'.
$glue.
'post_ID='.
$this->ID;
echo
'" title="'.
$title.
'"';
if( !empty( $class ) ) echo
' class="'.
$class.
'"';
* Template function: display status of item
* {@internal Item::status(-) }}
* @param string Output format, see {@link format_to_output()}
function status( $format =
'htmlbody' )
$this->disp( 'status', 'raw' );
* Template function: display title for item and link to related URL
* {@internal Item::title(-) }}
* @param string String to display before the title if there is something to display
* @param string String to display after the title if there is something to display
* @param boolean false if you don't want to link to URL
* @param string Output format, see {@link format_to_output()}
$before=
'', // HTML/text to be displayed before title
$after=
'', // HTML/text to be displayed after title
$add_link =
true, // Added link to this title?
if( empty($this->title) &&
$add_link )
if( $add_link &&
(!empty($this->url)) )
$title =
'<a href="'.
$this->url.
'">'.
$title.
'</a>';
* Template function: Displays trackback autodiscovery information
* {@internal Item::trackback_rdf(-) }}
// if (!stristr($_SERVER['HTTP_USER_AGENT'], 'W3C_Validator')) {
// fplanque WARNING: this isn't a very clean way to validate :/
// fplanque added: html comments (not perfect but better way of validating!)
echo
'<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" '.
"\n";
echo
' xmlns:dc="http://purl.org/dc/elements/1.1/"'.
"\n";
echo
' xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">'.
"\n";
echo
'<rdf:Description'.
"\n";
$this->title( ' dc:title="', '"'.
"\n", false, 'xmlattr' );
echo
' trackback:ping="';
* Template function: displays url to use to trackback this item
* {@internal Item::trackback_url(-) }}
global $htsrv_url, $Settings;
if( $Settings->get('links_extrapath') )
echo
"$htsrv_url/trackback.php/$this->ID";
echo
"$htsrv_url/trackback.php?tb_id=$this->ID";
* Template function: Display link to item related url
* {@internal Item::url_link(-) }}
* @param string string to display before the url (if exists)
* @param string string to display after the url (if exists)
* @param string Output format, see {@link format_to_output()}
function url_link( $before=
'', $after=
'', $format =
'htmlbody' )
if( !empty( $this->url ) )
* Template function: Display the number of words in the post
* {@internal Item::wordcount(-) }}