<?php
/*
 * blogs class - provides functions for blogs
 */

// Some useful validation functions
require_once("validation.lib.php");
// random other functions that aren't validation or db related
require_once("miscfunctions.lib.php");
//stuff from blog.lib will be useful
require_once("blog.lib.php");

//Our Blogs Class
class admin {
	//Blog ID
	var $id;
	//Blogger's Details
	var $userName;
	var $realName;
	//Errors
	var $error;
	//Date formats
	var $shortDateFormat;
	var $longDateFormat;
	//Paths
	var $httpPath;
	var $adminPath;
	var $blogPath;
	var $basePath;
	//[temporary] holder for instance of blog class
	var $blog;
			
	//Constructor - checks we've been given a valid username, and pulls in generic blog info
	function admin() 
	{
		global $session, $BlogDB, $baseurl;

		//set the error string first, so we dont wipe out any errors
		$this->error = '';
		//set the locale
		setlocale(LC_ALL, 'en_GB');
		//pull in the session stuff
		$this->startSession();
		//setup our environment
		$this->userName = $session->username;
		$this->realName = $session->fullname;

		$this->id = $BlogDB->GetOne("select id from users where username='".$this->userName."'");

		$this->shortDateFormat = "Y-m-d";
		$this->longDateFormat = "r";
		$this->httpPath = $baseurl."/Blogs/";
		$this->adminPath = $this->httpPath."Admin/";
		$this->basePath = $baseurl."/Blogs/";
		if($this->httpPath[strlen($this->httpPath)-1]!="/") {
			$this->httpPath .= "/";
		}
		//if we are logged in start a blog instance, and setup the blog path
		if ($this->userName) {
			$this->blog = new blogs($this->userName);
			$this->blogPath = $this->basePath.$this->userName."/";
		}
	}
	
	//start / check our session
	function startSession() 
	{
		//set the session time out in seconds
		$maxSessionAge = 10800; //1 hour
		//setup the session stuff
		session_name("BlogSession");
		session_set_cookie_params($maxSessionAge,dirname($_SERVER['SCRIPT_NAME'])."/");
		session_start();
		//if we dont have a session, start one
		if (!$_SESSION[time]) {
			$_SESSION[time] = time();
		}
		//close the session if its too old
		elseif ((time()-$_SESSION[time]) > $maxSessionAge) {
			session_unset();
			$this->error =_("Session Expired");
			$this->startSession();
		}
		//else we are happy, and we just update the session time
		else {
			$_SESSION[oldTime] = $_SESSION[time];
			$_SESSION[time] = time();
		}
	}
	
	//logs people in
	function login() 
	{		
		global $BlogDB, $smarty;
		$username = "";
		$password = "";
		//sanitise username
		if (isset($_POST['username']) && trim($_POST['username']) != "" && safeuname(trim($_POST['username']))) {
			$username = trim($_POST['username']);
		} 
		else {
			$this->error = _("Please check the username field");
		}
		//sanitise password
		if (isset($_POST['password']) && trim($_POST['password']) != "") {
			$password = trim($_POST['password']);
		} 
		else {
			$this->error = _("Please check the password field");
		}
		//no errors?
		if(!$this->error)
		{
			//try to pull in the users details
			$sqlRow = $BlogDB->GetRow("SELECT id, name, password from users where enabled = true and username = '".$username."' limit 1;");

			//check we returned a user
			if (!$sqlRow) {
				$this->error =_("Invalid Username or Password");
			}
			else	{
				//check the password the user gave us agaisnt the one in the database
				if ($sqlRow['password']!=crypt($password, $sqlRow['password'])) {
					$this->error =_("Invalid Username or Password");				
				}
				else {
					//if everything matches dump some persistant details into the session
					$_SESSION['id'] = $sqlRow['id'];
					$_SESSION['userName'] = $username;
					$_SESSION['realName'] = $sqlRow['name'];
					$this->id = $_SESSION['id'];
					$this->userName = $_SESSION['userName'];
					$this->realName = $_SESSION['realName'];
				}
			}
		}
		//return a state to indicate wether login was successful
		if ($this->error) {
			return false;
		}
		else {
			return true;
		}
	}
	
	//admin menu
	function menu() {
		global $BlogDB, $smarty, $session;

		$submenu = array();
		if (blogger($session->username)) {
			$submenu[_("My blog")] = $this->blogPath;
			$submenu[_("Write new entry")] = $this->adminPath."newentry";
			$submenu[_("Edit entries")] = $this->adminPath."showentries";
			$submenu[_("Settings")] = $this->adminPath."Settings";

			$comments = _("Comments");
			$result = $BlogDB->GetOne("SELECT count(comments.id) from comments join entries on comments.post = entries.id where moderated = false and entries.user_id = ".$this->id.";");
			if($result){
				$comments .= " (".$result.")";
				}
			$submenu[$comments] = $this->adminPath."moderatecomments";
		} else {
			$submenu[_("Start a Blog")] = $this->adminPath."signup";
		}

		$menu = $smarty->get_template_vars("menu");
		$menu[Blogs] = $submenu;
		$smarty->assign("menu", $menu);
	}
	
	//destroys the session
	function logout () 
	{
		session_unset();
		header("Location: ".$this->blogPath);
	}
	
	//prints a login form
	function printLoginForm() 
	{
		echo "The Login Form display function has been called. This should not happen.";
	}

