Location: PHPKode > projects > Blite > blite-0.1-beta6/blite/post.php
<?php
/*
 *      Copyright 2012 Douglas Robbins <hide@address.com>
 *      
 *      This file is part of Blite, a blogging application, available at
 *      <http://blite.ca/>.
 * 
 *      Blite is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 3 of the License, or
 *      (at your option) any later version.
 *      
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *      
 *      You should have received a copy of the GNU General Public License
 *      along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

require('configure.php');

if (!$authuser) {
	echo $lang['permdenied'];
	exit;
}

$postid = '';
$page['error'] = '';
$page['lastpage'] = $cfg['home'];

if (!empty($_POST['postid']) && is_numeric($_POST['postid'])) {
	$postid = $_POST['postid'];
}

if ($_SESSION['lastpage']) {
	$page['lastpage'] = $_SESSION['lastpage'];
}

// Check the nonce.

if ($_POST) {
	list($nonce, $noncestamp, $nonceerror) = verify_nonce('p_admin','The admin page expired.');
	if ( !empty($nonceerror) ) {
		echo $nonceerror;
		exit;
	}
}

// Retract a post.

if (!empty($_POST['retract']) && $postid) {
	// Confirm the post exists; get the datestamp & categories.
	$query_params = array ( 'postid' => 'int' );
	$results = db_query("SELECT stamp,categories FROM posts WHERE id=?");
	$post = db_getdata($results);
	if ($post['stamp']) {
		$year = date('Y', $post['stamp']);
		$month = date ('n', $post['stamp']);
		$catlist = explode(' ', $post['categories']);
		foreach ($catlist as $catid) {
			$query_params = array ( 'catid' => 'int' );
			db_query("UPDATE categories SET postcount=postcount-1 WHERE id=?");
		}
		$query_params = array ( 'postid' => 'int' );
		db_query("DELETE FROM categorized WHERE postid=?");
		$query_params = array ( 'year' => 'int', 'month' => 'int' );
		db_query("UPDATE archives SET postcount=postcount-1 WHERE year=? AND month=?");
		$query_params = array ( 'postid' => 'int' );
		db_query("UPDATE posts SET status='3' WHERE id=?");
		$query_params = array( 'nonce' => 'txt', 'noncestamp' => 'int' );
		db_query("INSERT INTO nonces (nonce, type, stamp) VALUES (?, 'p_admin', ?)");

		rm_cache($cfg['datadir'] . '/cache/recent-posts');
		rm_cache($cfg['datadir'] . '/cache/archives');
		
		header("Location: " . $_SESSION['lastpage']);
		exit;
	}
}

// Publish a post.

elseif (!empty($_POST['publish']) && $postid) {
	$query_params = array ( 'postid' => 'int' );
	$results = db_query("SELECT categories FROM posts WHERE id=?");
	$post = db_getdata($results);
	if ($post['categories']) {
		// Insert this post into categories and update categories counts
		$catlist = explode(' ', $post['categories']);
		foreach ($catlist as $catid) {
			$query_params = array ( 'postid' => 'int', 'catid' => 'int' );
			db_query("INSERT INTO categorized (postid, catid) VALUES (?, ?)");
			$query_params = array ( 'catid' => 'int' );
			db_query("UPDATE categories SET postcount=postcount+1 WHERE id=?");
		}
		
		// Update archives
		$now = time();
		$year = date('Y', $now);
		$month = date ('n', $now);
		$query_params = array ( 'year' => 'int', 'month' => 'int' );
		$results = db_query("SELECT id FROM archives WHERE year=? AND month=?");
		$row = db_getdata($results);
		$archid = $row['id'];
		if (!empty($archid)) {
			// Update existing entry.
			$query_params = array ( 'year' => 'int', 'month' => 'int' );
			db_query("UPDATE archives SET postcount=postcount+1 WHERE year=? AND month=?");
		}
		else {
			// Create new entry.
			$query_params = array ( 'year' => 'int', 'month' => 'int' );
			db_query("INSERT INTO archives (year, month, postcount) VALUES (?, ?, '1')");
			$archid = $db->lastInsertRowID();
		}
		
		// Set this post as published
		$archym = $year . '-' . $month;
		$query_params = array (
			'now'    => 'int',
			'archym' => 'txt',
			'postid' => 'int'
		);
		db_query("UPDATE posts SET status='1', stamp=?, arch=? WHERE id=?");
		$query_params = array( 'nonce' => 'txt', 'noncestamp' => 'int' );
		db_query("INSERT INTO nonces (nonce, type, stamp) VALUES (?, 'p_admin', ?)");

		rm_cache($cfg['datadir'] . '/cache/recent-posts');
		rm_cache($cfg['datadir'] . '/cache/archives');
		
		header("Location: ./?t=$postid");
		exit;
	}
}

// Save a post.

elseif (!empty($_POST['save']) || !empty($_POST['savedraft']) || !empty($_POST['saveretracted'])) {
	$now = time();
	$year = date('Y', $now);
	$month = date ('n', $now);
	$error = '';
	$status = 1;
	
	if (!empty($_POST['savedraft'])) {
		$status = 2;
	}
	elseif (!empty($_POST['saveretracted'])) {
		$status = 3;
	}
	
	$postbody = $_POST['postbody'];
	$postbody = preg_replace("/\r\n|\r/", "\n", $postbody);
	
	// Find and comment-out the excerpt marker.
	if ( preg_match ("/\n--\n/", $postbody) ) {
		$postbody = preg_replace("/\n--\n/", "\n<!-- -mark- -->\n", $postbody, 1);
	}
	
	$postbody = clean_blogpost($postbody, '2');
	$posttitle = clean_blogpost($_POST['posttitle'], '1');
	$newcat = clean_blogpost($_POST['newcat'], '1');
	
	// Put the category checks into a stored array.
	
	while (list ($key, $val) = each ($_POST)) {
		if (substr($key, 0, 4) == 'cat-') {
			$stored[$key] = $val;
		}
	}
	
	if (empty($posttitle)) {
		$error .= "<li>" . $lang['titlereq'] . "</li>\n";
	}
	if (empty($postbody)) {
		$error .= "<li>" . $lang['textreq'] . "</li>\n";
	}
	if (empty($stored) && empty($_POST['newcat'])) {
		$error .= "<li>" . $lang['catreq'] . "</li>\n";
	}
	
	if ($error) {
		$page['error'] = "\n<div id='error_box'>\n<div class='error_title'>".$lang['errors']."</div>\n<ol>\n$error</ol>\n</div>\n";
	}
	else {
	
		// Proceed to save data.
		// Put category ids into space-separated format for storage in posts table.
		
		foreach ($stored as $catid => $val) {
			$categories .= "$val ";
		}
		$categories = trim($categories);
		
		// Create a new category.
		
		if ($_POST['newcat']) {
			// If it exists, skip creation.
			$query_params = array( 'newcat' => 'txt' );
			$results = db_query("SELECT id FROM categories WHERE catname=?");
			$cat = db_getdata($results);
			if (empty($cat['id'])) {
				$query_params = array( 'newcat' => 'txt' );
				db_query("INSERT INTO categories (catname,postcount) VALUES (?,'0')");
				$newcatid = $db->lastInsertRowID();
			}
			else {
				$newcatid = $cat['id'];
			}
			$stored['cat-'.${newcatid}] = $newcatid;
			$categories .= " $newcatid";
			$categories = ltrim($categories);
		}

		if ($postid) {
		
			// Editing an existing post.
			// Get current category assignments for later comparison.
			
			$query_params = array( 'postid' => 'int' );
			$results = db_query("SELECT categories,stamp,status,arch FROM posts WHERE id=?");
			$old = db_getdata($results);
			$oldcategories = $old['categories'];
			$oldstatus = $old['status'];
			$arch = $old['arch'];
			$stamp = $old['stamp'];
			
			// If status is changing from draft to published, (a) set a new stamp, (b) update archives.
			
			if ($oldstatus > 1 && $status == 1) {
				
				$stamp = $now;
				$arch = $year . '-' . $month;
				
				// update archives.

				$query_params = array( 'year' => 'int', 'month' => 'int' );
				$results = db_query("SELECT id FROM archives WHERE year=? AND month=?");
				$row = db_getdata($results);
				$archid = $row['id'];
				if ($archid) {
					// Update existing entry.
					$query_params = array( 'year' => 'int', 'month' => 'int' );
					db_query("UPDATE archives SET postcount=postcount+1 WHERE year=? AND month=?");
				}
				else {
					// Create new entry.
					$query_params = array( 'year' => 'int', 'month' => 'int' );
					db_query("INSERT INTO archives (year, month, postcount) VALUES (?, ?, '1')");
					$archid = $db->lastInsertRowID();
				}
				
			}
			
			// Or if we're re-saving a draft, update the timestamp.
			
			elseif ( ($oldstatus == $status) && $status == '2' ) {
				$stamp = $now;
			}
			
			// Update the posts table and delete all entries in categorized table.
			
			$query_params = array (
				'status'     => 'int',
				'stamp'      => 'int',
				'arch'       => 'txt',
				'categories' => 'txt',
				'posttitle'  => 'txt',
				'postbody'   => 'txt',
				'postid'     => 'int'
			);
			db_query("UPDATE posts SET status=?, stamp=?, arch=?, categories=?, title=?, body=? WHERE id=?");
			$query_params = array( 'postid' => 'int' );
			db_query("DELETE FROM categorized WHERE postid=?");

			rm_cache($cfg['datadir'] . '/cache/excerpt-' . $postid);
		}
		
		else {
		
			// Adding a new post.
			// Create entry in posts table and get the new id.
			
			$archym = $year . '-' . $month;
			$query_params = array (
				'now'        => 'int',
				'status'     => 'int',
				'archym'     => 'txt',
				'categories' => 'txt',
				'posttitle'  => 'txt',
				'postbody'   => 'txt'
			);
			db_query("INSERT INTO posts (stamp, status, arch, categories, title, body, comcount) VALUES (?, ?, ?, ?, ?, ?, '0')");
			$postid = $db->lastInsertRowID();
			
			// Update or create new entry in archives table.
			
			if ($status == 1) {

				$query_params = array( 'year' => 'int', 'month' => 'int' );
				$results = db_query("SELECT id FROM archives WHERE year=? AND month=?");
				$row = db_getdata($results);
				$archid = $row['id'];
				if (!empty($archid)) {
					// Update existing entry.
					$query_params = array( 'year' => 'int', 'month' => 'int' );
					db_query("UPDATE archives SET postcount=postcount+1 WHERE year=? AND month=?");
				}
				else {
					// Create new entry.
					$query_params = array( 'year' => 'int', 'month' => 'int' );
					db_query("INSERT INTO archives (year, month, postcount) VALUES (?, ?, '1')");
					$archid = $db->lastInsertRowID();
				}

			}
		}
		
		
		if ($status == 1) {
			
			// Create entries in categorized table. If a new post, increment postcount for categories.
			
			foreach ($stored as $key => $catid) {
				$query_params = array( 'postid' => 'int', 'catid' => 'int' );
				db_query("INSERT INTO categorized (postid, catid) VALUES (?, ?)");

				if ($oldstatus > 1 || !$_POST['postid']) {
					$query_params = array( 'catid' => 'int' );
					db_query("UPDATE categories SET postcount=postcount+1 WHERE id=?");
				}
			}
			
			// Update postcounts in the categories table after (a) editing a post and changing categories or (b) changing status from draft to published..
			
			if ( $postid && !empty($oldcategories) && ($oldcategories !== $categories) ) {
				$oldlist = explode(' ', $oldcategories);
				$newlist = explode(' ', $categories);
				foreach ($oldlist as $catid) {
					if (!in_array($catid, $newlist)) {
						// Previous category removed.
						$query_params = array( 'catid' => 'int' );
						db_query("UPDATE categories SET postcount=postcount-1 WHERE id=?");
					}
				}
				foreach ($newlist as $catid) {
					if (!in_array($catid, $oldlist)) {
						// New category added.
						$query_params = array( 'catid' => 'int' );
						db_query("UPDATE categories SET postcount=postcount+1 WHERE id=?");
					}
				}
			}
		
		}

		$query_params = array( 'nonce' => 'txt', 'noncestamp' => 'int' );
		db_query("INSERT INTO nonces (nonce, type, stamp) VALUES (?, 'p_admin', ?)");

		rm_cache($cfg['datadir'] . '/cache/recent-posts');
		rm_cache($cfg['datadir'] . '/cache/archives');
		
		header("Location: " . $_SESSION['lastpage'] . '#post_' . $postid);

		exit;

	}

}

// Load data for editing a post.

elseif ($postid) {
	$query_params = array( 'postid' => 'int' );
	$results = db_query("SELECT title, status, categories, body FROM posts WHERE id=?");
	$post = db_getdata($results);
	if (stristr($post['categories'], ' ')) {
		$list = explode(' ', $post['categories']);
		foreach ($list as $catid) {
			$stored['cat-'.$catid] = $catid;
		}
	}
	else {
		$stored['cat-'.$post['categories']] = $post['categories'];
	}
	$poststatus = $post['status'];
	$posttitle = htmlspecialchars($post['title']);
	$postbody = $post['body'];
	
	// Decode any encoded <code> blocks.
	if ( stristr($postbody, '<code>') ) {
		$postbody = decode_code($postbody);
	}
	
	// Find and uncomment the excerpt marker.
	if ( preg_match ("/\n<!-- -mark- -->\n/", $postbody) ) {
		$postbody = preg_replace("/\n<!-- -mark- -->\n/", "\n--\n", $postbody, 1);
	}
	
	$postbody = htmlspecialchars($postbody);

}

// Build the category checks.

$query_params = '';
$results = db_query("SELECT categories.id, categories.catname FROM categories ORDER BY catname");

$catchecks = '';
while ($row = db_getdata($results)) {
	$catid = $row['id'];
	$catname = $row['catname'];
	$chk = '';
	if (!empty($stored['cat-'.$catid])) {
		$chk = 'checked';
	}
	$catchecks .= "<div class='cat'><label><input type='checkbox' name='cat-$catid' value='$catid' $chk> $catname</label></div>\n";
}
$catchecks = "<div class='cattitle'>Categories</div>\n$catchecks";

// Build a nonce if one hasn't been passed from previous submission.

if ( empty($nonce) ) {
	$noncestamp = time();
	$nonce = sha1( $noncestamp . $_SERVER['REMOTE_ADDR'] . $cfg['noncesalt'] );
}

if (empty($posttitle)) {
	$posttitle = '';
}
if (empty($postbody)) {
	$postbody = '';
}
if (empty($newcat)) {
	$newcat = '';
}
if (empty($poststatus)) {
	$poststatus = '';
}

$page['cssfile'] = 'themes/' . $cfg['theme'] . '/admin.css';
$page['pagetitle'] = $lang['newpost'];
$page['infobar'] = "<div class='infobar'>" . $lang['newpost'] . "</div>";
$page['textlabel'] = $lang['text'];
$page['titlelabel'] = $lang['title'];
$page['posttitle'] = $posttitle;
$page['postbody'] = $postbody;
$page['newcat'] = $newcat;
$page['postid'] = $postid;
$page['nonce'] = $nonce;
$page['stamp'] = $noncestamp;
$page['savedraft'] = '';
$page['savelabel'] = $lang['save'];
if (!$postid || $poststatus == 2) {
	$page['savelabel'] = $lang['savepublish'];
	$page['savedraft'] = "<input type='submit' name='savedraft' value='" . $lang['savedraft'] . "'>";
}
elseif ($poststatus == 3) {
	$page['savelabel'] = $lang['savepublish'];
	$page['savedraft'] = "<input type='submit' name='saveretracted' value='" . $lang['saveretracted'] . "'>";
}
$page['categories'] = $catchecks;
$page['contentclass'] = 'post';
$page['navbottom'] = "<ul class='adminnav'><li><a href='./'>Home</a></li>\n$adminnav</ul>\n";

if ($postid) {
	$page['pagetitle'] = $lang['editpost'];
	$page['infobar'] = "<div class='infobar'>" . $lang['editpost'] . "</div>";
}

if (empty($error)) {
	$page['onload'] = "onload='document.commentform.posttitle.focus();'";
}
else {
	if (empty($posttitle)) {
		$page['onload'] = "onload='document.commentform.posttitle.focus();'";
	}
	elseif (empty($postbody)) {
		$page['onload'] = "onload='document.commentform.postbody.focus();'";
	}
}
$subtemplate = file_get_contents('themes/' . $cfg['theme'] . '/templates/sub_post.tpl');
$template = file_get_contents('themes/' . $cfg['theme'] . '/templates/main.tpl');
$template = str_replace("#maincontent#", $subtemplate, $template);
foreach ($page as $key => $val) {
	$template = str_replace("#${key}#",$val,$template);
}
echo $template;
exit;


function clean_blogpost($text, $type) {
	if (get_magic_quotes_gpc()) {
		$text = stripslashes($text);
	}
	if ($type == '1') {
		$text = strip_tags($text);
	}
	elseif ($type == '2') {
		
		// Apply htmlentities() within any <code> blocks.
		if ( stristr($text, '<code>') ) {
			$text = encode_code($text);
		}
	
		// Put the text through the PHP DOM.
		if (extension_loaded('dom')) {
			$text = dom_it($text);
		}

		// Isolate comments on their own line - INCL. THE EXCERPT MARKER.
		// PHP DOM will sometimes collapse consecutive lines with html tags.
		$text = str_replace("><!-- ", ">\n<!-- ", $text);
		$text = str_replace(" --><", " -->\n<", $text);
		
		// Tweaks for code readibility.
		$text = pretty_code($text);
		
	}
	
	$text = trim($text);
	return $text;
}

function pretty_code($text) {
	
	// Add a newline after block-level closing tags.
	$tags = array ( '/div', '/p', '/pre', '/ul', '/ol', '/li', 'br', 'hr' );
	foreach ($tags as $tag) {
		$text = str_replace('<'.$tag.'><', '<'.$tag.">\n<", $text);
	}

	// Add a newline after select block-level tags (removed by PHP DOM).
	// These replacements should become RE's to allow for tag attributes.
	$tags = array ( 'ul', 'ol' );
	foreach ($tags as $tag) {
		$text = str_replace('<'.$tag.'><', '<'.$tag.">\n<", $text);
	}
	return $text;
	
}
?>
Return current item: Blite