Source for file BitBlogPost.php
Documentation is available at BitBlogPost.php
* @copyright (c) 2004 bitweaver.org
* All Rights Reserved. See below for details and a complete list of authors.
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See http://www.gnu.org/copyleft/lesser.html for details
* Virtual base class (as much as one can have such things in PHP) for all
* derived tikiwiki classes that require database access.
* @date created 2004/10/20
* @author drewslater <andrew@andrewslater.com>, spiderr <spider@steelsun.com>
require_once( LIBERTY_PKG_PATH. 'LibertyComment.php');
require_once( LIBERTY_PKG_PATH. 'LibertyMime.php');
require_once( BLOGS_PKG_PATH. 'BitBlog.php');
define( 'BITBLOGPOST_CONTENT_TYPE_GUID', 'bitblogpost' );
function BitBlogPost( $pPostId= NULL, $pContentId= NULL ) {
'content_name' => 'Blog Post',
'handler_class' => 'BitBlogPost',
'handler_package' => 'blogs',
'handler_file' => 'BitBlogPost.php',
'maintainer_url' => 'http://www.bitweaver.org'
* Load a Blog Post section
function load( $pContentId = NULL, $pPluginParams = NULL ) {
global $gBitSystem, $gBitUser, $gLibertySystem;
$bindVars = array(); $selectSql = ''; $joinSql = ''; $whereSql = '';
$lookupColumn = $this->verifyId( $this->mPostId )? 'post_id' : 'content_id';
$this->getServicesSql( 'content_load_sql_function', $selectSql, $joinSql, $whereSql, $bindVars );
SELECT bp.*, lc.*, lcds.`data` AS `summary`, lch.`hits`, uu.`login`, uu.`real_name`,
lfa.`file_name` as `avatar_file_name`, lfa.`mime_type` AS `avatar_mime_type`, laa.`attachment_id` AS `avatar_attachment_id`,
lfp.`file_name` AS `image_file_name`, lfp.`mime_type` AS `image_mime_type`, lap.`attachment_id` AS `image_attachment_id`
INNER JOIN `". BIT_DB_PREFIX. "liberty_content` lc ON (lc.`content_id` = bp.`content_id`)
INNER JOIN `". BIT_DB_PREFIX. "users_users` uu ON( uu.`user_id` = lc.`user_id` )
LEFT OUTER JOIN `". BIT_DB_PREFIX. "liberty_content_data` lcds ON (lc.`content_id` = lcds.`content_id` AND lcds.`data_type`='summary')
LEFT OUTER JOIN `". BIT_DB_PREFIX. "liberty_content_hits` lch ON( lch.`content_id` = lc.`content_id` )
LEFT OUTER JOIN `". BIT_DB_PREFIX. "liberty_attachments` laa ON (uu.`user_id` = laa.`user_id` AND uu.`avatar_attachment_id`=laa.`attachment_id`)
LEFT OUTER JOIN `". BIT_DB_PREFIX. "liberty_files` lfa ON (lfa.`file_id` = laa.`foreign_id`)
LEFT OUTER JOIN `". BIT_DB_PREFIX. "liberty_attachments` lap ON( lap.`content_id` = lc.`content_id` AND lap.`is_primary` = 'y' )
LEFT OUTER JOIN `". BIT_DB_PREFIX. "liberty_files` lfp ON( lfp.`file_id` = lap.`foreign_id` )
WHERE bp.`$lookupColumn`=? $whereSql ";
if( $this->mInfo = $this->mDb->getRow( $query, $bindVars ) ) {
// this is bad news right here, 'url' is wrong, standard is 'display_url'
// we should remove this now that display_url is added
foreach( array( 'avatar', 'image' ) as $img ) {
//for two text field auto split
$format = $this->mInfo['format_guid'];
$linebreak = $gLibertySystem->mPlugins[$format]['linebreak'];
$this->mInfo['raw'] = isset ( $parts[0] )? $parts[0] : $this->mInfo['raw'];
$this->mInfo['raw_more'] = isset ( $parts[1] )? $parts[1] : NULL ;
$this->mInfo['use_title'] = $gBitUser->getPreference( 'user_blog_posts_use_title', 'y', $this->mInfo['user_id'] ) ;
if( isset ($pPluginParams['load_comments']) and $pPluginParams['load_comments'] ) {
$comment->mRootObj = $this;
$this->mInfo['num_comments'] = $comment->getNumComments($this->mInfo['content_id']);
// Get the comments associated with this post
$this->mInfo['comments'] = $comment->getComments($this->mInfo['content_id'], $gBitSystem->getConfig( 'comments_per_page', 10 ) );
if (!$this->mInfo['trackbacks_from'] || $this->mInfo['trackbacks_from']=== null)
if (!$this->mInfo['trackbacks_to'] || $this->mInfo['trackbacks_to']=== null)
$this->mInfo['trackbacks_to_count'] = count($this->mInfo['trackbacks_to']);
foreach( array_keys( $this->mStorage ) as $key ) {
$this->mStorage[$key]['wiki_plugin_link'] = '{attachment id='. $key. '}';
if( !empty( $pHash['title'] ) ) {
$date_format = $gBitSystem->get_long_date_format();
if( $gBitSystem->get_display_offset() ) {
$date_string = $gBitSystem->mServerTimestamp->getDisplayDateFromUTC( !empty($pHash['created']) ? $pHash['created'] : $gBitSystem->getUTCTime());
$ret = $gBitSystem->mServerTimestamp->strftime( $date_format, $date_string, true );
if( @$this->verifyId( $pPostContentId ) ) {
$bindVars = array( (int) $pPostContentId );
$query = "SELECT b.`content_id` AS hash_key, bpm.*, b.*, lc.*
INNER JOIN `". BIT_DB_PREFIX. "blogs` b ON b.`content_id` = bpm.`blog_content_id`
INNER JOIN `". BIT_DB_PREFIX. "liberty_content` lc ON lc.`content_id` = b.`content_id`
WHERE bpm.post_content_id = ?";
if( $ret = $this->mDb->getAssoc( $query, $bindVars ) ) {
$this->mErrors['post_id'] = "Invalid post id.";
* Get the URL for any given post image
* @param $pParamHash pass in full set of data returned from post query
global $gBitSystem, $gThumbSizes;
if( !empty( $pParamHash['image_file_name'] )) {
'source_file' => $pParamHash['image_file_name']
$ret['original'] = BIT_ROOT_URL. $pParamHash['image_file_name'];
* Deal with images and text, modify them apprpriately that they can be returned to the form.
* @param $previewData data submitted by form - generally $_REQUEST
* @return array of data compatible with article form
global $gBitSystem, $gBitUser;
// preserve our split data if we are using to text fields cause it gets merged in verify
$data['raw'] = $data['edit'];
$data['raw_more'] = (!empty($data['edit_body'])? $data['edit_body']: '');
if( empty( $data['user_id'] ) ) {
$data['user_id'] = $gBitUser->mUserId;
if( empty( $data['hits'] ) ) {
if( empty( $data['publish_date'] ) ) {
$data['publish_date'] = $gBitSystem->getUTCTime();
// preserve checked blogs
if( !empty($pParamHash['blog_content_id']) ){
foreach($pParamHash['blog_content_id'] as $blog_content_id) {
$this->mInfo['blogs'][$blog_content_id] = $blog_content_id;
$data['use_title'] = $gBitUser->getPreference( 'user_blog_posts_use_title', 'y', $data['user_id'] );
$data['title'] = $this->getTitle($pParamHash);
if( empty( $data['parsed_data'] ) ) {
$data['no_cache'] = TRUE;
/* this is already taken care of by calling verify above
if (isset($data['edit_body'])){
$data['edit'] .= "...split...".$data['edit_body'];
$data['parsed_data'] = $this->parseData( $data['edit'], (!empty($data['format_guid']) ? $data['format_guid'] : 'tikiwiki' ));
//$data['parsed_data'] = $this->parseData( $data );
// replace the split syntax with a horizontal rule
* Make sure the data is safe to store
* @param pParamHash be sure to pass by reference in case we need to make modifcations to the hash
* This function is responsible for data integrity and validation before any operations are performed with the $pParamHash
* NOTE: This is a PRIVATE METHOD!!!! do not call outside this class, under penalty of death!
* @param array pParams reference to hash of values that will be used to store the page, they will be modified where necessary
* @return bool TRUE on success, FALSE if verify failed. If FALSE, $this->mErrors will have reason why
function verify( &$pParamHash ) {
global $gBitUser, $gBitSystem, $gLibertySystem;
// make sure we're all loaded up of we have a mPostId
$pParamHash['content_id'] = $this->mInfo['content_id'];
// It is possible a derived class set this to something different
if( empty( $pParamHash['content_type_guid'] )&& !empty( $this->mContentTypeGuid ) ) {
if( !empty( $pParamHash['data'] ) ) {
$pParamHash['edit'] = $pParamHash['data'];
// for two text field auto split
if (!empty($pParamHash['edit_body'])){
$linebreak = $gLibertySystem->mPlugins[$pParamHash['format_guid']]['linebreak'];
// we need two line breaks to simulate a paragraph break
$pParamHash['edit'] .= "...split...". $linebreak. $linebreak. $pParamHash['edit_body'];
// truncate length if too long
if( !empty( $pParamHash['title'] ) ) {
$pParamHash['title'] = substr( $pParamHash['title'], 0, 160 );
if( !empty( $pParamHash['publish_Month'] ) ) {
//$dateString = $pParamHash['publish_Year'].'-'.$pParamHash['publish_Month'].'-'.$pParamHash['publish_Day'].' '.$pParamHash['publish_Hour'].':'.$pParamHash['publish_Minute'];
//$timestamp = $gBitSystem->mServerTimestamp->getUTCFromDisplayDate( strtotime( $dateString ) );
$offset = $this->mDate->get_display_offset();
$dateString = $this->mDate->gmmktime(
$pParamHash['publish_Hour'],
$pParamHash['publish_Minute'],
isset ($pParamHash['publish_Second']) ? $pParamHash['publish_Second'] : 0,
$pParamHash['publish_Month'],
$pParamHash['publish_Day'],
$pParamHash['publish_Year']
$timestamp = $this->mDate->getUTCFromDisplayDate( $dateString );
if( $timestamp !== - 1 ) {
$pParamHash['publish_date'] = $timestamp;
if( !empty( $pParamHash['publish_date'] ) ) {
$pParamHash['post_store']['publish_date'] = $pParamHash['publish_date'];
$pParamHash['post_store']['publish_date'] = $gBitSystem->getUTCTime();
if( !empty( $pParamHash['expire_Month'] ) ) {
$dateString = $pParamHash['expire_Year']. '-'. $pParamHash['expire_Month']. '-'. $pParamHash['expire_Day']. ' '. $pParamHash['expire_Hour']. ':'. $pParamHash['expire_Minute'];
//$timestamp = $gBitSystem->mServerTimestamp->getUTCFromDisplayDate( strtotime( $dateString ) );
$offset = $this->mDate->get_display_offset();
$dateString = $this->mDate->gmmktime(
$pParamHash['expire_Hour'],
$pParamHash['expire_Minute'],
isset ($pParamHash['expire_Second']) ? $pParamHash['expire_Second'] : 0,
$pParamHash['expire_Month'],
$pParamHash['expire_Day'],
$pParamHash['expire_Year']
$timestamp = $this->mDate->getUTCFromDisplayDate( $dateString );
if( $timestamp !== - 1 ) {
$pParamHash['expire_date'] = $timestamp;
if( !empty( $pParamHash['expire_date'] ) ) {
$pParamHash['post_store']['expire_date'] = $pParamHash['expire_date'];
$pParamHash['post_store']['expire_date'] = $gBitSystem->getUTCTime();
// if we have an error we get them all by checking parent classes for additional errors
parent::verify( $pParamHash );
* Check that the class has a valid blog loaded
* Check if the current user is the blog owner
if( empty( $pUserId ) && $gBitUser->isValid() ) {
$pUserId = $gBitUser->mUserId;
if( $this->isValid() && ($pUserId == $this->mInfo["blog_user_id"]) ) {
* Check if the current post can have comments attached to it
return $gBitSystem->isFeatureActive( 'blog_posts_comments' );
* @todo users_watches is a legacy package and needs refactoring
function store( &$pParamHash ) {
$this->mDb->StartTrans();
// Send trackbacks recovering only successful trackbacks
if ( !empty( $pParamHash['trackback'] ) ){
$locId = array( "content_id" => $this->mContentId );
$result = $this->mDb->associateUpdate( $table, $pParamHash['post_store'], $locId );
$pParamHash['post_store']['content_id'] = $pParamHash['content_id'];
if( @$this->verifyId( $pParamHash['post_id'] ) ) {
// if pParamHash['post_id'] is set, someone is requesting a particular post_id. Use with caution!
$pParamHash['post_store']['post_id'] = $pParamHash['post_id'];
$pParamHash['post_store']['post_id'] = $this->mDb->GenID( 'blog_posts_post_id_seq' );
$this->mPostId = $pParamHash['post_store']['post_id'];
$result = $this->mDb->associateInsert( $table, $pParamHash['post_store'] );
// let's reload to get a full mInfo hash which is needed below
// if blog_content_id, then map the post to the relative blogs
if( !empty( $pParamHash['blog_content_id'] )){
// Update post with trackbacks successfully sent
// Can this be moved below into similar function below? -wjames5
// this throws an error on site population because post_id is not defined in pParamHash - wjames5
$query = "UPDATE `". BIT_DB_PREFIX. "blog_posts` SET `trackbacks_from`=?, `trackbacks_to` = ? WHERE `post_id`=?";
if( @BitBase::verifyId( $pParamHash['post_id'] )) {
$this->mDb->query( $query, array( serialize( array() ), $trackbacks, (int) $pParamHash['post_id'] ));
if( $gBitSystem->isFeatureActive( 'users_watches' ) ) {
global $gBitUser, $gBitSmarty;
if( isset ( $this->mInfo['blog_id'] ) && $nots = $gBitUser->getEventWatches( 'blog_post', $this->mInfo['blog_id'] ) ) {
foreach ($nots as $not) {
$gBitSmarty->assign('mail_site', $_SERVER["SERVER_NAME"]);
$gBitSmarty->assign('mail_title', $this->mInfo['title']);
$gBitSmarty->assign('mail_blogid', $this->mInfo['blog_id']);
$gBitSmarty->assign('mail_postid', $this->mPostId);
$gBitSmarty->assign('mail_date', $gBitSystem->getUTCTime());
$gBitSmarty->assign('mail_user', $this->mInfo['login']);
$gBitSmarty->assign('mail_data', $this->mInfo['data']);
$gBitSmarty->assign('mail_hash', $not['hash']);
$gBitSmarty->assign('mail_machine', $machine);
$parts = explode('/', $foo['path']);
unset ($parts[count($parts) - 1]);
$mail_data = $gBitSmarty->fetch('bitpackage:blogs/user_watch_blog_post.tpl');
@mail($not['email'], tra('Blog post'). ' ' . $title, $mail_data, "From: ". $gBitSystem->getPrefence( 'site_sender_email' ). "\r\nContent-type: text/plain;charset=utf-8\r\n");
//is this nearly identical to the above and can they be consolodated? -wjames5
// should this be $pParamHash['trackback'] or the above $pParamHash['trackbacks'] ? - xing
if( !empty( $pParamHash['trackbacks'] ) ) {
$query = "update `". BIT_DB_PREFIX. "blog_posts` set `trackbacks_to`=? where `post_id`=?";
$result = $this->mDb->query($query,array($trackbacks, $user_id, $post_id));
$this->mDb->CompleteTrans();
function loadPostMap( $pPostContentId, $pBlogContentId){
if( @BitBase::verifyId( $pPostContentId ) ){
$this->mDb->StartTrans();
$result = $this->mDb->getRow( "SELECT * FROM `". BIT_DB_PREFIX. "blogs_posts_map` WHERE `post_content_id`=? AND `blog_content_id`=?", array( $pPostContentId, $pBlogContentId ) );
$this->mDb->CompleteTrans();
if ( !empty( $result ) ){
* Map a Post to a Blog or multiple Blogs
* @param pPost a Post hash.
* @param pBlogMixed the content_id or and array of ids of the blogs we want the post to show up in.
* @param pCrosspostNote text to display with the blog post when viewed in the blog crossposted to.
* @param pAutoProcess a bool to distinguish if we are storing from the crosspost interface or from the blog posting interface.
function storePostMap( $pPost, $pBlogMixed, $pCrosspostNote = NULL, $pAutoProcess = FALSE ) {
global $gBitSystem, $gBitUser;
$postContentId = $pPost['content_id'];
if( @$this->verifyId( $postContentId ) ) {
$this->mDb->StartTrans();
//this is to set the time we add a post to a blog.
$currTime = $gBitSystem->getUTCTime();
$postTime = $pPost['publish_date'];
$timeStamp = ( $postTime > $currTime )? $postTime : $currTime;
if( !empty( $pBlogMixed )){
$blogIds = explode( ",", $pBlogMixed );
$blogIds = array( $pBlogMixed );
$currentMappings = array();
if( $allMappings = $this->mDb->getCol( "SELECT `blog_content_id` FROM `". BIT_DB_PREFIX. "blogs_posts_map` WHERE `post_content_id`=?", array( $postContentId ) ) ) {
// whiddle down all mappings to just those we have perm to
foreach( $allMappings as $blogContentId ) {
if( $this->checkContentPermission( array( 'user_id' => $gBitUser->mUserId, 'perm_name'=> 'p_blogs_post', 'content_id'=> $blogContentId ) ) ) {
$currentMappings[] = $blogContentId;
// Add new mappings for this post
$newBlogIds = array_diff( $blogIds, $currentMappings );
foreach( $newBlogIds as $blogContentId ) {
if( $this->verifyId( $blogContentId ) && $this->checkContentPermission( array( 'user_id' => $gBitUser->mUserId, 'perm_name'=> 'p_blogs_post', 'content_id'=> $blogContentId ) ) ) {
'post_content_id' => $postContentId,
'blog_content_id' => (int) $blogContentId,
'date_added' => $timeStamp,
'crosspost_note' => $pCrosspostNote,
/* if we are coming form the crossposting form then we
* want to update any change to the crosspost note.
* we dont want to if we are coming from the blog posting form.
// Update existing mappings
foreach( $updateBlogIds as $blogContentId ) {
if( $this->verifyId( $blogContentId ) && $this->checkContentPermission( array( 'user_id' => $gBitUser->mUserId, 'perm_name'=> 'p_blogs_post', 'content_id'=> $blogContentId ) ) ) {
'crosspost_note' => $pCrosspostNote,
'post_content_id' => $postContentId,
'blog_content_id' => (int) $blogContentId,
$this->mDb->CompleteTrans();
/* if we are coming from the blog posting form we
* want to automatically drop any crossposting if
* we have unchecked them there. we ignore this when
* coming from the crossposting form.
// Remove mappings for this post
$removedBlogIds = array_diff( $currentMappings, $blogIds );
$this->mDb->StartTrans();
if ( !empty($pBlogContentIds) ){
foreach( $pBlogContentIds as $blogContentId ) {
$this->mDb->query( "DELETE FROM `". BIT_DB_PREFIX. "blogs_posts_map` WHERE `blog_content_id`=? AND `post_content_id`=?", array( $blogContentId, $pPostContentId ) );
$this->mDb->CompleteTrans();
* Remove complete blog post set and any comments
// let's force a full load to make sure everything is loaded.
$this->mDb->StartTrans();
// remove all references in blogs_posts_map where post_content_id = content_id
$query_map = "DELETE FROM `". BIT_DB_PREFIX. "blogs_posts_map` WHERE `post_content_id` = ?";
$result = $this->mDb->query( $query_map, array( $this->mContentId ) );
$query = "DELETE FROM `". BIT_DB_PREFIX. "blog_posts` WHERE `content_id` = ?";
$result = $this->mDb->query( $query, array( $this->mContentId ) );
// Do this last so foreign keys won't complain (not the we have them... yet ;-)
$this->mDb->CompleteTrans();
$this->mDb->RollbackTrans();
* Return a summary for this content base on
* @param object PostId of the item to use
* @return object Url String
if( !($ret = $this->getField( 'summary' )) ) {
* Generate a valid url for the Blog
* @param object PostId of the item to use
* @return object Url String
if( @BitBase::verifyId( $pParamHash['content_id'] )) {
$rewrite_tag = $gBitSystem->isFeatureActive( 'pretty_urls_extended' ) ? 'view/' : '';
if( $gBitSystem->isFeatureActive( 'pretty_urls' ) || $gBitSystem->isFeatureActive( 'pretty_urls_extended' ) ) {
if( !empty( $pParamHash['post_id'] ) ) {
$ret = BLOGS_PKG_URL. $rewrite_tag. 'post/'. $pParamHash['post_id'];
$ret = BLOGS_PKG_URL. $rewrite_tag. 'content/'. $pParamHash['content_id'];
$ret = BLOGS_PKG_URL. 'view_post.php?content_id='. $pParamHash['content_id'];
* Generate a valid display link for the Blog
* @param object PostId of the item to use
* @return object Fully formatted html link for use by Liberty
function getDisplayLink( $pTitle= NULL, $pMixed= NULL, $pAnchor= NULL ) {
if( empty( $pTitle ) && !empty( $this ) ) {
if( empty( $pMixed ) && !empty( $this ) ) {
if( $gBitSystem->isPackageActive( 'blogs' ) ) {
* Returns include file that will
* @return the fully specified path to file to be included
return( BLOGS_PKG_PATH. 'display_bitblogpost_inc.php' );
if( $this->isValid() && !empty( $pTrackbacks ) ) {
$tracks = explode(',', $pTrackbacks);
'view_post', $parts['path']). '?post_id=' . $this->mPostId . '&blog_id=' . $this->mInfo['blog_id'];
foreach ($tracks as $track) {
@$fp = fopen($track, 'r');
$data .= fread($fp, 32767);
preg_match("/trackback:ping=(\"|\'|\s*)(.+)(\"|\'\s)/", $data, $reqs);
@$fp = fopen($reqs[2], 'r');
$submit_vars["url"] = $uri;
$submit_vars["blog_name"] = $this->mInfo['blogtitle'];
$submit_vars["title"] = $this->mInfo['title'] ? $this->mInfo['title'] : date("d/m/Y [h:i]", $this->mInfo['created']);
$submit_vars["excerpt"] = substr($post_info['data'], 0, 200);
$snoopy->submit($submit_url, $submit_vars);
$back = $snoopy->results;
if (!strstr('<error>1</error>', $back)) {
global $gBitUser, $gBitSystem;
$selectSql = ''; $joinSql = ''; $whereSql = '';
$this->getServicesSql( 'content_list_sql_function', $selectSql, $joinSql, $whereSql, $bindVars, NULL, $pListHash );
if( @$this->verifyId( $pListHash['blog_id'] ) ) {
$selectSql .= ', bpm.crosspost_note';
array_push( $bindVars, (int) $pListHash['blog_id'] );
$joinSql .= " LEFT OUTER JOIN `". BIT_DB_PREFIX. "blogs_posts_map` bpm ON ( bpm.`post_content_id` = bp.`content_id` ) ";
$joinSql .= " LEFT OUTER JOIN `". BIT_DB_PREFIX. "blogs` b ON ( bpm.`blog_content_id`=b.`content_id` ) ";
// " ON ( b.`content_id` = bpm.`blog_content_id` AND bp.`content_id` = bpm.`post_content_id` )";
$whereSql .= ' AND b.`blog_id` = ? ';
$pListHash['sort_mode'] = 'publish_date_desc';
if( @$this->verifyId( $pListHash['post_id_gt'] ) ) {
array_push( $bindVars, (int) $pListHash['post_id_gt'] );
$whereSql .= ' AND bp.`post_id` > ? ';
if( @$this->verifyId( $pListHash['post_id_lt'] ) ) {
array_push( $bindVars, (int) $pListHash['post_id_lt'] );
$whereSql .= ' AND bp.`post_id` < ? ';
if( @$this->verifyId( $pListHash['user_id'] ) ) {
array_push( $bindVars, (int) $pListHash['user_id'] );
$whereSql .= ' AND lc.`user_id` = ? ';
$this->getServicesSql( 'content_user_collection_function', $selectSql, $joinSql, $whereSql, $bindVars, NULL, $pListHash );
// map user to login in case we used one instead of the other
if( !empty( $pListHash['user'] ) ) {
$pListHash['login'] = $pListHash['user'];
if( !empty( $pListHash['login'] ) ) {
$whereSql .= ' AND uu.`login` = ? ';
if( $pListHash['find'] ) {
$findesc = '%' . strtoupper( $pListHash['find'] ) . '%';
$whereSql .= "AND (UPPER(lc.`data`) like ?) ";
if( !empty( $pListHash['date'] ) && is_numeric( $pListHash['date'] ) ) {
$whereSql .= " AND lc.`created`<=? ";
$bindVars[]= $pListHash['date'];
if( !empty( $pListHash['date_start'] ) && is_numeric( $pListHash['date_start'] ) ) {
$whereSql .= " AND lc.`created`>=? ";
$bindVars[]= $pListHash['date_start'];
if( !empty( $pListHash['date_end'] ) && is_numeric( $pListHash['date_end'] ) ) {
$whereSql .= " AND lc.`created`<=? ";
$bindVars[]= $pListHash['date_end'];
if( !empty( $pListHash['content_perm_name'] ) ) {
/* Check if the post wants to be viewed before / after respective dates
* Note: expiring posts are determined by the expired date being greater than the publish date
static::getDateRestrictions($pListHash, $whereSql, $bindVars);
/* sort_mode is never empty due to call to prepGetList above
* I think this will have to be perminently removed and default
* set before passing the list hash in if a different default is
* desired from that in prepGetList. -wjames5
if( empty( $pListHash['sort_mode'] ) ) {
$pListHash['sort_mode'] = 'publish_date_desc';
//$pListHash['sort_mode'] = 'created_desc';
if( !empty( $pListHash['sort_mode'] ) && !strpos( $pListHash['sort_mode'], '.' ) ) {
switch( $pListHash['sort_mode'] ) {
case 'publish_date_desc':
$sortModePrefix = 'bpm.';
$sortModePrefix = 'lch.';
// these technicall are not correct, however, we do not double join on users_users, so we sort by creator real_name
case 'creator_real_name_asc':
case 'modifier_real_name_asc':
$pListHash['sort_mode'] = 'real_name_asc';
case 'registration_date_desc':
$pListHash['sort_mode'] = 'registration_date_desc';
case 'creator_real_name_desc':
case 'modifier_real_name_desc':
$pListHash['sort_mode'] = 'real_name_desc';
$secondarySortMode = ($pListHash['sort_mode'] != 'last_modified_desc') ? ', last_modified DESC': '';
$sort_mode = $sortModePrefix . $this->mDb->convertSortmode( $pListHash['sort_mode'] ). $secondarySortMode;
bp.`post_id`, bp.`publish_date`, bp.`expire_date`, bp.`trackbacks_to`, bp.`trackbacks_from`,
lc.*, lch.`hits`, lcds.`data` AS `summary`, COALESCE( bp.`publish_date`, lc.`last_modified` ) AS sort_date,
uu.`email`, uu.`login`, uu.`real_name`,
lfa.`file_name` as `avatar_file_name`, lfa.`mime_type` AS `avatar_mime_type`, laa.`attachment_id` AS `avatar_attachment_id`,
lfp.`file_name` AS `image_file_name`, lfp.`mime_type` AS `image_mime_type`, lap.`attachment_id` AS `image_attachment_id`
INNER JOIN `". BIT_DB_PREFIX. "liberty_content` lc ON lc.`content_id` = bp.`content_id`
INNER JOIN `". BIT_DB_PREFIX. "users_users` uu ON uu.`user_id` = lc.`user_id`
LEFT OUTER JOIN `". BIT_DB_PREFIX. "liberty_content_hits` lch ON lc.`content_id` = lch.`content_id`
LEFT OUTER JOIN `". BIT_DB_PREFIX. "liberty_content_data` lcds ON (lc.`content_id` = lcds.`content_id` AND lcds.`data_type`='summary')
LEFT OUTER JOIN `". BIT_DB_PREFIX. "liberty_attachments` laa ON (uu.`user_id` = laa.`user_id` AND laa.`attachment_id` = uu.`avatar_attachment_id`)
LEFT OUTER JOIN `". BIT_DB_PREFIX. "liberty_files` lfa ON lfa.`file_id` = laa.`foreign_id`
LEFT OUTER JOIN `". BIT_DB_PREFIX. "liberty_attachments` lap ON lap.`content_id` = lc.`content_id` AND lap.`is_primary` = 'y'
LEFT OUTER JOIN `". BIT_DB_PREFIX. "liberty_files` lfp ON lfp.`file_id` = lap.`foreign_id`
WHERE lc.`content_type_guid` = ? $whereSql
# Get count of total number of items available
INNER JOIN `". BIT_DB_PREFIX. "liberty_content` lc ON lc.`content_id` = bp.`content_id`
INNER JOIN `". BIT_DB_PREFIX. "users_users` uu ON uu.`user_id` = lc.`user_id`
WHERE lc.`content_type_guid` = ? $whereSql ";
$cant = $this->mDb->getOne($query_cant,$bindVars);
$pListHash["cant"] = $cant;
# Check for offset out of range
if ( $pListHash['offset'] < 0 ) {
$pListHash['offset'] = 0;
} elseif ( $pListHash['offset'] > $pListHash["cant"] ) {
$lastPageNumber = ceil ( $pListHash["cant"] / $pListHash['max_records'] ) - 1;
$pListHash['offset'] = $pListHash['max_records'] * $lastPageNumber;
$result = $this->mDb->query($query,$bindVars,$pListHash['max_records'],$pListHash['offset']);
while ($res = $result->fetchRow()) {
$accessError = $this->invokeServices( 'content_verify_access', $res, FALSE );
if( empty( $accessError ) ) {
foreach( array( 'avatar', 'image' ) as $img ) {
$res['num_comments'] = $comment->getNumComments( $res['content_id'] );
$res['display_url'] = $res['post_url'];
if($res['trackbacks_from']!= null)
$res['trackbacks_from'] = unserialize($res['trackbacks_from']);
$res['trackbacks_from'] = array();
$res['trackbacks_from_count'] = count(array_keys($res['trackbacks_from']));
if($res['trackbacks_to']!= null)
$res['trackbacks_to'] = unserialize($res['trackbacks_to']);
if ($res['user_id'] == $gBitUser->mUserId) {
$res['trackbacks_to_count'] = count($res['trackbacks_to']);
$parseHash['format_guid'] = $res['format_guid'];
$parseHash['content_id'] = $res['content_id'];
$parseHash['user_id'] = $res['user_id'];
// support for ...split... and auto split
if( !empty( $pListHash['full_data'] ) ) {
$parseHash['data'] = $res['data'];
$res['parsed'] = $this->parseData( $parseHash );
$parseHash['data'] = $res['data'];
$parseHash['no_cache'] = TRUE;
$splitArray = $this->parseSplit($parseHash, $gBitSystem->getConfig( 'blog_posts_description_length', 500));
if( !empty( $this->mInfo['summary'] ) ) {
$res['summary'] = $parseHash['data'] = $this->mInfo['summary'];
$parseHash['no_cache'] = TRUE;
$res['parsed_summary'] = $this->parsedData( $parseHash );
if( !empty( $res['crosspost_note'] ) ){
$res['crosspost_note_raw'] = $parseHash['data'] = $res['crosspost_note'];
$parseHash['no_cache'] = TRUE;
$res['crosspost_note'] = $this->parseData( $parseHash );
} elseif( !empty( $accessError ) ) {
if( !empty( $accessError['access_control'] ) ) {
$res['display_url'] = $res['post_url'];
/* this needs to be part of loop that gets all blogs post is in
$res['blog_url'] = BitBlog::getDisplayUrlFromHash( $res['blog_content_id'] );
$res["parsed_data"] = $accessError['access_control'];
$pListHash["data"] = $ret;
* alters the whereSql and bindVars to limit the posts returned based on the dates
* expects the blog_psots table to be aliased as bp
global $gBitSystem, $gBitUser;
$now = $gBitSystem->getUTCTime();
if( !empty( $pListHash['show_future'] ) && !empty( $pListHash['show_expired'] ) && $gBitUser->hasPermission( 'p_blog_posts_read_future' ) && $gBitUser->hasPermission( 'p_blog_posts_read_expired' ) ) {
// this will show all post at once - future, current and expired
} elseif( !empty( $pListHash['show_future'] ) && $gBitUser->hasPermission( 'p_blog_posts_read_future' ) ) {
// hide expired posts but show future
$whereSql .= " AND ( bp.`expire_date` <= bp.`publish_date` OR bp.`expire_date` > ? ) ";
$bindVars[] = ( int ) $now;
} elseif( !empty( $pListHash['show_expired'] ) && $gBitUser->hasPermission( 'p_blog_posts_read_expired' ) ) {
// hide future posts but show expired
$whereSql .= " AND bp.`publish_date` < ?";
$bindVars[] = ( int ) $now;
} elseif( !empty( $pListHash['get_future'] ) && $gBitUser->hasPermission( 'p_blog_posts_read_future' ) ) {
$whereSql .= " AND bp.`publish_date` > ?";
$bindVars[] = ( int ) $now;
} elseif( !empty( $pListHash['get_expired'] ) && $gBitUser->hasPermission( 'p_blog_posts_read_expired' ) ) {
// show only expired posts
$whereSql .= " AND bp.`expire_date` < ? AND bp.`expire_date` > bp.`publish_date` ";
$bindVars[] = ( int ) $now;
// hide future and expired posts
$whereSql .= " AND ((bp.`publish_date` IS NULL AND bp.`expire_date` IS NULL) OR (bp.`publish_date` <= ? AND ((bp.`expire_date` IS NULL) OR ( bp.`expire_date` <= bp.`publish_date` ) OR ( bp.`expire_date` > ? ))))";
$bindVars[] = ( int ) $now;
$bindVars[] = ( int ) $now;
* Get a list of posts that are to be published in the future
* @param array $pParamHash contains listing options - same as getList()
$pParamHash['get_future'] = TRUE;
return( $this->getList( $pParamHash ));
* Get list of posts that have expired and are not displayed on the site anymore
* @param array $pParamHash contains listing options - same as getList()
$pParamHash['get_expired'] = TRUE;
return( $this->getList( $pParamHash ));
'blog_name' => $blog_name
$query = "update `". BIT_DB_PREFIX. "blog_posts` set `trackbacks_from`=? where `post_id`=?";
$this->mDb->query( $query, array( $st, $this->mPostId ) );
$st = $this->mDb->getOne("select `trackbacks_from` from `". BIT_DB_PREFIX. "blog_posts` where `post_id`=?",array( $this->mPostId ) );
$st = $this->mDb->getOne("select `trackbacks_to` from `". BIT_DB_PREFIX. "blog_posts` where `post_id`=?", array( $this->mPostId ) );
$query = "update `". BIT_DB_PREFIX. "blog_posts` set `trackbacks_from` = ? where `post_id`=?";
$this->mDb->query( $query, array( $empty, $this->mPostId ) );
$query = "update `". BIT_DB_PREFIX. "blog_posts` set `trackbacks_to` = ? where `post_id`=?";
$this->mDb->query( $query, array( $empty, $this->mPostId ) );
$ret = "bitpackage:liberty/center_". $pAction. "_generic.tpl";
$ret = "bitpackage:blogs/center_". $pAction. "_blog_posts.tpl";
* @return an array of content_status_id, content_status_names the current
* user can use on this content.
* NOTE: pUserMinimum and pUserMaximum are currently NOT inclusive in parent funtion, so these are one beyond the limit we desire
$ret = LibertyMime::getAvailableContentStatuses( $pUserMinimum, $pUserMaximum );
// this is a little ugly as we manually trim the list to just what we need for blog posts for regular users
if( !$gBitUser->hasPermission( 'p_liberty_edit_all_status' )) {
* Returns the create/edit url to a blog post
* @param number $pContentId a valid content id
* @param array $pMixed a hash of params to add to the url
function getEditUrl( $pContentId = NULL, $pMixed = NULL ){
if( @BitBase::verifyId( $pContentId ) ) {
$ret = BLOGS_PKG_URL. 'post.php?content_id='. $pContentId;
$ret = BLOGS_PKG_URL. 'post.php?content_id='. $this->mContentId;
$ret = BLOGS_PKG_URL. 'post.php'. (!empty( $pMixed )? "?": "");
foreach( $pMixed as $key => $value ){
if( $key != "content_id" || ( $key == "content_id" && @BitBase::verifyId( $value ) ) ) {
$ret .= (isset ($amp)? "&": ""). $key. "=". $value;
|