	// post an entry to the db
	function postEntry()
	{
		global $BlogDB;
		$category = '';
		$subject = '';
		$body = '';
		//sanitise category (make sure it IS a number!)
		if (isset($_POST['category']) && (int)$_POST['category'] != "" && (int)$_POST['category'] != 0) {
			$category = (int)$_POST['category'];
		} else {
			$this->error = _("Undefined Category!");
		}
		//sanitise subject
		if (isset($_POST['subject']) && trim($_POST['subject']) != "") {
			//complain if the subject contains html or html like things rather than dumping it without warning
			if (strip_tags($_POST['subject']) != $_POST['subject']) {
				$this->error = _("HTML is not allowed in the subject!");			
			}
			else {
				$subject = addslashes(trim($_POST['subject']));
			}
		} else {
			$this->error = _("No entry subject!");
		}		
		//sanitise body
		if (isset($_POST['body']) && trim($_POST['body']) != "") {
			$body = trim($_POST['body']);
			//we dont want to use nl2br if peeps are useing tinymce
			if (!$this->blog->editor) {
				$body = nl2br($body);
			}
			$body = addslashes($body);
		} else {
			$this->error = _("No entry body!");
		}
		//no errors, so continue..
		if (!$this->error) {
			//first we make our short subject
			$shortsubject = $this->blog->makeCleanString($subject,true);
			//need to check if there are any short titles like this one already
			$sql = $BlogDB->GetAll("SELECT shortsubject FROM entries WHERE user_id = {$this->id} AND shortsubject ~ '{$shortsubject}(_[0-9]{1,3}$|$)' ORDER BY char_length(shortsubject) DESC, shortsubject DESC LIMIT 1;");
			//if so we grab the last one, and add 1 to it..
			if (count($sql) != 0) {
				$sqlRow = array_shift($sql);
				// Put the matched _number into $matches[0] if there is one
				if (preg_match("/\_[0-9]{1,3}$/",$sqlRow['shortsubject'],$matches)) {
					// Remove the _ to get the number, add 1 and append
					$shortsubject .= '_' . ((int)substr($matches[0],1) + 1);
				} else {
					$shortsubject .= '_1';
				}
			}
			//shortsubject is now safe..
			//insert our new entry
			$sql = $BlogDB->Execute("INSERT INTO entries (category, subject, body, user_id, shortsubject) VALUES ({$category},'{$subject}','{$body}','{$this->id}','{$shortsubject}')");
			if (!$sql) {
				error(2,_("Database commit failed")." - ".$BlogDB->ErrorMsg());
			} 
			else {
				// $row = db_last($sql, "entries");
				$row = $BlogDB->GetRow("SELECT * FROM entries WHERE user_id = {$this->id} AND shortsubject='".$shortsubject."'");
				$this->blog->printEntry($row,false,false);
			}
		}
		//re-display entry form if there are errors
		else {
			$this->printEntryForm($_POST,true);
		}	
	}
	
	//update an entry in the db
	function updateEntry($shortSubject)
	{		
		global $BlogDB;
		$category = '';
		$subject = '';
		$body = '';		
		//sanitise and check for existance of a short subject
		$shortSubject = $this->blog->makeCleanString($shortSubject);
		if (!$shortSubject) {
			error(4,_("If you dont give me a post how do you expect me to update it"));
		}
		//sanitise category (make sure it IS a number!)
		if (isset($_POST['category']) && (int)$_POST['category'] != "" && (int)$_POST['category'] != 0) {
			$category = (int)$_POST['category'];
		} else {
			$this->error = _("Undefined Category!");
		}
		//sanitise subject
		if (isset($_POST['subject']) && trim($_POST['subject']) != "") {
			//complain if the subject contains html or html like things rather than dumping it without warning
			if (strip_tags($_POST['subject']) != $_POST['subject']) {
				$this->error = _("HTML is not allowed in the subject!");			
			}
			else {
				$subject = addslashes(trim($_POST['subject']));
			}
		} else {
			$this->error = _("No entry subject!");
		}		
		//sanitise body
		if (isset($_POST['body']) && trim($_POST['body']) != "") {
			$body = trim($_POST['body']);
			//we dont want to use nl2br if peeps are useing tinymce
			if (!$this->blog->editor) {
				$body = nl2br($body);
			}
			$body = addslashes($body);
		} else {
			$this->error = _("No entry body!");
		}

		//no errors, so continue..
		if (!$this->error) {
			//check to see this post exists
			$sql = $BlogDB->GetRow("SELECT id from entries where shortsubject = '".$shortSubject."' AND user_id='".$this->id."';");
			//yes?, we can update it then..
			if ($sql) { 
				$sql = $BlogDB->Execute("UPDATE entries SET category = {$category}, subject = '{$subject}', body = '{$body}' WHERE shortsubject = '{$shortSubject}' AND user_id = '".$this->id."';");
				if (!$sql) {
					error(2,_("Database commit failed - ").$BlogDB->ErrorMsg());
				} 
				else {
					echo "<div class=\"updateinfo\">"._("Updated!")."</div>\n";
					$this->updateForm($shortSubject);
				}
			}
			//cant update non-existant entrys
			else {
				 error(2,_("Cannot update entry, as it does not exist.".$BlogDB->ErrorMsg()));
			}
		}
		//redisplay entry form if there are errors
		else {
			$this->updateForm($shortSubject);
		}
	}

	//update form
	function updateForm($shortSubject)
	{
		global $BlogDB;
		//sanitise and check the short subject
		$shortSubject = $this->blog->makeCleanString($shortSubject);
		if (!$shortSubject) {
			error(4,_("If you dont give me a post how do you expect me to decide which one you want to edit?"));
		}
		//try to grab the post
		$row = $BlogDB->GetRow("SELECT subject, category, body, shortsubject from entries where shortsubject = '".$shortSubject."' AND user_id = '".$this->id."';");
		//if it exists we can do stuff with it
		if ($row) { 
			$this->printEntryForm($row,true,true);
		} 
		//else give an error
		else {
			error(2, _("Could not find the requested entry."));
		}
	}
/*	currently not used.. if we dont want to bring back the delete link in printEntry from blog.lib we can get rid of this entirely
	
	//delete an entry
	function deleteEntry($shortSubject)
	{
		//sanitise the short subject
		$shortSubject = $this->blog->makeCleanString($shortSubject);
		if (!$shortSubject) {
			error(4,_("If you dont give me a post how do you expect me to delete it"));
		}
		//check to see this post exists
		$sql = db_query("SELECT id from entries where shortsubject = '".$shortSubject."' AND user_id='".$this->id."';");
		$sqlNum = db_num_rows($sql);
		//yes?, we can delete it then..
		if ($sqlNum == 1) { 
			db_query("DELETE FROM entries WHERE shortsubject = '{$shortSubject}' AND user_id = '".$this->id."';");			
			echo "<p>"._("Entry deleted.")."</p>";
		}
		//can't delete non-existant entries
		else {
			 error(2,_("Cannot delete entry, as it does not exist.".db_error()));
		}
	}
*/
	//update settings
	function updateSettings()
	{
		global $BlogDB;
		$name = '';
		$title = '';
		$description = '';
		$css = 'blog.css';
		$password = "";
		//sanitise name
		if (isset($_POST['name']) && trim($_POST['name']) != "") {
			$name = addslashes(trim(strip_tags($_POST['name'])));
		} 
		else {
			$this->error = _("Bad Input - Realname");
		}
		//sanitise title
		if (isset($_POST['btitle']) && trim($_POST['btitle']) != "") {
			//complain if the title contains html or html like things rather than dumping it without warning
			if (strip_tags($_POST['btitle']) != $_POST['btitle']) {
				$this->error = _("HTML is not allowed in the title!");			
			}
			else {
				$title = addslashes(trim($_POST['btitle']));
			}
		} 
		else {
			$this->error = _("Bad Input - Title");
		}
		//sanitise description
		if (isset($_POST['description']) && trim($_POST['description']) != "") {
			//complain if the description contains html or html like things rather than dumping it without warning
			if (strip_tags($_POST['description']) != $_POST['description']) {
				$this->error = _("HTML is not allowed in the description!");			
			}
			else {
				$description = addslashes(trim($_POST['description']));
			}
		}
		else {
			$this->error = _("Bad Input - Description");
		}
		//sanitise css
		if (isset($_POST['css'])) { // if its not set its defaulted...
// It's no use checking if the css file exists in this version at present
//			if (trim($_POST['css']) != "" && is_file($_POST['css'])) {
			if (trim($_POST['css']) != "") {
				$css = $_POST['css'];
			} 
			else {
				$this->error = _("Bad Input - CSS location");
			}
		}
		//sanitise password and encrypt
		if ($_POST['pass1']) {
			if ((isset($_POST['pass1']) && trim($_POST['pass1']) != "") && ($_POST['pass1']==$_POST['pass2'])) {
				$password = crypt($_POST['pass1']);
			} 
			else {
				$this->error = _("Bad Input - Password");
			}
		}
		// checkbox for comment moderation, either is or isnt
		if ($_POST['moderate'] != "") {
			$moderate = "true";
		}
		else {
			$moderate = "false";
		}	
		// checkbox for editor, either is or isnt
		if ($_POST['editor'] != "") {
			$editor = "true";
		} 
		else {
			$editor = "false";
		}
		//if there are no errors
		if (!$this->error) {
			//construct the query
			$query = "UPDATE USERS SET name='{$name}', title='{$title}', description='{$description}', css='{$css}', moderate={$moderate}, editor={$editor}";
			//if the password is set add that too
			if ($password) {
				$query .= ", password='{$password}'";
			}
			$query .= " WHERE username='{$this->userName}';";
			//execute query
			if (!$BlogDB->Execute($query)) {
				error(2,_("Database Insertion failed."));
			} 
			//it it worked report sucsess
			else {
				echo "<div class=\"updateinfo\">"._("Blog settings updated.")."</div>\n";
			}
		} 
		//return the form, this also returns the errors if they exist
		$this->printSettingsForm();
	}
	
	//print the blog Entry form...
	//used for both new and edit
	function printEntryForm($row='',$show=false,$edit=false)
	{
		global $BlogDB;
		echo "<div class=\"entry\">\n";
		if ($this->error) {
			echo "<div class=\"errorinfo\">Error : " . $this->error . "</div>\n";
		}
		echo "<h2>".((!$edit) ?_("Write Entry") : _("Edit Entry"))."</h2>\n";
		echo "<form action=\"".$this->adminPath.((!$edit) ? "postentry" : "postupdate/{$row['shortsubject']}")."\" method=\"post\" id=\"entryform\">\n";
		echo "<div class=\"row\">\n";
		echo "<label for=\"subject\">"._(Subject)."</label>\n";
		echo "<span class=\"textinput\"><input type=\"text\" name=\"subject\" id=\"subject\" value=\"" . (($show) ? htmlentities(strip_tags(trim($row['subject']))) : "") . "\" style=\"width: 100%;\" maxlength=\"100\" tabindex=\"1\" /></span>\n";
		echo "</div>\n";
		echo "<div class=\"row\">\n";
		echo "<label for=\"category\">"._("Category")."</label>\n";
		echo "<span class=\"textinput\"><select name=\"category\" id=\"category\" tabindex=\"2\">";
		//pull in the list of catogories from the database
		$sql = $BlogDB->GetAll("SELECT id, name FROM categories ORDER BY name ASC;");
		while ($sqlRow = array_shift($sql)) {
			echo "<option value=\"{$sqlRow['id']}\"".(((int)$row['category'] == $sqlRow['id']) ? " selected=\"selected\"" : "").">{$sqlRow['name']}</option>\n";
		}
		echo "</select></span>\n";
		echo "</div>\n";
		echo "<div class=\"row\">\n";
		echo "<label for=\"body\">Body</label>\n";
		echo "<span class=\"textinput\"><textarea name=\"body\" id=\"body\" tabindex=\"3\" style=\"width: 100%; height: 30em;\">";
		if ($show) {
		//we dont want to use br2nl if peeps are using tinymce
			if (!$this->blog->editor) {
				echo "<![CDATA[".br2nl($row['body'])."]]>";
			}
			else {
				echo htmlentities($row['body'], ENT_QUOTES, "UTF-8");
			}
		}
		echo "</textarea></span>\n";
		echo "</div>\n";
		echo "<div class=\"row\">\n";
		echo "<span class=\"textinput\"><input name=\"submit\" type=\"submit\" id=\"submit\" tabindex=\"4\" value=\"Submit Entry\" /></span>\n";
		echo "</div>\n<div class=\"clear\"></div>\n";
		echo "</form>\n";
		echo "</div>\n";
	}

	//print the blog settings form...
	function printSettingsForm()
	{
		global $BlogDB;
		//pull in user's current settings from the database
		$settings = $BlogDB->GetRow("SELECT name, title, description, css, moderate, editor FROM users WHERE username='" . $this->userName . "'");
		echo "<div class=\"entry\">\n";
		if ($this->error) {
			echo "<div class=\"errorinfo\">Error : " . $this->error . "</div>\n";
		}
		echo "<h2>"._("Blog Settings")."</h2>\n";
		echo "<form action=\"".$this->adminPath."Settings\" method=\"post\" id=\"settingsform\">\n";
		echo "<div class=\"row\">\n";
		echo "<label for=\"name\">"._("Real name")."</label>\n";
		echo "<span class=\"textinput\"><input type=\"text\" name=\"name\" id=\"name\" value=\"" . $settings['name'] . "\" size=\"30\" maxlength=\"60\" tabindex=\"1\" /></span>\n";
		echo "</div>\n";
		echo "<div class=\"row\">\n";
		echo "<label for=\"btitle\">"._("Title")."</label>\n";
		echo "<span class=\"textinput\"><input type=\"text\" name=\"btitle\" id=\"btitle\" value=\"" . $settings['title'] . "\" size=\"30\" maxlength=\"60\" tabindex=\"2\" /></span>\n";
		echo "</div>\n";
		echo "<div class=\"row\">\n";
		echo "<label for=\"description\">"._("Description")."</label>\n";
		echo "<span class=\"textinput\"><input type=\"text\" name=\"description\" id=\"description\" value=\"" . $settings['description'] . "\" size=\"30\" maxlength=\"60\" tabindex=\"3\" /></span>\n";
		echo "</div>\n";
		echo "<div class=\"row\">\n";
		echo "<label for=\"css\">"._("CSS")."</label>\n";
		echo "<span class=\"textinput\"><input type=\"text\" name=\"css\" id=\"css\" value=\"" . $settings['css'] . "\" size=\"30\" maxlength=\"255\" tabindex=\"4\" /></span>\n";
		echo "</div>\n";
		echo "<div class=\"row\">\n";
		echo "<label for=\"moderate\">"._("Moderate new comments")."</label>\n";
		echo "<span class=\"textinput\"><input type=\"checkbox\" name=\"moderate\" id=\"moderate\" ".(($settings['moderate']=="t") ? "checked=\"checked\"" : "")." /></span>\n";
		echo "</div>\n";
		echo "<div class=\"row\">\n";
		echo "<label for=\"editor\">"._("Enable HTML editor")."</label>\n";
		echo "<span class=\"textinput\"><input type=\"checkbox\" name=\"editor\" id=\"editor\" ".(($settings['editor']=="t") ? "checked=\"checked\"" : "")." /></span>\n";
		echo "</div>\n";
/*		echo "<div class=\"row\">\n";
		echo "<label for=\"pass1\">"._("Password")."</label>\n";
		echo "<span class=\"textinput\"><input type=\"password\" name=\"pass1\" id=\"pass1\" value=\"\" size=\"15\" maxlength=\"16\" tabindex=\"5\" /></span>\n";
		echo "</div>\n";
		echo "<div class=\"row\">\n";
		echo "<label for=\"pass2\">"._("Again")."</label>\n";
		echo "<span class=\"textinput\"><input type=\"password\" name=\"pass2\" id=\"pass2\" value=\"\" size=\"15\" maxlength=\"16\" tabindex=\"6\" /></span>\n";
		echo "</div>\n"; */
		echo "<div class=\"row\">\n";
		echo "<span class=\"textinput\"><input name=\"submit\" type=\"submit\" id=\"submit\" tabindex=\"4\" value=\"Save Settings\" /></span>\n";
		echo "</div>\n";
		echo "<div class=\"clear\"></div>\n";
		echo "</form>\n";
		echo "</div>\n";	
	}
	//shows unmoderated comments
	function printComments() {
		global $BlogDB;
		//grab all unmoderated comments
		$result = $BlogDB->GetAll("SELECT comments.*, entries.shortsubject from comments join entries on comments.post = entries.id where moderated = false and entries.user_id = ".$this->id." ORDER BY entries.subject ASC;");
		if(count($result)==0) {
			return;
		}
		echo "<div class=\"entry\">\n";
		echo "<h2>Comments Pending Approval</h2>\n";
		echo "<p>The comments in red are probably spam. They are premarked to be deleted for your convience.</p>\n";
		echo "<form action=\"{$this->adminPath}updatecomments/\" method=\"post\">\n";
		echo "<table class=\"td\">\n";
		$post = '';		
		$count = 0;

		echo "<tfoot>\n\t<tr>\n\t\t<td></td>\n\t\t<td></td>\n\t\t<td></td>\n\t\t<td colspan=\"2\"><input type=\"submit\" value=\"Commit\" name=\"submit\" /></td>\n\t</tr>\n</tfoot>\n";
		echo "<tbody>\n";
		//for each comment
		while($r = array_shift($result)) {
			//if the post has changed
			if ($post != $r['shortsubject']) {
				//grab the post, display it and the subject then some headers
				$internalR = $BlogDB->GetRow("SELECT subject, body from entries where shortsubject = '".$r['shortsubject']."' and user_id = ".$this->id." limit 1;");
				echo "\t<tr>\n";
				echo "\t\t<th colspan=\"4\"><a href=\"{$this->blogPath}entry/{$r['shortsubject']}\">". htmlentities($internalR['subject']) ."</a></th>\n";
				echo "\t</tr>\n";
				echo "\t<tr>\n";
				echo "\t\t<td colspan=\"4\">{$internalR['body']}</td>\n";
				echo "\t</tr>\n";
				echo "\t<tr>\n";
				echo "\t\t<th>Author</th>\n";
				echo "\t\t<th>Body</th>\n";
				echo "\t\t<th>Approve</th>\n";
				echo "\t\t<th>Delete</th>\n";
				echo "\t</tr>\n";
				$post = $r['shortsubject'];
			}
			//how display each of the comments
			if ($r['spam'] == 't') { 
				echo "\t<tr class=\"errorinfo\">\n";
			} else {
				echo "\t<tr>\n";
			}
			echo "\t\t<td><a href=\"mailto:{$r['email']}\" title=\"IP: {$r['host']}\">{$r['name']}</a></td>\n";
			echo "\t\t<td>".htmlentities($r['body'], ENT_COMPAT, UTF-8)."</td>\n";
			echo "\t\t<td><input type=\"radio\" name=\"group[$count]\" value=\"a:{$r['id']}\" /></td>\n";
			if ($r['spam'] == 't') { 
				echo "\t\t<td><input type=\"radio\" name=\"group[".$count++."]\" value=\"d:{$r['id']}\" checked=\"checked\"/></td>\n";
			} else {
				echo "\t\t<td><input type=\"radio\" name=\"group[".$count++."]\" value=\"d:{$r['id']}\" /></td>\n";
			}
			echo "\t</tr>\n";
		}

		echo "</tbody>\n</table>\n";
		echo "</form>\n";
		echo "</div>\n";
	}
	// approve or delete comments
	function updateComments() {
		global $BlogDB;
		if (count($_POST['group'])==0) {
			error(2, _("No comments selected for approval/deletion."));
			return;
		}
		$check = "";
		$approved = "";
		$acount = 0;
		$deleted = "";
		$dcount = 0;
		//get the comment numbers and requested actions.
		foreach($_POST['group'] as $comment) {
			$c = explode(":", $comment);
			if ($c[0] == "a") {
				$approved .= (int)$c[1].", ";
				$acount++;
			} elseif ($c[0] == "d") {
				$deleted .= (int)$c[1].", ";
				$dcount++;
			} else {
				error(1, _("Malformed input."));
				return;
			}
		}
		$approved = substr($approved, 0, -2);
		$deleted = substr($deleted, 0, -2);
		//construct a list of comments to check
		if ($approved and $deleted) {
			$check = $deleted.", ".$approved;
		} else {
			$check = $deleted.$approved;
		}
		//check the comments exist and blong to the user
		$result = $BlogDB->GetRow("SELECT count(comments.id) from comments join entries on comments.post = entries.id where entries.user_id = ".$this->id." and comments.id IN($check);");
		if($result[count] != ($acount + $dcount)) {
			error(1,_("Cant find the requested comments, maybe they have already been deleted."));
			return;
		}
		//delete comments
		if($deleted!="") {
			$BlogDB->Execute("DELETE FROM comments WHERE id IN ($deleted);");
		}
		//set moderated flag on comments
		if($approved!="") {
			$BlogDB->Execute("UPDATE comments SET moderated=true WHERE id IN ($approved);");
		}
		//reprint the form
		echo "<div class=\"updateinfo\">$acount "._("comments approved").", $dcount "._("comments deleted").".</div>\n";
		$this->printComments();
		$this->printAuthorisedUsers();
	}

	//Delete moderated comments from (a single post)
	function deleteComments($entry) {
		global $BlogDB;
		if(isset($_POST['submit'])) {
			if(count($_POST['comment'])==0){
				error(5, _("No comments selected for deletion."));
				echo "<a href=\"{$this->blogPath}entry/$entry\">"._("Return to blog entry")."</a>\n";
			} else {
				$del = "(";
				foreach($_POST['comment'] as $c) {
					$del .= "comments.id = ".(int)$c." OR ";
				}
				$del = substr($del, 0, -4).")";
				//check the comments exist and blong to the user
				$result = $BlogDB->GetOne("SELECT count(comments.id) from comments join entries on comments.post = entries.id where entries.user_id = ".$this->id." and $del;");
				if($result[0] != count($_POST['comment'])) {
					error(1,_("Cant find the requested comments, maybe they have already been deleted."));
					return;
				}
				//delete the comments
				$sql = "DELETE FROM comments WHERE $del";
				if(!$BlogDB->Execute($sql)) {
					error(2, _("Database commit error."));
				} else {
					echo "<div class=\"updateinfo\">".count($_POST['comment'])._(" comment(s) deleted.")."</div>\n";
					echo "<a href=\"{$this->blogPath}entry/$entry\">"._("Return to blog entry")."</a>\n";
				}
			}
		}
	}
	//prints a form populated with email addresses that can avoid moderation on comments
	function printAuthorisedUsers() {
		global $BlogDB;
		echo "<div class=\"entry\">\n";
		echo "<a name=\"emails\"></a>\n";
		echo "<h2>"._("Known Users")."</h2>\n";
		//if comment moderation is off tell the user its a bit daft
		if(!$this->blog->comment_moderation) {
			echo "<p>"._("Comment moderation is turned off on your blog - anyone can post comments. To turn comment moderation on, visit the")." <a href=\"".$this->adminPath."Settings\">"._("settings page")."</a>.</p>\n";
			echo "</div>";
			return;
		}
		echo "<p>"._("Comments posted to your blog with an e-mail address that appears in the list below avoid the moderation queue and appear on your blog immediately.")."</p>\n";
		echo "<p>"._("To turn off comment moderation, visit the")." <a href=\"{$this->adminPath}Settings\">"._("settings page")."</a>.</p>\n";
		echo "<form name=\"emailform\" id=\"emailform\" action=\"".$this->adminPath."updateauthusers\" method=\"post\">\n";
		echo "<select multiple=\"multiple\" name=\"emaillist[]\" size=\"10\">\n";
		$result = $BlogDB->GetAll("SELECT name,email FROM authorised_emails WHERE user_id=".$this->id." ORDER BY email ASC");
		while($r = array_shift($result)) {
			echo "\t<option value=\"{$r['email']}\">{$r['email']} ({$r['name']})</option>\n";
		}
		echo "</select><br />\n";
		echo "<input type=\"submit\" name=\"delete\" value=\"Delete selected\" />\n";
		echo "</form>\n";
		//close and start a new form, so pressing enter in the 2nd bit of the form submits with addnew rather than delete
		echo "<form name=\"emailform\" id=\"emailform\" action=\"".$this->adminPath."updateauthusers\" method=\"post\">\n";
		echo "<h3>"._("Add Address")."</h3>\n";
		echo "<div class=\"row\">\n";
		echo "<label for=\"name\"> "._("Name (not displayed anywhere but here)")."</label>\n";
		echo "<span class=\"textinput\"><input type=\"text\" name=\"name\" id=\"name\" /></span>\n";
		echo "</div>\n";
		echo "<div class=\"row\">\n";
		echo "<label for=\"email\"> "._("E-mail address")."</label>\n";
		echo "<span class=\"textinput\"><input type=\"text\" name=\"email\" id=\"email\" /></span>\n";
		echo "</div>\n";
		echo "<div class=\"row\">\n";
		echo "<span class=\"textinput\"><input type=\"submit\" name=\"addnew\" value=\"Add address\" /></span>\n";
		echo "</div>\n<div class=\"clear\"></div>\n";
		echo "</form>\n";
		echo "</div>\n";
	}
	//udates the list of authorised users.
	function updateAuthorisedUsers($quiet=FALSE) {
		global $BlogDB;
		//hack so we get error returned from validEmail
		global $error;
		//if we have a delete action
		if(isset($_POST['delete'])) {
			if (count($_POST['emaillist'])==0) {
				error(5,_("No addresses selected for deletion."));
			} else {
				$del = "(";
				foreach($_POST['emaillist'] as $addr) {
					if(validEmail($addr)) {
						$del .= "email='$addr' OR ";
					} else {
						error(2,_("Invalid email address : ".$error));
						return;
					}
				}
				$del = substr($del, 0, -4).")";
				$sql = "DELETE FROM authorised_emails WHERE $del AND user_id={$this->id}";
				$ret = $BlogDB->Execute($sql);
				if(!$ret) {
					error(2, _("Database commit error: ").$BlogDB->ErrorMsg());
				} else {
					echo "<div class=\"updateinfo\">"._("Address(es) deleted")."</div>\n";
				}
			}
		} 
		//if we have an add action
		elseif(isset($_POST['addnew'])) {
			if(trim($_POST['name'])=="" or !preg_match("/^([a-z0-9]+([:space:][a-z0-9]*))$/i",trim($_POST['name']))) {
				$this->error = _("Check name");
			}
			if(!validEmail($_POST['email'])) {
				$this->error = _("Invalid e-mail address : ".$error);
			}
			if($this->error==""){
				$name = addslashes(trim($_POST['name']));
				$email = addslashes(trim($_POST['email']));
				$ret = $BlogDB->Execute("INSERT INTO authorised_emails (user_id, name, email) VALUES ('{$this->id}', '{$name}', '{$email}');");
				if(!$ret){
					error(2, $BlogDB->ErrorMsg());
				} else {
					echo "<div class=\"updateinfo\">"._("Address added")."</div>\n";
				}
			}
			else {
				error(3,$this->error);
			}
		}
		if(!$quiet){
			$this->printComments();
			$this->printAuthorisedUsers();
		}
	}
	//prints a list of entries for the admin front page.
	function printEntries($amount=0, $title=TRUE) {
		global $BlogDB;
		$limit = ($amount > 0) ? " LIMIT $amount" : "";
		$result = $BlogDB->GetAll("SELECT shortsubject,timestamp,subject FROM entries WHERE user_id = '".$this->id."' ORDER BY timestamp DESC $limit;");
		if(count($result)==0){
			error(5, _("No entries found."));
		} else {
			if($title){
				echo "<div class=\"entry\"><h2>"._("Edit Entries")."</h2>\n";
			}
			echo "<form action=\"{$this->adminPath}confirmdeleteentries/\" method=\"post\">\n<table class=\"td\">\n\t<tr>\n\t\t<th width=\"38%\">Date</th>\n\t\t<th>Title</th>\n\t\t<th width=\"5%\">Delete</th>\n\t</tr>\n";
			$rownum = 0;
			while($row = array_shift($result)){
				echo "\t<tr>\n";
				echo "\t\t<td>".strftime($this->blog->longDateFormat, strtotime($row['timestamp']))."</td>\n";
				echo "\t\t<td><a href=\"".$this->adminPath."update/".$row['shortsubject']."\">".htmlentities($row['subject'])."</a></td>\n";
				echo "\t\t<td><input type=\"checkbox\" name=\"entry[".$rownum++."]\" value=\"{$row['shortsubject']}\" /></td>\n";
				echo "\t</tr>\n";
			}
			echo "\t<tr>\n";
			echo "\t\t<td colspan=\"3\" align=\"right\"><input type=\"submit\" name=\"submit\" value=\""._("Delete Selected")."\" /></td>\n";
			echo "\t</tr>\n";
			echo "</table>\n";
			echo "</form>\n";
			if($title) {
				echo "</div>\n";
			}
		}
	}
	//confirm entry deletion
	function confirmDeleteEntries() {
		echo "<form action=\"{$this->adminPath}deleteentries/\" method=\"post\">\n";
		echo "<p>"._("Are you sure you want to delete the following entries?")."</p>\n<ul>\n";
		$rownum = 0;
		foreach ($_REQUEST[entry] as $entry) {
			$entry = $this->blog->makeCleanString($entry);
			echo "<input type=\"hidden\" name=\"entry[".$rownum++."]\" value=\"{$entry}\" />";
			echo "<li>".$entry."</li>\n";
		}
		echo "</ul>\n";
		echo "<p><input type=\"submit\" name=\"submit\" value=\""._("Yes")."\" />\n<input type=\"submit\" name=\"submit\" value=\""._("No")."\" /></p>\n";
		echo "</form>\n";
	}
	//deletes entries
	function deleteEntries() {
		global $BlogDB;
		if (count($_POST['entry'])==0) {
			error(4, _("No entries marked for deletion."));
		} else {
			if ($_REQUEST[submit]==_("Yes")) {
				$sql = "DELETE FROM entries WHERE (";
				foreach($_POST['entry'] as $id) {
					$sql .= "shortsubject = '".$this->blog->makeCleanString($id)."' OR ";
				}
				$sql = substr($sql, 0, -4);
				$sql .= ") AND user_id = {$this->id};";
				$BlogDB->Execute($sql);
				echo $BlogDB->Affected_Rows()._(" post(s) deleted");
			} else {
				error(4, _("Entries not deleted."));
			}
		}
	}
	//constructs the main page
	function mainPage() {
		//Should display blog entries here
		echo "<div class=\"entry\">\n";
		echo "<h2>"._("Blog Management")."</h2>\n";
		echo "<div class=\"td\">\n";
		echo "<p>"._("Use the links on the left to manage your blog, or choose a recent entry to edit:")."</p>\n";
		$this->printEntries(5, FALSE);
		echo "<a href=\"".$this->adminPath."showentries\">show all entries...</a></div>\n";
		echo "</div>\n";
	}
	//adds a user
	function addUser() {
		global $BlogDB, $session;
		$username = '';
		$password = makePassword();
		$name = '';
		$title = '';
		$description = '';
		//sanitise username
		if (trim($session->username) != "") {
			if (safeuname($session->username)) {
				$username = $session->username;
			} else {
				$this->error = _("Invalid Username Provided");
			}
		} else {
			$this->error = _("No Username Provided");
		}

		//sanitise name, perhaps a bit too strict?
		if (trim($session->fullname)) {
//			if (eregi("^([a-z]+([:space:][a-z]*))$",trim($session->fullname))) {
// Not working, so changed to something that does work

		if (isset($session->fullname)) {

				$name = trim($session->fullname);
			}
			else {
				$this->error = _("Invalid Name Provided");
			}
		} else {
			$this->error = _("No Real Name Provided");
		}
		//sanitise title, regexp? ^([a-z0-9]+([:space:][a-z0-9]*))$ as a base form and '\', '-', '.', ',', ':', ';', '?', '!'
		if (isset($_POST['btitle']) && trim($_POST['btitle']) != "") {
			$title = addslashes(trim(strip_tags($_POST['btitle'])));
		} else {
			$this->error = _("No Title Provided");
		}
		//sanitise description, same check as title gets
		if (isset($_POST['description']) && trim($_POST['description']) != "") {
			$description = addslashes(trim(strip_tags($_POST['description'])));
		} else {
			$this->error = _("No Description Provided");
		}
		//check the user doesn't already exist
		$sql = $BlogDB->GetAll("SELECT username from users where username = '".$username."';");
		if (count($sql) != 0) {
			$this->error = _("Username already in use!");
		}
		//check there is a system user with this name (ie if they are a sucs member)
		if(!posix_getpwnam($username)) {
			$this->error = _("You need to be a SUCS member to sign up for a blog here!");
		} else {
			//check the user is a member of the users, staff or societies groups
			$posixInfo = posix_getpwnam($username);
			if ($posixInfo[gid] != 100 && $posixInfo[gid] != 106 && $posixInfo[gid] != 113) {
				$this->error = _("Err, no, you're not really a system user now are you?");
			}
		}
		//if we dont have any errors
		if (!$this->error) {
			//encrypt the password
			$cryptPassword = crypt($password);
			//add to the database
			$sql = ("INSERT into USERS (username,password,name,title,description) VALUES ('{$username}','{$cryptPassword}','{$name}','{$title}','{$description}');");
			//error if that failed
			if (!$BlogDB->Execute($sql)) {
				error(2,_("Database Insertion failed - ").$BlogDB->ErrorMsg());
			} else {
				//else mail the password to the user and report sucsess
				mail(
					"{$username}@sucs.org",
					_("Blog Password"),
					_("Welcome to SUCS Blogs")."\n\n"._("The multi-user web log system created by SUCS members for SUCS members.")."\n\n"._("You Blog Password is : ").$password."\n"._("Please login and change it at ")."http://".$_SERVER["SERVER_NAME"].$this->adminPath,
					"From: \"Blog Admin\" <blogadmin@sucs.org>"
				);
				echo _("Account Added!<br />Your password has been sent to your SUCS email account");
				//bodge it so the username is filled in
				$session->username = $username;
			}
		} else {
			//return to the form
			$this->addUserForm();
		}
	}
	//this should take all the input and post it to addUser, passing in the current user and stuff... i think...
	function addUserForm() {
		global $session;
		echo "<div class=\"entry\">\n";
		if ($this->error != "") {
			echo "<div class=\"errorinfo\">"._("Error")." : " . $this->error . "</div>\n";
		}
		echo "<h2>"._("Register for a Blog")."</h2>\n";
		echo "<div class=\"td\">\n";
		echo "<form action=\"".$this->adminPath."adduser\" method=\"post\" id=\"adduserform\">\n";
		echo "<div class=\"row\">\n";
		echo "<label for=\"username\">"._("Username")."</label>\n";
//		echo "<span class=\"textinput\"><input type=\"text\" name=\"username\" id=\"username\" value=\"" . (($this->error != "") ? strip_tags(trim($_POST['username'])) : "") . "\" size=\"30\" maxlength=\"60\" tabindex=\"1\" /></span>\n";
		echo "<span class=\"textinput\">{$session->username}</span>\n";
		echo "</div>\n";
		echo "<div class=\"row\">\n";
		echo "<label for=\"name\">"._("Real name")."</label>\n";
//		echo "<span class=\"textinput\"><input type=\"text\" name=\"name\" id=\"name\" value=\"" . (($this->error != "") ? strip_tags(trim($_POST['name'])) : "") . "\" size=\"30\" maxlength=\"60\" tabindex=\"2\" /></span>\n";
		echo "<span class=\"textinput\">{$session->fullname}</span>\n";
		echo "</div>\n";
		echo "<div class=\"row\">\n";
		echo "<label for=\"btitle\">"._("Title")."</label>\n";
		echo "<span class=\"textinput\"><input type=\"text\" name=\"btitle\" id=\"btitle\" value=\"" . (($this->error != "") ? strip_tags(trim($_POST['btitle'])) : "") . "\" size=\"30\" maxlength=\"60\" tabindex=\"3\" /></span>\n";
		echo "</div>\n";
		echo "<div class=\"row\">\n";
		echo "<label for=\"title\">"._("Description")."</label>\n";
		echo "<span class=\"textinput\"><input type=\"text\" name=\"description\" id=\"description\" value=\"" . (($this->error != "") ? strip_tags(trim($_POST['description'])) : "") . "\" size=\"30\" maxlength=\"60\" tabindex=\"4\" /></span>\n";
		echo "</div>\n";
		echo "<div class=\"row\">\n";
		echo "<span class=\"textinput\"><input name=\"submit\" type=\"submit\" id=\"submit\" tabindex=\"4\" value=\""._("Sign Up")."\" /></span>\n";
		echo "</div>\n<div class=\"clear\"></div>\n";
		echo "</form>\n";
		echo "<p>"._("You need to be a member of ")."<a href=\"http://sucs.org/\">SUCS</a>"._(" to register")."<br />"._("The normal ")."<a href=\"http://sucs.org/About/Conditions\">"._("Terms and Conditions")."</a>"._(" apply")."</p>\n";
		echo "</div>\n";
		echo "</div>\n";
	}
}