<?php /*

 ocPortal
 Copyright (c) ocProducts, 2004-2012

 See text/EN/licence.txt for full licencing information.


 NOTE TO PROGRAMMERS:
   Do not edit this file. If you need to make changes, save your changed file to the appropriate *_custom folder
   **** If you ignore this advice, then your website upgrades (e.g. for bug fixes) will likely kill your changes ****

*/

/**
 * @license		http://opensource.org/licenses/cpal_1.0 Common Public Attribution License
 * @copyright	ocProducts Ltd
 * @package		ocf_forum
 */

/**
 * Module page class.
 */
class Module_topics
{

	/**
	 * Standard modular info function.
	 *
	 * @return ?array	Map of module info (NULL: module is disabled).
	 */
	function info()
	{
		$info=array();
		$info['author']='Chris Graham';
		$info['organisation']='ocProducts';
		$info['hacked_by']=NULL;
		$info['hack_version']=NULL;
		$info['version']=2;
		$info['locked']=false;
		return $info;
	}

	/**
	 * Standard modular entry-point finder function.
	 *
	 * @return ?array	A map of entry points (type-code=>language-code) (NULL: disabled).
	 */
	function get_entry_points()
	{
		return is_guest()?array():array('new_pt'=>'ADD_PERSONAL_TOPIC');
	}

	/**
	 * Standard modular privilege-overide finder function.
	 *
	 * @return array	A map of privileges that are overridable; sp to 0 or 1. 0 means "not category overridable". 1 means "category overridable".
	 */
	function get_sp_overrides()
	{
		require_lang('ocf');
		return array('submit_lowrange_content'=>array(1,'MAKE_POST'),'bypass_validation_lowrange_content'=>array(1,'BYPASS_POST_VALIDATION'),'edit_own_lowrange_content'=>array(1,'EDIT_OWN_POST'),'edit_lowrange_content'=>array(1,'EDIT_POST'),'delete_own_lowrange_content'=>array(1,'DELETE_OWN_POST'),'delete_lowrange_content'=>array(1,'DELETE_POST'),'submit_midrange_content'=>array(1,'ADD_TOPIC'),'bypass_validation_midrange_content'=>array(1,'BYPASS_TOPIC_VALIDATION'),'edit_own_midrange_content'=>array(1,'EDIT_OWN_TOPIC'),'edit_midrange_content'=>array(1,'EDIT_TOPIC'),'delete_own_midrange_content'=>array(1,'DELETE_OWN_TOPIC'),'delete_midrange_content'=>array(1,'DELETE_TOPIC'));
	}

	/**
	 * Standard modular run function.
	 *
	 * @return tempcode	The result of execution.
	 */
	function run()
	{
		if (get_forum_type()!='ocf') warn_exit(do_lang_tempcode('NO_OCF')); else ocf_require_all_forum_stuff();
		require_css('ocf');

		require_code('form_templates');

		global $NON_CANONICAL_PARAMS;
		foreach (array_keys($_GET) as $key)
			if ((substr($key,0,3)=='kfs') || (substr($key,0,5)=='mark_')) $NON_CANONICAL_PARAMS[]=$key;

		$type=get_param('type','misc');

		$valid_types=array(
			'whisper',
			'mark_read',
			'mark_read_topic',
			'mark_unread_topic',
			'delete_topic',
			'_delete_topic',
			'delete_topics',
			'_delete_topics',
			'categorise_pts',
			'_categorise_pts',
			'move_topic',
			'_move_topic',
			'validate_posts',
			'delete_posts',
			'_delete_posts',
			'delete_post',
			'_delete_post',
			'move_posts_a',
			'move_posts_b',
			'_move_posts',
			'move_topics',
			'_move_topics',
			'new_topic',
			'new_post',
			'new_pt',
			'_add_reply',
			'toggle_notifications_topic',
			'toggle_notifications_forum',
			'vote_poll',
			'add_poll',
			'_add_poll',
			'edit_poll',
			'_edit_poll',
			'delete_poll',
			'_delete_poll',
			'edit_post',
			'_edit_post',
			'edit_topic',
			'_edit_topic',
			'pin_topic',
			'unpin_topic',
			'sink_topic',
			'unsink_topic',
			'cascade_topic',
			'uncascade_topic',
			'open_topic',
			'close_topic',
			'validate_post',
			'topic_history',
			'birthday',
			'make_personal',
			'_make_personal',
			'pin_topics',
			'unpin_topics',
			'sink_topics',
			'unsink_topics',
			'cascade_topics',
			'uncascade_topics',
			'open_topics',
			'close_topics',
			'mark_topics_read',
			'mark_topics_unread',
			'_mass_multimod',
			'invite_member',
			'_invite_member',
		);
		if (addon_installed('ocf_reported_posts'))
			$valid_types[]='report_post';
		if (addon_installed('ocf_multi_moderations'))
		{
			$valid_types[]='multimod';
			$valid_types[]='_multimod';
		}

		if (in_array($type,$valid_types)) return ocf_wrapper(new ocp_tempcode(),call_user_func(array($this,$type)),false,false);

		if (substr($type,0,3)=='mm_') return $this->multimod();
		if (substr($type,0,4)=='mmt_') return $this->mass_multimod();

		if ($type=='misc')
		{
			global $EXTRA_HEAD;
			$EXTRA_HEAD->attach('<meta name="robots" content="noindex" />'); // XHTMLXHTML

			warn_exit(do_lang_tempcode('NOTHING_SELECTED'));
		}

		return new ocp_tempcode();
	}

	/**
	 * The UI for a trivial form page that just asks a reason before relaying the results to the same URL, but with an underscored type.
	 *
	 * @param  ID_TEXT		The language ID for the title to use in the page
	 * @return tempcode		The UI
	 */
	function relay_with_reason($_title)
	{
		$title=get_page_title($_title);
		$text=paragraph(do_lang_tempcode('OPTIONAL_REASON'));
		$submit_name=do_lang_tempcode('PROCEED');
		$type='_'.get_param('type','misc');
		$post_url=build_url(array('page'=>'_SELF','type'=>$type,'id'=>get_param_integer('id',-1)),'_SELF',NULL,true);
		$fields=new ocp_tempcode();
		$hidden=new ocp_tempcode();
		$hidden->attach(build_keep_post_fields());
		$hidden->attach(build_keep_form_fields());
		$fields->attach(form_input_line(do_lang_tempcode('REASON'),'','reason','',false));

		return do_template('FORM_SCREEN',array('_GUID'=>'85e30370bb9e45b2b9a7cd6463d69557','SKIP_VALIDATION'=>true,'STAFF_HELP_URL'=>brand_base_url().'/docs'.strval(ocp_version()).'/pg/tut_mod','HIDDEN'=>$hidden,'TITLE'=>$title,'TEXT'=>$text,'URL'=>$post_url,'FIELDS'=>$fields,'SUBMIT_NAME'=>$submit_name));
	}

	/**
	 * Do a redirection page to a certain topic/post (because we've just done an action and want to go back).
	 *
	 * @param  ID_TEXT		The language ID for the title to use in the page
	 * @param  AUTO_LINK		The ID of the topic to redirect to
	 * @param  ?mixed			What to output (Tempcode or string) (NULL: default)
	 * @param  ?AUTO_LINK	The ID of the post to redirect to (NULL: redirect to topic instead)
	 * @return tempcode		The UI
	 */
	function redirect_to($_title,$topic_id,$lang=NULL,$post_id=NULL)
	{
		require_code('ocf_topicview');

		if (is_null($lang)) $lang=do_lang_tempcode('SUCCESS');
		$title=get_page_title($_title);

		// Show it worked / Refresh
		if (is_null($post_id))
		{
			$url=find_first_unread_url($topic_id);
		} else
		{
			$url=find_post_id_url($post_id);
		}

		return redirect_screen($title,$url,$lang);
	}

	/**
	 * Do a redirection page to a certain forum (because we've just done an action and want to go back).
	 *
	 * @param  ID_TEXT		The language ID for the title to use in the page
	 * @param  AUTO_LINK		The ID of the forum to redirect to
	 * @param  ?mixed			What to output (Tempcode or string) (NULL: default)
	 * @return tempcode		The UI
	 */
	function redirect_to_forum($_title,$forum_id,$lang=NULL)
	{
		if (is_null($lang)) $lang=do_lang_tempcode('SUCCESS');
		$title=get_page_title($_title);

		// Show it worked / Refresh
		if (is_null($forum_id))
		{
			$url=build_url(array('page'=>'members','type'=>'view','id'=>get_member()),get_module_zone('members'),NULL,false,false,false,'tab__pts');
		} else
		{
			$url=build_url(array('page'=>'forumview','id'=>$forum_id),get_module_zone('forumview'));
		}

		return redirect_screen($title,$url,$lang);
	}

	/**
	 * Extract marker IDs that were past through in the GET/POST.
	 *
	 * @return array		A list of markers
	 */
	function get_markers()
	{
		$markers=array();
		foreach (array_keys($_REQUEST) as $key)
		{
			if (substr($key,0,5)=='mark_') $markers[]=intval(substr($key,5));
		}
		return $markers;
	}

	/**
	 * Copy marker IDs that were past through in the GET/POST into hidden form fields, so they may be relayed.
	 *
	 * @return tempcode	Hidden fields facilitating the marker relaying
	 */
	function keep_markers()
	{
		$markers=new ocp_tempcode();
		$_markers=$this->get_markers();
		foreach ($_markers as $marker)
		{
			$markers->attach(form_input_hidden('mark_'.strval($marker),'1'));
		}
		return $markers;
	}

	// ===========
	// FORUM LEVEL
	// ===========

	/**
	 * The actualiser to toggle notifications for a forum.
	 *
	 * @return tempcode		The UI
	 */
	function toggle_notifications_forum() // Type
	{
		require_code('notifications2');
		return notifications_ui_advanced('ocf_topic',do_lang_tempcode('NOW_ENABLED_NOTIFICATIONS_FORUM'),do_lang_tempcode('NOW_DISABLED_NOTIFICATIONS_FORUM'));
	}

	// =================
	// WITH MARKED POSTS
	// =================

	/**
	 * The actualiser to validate some posts.
	 *
	 * @return tempcode		The UI
	 */
	function validate_posts() // Type
	{
		$posts=$this->get_markers();
		if (count($posts)==0) warn_exit(do_lang_tempcode('NO_MARKERS_SELECTED'));

		$post_info=$GLOBALS['FORUM_DB']->query_select('f_posts',array('*'),array('id'=>$posts[0]),'',1);
		$topic_id=$post_info[0]['p_topic_id'];
		$forum_id=$post_info[0]['p_cache_forum_id'];
		$poster=$post_info[0]['p_poster'];
		$post=get_translated_text($post_info[0]['p_post'],$GLOBALS['FORUM_DB']);

		$topic_info=$GLOBALS['FORUM_DB']->query_select('f_topics',array('*'),array('id'=>$topic_id),'',1);
		if (!array_key_exists(0,$topic_info)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$this->handle_topic_breadcrumbs($topic_info[0]['t_forum_id'],$topic_id,$topic_info[0]['t_cache_first_title'],do_lang_tempcode('VALIDATE_POSTS'));

		require_code('ocf_posts_action');
		require_code('ocf_posts_action2');
		require_code('ocf_posts_action3');

		foreach ($posts as $post_id)
		{
			ocf_validate_post($post_id,$topic_id,$forum_id,$poster,$post);
		}

		return $this->redirect_to('VALIDATE_POSTS',$topic_id);
	}

	/**
	 * The UI to delete some posts.
	 *
	 * @return tempcode		The UI
	 */
	function delete_posts() // Type
	{
		$posts=$this->get_markers();
		if (count($posts)==0) warn_exit(do_lang_tempcode('NO_MARKERS_SELECTED'));

		$topic_id=$GLOBALS['FORUM_DB']->query_value_null_ok('f_posts','p_topic_id',array('id'=>$posts[0]));
		if (is_null($topic_id)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$topic_info=$GLOBALS['FORUM_DB']->query_select('f_topics',array('*'),array('id'=>$topic_id),'',1);
		if (!array_key_exists(0,$topic_info)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$this->handle_topic_breadcrumbs($topic_info[0]['t_forum_id'],$topic_id,$topic_info[0]['t_cache_first_title'],do_lang_tempcode('DELETE_POSTS'));

		return $this->relay_with_reason('DELETE_POSTS');
	}

	/**
	 * The actualiser to delete some posts.
	 *
	 * @return tempcode		The UI
	 */
	function _delete_posts() // Type
	{
		$posts=$this->get_markers();
		if (count($posts)==0) warn_exit(do_lang_tempcode('NO_MARKERS_SELECTED'));

		$topic_id=$GLOBALS['FORUM_DB']->query_value_null_ok('f_posts','p_topic_id',array('id'=>$posts[0]));
		if (is_null($topic_id)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		require_code('ocf_posts_action');
		require_code('ocf_posts_action2');
		require_code('ocf_posts_action3');
		ocf_delete_posts_topic($topic_id,$posts,post_param('reason'));

		$test=$GLOBALS['FORUM_DB']->query_value('f_posts','COUNT(*)',array('p_topic_id'=>$topic_id));
		if ($test==0)
		{
			return $this->redirect_to_forum('MOVE_POSTS',db_get_first_id());
		}

		return $this->redirect_to('DELETE_POSTS',$topic_id);
	}

	/**
	 * The UI to move some posts to an existing topic.
	 *
	 * @return tempcode		The UI
	 */
	function move_posts_a() // Type
	{
		$posts=$this->get_markers();
		if (count($posts)==0) warn_exit(do_lang_tempcode('NO_MARKERS_SELECTED'));

		$post_url=build_url(array('page'=>'_SELF','type'=>'_move_posts'),'_SELF');

		$topic_id=$GLOBALS['FORUM_DB']->query_value_null_ok('f_posts','p_topic_id',array('id'=>$posts[0]));
		if (is_null($topic_id)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$topic_info=$GLOBALS['FORUM_DB']->query_select('f_topics',array('*'),array('id'=>$topic_id),'',1);
		if (!array_key_exists(0,$topic_info)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$this->handle_topic_breadcrumbs($topic_info[0]['t_forum_id'],$topic_id,$topic_info[0]['t_cache_first_title'],do_lang_tempcode('MOVE_POSTS'));

		// Certain aspects relating to the posting system
		$fields=new ocp_tempcode();
		$hidden=$this->keep_markers();
		$fields->attach(form_input_tree_list(do_lang_tempcode('DESTINATION_TOPIC'),'','select_topic_id',NULL,'choose_forum_topic',array(),false));
		$fields->attach(form_input_integer(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('DESTINATION_TOPIC_ID')),do_lang_tempcode('DESCRIPTION_DESTINATION_TOPIC'),'manual_topic_id',NULL,false));
		$fields->attach(form_input_tick(do_lang_tempcode('DELETE_IF_EMPTY'),do_lang_tempcode('DESCRIPTION_DELETE_IF_EMPTY'),'delete_if_empty',true));
		$fields->attach(form_input_line(do_lang_tempcode('REASON'),do_lang_tempcode('DESCRIPTION_REASON'),'reason','',false));

		$title=get_page_title('MOVE_POSTS');
		$submit_name=do_lang_tempcode('MOVE_POSTS');
		$text=do_lang_tempcode('MOVE_POSTS_A_TEXT');

		return do_template('FORM_SCREEN',array('_GUID'=>'d62d2c81583398f26f900ee3df1894b1','STAFF_HELP_URL'=>brand_base_url().'/docs'.strval(ocp_version()).'/pg/tut_mod','HIDDEN'=>$hidden,'TITLE'=>$title,'FIELDS'=>$fields,'TEXT'=>$text,'SUBMIT_NAME'=>$submit_name,'URL'=>$post_url,'JAVASCRIPT'=>'standardAlternateFields(\'select_topic_id\',\'manual_topic_id\');'));
	}

	/**
	 * The UI to move some posts to a new topic.
	 *
	 * @return tempcode		The UI
	 */
	function move_posts_b() // Type
	{
		$posts=$this->get_markers();
		if (count($posts)==0) warn_exit(do_lang_tempcode('NO_MARKERS_SELECTED'));

		$post_url=build_url(array('page'=>'_SELF','type'=>'_move_posts'),'_SELF');

		$topic_id=$GLOBALS['FORUM_DB']->query_value_null_ok('f_posts','p_topic_id',array('id'=>$posts[0]));
		if (is_null($topic_id)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$topic_info=$GLOBALS['FORUM_DB']->query_select('f_topics',array('*'),array('id'=>$topic_id),'',1);
		if (!array_key_exists(0,$topic_info)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$this->handle_topic_breadcrumbs($topic_info[0]['t_forum_id'],$topic_id,$topic_info[0]['t_cache_first_title'],do_lang_tempcode('MOVE_POSTS'));
		$default_title=do_lang('POSTS_SPLIT_FROM',$topic_info[0]['t_cache_first_title']);

		require_code('ocf_forums2');

		// Certain aspects relating to the posting system
		$fields=new ocp_tempcode();
		$hidden=$this->keep_markers();
		$fields->attach(form_input_tree_list(do_lang_tempcode('DESTINATION_FORUM'),do_lang_tempcode('DESCRIPTION_POSTS_DESTINATION_FORUM'),'to_forum_id',NULL,'choose_forum',array(),true,strval($topic_info[0]['t_forum_id'])));
		$fields->attach(form_input_line(do_lang_tempcode('TITLE'),do_lang_tempcode('TOPIC_TITLE_WILL_BE'),'title',$default_title,false));
		$fields->attach(form_input_tick(do_lang_tempcode('DELETE_IF_EMPTY'),do_lang_tempcode('DESCRIPTION_DELETE_IF_EMPTY'),'delete_if_empty',true));
		$fields->attach(form_input_line(do_lang_tempcode('REASON'),do_lang_tempcode('DESCRIPTION_REASON'),'reason','',false));
		$default_title=$GLOBALS['FORUM_DB']->query_value('f_posts','p_title',array('id'=>$posts[0]));

		$title=get_page_title('MOVE_POSTS');
		$submit_name=do_lang_tempcode('MOVE_POSTS');
		$text=do_lang_tempcode('MOVE_POSTS_B_TEXT');

		return do_template('FORM_SCREEN',array('_GUID'=>'a476da1fecfbd932db4853cdbd7cfedd','STAFF_HELP_URL'=>brand_base_url().'/docs'.strval(ocp_version()).'/pg/tut_mod','HIDDEN'=>$hidden,'TITLE'=>$title,'FIELDS'=>$fields,'TEXT'=>$text,'SUBMIT_NAME'=>$submit_name,'URL'=>$post_url));
	}

	/**
	 * The actualiser to move some posts.
	 *
	 * @return tempcode		The UI
	 */
	function _move_posts() // Type
	{
		$posts=$this->get_markers();
		if (count($posts)==0) warn_exit(do_lang_tempcode('NO_MARKERS_SELECTED'));

		$to_forum_id=NULL;
		$to_topic_id=post_param_integer('select_topic_id',-1);
		if ($to_topic_id==-1)
		{
			$_to_topic_id=post_param('manual_topic_id','');
			if ($_to_topic_id=='')
			{
				$to_topic_id=NULL;
				$to_forum_id=post_param_integer('to_forum_id');
				if ($to_forum_id==-1) warn_exit(do_lang_tempcode('MUST_MOVE_POSTS_SOMEWHERE'));
			} else $to_topic_id=intval($_to_topic_id);
		}
		$from_topic_id=$GLOBALS['FORUM_DB']->query_value_null_ok('f_posts','p_topic_id',array('id'=>$posts[0]));
		if (is_null($from_topic_id)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		require_code('ocf_posts_action');
		require_code('ocf_posts_action2');
		require_code('ocf_posts_action3');
		$delete_if_empty=post_param_integer('delete_if_empty',0)==1;
		$test=ocf_move_posts($from_topic_id,$to_topic_id,$posts,post_param('reason'),$to_forum_id,$delete_if_empty,post_param('title',NULL));

		if ($test)
		{
			return $this->redirect_to_forum('MOVE_POSTS',db_get_first_id());
		}

		return $this->redirect_to('MOVE_POSTS',$from_topic_id);
	}

	// ==================
	// WITH MARKED TOPICS
	// ==================

	/**
	 * The actualiser to mark topics as read.
	 *
	 * @return tempcode		The UI
	 */
	function mark_topics_read() // Type
	{
		$topics=$this->get_markers();
		if (count($topics)==0) warn_exit(do_lang_tempcode('NO_MARKERS_SELECTED'));

		$forum_id=NULL;
		foreach ($topics as $i=>$topic_id)
		{
			if ($i==0)
			{
				$forum_id=$GLOBALS['FORUM_DB']->query_value('f_topics','t_forum_id',array('id'=>$topic_id));
			}
			ocf_ping_topic_read($topic_id);
		}

		if (is_null($forum_id))
		{
			decache('side_ocf_personal_topics',array(get_member()));
			decache('_new_pp',array(get_member()));
		}

		$title=get_page_title('MARK_READ');

		// Show it worked / Refresh
		$url=get_param('redirect',NULL);
		if ($url!==NULL)
			return redirect_screen($title,$url,do_lang_tempcode('SUCCESS'));

		// Show it worked / Refresh
		return $this->redirect_to_forum('MARK_READ',$forum_id);
	}

	/**
	 * Mark a topic as unread by the current member.
	 *
	 * @param  AUTO_LINK The ID of the topic to mark as unread.
	 * @return boolean   Success status.
	 */
	function ocf_ping_topic_unread($topic_id)
	{
		$last_time=$GLOBALS['FORUM_DB']->query_value('f_topics','t_cache_last_time',array('id'=>$topic_id));
		$too_old=$last_time<time()-60*60*24*intval(get_option('post_history_days'));
		if (!$too_old)
		{
			$GLOBALS['FORUM_DB']->query_delete('f_read_logs',array('l_topic_id'=>$topic_id,'l_member_id'=>get_member()),'',1);
			return true;
		}
		return false;
	}

	/**
	 * The actualiser to mark topics as unread.
	 *
	 * @return tempcode		The UI
	 */
	function mark_topics_unread() // Type
	{
		$topics=$this->get_markers();
		if (count($topics)==0) warn_exit(do_lang_tempcode('NO_MARKERS_SELECTED'));

		$forum_id=NULL;
		$success=0;
		foreach ($topics as $i=>$topic_id)
		{
			if ($i==0)
			{
				$forum_id=$GLOBALS['FORUM_DB']->query_value('f_topics','t_forum_id',array('id'=>$topic_id));
			}
			if ($this->ocf_ping_topic_unread($topic_id)) $success++;
		}

		if ($success!=count($topics))
		{
			attach_message(do_lang_tempcode('MARK_UNREAD_TOO_OLD',escape_html(integer_format(count($topics)-$success)),escape_html(integer_format(intval(get_option('post_history_days'))))),'warn');
		}

		if (is_null($forum_id))
		{
			decache('side_ocf_personal_topics',array(get_member()));
			decache('_new_pp',array(get_member()));
		}

		return $this->redirect_to_forum('MARK_UNREAD',$forum_id);
	}

	/**
	 * The actualiser to pin topics.
	 *
	 * @return tempcode		The UI
	 */
	function pin_topics() // Type
	{
		require_code('ocf_topics_action');
		require_code('ocf_topics_action2');

		$topics=$this->get_markers();
		if (count($topics)==0) warn_exit(do_lang_tempcode('NO_MARKERS_SELECTED'));

		$forum_id=NULL;
		foreach ($topics as $i=>$topic_id)
		{
			if ($i==0)
			{
				$forum_id=$GLOBALS['FORUM_DB']->query_value('f_topics','t_forum_id',array('id'=>$topic_id));
			}
			ocf_edit_topic($topic_id,NULL,NULL,NULL,NULL,1,NULL,NULL,'');
		}

		return $this->redirect_to_forum('PIN_TOPIC',$forum_id);
	}

	/**
	 * The actualiser to unpin topics.
	 *
	 * @return tempcode		The UI
	 */
	function unpin_topics() // Type
	{
		require_code('ocf_topics_action');
		require_code('ocf_topics_action2');

		$topics=$this->get_markers();
		if (count($topics)==0) warn_exit(do_lang_tempcode('NO_MARKERS_SELECTED'));

		$forum_id=NULL;
		foreach ($topics as $i=>$topic_id)
		{
			if ($i==0)
			{
				$forum_id=$GLOBALS['FORUM_DB']->query_value('f_topics','t_forum_id',array('id'=>$topic_id));
			}
			ocf_edit_topic($topic_id,NULL,NULL,NULL,NULL,0,NULL,NULL,'');
		}

		return $this->redirect_to_forum('UNPIN_TOPIC',$forum_id);
	}

	/**
	 * The actualiser to pin topics.
	 *
	 * @return tempcode		The UI
	 */
	function sink_topics() // Type
	{
		require_code('ocf_topics_action');
		require_code('ocf_topics_action2');

		$topics=$this->get_markers();
		if (count($topics)==0) warn_exit(do_lang_tempcode('NO_MARKERS_SELECTED'));

		$forum_id=NULL;
		foreach ($topics as $i=>$topic_id)
		{
			if ($i==0)
			{
				$forum_id=$GLOBALS['FORUM_DB']->query_value('f_topics','t_forum_id',array('id'=>$topic_id));
			}
			ocf_edit_topic($topic_id,NULL,NULL,NULL,NULL,1,NULL,NULL,'');
		}

		return $this->redirect_to_forum('SINK_TOPIC',$forum_id);
	}

	/**
	 * The actualiser to unpin topics.
	 *
	 * @return tempcode		The UI
	 */
	function unsink_topics() // Type
	{
		require_code('ocf_topics_action');
		require_code('ocf_topics_action2');

		$topics=$this->get_markers();
		if (count($topics)==0) warn_exit(do_lang_tempcode('NO_MARKERS_SELECTED'));

		$forum_id=NULL;
		foreach ($topics as $i=>$topic_id)
		{
			if ($i==0)
			{
				$forum_id=$GLOBALS['FORUM_DB']->query_value('f_topics','t_forum_id',array('id'=>$topic_id));
			}
			ocf_edit_topic($topic_id,NULL,NULL,NULL,NULL,0,NULL,NULL,'');
		}

		return $this->redirect_to_forum('UNSINK_TOPIC',$forum_id);
	}

	/**
	 * The actualiser to cascade topics.
	 *
	 * @return tempcode		The UI
	 */
	function cascade_topics() // Type
	{
		require_code('ocf_topics_action');
		require_code('ocf_topics_action2');

		$topics=$this->get_markers();
		if (count($topics)==0) warn_exit(do_lang_tempcode('NO_MARKERS_SELECTED'));

		$forum_id=NULL;
		foreach ($topics as $i=>$topic_id)
		{
			if ($i==0)
			{
				$forum_id=$GLOBALS['FORUM_DB']->query_value('f_topics','t_forum_id',array('id'=>$topic_id));
			}
			ocf_edit_topic($topic_id,NULL,NULL,NULL,NULL,NULL,NULL,1,'');
		}

		return $this->redirect_to_forum('CASCADE_TOPIC',$forum_id);
	}

	/**
	 * The actualiser to uncascade topics.
	 *
	 * @return tempcode		The UI
	 */
	function uncascade_topics() // Type
	{
		require_code('ocf_topics_action');
		require_code('ocf_topics_action2');

		$topics=$this->get_markers();
		if (count($topics)==0) warn_exit(do_lang_tempcode('NO_MARKERS_SELECTED'));

		$forum_id=NULL;
		foreach ($topics as $i=>$topic_id)
		{
			if ($i==0)
			{
				$forum_id=$GLOBALS['FORUM_DB']->query_value('f_topics','t_forum_id',array('id'=>$topic_id));
			}
			ocf_edit_topic($topic_id,NULL,NULL,NULL,NULL,NULL,NULL,0,'');
		}

		return $this->redirect_to_forum('UNCASCADE_TOPIC',$forum_id);
	}

	/**
	 * The actualiser to open topics.
	 *
	 * @return tempcode		The UI
	 */
	function open_topics() // Type
	{
		require_code('ocf_topics_action');
		require_code('ocf_topics_action2');

		$topics=$this->get_markers();
		if (count($topics)==0) warn_exit(do_lang_tempcode('NO_MARKERS_SELECTED'));

		$forum_id=NULL;
		foreach ($topics as $i=>$topic_id)
		{
			if ($i==0)
			{
				$forum_id=$GLOBALS['FORUM_DB']->query_value('f_topics','t_forum_id',array('id'=>$topic_id));
			}
			ocf_edit_topic($topic_id,NULL,NULL,NULL,1,NULL,NULL,NULL,'');
		}

		return $this->redirect_to_forum('OPEN_TOPIC',$forum_id);
	}

	/**
	 * The actualiser to close topics.
	 *
	 * @return tempcode		The UI
	 */
	function close_topics() // Type
	{
		require_code('ocf_topics_action');
		require_code('ocf_topics_action2');

		$topics=$this->get_markers();
		if (count($topics)==0) warn_exit(do_lang_tempcode('NO_MARKERS_SELECTED'));

		$forum_id=NULL;
		foreach ($topics as $i=>$topic_id)
		{
			if ($i==0)
			{
				$forum_id=$GLOBALS['FORUM_DB']->query_value('f_topics','t_forum_id',array('id'=>$topic_id));
			}
			ocf_edit_topic($topic_id,NULL,NULL,NULL,0,NULL,NULL,NULL,'');
		}

		return $this->redirect_to_forum('CLOSE_TOPIC',$forum_id);
	}

	/**
	 * The UI to run multi-moderations.
	 *
	 * @return tempcode		The UI
	 */
	function mass_multimod() // Type
	{
		$mm_id=intval(substr(get_param('type','misc'),4));

		$topics=$this->get_markers();
		if (count($topics)==0) warn_exit(do_lang_tempcode('NO_MARKERS_SELECTED'));

		$forum_id=NULL;
		foreach ($topics as $i=>$topic_id)
		{
			if ($i==0)
			{
				$forum_id=$GLOBALS['FORUM_DB']->query_value('f_topics','t_forum_id',array('id'=>$topic_id));
			}
			$this->check_has_mod_access($topic_id);
		}

		$tree=ocf_forum_breadcrumbs($forum_id,NULL,NULL,false);
		breadcrumb_add_segment($tree,do_lang_tempcode('PERFORM_MULTI_MODERATION'));

		$title=get_page_title('PERFORM_MULTI_MODERATION');
		$mm=$GLOBALS['FORUM_DB']->query_select('f_multi_moderations',array('*'),array('id'=>$mm_id),'',1);
		if (!array_key_exists(0,$mm)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$_mm=$mm[0];
		$post_text=$_mm['mm_post_text'];
		$submit_name=do_lang_tempcode('PERFORM_MULTI_MODERATION');
		$post_url=build_url(array('page'=>'_SELF','type'=>'_mass_multimod','mm_id'=>$mm_id),'_SELF',NULL,true);
		$fields=new ocp_tempcode();
		$hidden=new ocp_tempcode();
		$hidden->attach(build_keep_post_fields());
		$hidden->attach(build_keep_form_fields());
		$fields->attach(form_input_text(do_lang_tempcode('MM_POST_TEXT'),do_lang_tempcode('DESCRIPTION_MM_POST_TEXT'),'post_text',$post_text,false));
		$options=array();
		if (get_value('disable_skip_sig')!=='1')
		{
			if (addon_installed('ocf_signatures'))
				$options[]=array(do_lang_tempcode('SKIP_SIGNATURE'),'skip_sig',false,do_lang_tempcode('DESCRIPTION_SKIP_SIGNATURE'));
		}
		if (get_value('disable_post_emphasis')!=='1')
			$options[]=array(do_lang_tempcode('EMPHASISED'),'is_emphasised',true,do_lang_tempcode('DESCRIPTION_EMPHASISED'));
		$fields->attach(form_input_various_ticks($options,''));
		$fields->attach(form_input_line(do_lang_tempcode('REASON'),do_lang_tempcode('OPTIONAL_REASON'),'reason','',false));

		$mm_title=get_translated_text($_mm['mm_name'],$GLOBALS['FORUM_DB']);
		$action_list=new ocp_tempcode();
		if ($_mm['mm_open_state']==1)
			$action_list->attach(do_lang_tempcode('MULTI_MODERATION_WILL_OPEN'));
		if ($_mm['mm_open_state']==0)
			$action_list->attach(do_lang_tempcode('MULTI_MODERATION_WILL_CLOSE'));
		if ($_mm['mm_pin_state']==1)
			$action_list->attach(do_lang_tempcode('MULTI_MODERATION_WILL_PIN'));
		if ($_mm['mm_pin_state']==0)
			$action_list->attach(do_lang_tempcode('MULTI_MODERATION_WILL_UNPIN'));
		if ($_mm['mm_sink_state']==1)
			$action_list->attach(do_lang_tempcode('MULTI_MODERATION_WILL_SINK'));
		if ($_mm['mm_sink_state']==0)
			$action_list->attach(do_lang_tempcode('MULTI_MODERATION_WILL_UNSINK'));
		if ($_mm['mm_title_suffix']!='')
			$action_list->attach(do_lang_tempcode('MULTI_MODERATION_WILL_TITLE_SUFFIX',escape_html($_mm['mm_title_suffix'])));
		if (!is_null($_mm['mm_move_to']))
		{
			$target_forum=$GLOBALS['FORUM_DB']->query_value('f_forums','f_name',array('id'=>$_mm['mm_move_to']));
			$action_list->attach(do_lang_tempcode('MULTI_MODERATION_WILL_MOVE',escape_html($target_forum)));
		}
		$action_list->attach(do_lang_tempcode('MULTI_MODERATION_WILL_POST'));
		$text=do_lang_tempcode('MULTI_MODERATION_WILL',make_string_tempcode($mm_title),$action_list);

		return do_template('FORM_SCREEN',array('STAFF_HELP_URL'=>brand_base_url().'/docs'.strval(ocp_version()).'/pg/tut_forum_helpdesk','PREVIEW'=>true,'HIDDEN'=>$hidden,'TITLE'=>$title,'TEXT'=>$text,'URL'=>$post_url,'FIELDS'=>$fields,'SUBMIT_NAME'=>$submit_name));
	}

	/**
	 * The actualiser to run multi moderations.
	 *
	 * @return tempcode		The UI
	 */
	function _mass_multimod() // Type
	{
		$mm_id=get_param_integer('mm_id');
		require_code('ocf_moderation_action');
		require_code('ocf_moderation_action2');

		$topics=$this->get_markers();
		if (count($topics)==0) warn_exit(do_lang_tempcode('NO_MARKERS_SELECTED'));

		$forum_id=NULL;
		foreach ($topics as $i=>$topic_id)
		{
			if ($i==0)
			{
				$forum_id=$GLOBALS['FORUM_DB']->query_value('f_topics','t_forum_id',array('id'=>$topic_id));
			}
			ocf_perform_multi_moderation($mm_id,$topic_id,post_param('reason'),post_param('post_text'),post_param_integer('is_emphasised',0),post_param_integer('skip_sig',0));
		}

		return $this->redirect_to_forum('PERFORM_MULTI_MODERATION',$forum_id);
	}

	/**
	 * The UI to move some topics.
	 *
	 * @return tempcode		The UI
	 */
	function move_topics() // Type
	{
		$topics=$this->get_markers();
		if (count($topics)==0) warn_exit(do_lang_tempcode('NO_MARKERS_SELECTED'));

		$forum_id=$GLOBALS['FORUM_DB']->query_value('f_topics','t_forum_id',array('id'=>$topics[0]));

		$post_url=build_url(array('page'=>'_SELF','type'=>'_move_topics'),'_SELF');

		require_code('ocf_forums2');

		// Certain aspects relating to the posting system
		$fields=new ocp_tempcode();
		$fields->attach(form_input_tree_list(do_lang_tempcode('DESTINATION_FORUM'),do_lang_tempcode('DESCRIPTION_DESTINATION_FORUM'),'to',NULL,'choose_forum',array(),true,strval($forum_id)));
		$fields->attach(form_input_line(do_lang_tempcode('REASON'),do_lang_tempcode('DESCRIPTION_REASON'),'description','',false));
		$hidden=$this->keep_markers();

		$tree=ocf_forum_breadcrumbs($forum_id,NULL,NULL,false);
		breadcrumb_add_segment($tree,do_lang_tempcode('MOVE_TOPICS'));

		$title=get_page_title('MOVE_TOPICS');
		$submit_name=do_lang_tempcode('MOVE_TOPICS');
		return do_template('FORM_SCREEN',array('_GUID'=>'7532b5e7239e0f9ceb64d09c28fd7261','SKIP_VALIDATION'=>true,'STAFF_HELP_URL'=>brand_base_url().'/docs'.strval(ocp_version()).'/pg/tut_mod','HIDDEN'=>$hidden,'TITLE'=>$title,'FIELDS'=>$fields,'TEXT'=>'','SUBMIT_NAME'=>$submit_name,'URL'=>$post_url));
	}

	/**
	 * The actualiser to move some topics.
	 *
	 * @return tempcode		The UI
	 */
	function _move_topics() // Type
	{
		$topics=$this->get_markers();
		if (count($topics)==0) warn_exit(do_lang_tempcode('NO_MARKERS_SELECTED'));

		$to=post_param_integer('to');
		$from=$GLOBALS['FORUM_DB']->query_value_null_ok('f_topics','t_forum_id',array('id'=>$topics[0]));
//		if (is_null($from)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		require_code('ocf_topics_action');
		require_code('ocf_topics_action2');
		ocf_move_topics($from,$to,$topics);
		return $this->redirect_to_forum('MOVE_TOPIC',$from);
	}

	/**
	 * The UI to delete some topics.
	 *
	 * @return tempcode		The UI
	 */
	function delete_topics() // Type
	{
		$topics=$this->get_markers();
		if (count($topics)==0) warn_exit(do_lang_tempcode('NO_MARKERS_SELECTED'));

		$topic_id=$topics[0];
		$topic_info=$GLOBALS['FORUM_DB']->query_select('f_topics',array('*'),array('id'=>$topic_id),'',1);
		if (!array_key_exists(0,$topic_info)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$this->handle_topic_breadcrumbs($topic_info[0]['t_forum_id'],$topic_id,$topic_info[0]['t_cache_first_title'],do_lang_tempcode('DELETE_TOPICS'));

		return $this->relay_with_reason('DELETE_TOPICS');
	}

	/**
	 * The actualiser to delete some topics.
	 *
	 * @return tempcode		The UI
	 */
	function _delete_topics() // Type
	{
		$topics=$this->get_markers();
		if (count($topics)==0) warn_exit(do_lang_tempcode('NO_MARKERS_SELECTED'));
		require_code('ocf_topics_action');
		require_code('ocf_topics_action2');
		foreach ($topics as $topic_id)
		{
			$forum_id=ocf_delete_topic($topic_id,post_param('reason'),NULL);
		}
		return $this->redirect_to_forum('DELETE_TOPICS',$forum_id);
	}

	/**
	 * The UI to categorise some PTs.
	 *
	 * @return tempcode		The UI
	 */
	function categorise_pts() // Type
	{
		$topics=$this->get_markers();
		if (count($topics)==0)
		{
			$topics[]=get_param('id',NULL);
			if (is_null($topics[0])) warn_exit(do_lang_tempcode('NO_MARKERS_SELECTED'));
			$_REQUEST['mark_'.$topics[0]]=1;
		}

		$post_url=build_url(array('page'=>'_SELF','type'=>'_categorise_pts'),'_SELF');

		// Certain aspects relating to the posting system
		$fields=new ocp_tempcode();
		$filter_cats=ocf_get_filter_cats();
		$list=new ocp_tempcode();
		foreach ($filter_cats as $filter_cat)
		{
			$filter_cat_text=($filter_cat=='')?do_lang_tempcode('NONE_EM'):make_string_tempcode($filter_cat);
			$list->attach(form_input_list_entry($filter_cat,$filter_cat=='',$filter_cat_text));
		}
		$fields->attach(form_input_list(do_lang_tempcode('CATEGORY'),do_lang_tempcode('DESCRIPTION_CATEGORY'),'category_a',$list,NULL,true));
		$fields->attach(form_input_line(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('NEW')),do_lang_tempcode('DESCRIPTION_ALTERNATE',protect_from_escaping(strtolower(do_lang('CATEGORY')))),'category_b','',false));
		$hidden=$this->keep_markers();

		breadcrumb_set_parents(array(array('_SEARCH:forumview:pt',do_lang_tempcode('PERSONAL_TOPICS'))));

		$title=get_page_title('CATEGORISE_PTS');
		$submit_name=do_lang_tempcode('CATEGORISE_PTS');
		return do_template('FORM_SCREEN',array('_GUID'=>'c6d0e273b5ce0e84d50a1c6294ece157','SKIP_VALIDATION'=>true,'HIDDEN'=>$hidden,'TITLE'=>$title,'FIELDS'=>$fields,'TEXT'=>'','SUBMIT_NAME'=>$submit_name,'URL'=>$post_url));
	}

	/**
	 * The actualiser to categorise some PTs.
	 *
	 * @return tempcode		The UI
	 */
	function _categorise_pts() // Type
	{
		$topics=$this->get_markers();
		if (count($topics)==0) warn_exit(do_lang_tempcode('NO_MARKERS_SELECTED'));
		require_code('ocf_topics_action');
		require_code('ocf_topics_action2');
		$category=post_param('category_b','');
		if ($category=='') $category=post_param('category_a');
		foreach ($topics as $topic_id)
		{
			$topic_info=$GLOBALS['FORUM_DB']->query_select('f_topics',array('t_pt_from','t_pt_to','t_pt_from_category','t_pt_to_category'),array('id'=>$topic_id),'',1);
			if (array_key_exists(0,$topic_info))
			{
				if ($topic_info[0]['t_pt_from']==get_member())
				{
					$t='t_pt_from_category';
					if ((get_option('delete_trashed_pts')=='1') && ($category==do_lang('TRASH')) && ($topic_info[0]['t_pt_to_category']==do_lang('TRASH')))
					{
						ocf_delete_topic($topic_id,'');
						return $this->redirect_to_forum('CATEGORISE_PTS',NULL);
					}
				}
				elseif ($topic_info[0]['t_pt_to']==get_member())
				{
					$t='t_pt_to_category';
					if ((get_option('delete_trashed_pts')=='1') && ($category==do_lang('TRASH')) && ($topic_info[0]['t_pt_from_category']==do_lang('TRASH')))
					{
						ocf_delete_topic($topic_id,'');
						return $this->redirect_to_forum('CATEGORISE_PTS',NULL);
					}
				}
				else warn_exit(do_lang_tempcode('CANNOT_CATEGORISE_INVITED'));
				$GLOBALS['FORUM_DB']->query_update('f_topics',array($t=>$category),array('id'=>$topic_id),'',1);
			}
		}
		return $this->redirect_to_forum('CATEGORISE_PTS',NULL);
	}

	// ======================
	// POST/REPLY BASED TYPES
	// ======================

	/**
	 * The UI to choose between the two types of whisper.
	 *
	 * @return tempcode		The UI
	 */
	function whisper()
	{
		$title=get_page_title('WHISPER');

		$url=build_url(array('page'=>'_SELF'),'_SELF',array('type'=>1),true,true);

		$member_id=get_param_integer('intended_solely_for');
		$username=$GLOBALS['FORUM_DRIVER']->get_username($member_id);

		$topic_id=$GLOBALS['FORUM_DB']->query_value_null_ok('f_posts','p_topic_id',array('id'=>get_param_integer('quote')));
		if (is_null($topic_id)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$topic_info=$GLOBALS['FORUM_DB']->query_select('f_topics',array('*'),array('id'=>$topic_id),'',1);
		if (!array_key_exists(0,$topic_info)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$this->handle_topic_breadcrumbs($topic_info[0]['t_forum_id'],$topic_id,$topic_info[0]['t_cache_first_title'],do_lang_tempcode('WHISPER'));

		global $NON_CANONICAL_PARAMS;
		$NON_CANONICAL_PARAMS[]='quote';

		global $EXTRA_HEAD;
		$EXTRA_HEAD->attach('<meta name="robots" content="noindex" />'); // XHTMLXHTML

		return do_template('OCF_WHISPER_CHOICE_SCREEN',array('_GUID'=>'1ecaa02e7e87a4d73798d3085cc27229','URL'=>$url,'TITLE'=>$title,'USERNAME'=>$username));
	}

	/**
	 * Choose an emoticon for a topic.
	 *
	 * @param  ID_TEXT		The currently selected emoticon
	 * @return tempcode		The emoticon input field
	 */
	function choose_topic_emoticon($selected_path='')
	{
		$tabindex=get_form_field_tabindex(NULL);

		$content=array();
		$extra=has_specific_permission(get_member(),'use_special_emoticons')?'':' AND e_is_special=0';
		$rows=$GLOBALS['FORUM_DB']->query('SELECT e_theme_img_code FROM '.$GLOBALS['FORUM_DB']->get_table_prefix().'f_emoticons WHERE e_use_topics=1'.$extra);
		$content[]=do_template('FORM_SCREEN_INPUT_RADIO_LIST_ENTRY_PICTURE_3_NA',array('_GUID'=>'d9f9399072af3f19f21695aef01168c7','CHECKED'=>$selected_path=='','NAME'=>'emoticon'));

		foreach ($rows as $row)
		{
			$path=$row['e_theme_img_code'];

			$url=find_theme_image($path);
			$content[]=do_template('FORM_SCREEN_INPUT_RADIO_LIST_ENTRY_PICTURE_3',array('PRETTY'=>'','CHECKED'=>$path==$selected_path,'NAME'=>'emoticon','CODE'=>$path,'URL'=>$url));
		}
		if (count($content)==0) return new ocp_tempcode();

		$_content=wrap_image_radio_list($content);

		$input=do_template('FORM_SCREEN_INPUT_RADIO_LIST',array('NAME'=>'emoticon','CODE'=>$selected_path,'TABINDEX'=>strval($tabindex),'CONTENT'=>$_content));

		return _form_input('',do_lang_tempcode('TOPIC_EMOTICON'),'',$input,false);
	}

	/**
	 * Create a default post based on a template of quoting the given list of quotes.
	 *
	 * @param  array			A list of posts to quote
	 * @return tempcode		The default post
	 */
	function attach_quotes($quotes)
	{
		$post=new ocp_tempcode();
		foreach ($quotes as $quote)
		{
			$_postdetails=$GLOBALS['FORUM_DB']->query_select('f_posts',array('p_cache_forum_id','p_post','p_poster_name_if_guest','p_topic_id','p_intended_solely_for','p_poster','p_validated','p_ip_address'),array('id'=>$quote),'',1);
			if (!array_key_exists(0,$_postdetails)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
			if (!is_null($_postdetails[0]['p_cache_forum_id']))
			{
				if (!has_category_access(get_member(),'forums',strval($_postdetails[0]['p_cache_forum_id'])))
					access_denied('I_ERROR');
				if ((is_guest()) && (!is_null($_postdetails[0]['p_intended_solely_for'])))
					access_denied('I_ERROR');
				elseif ((!has_specific_permission(get_member(),'view_other_pt')) && ($_postdetails[0]['p_intended_solely_for']!=get_member()) && ($_postdetails[0]['p_poster']!=get_member()) && (!is_null($_postdetails[0]['p_intended_solely_for'])))
					access_denied('I_ERROR');
				if ((!has_specific_permission(get_member(),'see_unvalidated')) && (!$_postdetails[0]['p_validated']) && (($_postdetails[0]['p_poster']!=get_member()) || ((is_guest($_postdetails[0]['p_poster'])) && ($_postdetails[0]['p_ip_address']!=get_ip_address()))))
					access_denied('I_ERROR');

				$_topic=$GLOBALS['FORUM_DB']->query_select('f_topics',array('t_pt_to','t_pt_from','t_cache_first_title'),array('id'=>$_postdetails[0]['p_topic_id']),'',1);
				if (!array_key_exists(0,$_topic)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
			} else
			{
				$_topic=$GLOBALS['FORUM_DB']->query_select('f_topics',array('t_pt_to','t_pt_from','t_cache_first_title'),array('id'=>$_postdetails[0]['p_topic_id']),'',1);
				if (!array_key_exists(0,$_topic)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
				$from=$_topic[0]['t_pt_from'];
				$to=$_topic[0]['t_pt_to'];
				if (($from!=get_member()) && ($to!=get_member()) && (!ocf_has_special_pt_access($_postdetails[0]['p_topic_id'])) && (!has_specific_permission(get_member(),'view_other_pt')))
					access_denied('I_ERROR');
			}
			$post->attach(do_template('OCF_QUOTE_FCOMCODE',array('_GUID'=>'5542508cad43a0cd5798afbb06f9e616','ID'=>strval($quote),'TITLE'=>$_topic[0]['t_cache_first_title'],'POST'=>get_translated_text($_postdetails[0]['p_post'],$GLOBALS['FORUM_DB']),'BY'=>$_postdetails[0]['p_poster_name_if_guest'])));
		}

		return $post;
	}

	/**
	 * Get a list of post templates that apply to a certain forum.
	 *
	 * @param  AUTO_LINK The ID of the forum.
	 * @return array 		The list of applicable post templates.
	 */
	function ocf_get_post_templates($forum_id)
	{
		if (!addon_installed('ocf_post_templates')) return array();

		$all_templates=$GLOBALS['FORUM_DB']->query_select('f_post_templates',array('*'));
		$apply=array();
		foreach ($all_templates as $template)
		{
			require_code('ocfiltering');
			$idlist=ocfilter_to_idlist_using_db($template['t_forum_multi_code'],'id','f_forums','f_forums','f_parent_forum','f_parent_forum','id',true,true,$GLOBALS['FORUM_DB']);
			if (in_array($forum_id,$idlist))
			{
				if (strpos($template['t_text'],'{')!==false)
				{
					require_code('tempcode_compiler');
					$e=template_to_tempcode($template['t_text']);
					$template['t_text']=$e->evaluate();
				}
				$apply[]=array($template['t_title'],$template['t_text'],$template['t_use_default_forums']);
			}
		}
		return $apply;
	}

	/**
	 * The form element for choosing a post template.
	 *
	 * @param  AUTO_LINK		The forum ID we are looking for post templates active in
	 * @return array			A pair: The form element (tempcode) and the default post to make
	 */
	function post_templates($forum_id)
	{
		if (!addon_installed('ocf_post_templates')) return array(new ocp_tempcode(),'');

		$specialisation=new ocp_tempcode();

		$templates=$this->ocf_get_post_templates($forum_id);
		$post_templates=new ocp_tempcode();
		$post='';
		foreach ($templates as $template)
		{
			list($title,$text,$default)=$template;
			if ($default) $post=$text;
			$post_templates->attach(form_input_list_entry(str_replace(chr(10),'\n',$text),$default==1,$title));
		}
		if ((!$post_templates->is_empty()) && (has_js()))
		{
			$post_templates2=form_input_list_entry('',false,do_lang_tempcode('NA_EM'));
			$post_templates2->attach($post_templates);

			$input=do_template('OCF_POST_TEMPLATE_SELECT',array('_GUID'=>'2e4270e8fb8050f0201f5aa2af56270a','TABINDEX'=>'3','LIST'=>$post_templates2));
			$specialisation->attach(_form_input('post_template',do_lang_tempcode('POST_TEMPLATE'),do_lang_tempcode('DESCRIPTION_POST_TEMPLATE'),$input,false,false));
		}

		return array($specialisation,$post);
	}

	/**
	 * The UI to create a new topic.
	 *
	 * @param  boolean		Whether a new Private Topic is being created
	 * @param  ?MEMBER		The member ID being whispered too (NULL: N/A)
	 * @param  string			Theme image code
	 * @param  ?tempcode		Text of screen (NULL: none)
	 * @return tempcode		The UI
	 */
	function new_topic($personal_topic=false,$member_id=NULL,$img_path='',$text=NULL) // Type
	{
		if (!$personal_topic)
		{
			$forum_id=get_param_integer('id');
		} else
		{
			$forum_id=NULL;
		}

		// Breadcrumbs etc
		if ($personal_topic)
		{
			check_specific_permission('use_pt');

			breadcrumb_set_parents(array(array('_SEARCH:forumview:pt',do_lang_tempcode('PERSONAL_TOPICS'))));

			$username=mixed();
			$username=($member_id==get_member())?false:$GLOBALS['FORUM_DRIVER']->get_username($member_id);
			if (is_null($username)) warn_exit(do_lang_tempcode('USER_NO_EXIST'));

			$staff_help_url=brand_base_url().'/docs'.strval(ocp_version()).'/pg/tut_correspondance';
		} else
		{
			if (!is_null($forum_id))
			{
	         if (!has_category_access(get_member(),'forums',strval($forum_id))) access_denied('CATEGORY_ACCESS'); // Can happen if trying to reply to a stated whisper made to you in a forum you don't have access to
			}

			$staff_help_url=NULL;

			$tree=ocf_forum_breadcrumbs($forum_id,NULL,NULL,false);
			breadcrumb_add_segment($tree,do_lang_tempcode('ADD_TOPIC'));
		}

		$hidden_fields=new ocp_tempcode();
		$specialisation=new ocp_tempcode();

		global $NON_CANONICAL_PARAMS;
		$NON_CANONICAL_PARAMS[]='quote';

		// Where to post to
		$map=array('page'=>'_SELF','type'=>'_add_reply');
		$redirect=get_param('redirect','');
		if ($redirect!='') $map['redirect']=$redirect;
		$post_url=build_url($map,'_SELF');

		// Title
		$specialisation->attach(form_input_line(do_lang_tempcode('TITLE'),'','title',post_param('title',''),true,1));

		// Where it goes to
		if ($personal_topic)
		{
			if ($member_id==get_member())
			{
				$specialisation->attach(form_input_username_multi(do_lang_tempcode('TO'),'','to_member_id_',array(),1,true,1));
				check_specific_permission('use_pt');
			} else
			{
				$hidden_fields->attach(form_input_hidden('member_id',strval($member_id)));
			}
			$threaded=false;
		} else
		{
			$hidden_fields->attach(form_input_hidden('forum_id',strval($forum_id)));
			$threaded=($GLOBALS['FORUM_DB']->query_value('f_forums','f_is_threaded',array('id'=>$forum_id))==1);
		}

		// Description
		if ((get_option('is_on_topic_descriptions')=='1') && (!$threaded))
			$specialisation->attach(form_input_line(do_lang_tempcode('DESCRIPTION'),'','description',post_param('description',''),false,2));

		// Set up some post details
		$post=post_param('post','');
		$quote=get_param_integer('quote',-1);
		if ($quote!=-1)
		{
			$_postdetails=$this->attach_quotes(array($quote));
			$post=$_postdetails->evaluate();
		}
		if (!$personal_topic)
		{
			list($post_templates,$post2)=$this->post_templates($forum_id);
			if ($post=='') $post=$post2;
			$specialisation->attach($post_templates);
		}
		if (get_option('is_on_topic_emoticons')=='1')
			$specialisation->attach($this->choose_topic_emoticon($img_path));

		if (is_guest())
		{
			$specialisation->attach(form_input_line(do_lang_tempcode('GUEST_NAME'),new ocp_tempcode(),'poster_name_if_guest',do_lang('GUEST'),true));
		}

		/*if (has_specific_permission(get_member(),'decide_comment_type'))	Threaded topics not implemented (yet?)
		{
			$topic_types=new ocp_tempcode();
			$topic_types->attach(form_input_list_entry('0',get_option('threaded_topics_default')=='0',do_lang_tempcode('LINEAR_TOPIC')));
			$topic_types->attach(form_input_list_entry('1',get_option('threaded_topics_default')=='1',do_lang_tempcode('THREADED_TOPIC')));
			$specialisation->attach(form_input_list(do_lang_tempcode('TOPIC_TYPE'),do_lang_tempcode('DESCRIPTION_TOPIC_TYPE'),'topic_type',do_lang('GUEST'),$topic_types));
		} else
		{
			$hidden_fields->attach(form_input_hidden('topic_type',get_option('threaded_topics_default')));
		}*/

		// Various kinds of tick options
		if ((!$personal_topic) && (ocf_may_moderate_forum($forum_id,get_member())))
		{
			$moderation_options=array(
								array(do_lang_tempcode('OPEN'),'open',true,do_lang_tempcode('DESCRIPTION_OPEN')),
								array(do_lang_tempcode('EMPHASISED'),'is_emphasised',false,do_lang_tempcode('DESCRIPTION_EMPHASISED')),
								array(do_lang_tempcode('PINNED'),'pinned',false,do_lang_tempcode('DESCRIPTION_PINNED')),
						);
			if (addon_installed('unvalidated'))
				$moderation_options[]=array(do_lang_tempcode('VALIDATED'),'validated',true,do_lang_tempcode('DESCRIPTION_VALIDATED'));
			if (get_value('disable_sunk')!=='1')
				$moderation_options[]=array(do_lang_tempcode('SUNK'),'sunk',false,do_lang_tempcode('DESCRIPTION_SUNK'));
			if (!$personal_topic) $moderation_options[]=array(do_lang_tempcode('CASCADING'),'cascading',false,do_lang_tempcode('DESCRIPTION_CASCADING'));
		} else
		{
			$hidden_fields->attach(form_input_hidden('open','1'));
			$hidden_fields->attach(form_input_hidden('validated','1'));
			$moderation_options=array();
		}
		$hidden_fields->attach(form_input_hidden('from_url',get_self_url(true)));
		$options=array();
		if (!is_guest())
		{
			if (get_value('disable_skip_sig')!=='1')
			{
				if (addon_installed('ocf_signatures'))
					$options[]=array(do_lang_tempcode('SKIP_SIGNATURE'),'skip_sig',false,do_lang_tempcode('DESCRIPTION_SKIP_SIGNATURE'));
			}
			if (get_option('is_on_anonymous_posts')=='1')
				$options[]=array(do_lang_tempcode('_MAKE_ANONYMOUS_POST'),'anonymous',false,do_lang_tempcode('MAKE_ANONYMOUS_POST_DESCRIPTION'));
		}
		$options[]=array(do_lang_tempcode('ADD_TOPIC_POLL'),'add_poll',false,do_lang_tempcode('DESCRIPTION_ADD_TOPIC_POLL'));
		$specialisation2=new ocp_tempcode();
		if (count($options)==1) // Oh, actually we know this was just the option to add a poll, so show simply
		{
			$specialisation->attach(form_input_tick(do_lang_tempcode('ADD_TOPIC_POLL'),do_lang_tempcode('DESCRIPTION_ADD_TOPIC_POLL'),'add_poll',false));
		} else
		{
			$specialisation2->attach(form_input_various_ticks($options,''));
		}
		if (count($moderation_options)!=0)
		{
			$specialisation2->attach(form_input_various_ticks($moderation_options,'',NULL,do_lang_tempcode('MODERATION_OPTIONS')));
		}

		// Custom fields?
		require_code('fields');
		if (has_tied_catalogue('topic'))
		{
			append_form_custom_fields('topic',NULL,$specialisation,$hidden_fields);
		}
		if (has_tied_catalogue('post'))
		{
			append_form_custom_fields('post',NULL,$specialisation,$hidden_fields);
		}

		if (is_null($text))
			$text=new ocp_tempcode();

		// CAPTCHA?
		if (addon_installed('captcha'))
		{
			require_code('captcha');
			if (use_captcha())
			{
				$specialisation->attach(form_input_captcha());
				$text->attach(paragraph(do_lang_tempcode('FORM_TIME_SECURITY')));
			}
		}

		// Note about points?
		if (addon_installed('points'))
		{
			$login_url=build_url(array('page'=>'login','type'=>'misc','redirect'=>get_self_url(true,true)),get_module_zone('login'));
			$_login_url=escape_html($login_url->evaluate());
			if ((is_guest()) && ((get_forum_type()!='ocf') || (has_actual_page_access(get_member(),'join')))) $text->attach(paragraph(do_lang_tempcode('NOT_LOGGED_IN_NO_CREDIT',$_login_url)));
		}

		// Needs validating?
		if ((!is_null($forum_id)) && (!has_specific_permission(get_member(),'bypass_validation_midrange_content','topics',array('forums',$forum_id))))
		{
			$text->attach(paragraph(do_lang_tempcode('WILL_NEED_VALIDATING')));
		}

		// Awards?
		if (addon_installed('awards'))
		{
			require_code('awards');
			$specialisation->attach(get_award_fields('seedy_page'));
		}

		// Render form
		$posting_form=get_posting_form(do_lang($personal_topic?'ADD_PERSONAL_TOPIC':'ADD_TOPIC'),$post,$post_url,$hidden_fields,$specialisation,NULL,'',$specialisation2,NULL,$this->_post_javascript().(function_exists('captcha_ajax_check')?captcha_ajax_check():''));

		// Work out title to show
		if (!$personal_topic)
		{
			$forum_name=$GLOBALS['FORUM_DB']->query_value_null_ok('f_forums','f_name',array('id'=>$forum_id));
			if (is_null($forum_name)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		}
		if ($personal_topic)
		{
			if ($username===false)
			{
				$title=do_lang_tempcode('_ADD_PERSONAL_TOPIC_UNKNOWN');
			} else
			{
				$title=do_lang_tempcode('_ADD_PERSONAL_TOPIC',escape_html($username));
			}
		} else
		{
			$title=do_lang_tempcode('_ADD_TOPIC',escape_html($forum_name));
		}
		$_title=get_page_title($title,false);

		return do_template('POSTING_SCREEN',array('_GUID'=>'ba5308fe0a8f9f9a24988209423a3a16','STAFF_HELP_URL'=>$staff_help_url,'TEXT'=>$text,'TITLE'=>$_title,'POSTING_FORM'=>$posting_form));
	}

	/**
	 * The UI to create a PT.
	 *
	 * @return tempcode		The UI
	 */
	function new_pt() // Type
	{
		if (is_guest()) access_denied('NOT_AS_GUEST');

		$member_id=get_param_integer('intended_solely_for',get_param_integer('id',get_member()));

		check_specific_permission('use_pt');
		require_code('ocf_members2');
		if (!ocf_may_whisper($member_id)) warn_exit(do_lang_tempcode('NO_PT_FROM_ALLOW'));

		if (get_value('disable_pt_restrict')!=='1')
		{
			$agreed=get_param_integer('agreed',0);
			$rules=get_translated_tempcode($GLOBALS['FORUM_DRIVER']->get_member_row_field($member_id,'m_pt_rules_text'),$GLOBALS['FORUM_DB']);
			if (($agreed==0) && (!$rules->is_empty()))
			{
				$url=get_self_url(false,false,array('agreed'=>'1'));
				$title=get_page_title('NEW_PERSONAL_TOPIC');
				return do_template('OCF_MEMBER_PT_RULES_SCREEN',array('_GUID'=>'0c39906d4aeb728cc386cd9a79a338c7','TITLE'=>$title,'USERNAME'=>$GLOBALS['FORUM_DRIVER']->get_username($member_id),'MEMBER_ID'=>strval($member_id),'URL'=>$url,'RULES'=>$rules));
			}
		}

		$text=do_lang_tempcode('PERSONAL_TOPIC_DOC');

		return $this->new_topic(true,$member_id,'',$text);
	}

	/**
	 * Sort out breadcrumbing for a forum/topic/additional combination.
	 *
	 * @param  AUTO_LINK		The forum for breadcrumbing
	 * @param  AUTO_LINK		The topic for breadcrumbing
	 * @param  string			The topic title
	 * @param  string			The action currently being done
	 */
	function handle_topic_breadcrumbs($forum_id,$topic_id,$topic_title,$doing)
	{
		if (is_null($forum_id))
		{
			breadcrumb_set_parents(array(array('_SEARCH:forumview:pt',do_lang_tempcode('PERSONAL_TOPICS')),array('_SEARCH:topicview:id='.strval($topic_id),$topic_title)));
		} else
		{
			$tree=ocf_forum_breadcrumbs($forum_id,NULL,NULL,false);
			breadcrumb_add_segment($tree,array(array('_SEARCH:topicview:id='.strval($topic_id),$topic_title),array('',$doing)));
		}
	}

	/**
	 * The UI to make a post.
	 *
	 * @return tempcode		The UI
	 */
	function new_post()
	{
		require_code('ocf_posts2');

		global $NON_CANONICAL_PARAMS;
		$NON_CANONICAL_PARAMS[]='quote';
		$NON_CANONICAL_PARAMS[]='intended_solely_for';

		$topic_id=get_param_integer('id');
		$parent_id=either_param_integer('parent_id',NULL);
		$intended_solely_for=get_param_integer('intended_solely_for',-1);
		$post=post_param('post',NULL); // Copy existing post into box (from quick reply 'more options' button)
		if (is_null($post))
		{
			$quotes=array();
			$quote=get_param_integer('quote',-1);
			if ($quote==-1)
			{
				$quotes=$this->get_markers();

			} else $quotes[]=$quote;
			$post=$this->attach_quotes($quotes);
		}

		$topic_info=$GLOBALS['FORUM_DB']->query_select('f_topics',array('*'),array('id'=>$topic_id),'',1);
		if (!array_key_exists(0,$topic_info)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$forum_id=$topic_info[0]['t_forum_id'];
		$topic_title=$topic_info[0]['t_cache_first_title'];
		if ($topic_title=='') $topic_title=$GLOBALS['FORUM_DB']->query_value_null_ok('f_posts','p_title',array('p_topic_id'=>$topic_id));
		if (is_null($topic_title)) $topic_title='';
		if (!is_null($forum_id))
		{
         if (!has_category_access(get_member(),'forums',strval($forum_id))) access_denied('CATEGORY_ACCESS'); // Can happen if trying to reply to a stated whisper made to you in a forum you don't have access to
		} else
		{
			// It must be a Private Topic. Do we have access?
			$from=$topic_info[0]['t_pt_from'];
			$to=$topic_info[0]['t_pt_to'];

			if (($from!=get_member()) && ($to!=get_member()) && (!ocf_has_special_pt_access($topic_id)) && (!has_specific_permission(get_member(),'view_other_pt')))
			{
				access_denied('SPECIFIC_PERMISSION','view_other_pt');
			}
		}
		$this->handle_topic_breadcrumbs($forum_id,$topic_id,$topic_title,do_lang_tempcode('ADD_POST'));

		if ($topic_info[0]['t_is_open']==0)
		{
			$may_moderate_forum=ocf_may_moderate_forum($forum_id);
			if (!$may_moderate_forum)
			{
				warn_exit(do_lang_tempcode('TOPIC_IS_CLOSED'));
			}
		}

		$hidden_fields=new ocp_tempcode();
		$hidden_fields->attach(form_input_hidden('topic_id',strval($topic_id)));
		$hidden_fields->attach(form_input_hidden('from_url',get_self_url(true,false,array('type'=>get_param('type','misc')))));

		$map=array('page'=>'_SELF','type'=>'_add_reply','parent_id'=>$parent_id);
		$test=get_param_integer('kfs'.(is_null($forum_id)?'':strval($forum_id)),-1);
		if (($test!=-1) && ($test!=0)) $map['kfs'.(is_null($forum_id)?'':strval($forum_id))]=$test;
		$test=get_param_integer('threaded',-1);
		if ($test!=-1) $map['threaded']=$test;
		$post_url=build_url($map,'_SELF');

		// Certain aspects relating to the posting system
		$specialisation=new ocp_tempcode();
		if (get_option('is_on_post_titles')=='1')
			$specialisation->attach(form_input_line(do_lang_tempcode('TITLE'),'','title',post_param('title',''),false,1));
		if (ocf_may_moderate_forum($forum_id,get_member()))
		{
			$moderation_options=array(
								array(do_lang_tempcode('EMPHASISED'),'is_emphasised',false,do_lang_tempcode('DESCRIPTION_EMPHASISED'))
						);
			if (addon_installed('unvalidated'))
				$moderation_options[]=array(do_lang_tempcode('VALIDATED'),'validated',true,do_lang_tempcode('DESCRIPTION_VALIDATED'));
			//if ($intended_solely_for==-1) $moderation_options[]=array(do_lang_tempcode('CASCADING'),'cascading',false,do_lang_tempcode('DESCRIPTION_CASCADING'));
		} else
		{
			$moderation_options=array();
			$hidden_fields->attach(form_input_hidden('validated','1'));
		}
		$options=array();
		if (!is_guest())
		{
			if (get_value('disable_skip_sig')!=='1')
			{
				if (addon_installed('ocf_signatures'))
					$options[]=array(do_lang_tempcode('SKIP_SIGNATURE'),'skip_sig',false,do_lang_tempcode('DESCRIPTION_SKIP_SIGNATURE'));
			}
			if (get_option('is_on_anonymous_posts')=='1')
				$options[]=array(do_lang_tempcode('_MAKE_ANONYMOUS_POST'),'anonymous',false,do_lang_tempcode('MAKE_ANONYMOUS_POST_DESCRIPTION'));
		}
		$specialisation2=form_input_various_ticks($options,'');
		if (count($moderation_options)!=0) $specialisation2->attach(form_input_various_ticks($moderation_options,'',NULL,do_lang_tempcode('MODERATION_OPTIONS')));

		if (!is_null($forum_id))
		{
			$post_templates=$this->post_templates($forum_id);
			$specialisation->attach($post_templates[0]);
			if (((is_object($post)) && ($post->is_empty())) || ($post==='')) $post=$post_templates[1];
		}

		$_intended_solely_for='';
		if ($intended_solely_for!=-1)
		{
			$_intended_solely_for=$GLOBALS['FORUM_DRIVER']->get_username($intended_solely_for);
			if (is_null($_intended_solely_for)) $_intended_solely_for='';
		}
		if (ocf_may_make_personal_topic())
		{
			if (($_intended_solely_for!='') || (get_value('no_inline_pp_advertise')!=='1'))
				$specialisation->attach(form_input_username(do_lang_tempcode('WHISPER'),do_lang_tempcode('DESCRIPTION_WHISPER'),'intended_solely_for',$_intended_solely_for,false));
		}

		if (is_guest())
		{
			$specialisation->attach(form_input_line(do_lang_tempcode('_DESCRIPTION_NAME'),'','poster_name_if_guest',do_lang('GUEST'),true));
		}

		require_code('fields');
		if (has_tied_catalogue('post'))
		{
			append_form_custom_fields('post',NULL,$specialisation,$hidden_fields);
		}

		$text=new ocp_tempcode();

		if (addon_installed('captcha'))
		{
			require_code('captcha');
			if (use_captcha())
			{
				$specialisation->attach(form_input_captcha());
				$text->attach(paragraph(do_lang_tempcode('FORM_TIME_SECURITY')));
			}
		}

		if (addon_installed('points'))
		{
			$login_url=build_url(array('page'=>'login','type'=>'misc','redirect'=>get_self_url(true,true)),get_module_zone('login'));
			$_login_url=escape_html($login_url->evaluate());
			if ((is_guest()) && ((get_forum_type()!='ocf') || (has_actual_page_access(get_member(),'join')))) $text->attach(paragraph(do_lang_tempcode('NOT_LOGGED_IN_NO_CREDIT',$_login_url)));
		}

		if ((!is_null($forum_id)) && (!has_specific_permission(get_member(),'bypass_validation_lowrange_content','topics',array('forums',$forum_id))))
		{
			$text->attach(paragraph(do_lang_tempcode('WILL_NEED_VALIDATING')));
		}

		// Awards?
		if (addon_installed('awards'))
		{
			require_code('awards');
			$specialisation->attach(get_award_fields('post'));
		}

		// Moderator reply
		if (ocf_may_moderate_forum($forum_id,get_member()))
		{
			require_code('ocf_forums2');

			$specialisation2->attach(do_template('FORM_SCREEN_FIELD_SPACER',array('SECTION_HIDDEN'=>true,'TITLE'=>do_lang_tempcode('TOPIC_MODERATION'))));
			$specialisation2->attach(form_input_line(do_lang_tempcode('TITLE'),'','new_title',$topic_title,false));
			$specialisation2->attach(form_input_tree_list(do_lang_tempcode('DESTINATION_FORUM'),do_lang_tempcode('DESCRIPTION_DESTINATION_FORUM'),'to',NULL,'choose_forum',array(),false,is_null($forum_id)?'':strval($forum_id)));
			$options=array(
								array(do_lang_tempcode('OPEN'),'open',$topic_info[0]['t_is_open']==1,do_lang_tempcode('DESCRIPTION_OPEN')),
								array(do_lang_tempcode('PINNED'),'pinned',$topic_info[0]['t_pinned']==1,do_lang_tempcode('DESCRIPTION_PINNED')),
						);
			if (addon_installed('unvalidated'))
			{
				if ($topic_info[0]['t_validated']==0)
				{
					$topic_info[0]['t_validated']=get_param_integer('validated',0);
					if ($topic_info[0]['t_validated']==1) attach_message(do_lang_tempcode('WILL_BE_VALIDATED_WHEN_SAVING'));
				}

				$options[]=array(do_lang_tempcode('VALIDATED'),'topic_validated',$topic_info[0]['t_validated']==1,do_lang_tempcode('DESCRIPTION_VALIDATED'));
			}
			if (get_value('disable_sunk')!=='1')
				$moderation_options[]=array(do_lang_tempcode('SUNK'),'sunk',$topic_info[0]['t_sunk']==1,do_lang_tempcode('DESCRIPTION_SUNK'));
			if (!is_null($forum_id)) $options[]=array(do_lang_tempcode('CASCADING'),'cascading',$topic_info[0]['t_cascading']==1,do_lang_tempcode('DESCRIPTION_CASCADING'));
			$specialisation2->attach(form_input_various_ticks($options,''));
			if (addon_installed('calendar'))
				$specialisation2->attach(form_input_date__scheduler(do_lang_tempcode('OCF_PUBLICATION_TIME'),do_lang_tempcode('OCF_DESCRIPTION_PUBLICATION_TIME'),'schedule',true,true,true));
		}

		$topic_posts=new ocp_tempcode();
		$posts=$GLOBALS['FORUM_DB']->query('SELECT *,p.id AS id FROM '.$GLOBALS['FORUM_DB']->get_table_prefix().'f_posts p LEFT JOIN '.$GLOBALS['FORUM_DB']->get_table_prefix().'translate t ON '.db_string_equal_to('language',user_lang()).' AND t.id=p.p_post WHERE p_topic_id='.strval($topic_id).' AND (p_intended_solely_for IS NULL OR p_intended_solely_for='.strval(get_member()).' OR p_poster='.strval(get_member()).') AND p_validated=1 ORDER BY p_time DESC,p.id DESC',30);
		foreach ($posts as $row)
		{
			$topic_posts->attach(do_template('OCF_POSTING_SCREEN_POST',array('TITLE'=>$row['p_title'],'ID'=>strval($row['id']),'POSTER'=>strval($row['p_poster']),'POST'=>ocf_show_isolated_post($row,true))));
		}
		if (!$topic_posts->is_empty()) $topic_posts=do_template('OCF_POSTING_SCREEN_POSTS',array('_GUID'=>'3d3b14cf3a48b2a16eed5b1bd92b1187','POSTS'=>$topic_posts));

		if (is_object($post)) $post=$post->evaluate();
		$posting_form=get_posting_form(do_lang('ADD_POST'),$post,$post_url,$hidden_fields,$specialisation,NULL,$topic_posts->evaluate(),$specialisation2,NULL,$this->_post_javascript());

		$title=get_page_title('_ADD_POST',true,array(escape_html($topic_title)));

		if (post_param_integer('add_poll',0)==1)
		{
			// Show it worked / Refresh
			$url=build_url(array('page'=>'_SELF','type'=>'add_poll'),'_SELF');
			return redirect_screen($title,$url,do_lang_tempcode('SUCCESS'));
		}

		return do_template('POSTING_SCREEN',array('_GUID'=>'ca2eab9a9ffdab267a48eb7be48ccdc0','TEXT'=>$text,'TITLE'=>$title,'POSTING_FORM'=>$posting_form));
	}

	/**
	 * The UI to report a post.
	 *
	 * @return tempcode		The UI
	 */
	function report_post() // Type
	{
		$post_id=get_param_integer('id');

		$post_info=$GLOBALS['FORUM_DB']->query_select('f_posts',array('*'),array('id'=>$post_id),'',1);
		if (!array_key_exists(0,$post_info)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$topic_id=$post_info[0]['p_topic_id'];
		$topic_info=$GLOBALS['FORUM_DB']->query_select('f_topics',array('*'),array('id'=>$topic_id),'',1);
		if (!array_key_exists(0,$topic_info)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));

		$this->handle_topic_breadcrumbs($topic_info[0]['t_forum_id'],$topic_id,$topic_info[0]['t_cache_first_title'],do_lang_tempcode('REPORT_POST'));

		$this->check_has_mod_access($topic_id);

		$poster=$post_info[0]['p_poster_name_if_guest'];

		$member=$poster;
		if (!is_guest($post_info[0]['p_poster'])) $member='[page type="view" id="'.strval($post_info[0]['p_poster']).'" param="'.get_module_zone('members').'" caption="'.$poster.'"]members[/page]';

		$_postdetails=post_param('post',NULL);
		if (is_null($_postdetails))
		{
			$__post=get_translated_text($post_info[0]['p_post'],$GLOBALS['FORUM_DB']);
			$post=do_template('OCF_REPORTED_POST_FCOMCODE',array('_GUID'=>'e0f65423f3cb7698d5f04431dbe52ddb','POST_ID'=>strval($post_id),'MEMBER'=>$member,'TOPIC_TITLE'=>$topic_info[0]['t_cache_first_title'],'POST'=>$__post,'POSTER'=>$poster));
		} else $post=make_string_tempcode($_postdetails);

		$hidden_fields=new ocp_tempcode();
		if (!is_guest())
		{
			$options=array();
			if (get_option('is_on_anonymous_posts')=='1')
				$options[]=array(do_lang_tempcode('_MAKE_ANONYMOUS_POST'),'anonymous',false,do_lang_tempcode('MAKE_ANONYMOUS_POST_DESCRIPTION'));
			$specialisation=form_input_various_ticks($options,'');
		} else $specialisation=new ocp_tempcode();

		$hidden_fields->attach(form_input_hidden('forum_id','-2'));
		$hidden_fields->attach(form_input_hidden('validated','1'));
		$report_title=$post_info[0]['p_title'];
		if ($report_title=='') $report_title=$topic_info[0]['t_cache_first_title'];
		$hidden_fields->attach(form_input_hidden('title',do_lang('REPORTED_POST_TITLE',$report_title)));
		$hidden_fields->attach(form_input_hidden('o_post_id',strval($post_id)));
		$hidden_fields->attach(form_input_hidden('from_url',get_self_url(true)));

		$text=new ocp_tempcode();

		if (addon_installed('captcha'))
		{
			require_code('captcha');
			if (use_captcha())
			{
				$specialisation->attach(form_input_captcha());
				$text->attach(paragraph(do_lang_tempcode('FORM_TIME_SECURITY')));
			}
		}

		if (addon_installed('points'))
		{
			$login_url=build_url(array('page'=>'login','type'=>'misc','redirect'=>get_self_url(true,true)),get_module_zone('login'));
			$_login_url=escape_html($login_url->evaluate());
			if ((is_guest()) && ((get_forum_type()!='ocf') || (has_actual_page_access(get_member(),'join')))) $text->attach(paragraph(do_lang_tempcode('NOT_LOGGED_IN_NO_CREDIT',$_login_url)));
		}

		$post_url=build_url(array('page'=>'_SELF','type'=>'_add_reply'),'_SELF');

		$posting_form=get_posting_form(do_lang('REPORT_POST'),$post->evaluate(),$post_url,$hidden_fields,$specialisation,NULL,'',NULL,NULL,$this->_post_javascript().(function_exists('captcha_ajax_check')?captcha_ajax_check():''),NULL,true,false);

		$title=get_page_title('REPORT_POST');
		return do_template('POSTING_SCREEN',array('_GUID'=>'eee64757e66fed702f74fecf8d595260','TITLE'=>$title,'TEXT'=>$text,'POSTING_FORM'=>$posting_form));
	}

	/**
	 * The actualiser to add a reply.
	 *
	 * @return tempcode		The UI
	 */
	function _add_reply() // Type
	{
		if (addon_installed('captcha'))
		{
			require_code('captcha');
			enforce_captcha();
		}

		require_code('attachments2');
		require_code('ocf_posts_action');
		require_code('ocf_posts_action2');

		$invited_members=array();

		$topic_id=either_param_integer('topic_id',-1); // Posting into an existing topic?
		$forum_id=post_param_integer('forum_id',-1); // New topic in existing forum? (NB: -2 represents reported posts forum)
		$member_id=post_param_integer('member_id',-1); // Send TOPIC to specific member? Could be Private Topic (topic_id==-1, forum_id==-1), or personal post (topic_id!=-1, forum_id==-1)
		$parent_id=either_param_integer('parent_id',NULL);
		if ($member_id==-1)
		{
			$member_username=post_param('to_member_id_0','');
			if ($member_username!='')
			{
				$member_id=$GLOBALS['FORUM_DRIVER']->get_member_from_username($member_username);
				if (is_null($member_id)) warn_exit(do_lang_tempcode('_USER_NO_EXIST',$member_username));
			}
			foreach ($_POST as $key=>$_invited_member)
			{
				if (substr($key,0,13)!='to_member_id_') continue;
				if ($key=='to_member_id_0') continue;
				if ($_invited_member=='') continue;

				if (get_magic_quotes_gpc()) $_invited_member=stripslashes($_invited_member);

				$invited_member=$GLOBALS['FORUM_DRIVER']->get_member_from_username($_invited_member);
				if (is_null($invited_member))
				{
					attach_message(do_lang_tempcode('_USER_NO_EXIST',$_invited_member),'warn');
				} else
				{
					$invited_members[]=intval($invited_member);
				}
			}
		}

		$validated=post_param_integer('validated',post_param_integer('_validated',0));
		$is_emphasised=post_param_integer('is_emphasised',0);
		$skip_sig=post_param_integer('skip_sig',0);

		$post=post_param('post');
		$title=post_param('title',NULL);
		if (is_null($title)) $title='';

		$check_permissions=true;
		$add_poll=post_param_integer('add_poll',0);
		$topic_validated=$validated;
		if ($validated==1) $topic_validated=1-$add_poll; // If a topic is gonna have a poll added, it starts unvalidated. Adding the poll will validate it.

		$anonymous=post_param_integer('anonymous',0);
		$poster_name_if_guest=post_param('poster_name_if_guest',NULL);
		if ($poster_name_if_guest=='') $poster_name_if_guest=NULL;
		if (!is_null($poster_name_if_guest))
		{
			$restricted_usernames=explode(',',get_option('restricted_usernames'));
			$restricted_usernames[]=do_lang('GUEST');
			$restricted_usernames[]=do_lang('UNKNOWN');
			$restricted_usernames[]=do_lang('SYSTEM');
			foreach ($restricted_usernames as $_restricted_username)
			{
				$restricted_username=trim($_restricted_username);
				if ($restricted_username=='') continue;
				if (strpos($poster_name_if_guest,$restricted_username)!==false)
				{
					$poster_name_if_guest=NULL;
					break;
				}
			}
		}

		$new_topic=($topic_id==-1);

		if (!$new_topic)
		{
			$_intended_solely_for=post_param('intended_solely_for','');
			if ($_intended_solely_for=='')
			{
				$intended_solely_for=NULL;
			} else
			{
				$intended_solely_for=$GLOBALS['FORUM_DRIVER']->get_member_from_username($_intended_solely_for);
				if (is_null($intended_solely_for)) warn_exit(do_lang_tempcode('_USER_NO_EXIST',$_intended_solely_for));
			}
		} else $intended_solely_for=NULL;

		require_code('ocf_topics_action');
		require_code('ocf_topics_action2');
		if ($new_topic) // A new topic
		{
			ocf_check_post($post);

			if ($title=='') warn_exit(do_lang_tempcode('NO_PARAMETER_SENT','title'));

			$sunk=post_param_integer('sunk',0);
			$topic_title=$title;

			if ($forum_id==-1) // New Private Topic
			{
				require_code('ocf_members2');
				if (!ocf_may_whisper($member_id)) warn_exit(do_lang_tempcode('NO_PT_FROM_ALLOW'));
				check_specific_permission('use_pt');

				$topic_id=ocf_make_topic(NULL,post_param('description',''),post_param('emoticon',''),$topic_validated,post_param_integer('open',0),post_param_integer('pinned',0),$sunk,post_param_integer('cascading',0),get_member(),$member_id);
				$_title=get_page_title('ADD_PERSONAL_TOPIC');
			}
			elseif ($forum_id==-2) // New reported post topic
			{
				$forum_id=$GLOBALS['FORUM_DRIVER']->forum_id_from_name(get_option('reported_posts_forum'));
				if (is_null($forum_id)) warn_exit(do_lang_tempcode('NO_REPORTED_POST_FORUM'));

				// See if post already reported...
				$topic_id=$GLOBALS['FORUM_DB']->query_value_null_ok('f_topics t LEFT JOIN '.$GLOBALS['FORUM_DB']->get_table_prefix().'f_posts p ON p.id=t.t_cache_first_post_id','t.id',array('p.p_title'=>$title,'t.t_forum_id'=>$forum_id));
				if (!is_null($topic_id))
				{
					// Already a topic
				} else // New topic
				{
					$topic_id=ocf_make_topic($forum_id,'','',1,1,0,0,0,NULL,NULL,false);
				}

				$_title=get_page_title('REPORT_POST');
				$check_permissions=false;
			} else // New topic
			{
				$topic_id=ocf_make_topic($forum_id,post_param('description',''),post_param('emoticon',''),$topic_validated,post_param_integer('open',0),post_param_integer('pinned',0),$sunk,post_param_integer('cascading',0));
				$_title=get_page_title('ADD_TOPIC');

				if (addon_installed('awards'))
				{
					require_code('awards');
					handle_award_setting('topic',strval($topic_id));
				}
			}
			$first_post=true;

			require_code('fields');
			if (has_tied_catalogue('topic'))
			{
				save_form_custom_fields('topic',strval($topic_id));
			}
		} else
		{
			$_title=get_page_title('ADD_POST');
			$first_post=false;

			$topic_info=$GLOBALS['FORUM_DB']->query_select('f_topics',array('t_cache_first_title','t_sunk','t_forum_id','t_is_open','t_description'),array('id'=>$topic_id),'',1);
			if (!array_key_exists(0,$topic_info)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
			$forum_id=$topic_info[0]['t_forum_id'];
			$topic_title=$topic_info[0]['t_cache_first_title'];
			$sunk=$topic_info[0]['t_sunk'];

			if ($topic_info[0]['t_is_open']==0)
			{
				$may_moderate_forum=ocf_may_moderate_forum($forum_id);
				if (!$may_moderate_forum)
				{
					warn_exit(do_lang_tempcode('TOPIC_IS_CLOSED'));
				}
			}

			// Moderator reply
			$new_title=post_param('new_title',NULL);
			if ((!is_null($new_title)) && (!is_null($forum_id)) && (ocf_may_moderate_forum($forum_id,get_member())))
			{
				$cascading=post_param_integer('cascading',0);
				$pinned=post_param_integer('pinned',0);
				$sunk=post_param_integer('sunk',0);
				$open=post_param_integer('open',0);
				$topic_validated=post_param_integer('topic_validated',0);
				$to=post_param_integer('to',NULL);
				$schedule=get_input_date('schedule');

				if ((!is_null($schedule)) && (addon_installed('calendar')))
				{
					$_intended_solely_for=is_null($intended_solely_for)?'NULL':strval($intended_solely_for);
					$_postdetailser_name_if_guest=is_null($poster_name_if_guest)?'NULL':('\''.addslashes($poster_name_if_guest).'\'');
					$_first_post=$first_post?'true':'false';
					$__title=is_null($title)?'NULL':('\''.str_replace(chr(10),'\'.chr(10).\'',addslashes($title)).'\'');
					$_postdetails=is_null($post)?'NULL':('\''.str_replace(chr(10),'\'.chr(10).\'',addslashes($post)).'\'');
					$_new_title=is_null($new_title)?'NULL':('\''.str_replace(chr(10),'\'.chr(10).\'',addslashes($new_title)).'\'');

$schedule_code=<<<END
:require_code('ocf_topics_action2'); require_code('ocf_topics_action'); ocf_edit_topic($topic_id,NULL,NULL,$validated,$open,$pinned,$sunk,$cascading,'',$_new_title); if (($to!=$forum_id) && (!is_null($to))) ocf_move_topics($forum_id,$to,array($topic_id)); \$post_id=ocf_make_post($topic_id,$__title,$_postdetails,$skip_sig,$_first_post,$validated,$is_emphasised,$_postdetailser_name_if_guest,NULL,NULL,NULL,$_intended_solely_for,NULL,NULL,false,true,NULL,true,$topic_title,$sunk,NULL,$anonymous==1); if (addon_installed('awards')) { require_code('awards'); handle_award_setting('post',strval(\$post_id)); }
END;
					require_code('calendar');
					$start_year=post_param_integer('schedule_year');
					$start_month=post_param_integer('schedule_month');
					$start_day=post_param_integer('schedule_day');
					$start_hour=post_param_integer('schedule_hour');
					$start_minute=post_param_integer('schedule_minute');
					require_code('calendar2');
					$event_id=add_calendar_event(db_get_first_id(),'',NULL,0,do_lang('ADD_POST'),$schedule_code,3,0,$start_year,$start_month,$start_day,$start_hour,$start_minute);
					regenerate_event_reminder_jobs($event_id);

					$text=do_lang_tempcode('SUCCESS');
					$map=array('page'=>'topicview','id'=>$topic_id,'type'=>'first_unread');
					$test=get_param_integer('kfs'.(is_null($forum_id)?'':strval($forum_id)),-1);
					if (($test!=-1) && ($test!=0)) $map['kfs'.(is_null($forum_id)?'':strval($forum_id))]=$test;
					$test=get_param_integer('threaded',-1);
					if ($test!=-1) $map['threaded']=$test;
					$_url=build_url($map,get_module_zone('topicview'));
					$url=$_url->evaluate();
					$url.='#first_unread';
					$url=get_param('redirect',$url);
					return redirect_screen($_title,$url,$text);
				}

				ocf_edit_topic($topic_id,NULL,NULL,$topic_validated,$open,$pinned,$sunk,$cascading,'',($new_title=='')?NULL:$new_title);
				if (($to!=$forum_id) && (!is_null($to))) ocf_move_topics($forum_id,$to,array($topic_id));
			}
		}

		$post_id=ocf_make_post($topic_id,$title,$post,$skip_sig,$first_post,$validated,$is_emphasised,$poster_name_if_guest,NULL,NULL,NULL,$intended_solely_for,NULL,NULL,$check_permissions,true,NULL,true,$topic_title,$sunk,NULL,$anonymous==1,$forum_id==-1 || is_null($forum_id),$forum_id==-1 || is_null($forum_id),false,$parent_id);

		if ((!is_null($forum_id)) && ($anonymous==0) && ($intended_solely_for===NULL))
		{
			if ((has_actual_page_access($GLOBALS['FORUM_DRIVER']->get_guest_id(),'forumview')) && (has_category_access($GLOBALS['FORUM_DRIVER']->get_guest_id(),'forums',strval($forum_id))))
				syndicate_described_activity($first_post?'ocf:ACTIVITY_ADD_TOPIC':'ocf:ACTIVITY_ADD_POST_IN',$first_post?$title:$topic_title,'','','_SEARCH:topicview:misc:'.strval($topic_id).'#post_'.strval($post_id),'','','ocf_forum');
		}

		require_code('fields');
		if (has_tied_catalogue('post'))
		{
			save_form_custom_fields('post',strval($post_id));
		}

		$validated=$GLOBALS['FORUM_DB']->query_value('f_posts','p_validated',array('id'=>$post_id));

		$rep_post_id=post_param_integer('o_post_id',-1);
		if ($rep_post_id!=-1)
		{
			$map=array('page'=>'topicview','id'=>$rep_post_id,'type'=>'findpost');
			$_url=build_url($map,get_module_zone('topicview'));
			$url=$_url->evaluate();
			$url.='#post_'.strval($rep_post_id);
		} else
		{
			$map=array('page'=>'topicview','id'=>$post_id,'type'=>'findpost');
			$test=get_param_integer('kfs'.(is_null($forum_id)?'':strval($forum_id)),-1);
			if (($test!=-1) && ($test!=0)) $map['kfs'.(is_null($forum_id)?'':strval($forum_id))]=$test;
			$test=get_param_integer('threaded',-1);
			if ($test!=-1) $map['threaded']=$test;
			$_url=build_url($map,get_module_zone('topicview'));
			$url=$_url->evaluate();
			if ($validated!=0) $url.='#post_'.strval($post_id);
		}

		if (($new_topic) && ($forum_id==-1))
		{
			require_code('notifications');

			enable_notifications('ocf_topic',strval($topic_id),get_member()); // from
			enable_notifications('ocf_topic',strval($topic_id),$member_id); // to
			foreach ($invited_members as $invited_member)
			{
				enable_notifications('ocf_topic',strval($topic_id),$invited_member);

				ocf_invite_to_pt(intval($invited_member),$topic_id);
			}
		}

		if ($anonymous==1)
		{
			log_it('MAKE_ANONYMOUS_POST',strval($post_id),$title);
		}

		if (addon_installed('awards'))
		{
			require_code('awards');
			handle_award_setting('post',strval($post_id));
		}

		if (($forum_id==-1) && ($member_id!=-1))
		{
			send_pt_notification($post_id,$title,$topic_id,$member_id,NULL,$post);
		}

		if ($add_poll==1)
		{
			if (post_param_integer('add_poll',0)==1)
			{
				// Show it worked / Refresh
				$_url=build_url(array('page'=>'_SELF','type'=>'add_poll','id'=>$topic_id,'try_validate'=>1),'_SELF');
				return redirect_screen($_title,$_url,do_lang_tempcode('SUCCESS'));
			}
		}

		if ((!$new_topic) && ($forum_id!=-1) && ($member_id==-1))
		{
			handle_topic_ticket_reply($forum_id,$topic_id,$topic_title,$post);
		}

		$text=($validated==1)?do_lang_tempcode('SUCCESS'):do_lang_tempcode('SUBMIT_UNVALIDATED');

		require_code('autosave');
		clear_ocp_autosave();

		// Show it worked / Refresh
		$url=get_param('redirect',$url);
		return redirect_screen($_title,$url,$text);
	}

	/**
	 * The actualiser to toggle notifications for a topic.
	 *
	 * @return tempcode		The UI
	 */
	function toggle_notifications_topic() // Type
	{
		require_code('notifications2');
		return notifications_ui_advanced('ocf_topic',do_lang_tempcode('NOW_ENABLED_NOTIFICATIONS_TOPIC'),do_lang_tempcode('NOW_DISABLED_NOTIFICATIONS_TOPIC'));
	}

	/**
	 * The actualiser to mark a topic as read.
	 *
	 * @return tempcode		The UI
	 */
	function mark_read_topic() // Type
	{
		$topic_id=get_param_integer('id');
		$forum_id=$GLOBALS['FORUM_DB']->query_value('f_topics','t_forum_id',array('id'=>$topic_id));

		ocf_ping_topic_read($topic_id);
		if ((is_null($forum_id)) || (get_param_integer('ajax',0)==1))
		{
			decache('side_ocf_personal_topics',array(get_member()));
			decache('_new_pp',array(get_member()));
		}

		$title=get_page_title('MARK_READ');

		if (get_param_integer('ajax',0)==1) exit();

		// Show it worked / Refresh
		$url=get_param('redirect');
		return redirect_screen($title,$url,do_lang_tempcode('SUCCESS'));
	}

	/**
	 * The actualiser to mark a topic as unread.
	 *
	 * @return tempcode		The UI
	 */
	function mark_unread_topic() // Type
	{
		$topic_id=get_param_integer('id');
		$forum_id=$GLOBALS['FORUM_DB']->query_value('f_topics','t_forum_id',array('id'=>$topic_id));
		if (is_null($forum_id))
		{
			decache('side_ocf_personal_topics',array(get_member()));
			decache('_new_pp',array(get_member()));
		}

		$this->ocf_ping_topic_unread($topic_id);

		return $this->redirect_to_forum('MARK_UNREAD',$forum_id,do_lang_tempcode('TOPIC_MARKED_UNREAD'));
	}

	/**
	 * The UI to grab a reason for deleting a post.
	 *
	 * @return tempcode		The UI
	 */
	function delete_post() // Type
	{
		$post_id=get_param_integer('id');
		$topic_id=$GLOBALS['FORUM_DB']->query_value_null_ok('f_posts','p_topic_id',array('id'=>$post_id));
		if (is_null($topic_id)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$topic_info=$GLOBALS['FORUM_DB']->query_select('f_topics',array('*'),array('id'=>$topic_id),'',1);
		if (!array_key_exists(0,$topic_info)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$this->handle_topic_breadcrumbs($topic_info[0]['t_forum_id'],$topic_id,$topic_info[0]['t_cache_first_title'],do_lang_tempcode('DELETE_POST'));

		if (has_specific_permission(get_member(),'mass_delete_from_ip'))
		{
			$title=get_page_title('DELETE_POST');
			$post_rows=$GLOBALS['FORUM_DB']->query_select('f_posts',array('p_ip_address','p_time'),array('id'=>$post_id));
			if (!array_key_exists(0,$post_rows)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
			$ip=$post_rows[0]['p_ip_address'];
			$time=$post_rows[0]['p_time'];
			$count=$GLOBALS['FORUM_DB']->query_value_null_ok_full('SELECT COUNT(*) FROM '.$GLOBALS['FORUM_DB']->get_table_prefix().'f_posts WHERE p_time>'.strval($time-60*60*24).' AND p_time<'.strval($time+60*60*24).' AND '.db_string_equal_to('p_ip_address',$ip));
			$_ip_link=build_url(array('page'=>'admin_lookup','param'=>get_ip_address()),get_module_zone('admin_lookup'));
			$ip_link=$_ip_link->evaluate();
			$text=paragraph(do_lang_tempcode('DELETE_POSTS_DESCRIPTION',integer_format($count),escape_html($ip),escape_html($ip_link)));
			$submit_name=do_lang_tempcode('DELETE_POST');
			$post_url=build_url(array('page'=>'_SELF','type'=>'_delete_post','id'=>$post_id),'_SELF',NULL,true);
			$fields=new ocp_tempcode();
			$hidden=new ocp_tempcode();
			$hidden->attach(build_keep_post_fields());
			$hidden->attach(build_keep_form_fields());
			$fields->attach(form_input_line(do_lang_tempcode('REASON'),'','reason','',false));

			$fields->attach(form_input_tick(do_lang_tempcode('DELETE_POSTS_FROM_IP'),do_lang_tempcode('DELETE_POSTS_FROM_IP_DESCRIPTION'),'post_all',false));

			return do_template('FORM_SCREEN',array('SKIP_VALIDATION'=>true,'STAFF_HELP_URL'=>brand_base_url().'/docs'.strval(ocp_version()).'/pg/tut_mod','HIDDEN'=>$hidden,'TITLE'=>$title,'TEXT'=>$text,'URL'=>$post_url,'FIELDS'=>$fields,'SUBMIT_NAME'=>$submit_name));
		}

		return $this->relay_with_reason('DELETE_POST');
	}

	/**
	 * The actualiser for deleting a post.
	 *
	 * @return tempcode		The UI
	 */
	function _delete_post() // Type
	{
      $post_id=either_param_integer('id',NULL);
      if (is_null($post_id)) $post_id=either_param_integer('post_id');
		$reason=post_param('reason');

		require_code('ocf_posts_action');
		require_code('ocf_posts_action2');
		require_code('ocf_posts_action3');

		if ((has_specific_permission(get_member(),'mass_delete_from_ip')) && (post_param_integer('post_all',0)==1))
		{
			$post_rows=$GLOBALS['FORUM_DB']->query_select('f_posts',array('p_ip_address','p_time','p_topic_id'),array('id'=>$post_id));
			if (!array_key_exists(0,$post_rows)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
			$ip=$post_rows[0]['p_ip_address'];
			$time=$post_rows[0]['p_time'];
			$topic_id=$post_rows[0]['p_topic_id'];
			$posts=$GLOBALS['FORUM_DB']->query('SELECT id,p_topic_id,p_title FROM '.$GLOBALS['FORUM_DB']->get_table_prefix().'f_posts WHERE p_time>'.strval($time-60*60*24).' AND p_time<'.strval($time+60*60*24).' AND '.db_string_equal_to('p_ip_address',$ip));

			$post_id=post_param_integer('id',NULL);
			if (is_null($post_id))
			{
				$post_id=get_param_integer('id');

				$post_url=build_url(array('page'=>'_SELF','type'=>get_param('type')),'_SELF',NULL,true);
				$hidden=form_input_hidden('id',strval($post_id));
				$hidden=form_input_hidden('reason',post_param('reason'));

				$stuff=new ocp_tempcode();
				foreach ($posts as $post)
				{
					if (!$stuff->is_empty()) $stuff->attach(do_lang_tempcode('LIST_SEP'));

					$url=$GLOBALS['FORUM_DRIVER']->post_url($post['id'],$post['p_topic_id']);

					if ($post['p_title']!='')
					{
						$stuff->attach(hyperlink($url,$post['p_title'],true,true));
					} else
					{
						$stuff->attach(hyperlink($url,'#'.strval($post['id']),true,true));
					}
				}

				return do_template('YESNO_SCREEN',array('TITLE'=>get_page_title('DELETE_POSTS'),'TEXT'=>do_lang_tempcode('CONFIRM_DELETE',$stuff),'URL'=>$post_url,'HIDDEN'=>$hidden));
			}

			foreach ($posts as $post)
			{
				require_code('fields');
				if (has_tied_catalogue('post'))
				{
					delete_form_custom_fields('post',$post['id']);
				}

				ocf_delete_posts_topic($post['p_topic_id'],array($post['id']),$reason);
			}

			return $this->redirect_to('DELETE_POSTS_FROM_IP',$topic_id);
		}

		$topic_id=$GLOBALS['FORUM_DB']->query_value_null_ok('f_posts','p_topic_id',array('id'=>$post_id));
		if (is_null($topic_id)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$_topic_info=$GLOBALS['FORUM_DB']->query_select('f_topics',array('t_cache_first_title','t_cache_first_post_id','t_forum_id'),array('id'=>$topic_id),'',1);
		$current_title=$_topic_info[0]['t_cache_first_title'];
		$deleted_all=ocf_delete_posts_topic($topic_id,array($post_id),$reason);
		if ($_topic_info[0]['t_cache_first_post_id']==$post_id) // See if we need to copy title
		{
			$_topic_info2=$GLOBALS['FORUM_DB']->query_select('f_topics',array('t_cache_first_title','t_cache_first_post_id'),array('id'=>$topic_id),'',1);
			if (array_key_exists(0,$_topic_info2))
			{
				if ($_topic_info2[0]['t_cache_first_title']==do_lang('NO_TOPIC_TITLE',strval($topic_id)))
				{
					$GLOBALS['FORUM_DB']->query_update('f_posts',array('p_title'=>$current_title),array('id'=>$_topic_info2[0]['t_cache_first_post_id']),'',1);
				}
			}
		}

		require_code('fields');
		if (has_tied_catalogue('post'))
		{
			delete_form_custom_fields('post',strval($post_id));
		}

		if ($deleted_all)
		{
			return $this->redirect_to_forum('DELETE_POST',$_topic_info[0]['t_forum_id']);
		}
		return $this->redirect_to('DELETE_POST',$topic_id);
	}

	/**
	 * The actualiser to vote in a poll.
	 *
	 * @return tempcode		The UI
	 */
	function vote_poll() // Type
	{
		$topic_id=get_param_integer('id'); // Yes, that's right -- we need to find the pollID from this, and will redirect back to given topic
		$topic_info=$GLOBALS['FORUM_DB']->query_select('f_topics',array('*'),array('id'=>$topic_id),'',1);
		if (!array_key_exists(0,$topic_info)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$poll_id=$topic_info[0]['t_poll_id'];

		$votes=array();
		$vote=post_param_integer('vote',-1);

		if ($vote!=-1)
		{
			$votes[]=$vote;
		}
		else
		{
			foreach (array_keys($_POST) as $key)
			{
				if (substr($key,0,5)=='vote_')
				{
					$votes[]=intval(substr($key,5));
				}
			}
		}

		require_code('ocf_polls_action');
		require_code('ocf_polls_action2');
		ocf_vote_in_poll($poll_id,$votes,NULL,$topic_info);

		return $this->redirect_to('VOTE_IN_POLL',$topic_id,do_lang_tempcode('THANKYOU_VOTING'));
	}

	/**
	 * Get tempcode for a poll adding/editing form.
	 *
	 * @param  SHORT_TEXT	The poll question
	 * @param  ?array			A list of current answers for the poll (NULL: none yet)
	 * @param  BINARY			Whether it is a private poll (blind poll, where the results aren't visible until made public)
	 * @param  BINARY			Whether the poll is open for voting
	 * @param  BINARY			Whether a reply to the poll topic is required before voting
	 * @param  BINARY			The minimum number of selections for voters
	 * @param  BINARY			The maximum number of selections for voters
	 * @return tempcode		The tempcode for the fields
	 */
	function get_poll_form_fields($question='',$answers=NULL,$is_private=0,$is_open=1,$requires_reply=0,$minimum_selections=1,$maximum_selections=1)
	{
		require_lang('polls');

		if (is_null($answers)) $answers=array();

		$fields=new ocp_tempcode();
		$fields->attach(form_input_line(do_lang_tempcode('QUESTION'),do_lang_tempcode('DESCRIPTION_QUESTION'),'question',$question,true));
		$fields->attach(form_input_line_multi(do_lang_tempcode('ANSWER'),do_lang_tempcode('_DESCRIPTION_ANSWER'),'answer_',$answers,2));

		$options=array(
							array(do_lang_tempcode('POLL_IS_OPEN'),'is_open',$is_open==1,do_lang_tempcode('DESCRIPTION_POLL_IS_OPEN')),
							array(do_lang_tempcode('_POLL_REQUIRES_REPLY'),'requires_reply',$requires_reply==1,do_lang_tempcode('DESCRIPTION_POLL_REQUIRES_REPLY')),
					);
		if ((has_specific_permission(get_member(),'may_unblind_own_poll')) && (!is_null($is_private)))
		{
			$options[]=array(do_lang_tempcode('POLL_IS_PRIVATE'),'is_private',$is_private==1,do_lang_tempcode('DESCRIPTION_POLL_IS_PRIVATE'));
		}
		$fields->attach(form_input_various_ticks($options,''));

		$fields->attach(form_input_integer(do_lang_tempcode('MINIMUM_SELECTIONS'),do_lang_tempcode('DESCRIPTION_MINIMUM_SELECTIONS'),'minimum_selections',$minimum_selections,true));
		$fields->attach(form_input_integer(do_lang_tempcode('MAXIMUM_SELECTIONS'),do_lang_tempcode('DESCRIPTION_MAXIMUM_SELECTIONS'),'maximum_selections',$maximum_selections,true));
		return $fields;
	}

	/**
	 * The UI to add a poll.
	 *
	 * @param  ?AUTO_LINK	The topic ID to add the poll to (NULL: it is instead gettable from a GET parameter named 'id')
	 * @return tempcode		The UI
	 */
	function add_poll($topic_id=NULL) // Type
	{
		if (is_null($topic_id)) $topic_id=get_param_integer('id');

		$map=array('page'=>'_SELF','type'=>'_add_poll','id'=>$topic_id);
		if (get_param_integer('try_validate',0)==1) $map['try_validate']=1;
		if ((get_param('type','misc')=='_add_reply') && (post_param_integer('validated',0)==1))
			$map['re_validate']=1;
		$post_url=build_url($map,'_SELF');

		$fields=new ocp_tempcode();

		$fields->attach($this->get_poll_form_fields());

		// Find polls we can grab
		$groups=_get_where_clause_groups(get_member());
		if (!is_null($groups))
		{
			$perhaps=$GLOBALS['SITE_DB']->query('SELECT category_name FROM '.get_table_prefix().'group_category_access WHERE '.db_string_equal_to('module_the_name','forums').' AND ('.$groups.')');
			$or_list='';
			foreach ($perhaps as $row)
			{
				if ($or_list!='') $or_list.=' OR ';
				$or_list.='t.t_forum_id='.strval((integer)$row['category_name']);
			}
			if ($or_list!='')
			{
				$polls=$GLOBALS['FORUM_DB']->query('SELECT p.*,t_cache_first_username FROM '.$GLOBALS['FORUM_DB']->get_table_prefix().'f_topics t LEFT JOIN '.$GLOBALS['FORUM_DB']->get_table_prefix().'f_polls p ON p.id=t.t_poll_id WHERE ('.$or_list.') AND p.id IS NOT NULL ORDER BY id DESC',30);
			} else $polls=array();
		} else
		{
			$polls=$GLOBALS['FORUM_DB']->query('SELECT p.*,t_cache_first_username FROM '.$GLOBALS['FORUM_DB']->get_table_prefix().'f_topics t LEFT JOIN '.$GLOBALS['FORUM_DB']->get_table_prefix().'f_polls p ON p.id=t.t_poll_id WHERE p.id IS NOT NULL ORDER BY id DESC',30);
		}
		if (count($polls)!=0)
		{
			$fields->attach(do_template('FORM_SCREEN_FIELD_SPACER',array('SECTION_HIDDEN'=>true,'TITLE'=>do_lang_tempcode('ALT_COPY_EXISTING_POLL'))));

			$list=new ocp_tempcode();
			$list->attach(form_input_list_entry('',true,''));
			foreach ($polls as $poll)
			{
				$list->attach(form_input_list_entry(strval($poll['id']),false,do_lang_tempcode('POLL_IN_LIST',escape_html($poll['po_question']),escape_html($poll['t_cache_first_username']))));
			}
			$fields->attach(form_input_list(do_lang_tempcode('EXISTING'),do_lang_tempcode('COPY_EXISTING_POLL'),'existing',$list,NULL,false,false));

			$javascript='var existing=document.getElementById(\'existing\'); var form=existing.form; var ch_func=function() { var disable_all=(existing.selectedIndex!=0); var i; for (i=0;i<form.elements.length;i++) if ((form.elements[i]!=existing) && (form.elements[i].id!=\'perform_keywordcheck\') && ((form.elements[i].getAttribute(\'type\')==\'checkbox\') || (form.elements[i].getAttribute(\'type\')==\'text\'))) { setRequired(form.elements[i].name,(!disable_all) && ((form.elements[i].id==\'question\') || (form.elements[i].id==\'answer_0\'))); setLocked(form.elements[i].name,disable_all); } }; for (i=0;i<form.elements.length;i++) addEventListenerAbstract(form.elements[i],\'change\',ch_func);';
		} else
		{
			$javascript='';
		}

		$title=get_page_title('ADD_TOPIC_POLL');
		$submit_name=do_lang_tempcode('ADD_TOPIC_POLL');

		$topic_info=$GLOBALS['FORUM_DB']->query_select('f_topics',array('*'),array('id'=>$topic_id),'',1);
		if (!array_key_exists(0,$topic_info)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$this->handle_topic_breadcrumbs($topic_info[0]['t_forum_id'],$topic_id,$topic_info[0]['t_cache_first_title'],do_lang_tempcode('ADD_TOPIC_POLL'));

		return do_template('FORM_SCREEN',array('_GUID'=>'ce1752a0c5508a061bffbf242a13e5bd','HIDDEN'=>'','TITLE'=>$title,'FIELDS'=>$fields,'TEXT'=>'','SUBMIT_NAME'=>$submit_name,'URL'=>$post_url,'JAVASCRIPT'=>$javascript));
	}

	/**
	 * The actualiser to add a poll.
	 *
	 * @return tempcode		The UI
	 */
	function _add_poll() // Type
	{
		$topic_id=get_param_integer('id');

		require_code('ocf_polls_action');
		require_code('ocf_polls_action2');

		$_existing=post_param('existing','');
		if ($_existing!='')
		{
			$existing=intval($_existing);

			$_poll_row=$GLOBALS['FORUM_DB']->query_select('f_topics t LEFT JOIN '.$GLOBALS['FORUM_DB']->get_table_prefix().'f_polls p ON t.t_poll_id=p.id',array('t_forum_id','p.*'),array('p.id'=>$existing),'',1);
			if (!array_key_exists(0,$_poll_row)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
			$row=$_poll_row[0];
			$existing_forum_id=$row['t_forum_id'];
			if (!has_category_access(get_member(),'forums',strval($existing_forum_id))) access_denied('CATEGORY_ACCESS_LEVEL');

			$answer_rows=$GLOBALS['FORUM_DB']->query_select('f_poll_answers',array('pa_answer'),array('pa_poll_id'=>$existing),'ORDER BY id');
			$answers=array();
			foreach ($answer_rows as $trow)
			{
				$answers[]=$trow['pa_answer'];
			}

			ocf_make_poll($topic_id,$row['po_question'],$row['po_is_private'],$row['po_is_open'],$row['po_minimum_selections'],$row['po_maximum_selections'],$row['po_requires_reply'],$answers);

			return $this->redirect_to('ADD_TOPIC_POLL',$topic_id);
		}

		$question=post_param('question');
		$is_private=post_param_integer('is_private',0);
		$is_open=post_param_integer('is_open',0);
		$minimum_selections=post_param_integer('minimum_selections',0);
		$maximum_selections=post_param_integer('maximum_selections',0);
		$requires_reply=post_param_integer('requires_reply',0);

		$answers=array();
		foreach ($_POST as $key=>$val)
		{
			if (!is_string($val)) continue;

			if (substr($key,0,7)=='answer_')
			{
				if (get_magic_quotes_gpc()) $val=stripslashes($val);
				if ($val!='') $answers[]=array($val,0);
			}
		}

		ocf_make_poll($topic_id,$question,$is_private,$is_open,$minimum_selections,$maximum_selections,$requires_reply,$answers);

		if (get_param_integer('try_validate',0)==1)
		{
			$forum_id=$GLOBALS['FORUM_DB']->query_value('f_topics','t_forum_id',array('id'=>$topic_id));
			if ((!is_null($forum_id)) && (!has_specific_permission(get_member(),'bypass_validation_midrange_content','topics',array('forums',$forum_id)))) $validated=0; else $validated=1;
			if ($validated==1)
			{
				$GLOBALS['FORUM_DB']->query_update('f_topics',array('t_validated'=>1),array('id'=>$topic_id),'',1);
			}
		}

		return $this->redirect_to('ADD_TOPIC_POLL',$topic_id);
	}

	// ===============
	// POST MODERATION
	// ===============

	/**
	 * The UI to edit a post.
	 *
	 * @return tempcode		The UI
	 */
	function edit_post() // Type
	{
		$post_id=get_param_integer('id');

		$post_details=$GLOBALS['FORUM_DB']->query_select('f_posts',array('*'),array('id'=>$post_id),'',1);
		if (!array_key_exists(0,$post_details)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));

		$forum_id=$post_details[0]['p_cache_forum_id'];
		if (!is_null($forum_id))
		{
			$_comments_forum=get_option('comments_forum_name');
			if (is_numeric($_comments_forum))
			{
				$comments_forum=$_comments_forum;
			} else
			{
				$comments_forum=$GLOBALS['FORUM_DRIVER']->forum_id_from_name($_comments_forum);
			}
			if ((!has_category_access(get_member(),'forums',strval($forum_id))) && ($forum_id!=$comments_forum)) access_denied('CATEGORY_ACCESS'); // Can happen if trying to reply to a stated whisper made to you in a forum you don't have access to
		}

		if (!ocf_may_edit_post_by($post_details[0]['p_poster'],$forum_id))
			access_denied('I_ERROR');

		$topic_info=$GLOBALS['FORUM_DB']->query_select('f_topics',array('*'),array('id'=>$post_details[0]['p_topic_id']),'',1);
		if (!array_key_exists(0,$topic_info)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$this->handle_topic_breadcrumbs($forum_id,$post_details[0]['p_topic_id'],$topic_info[0]['t_cache_first_title'],do_lang_tempcode('EDIT_POST'));

		$hidden_fields=new ocp_tempcode();
		$intended_solely_for=$post_details[0]['p_intended_solely_for'];
		if (!is_null($intended_solely_for))
			$hidden_fields->attach(form_input_hidden('intended_solely_for',strval($intended_solely_for)));
		$hidden_fields->attach(form_input_hidden('from_url',get_self_url(true)));
		$hidden_fields->attach(form_input_hidden('post_id',strval($post_id)));

		$map=array('page'=>'_SELF','type'=>'_edit_post');
		$redirect=get_param('redirect','');
		if ($redirect!='') $map['redirect']=$redirect;
		$test=get_param_integer('kfs'.(is_null($forum_id)?'':strval($forum_id)),-1);
		if (($test!=-1) && ($test!=0)) $map['kfs'.(is_null($forum_id)?'':strval($forum_id))]=$test;
		$test=get_param_integer('threaded',-1);
		if ($test!=-1) $map['threaded']=$test;
		$post_url=build_url($map,'_SELF');

		$post=post_param('post',get_translated_text($post_details[0]['p_post'],$GLOBALS['FORUM_DB']));

		// Certain aspects relating to the posting system
		$specialisation=new ocp_tempcode();
		if (((get_option('is_on_post_titles')=='1') || ($post_details[0]['p_title']!='') || ($post_id==$topic_info[0]['t_cache_first_post_id'])))
			$specialisation->attach(form_input_line(do_lang_tempcode('TITLE'),'','title',post_param('title',$post_details[0]['p_title']),false,1));
		$specialisation->attach(form_input_line(do_lang_tempcode('REASON'),'','reason','',false,2));
		if (ocf_may_moderate_forum($forum_id,get_member()))
		{
			$moderation_options=array(
								array(do_lang_tempcode('EMPHASISED'),'is_emphasised',$post_details[0]['p_is_emphasised']==1,do_lang_tempcode('DESCRIPTION_EMPHASISED')),
						);
			if (addon_installed('unvalidated'))
			{
				if ($post_details[0]['p_validated']==0)
				{
					$post_details[0]['p_validated']=get_param_integer('validated',0);
					if ($post_details[0]['p_validated']==1) attach_message(do_lang_tempcode('WILL_BE_VALIDATED_WHEN_SAVING'));
				}
				$moderation_options[]=array(do_lang_tempcode('VALIDATED'),'validated',$post_details[0]['p_validated']==1,do_lang_tempcode('DESCRIPTION_VALIDATED'));
			}
		} else
		{
			$moderation_options=array();
			$hidden_fields->attach(form_input_hidden('validated','1'));
		}

		$specialisation2=new ocp_tempcode();

		require_code('fields');
		if (has_tied_catalogue('post'))
		{
			append_form_custom_fields('post',strval($post_id),$specialisation2,$hidden_fields);
		}

		if (count($moderation_options)!=0) $specialisation2->attach(form_input_various_ticks($moderation_options,'',NULL,do_lang_tempcode('MODERATION_OPTIONS')));
		$specialisation2->attach(do_template('FORM_SCREEN_FIELD_SPACER',array('TITLE'=>do_lang_tempcode('ACTIONS'))));
		$options=array();
		$options[]=array(do_lang_tempcode('MARK_UNREAD'),'mark_as_unread',false,do_lang_tempcode('DESCRIPTION_MARK_UNREAD'));
		$options[]=array(do_lang_tempcode('SHOW_AS_EDITED'),'show_as_edited',((time()-$post_details[0]['p_time'])>60*3),do_lang_tempcode('DESCRIPTION_POST_SHOW_AS_EDITED'));
		$specialisation2->attach(form_input_various_ticks($options,''));
		if (ocf_may_delete_post_by($post_details[0]['p_poster'],$forum_id))
		{
			$specialisation2->attach(form_input_tick(do_lang_tempcode('DELETE'),do_lang_tempcode('DESCRIPTION_DELETE'),'delete',false));
		}

		// Awards?
		if (addon_installed('awards'))
		{
			require_code('awards');
			$specialisation->attach(get_award_fields('post',strval($post_id)));
		}

		if (is_null(get_param('post',NULL)))
		{
			$parsed=get_translated_tempcode($post_details[0]['p_post'],$GLOBALS['FORUM_DB']);
		} else $parsed=NULL;
		$posting_form=get_posting_form(do_lang('SAVE'),$post,$post_url,$hidden_fields,$specialisation,NULL,'',$specialisation2,$parsed,$this->_post_javascript());

		list($warning_details,$ping_url)=handle_conflict_resolution();

		$title=get_page_title('EDIT_POST');
		return do_template('POSTING_SCREEN',array('_GUID'=>'347e469de58882bf77722bba6ed4aba4','STAFF_HELP_URL'=>brand_base_url().'/docs'.strval(ocp_version()).'/pg/tut_mod','TITLE'=>$title,'PING_URL'=>$ping_url,'WARNING_DETAILS'=>$warning_details,'POSTING_FORM'=>$posting_form));
	}

	/**
	 * Get Javascript to restrict post lengths.
	 *
	 * @return string			The post Javascript
	 */
	function _post_javascript()
	{
		$size=ocf_get_member_best_group_property(get_member(),'max_post_length_comcode');

		$javascript='';

		$javascript.="
			var form=document.getElementById('post').form;
			form.old_submit=form.onsubmit;
			form.onsubmit=function()
				{
					var post=form.elements['post'];
					if ((!post.value) && (post[1])) post=post[1];
					if (post.value.length>".strval($size).")
					{
						window.fauxmodal_alert('".php_addslashes(do_lang('_POST_TOO_LONG'))."');
						return false;
					}
		";

		$stub=get_param('stub','',true);
		if ($stub!='') $javascript.="
					var df='".str_replace(chr(10),'\n',addslashes($stub))."';

					var pv=post.value;
					if ((post) && (pv.substring(0,df.length)==df))
					{
						pv=pv.substring(df.length,pv.length);
					}
					post.value=pv;
		";

		$javascript.="
					if (typeof form.old_submit!='undefined' && form.old_submit) return form.old_submit();

					return true;
				};
		";

		return $javascript;
	}

	/**
	 * The actualiser to edit a post.
	 *
	 * @return tempcode		The UI
	 */
	function _edit_post() // Type
	{
		require_code('attachments2');

		if (post_param_integer('delete',0)==1) return $this->_delete_post();

		$post_id=post_param_integer('post_id');

		$post_details=$GLOBALS['FORUM_DB']->query_select('f_posts',array('*'),array('id'=>$post_id),'',1);
		if (!array_key_exists(0,$post_details)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$forum_id=$post_details[0]['p_cache_forum_id'];

		$intended_solely_for=post_param_integer('intended_solely_for',-1);
		if ($intended_solely_for==-1) $intended_solely_for=NULL;
		$validated=post_param_integer('validated',0);
		if ((!is_null($forum_id)) && (!has_specific_permission(get_member(),'bypass_validation_lowrange_content','topics',array('forums',$forum_id)))) $validated=0;
		$old_validated=$post_details[0]['p_validated'];
		require_code('ocf_posts_action');
		require_code('ocf_posts_action2');
		require_code('ocf_posts_action3');
		$topic_id=ocf_edit_post($post_id,$validated,post_param('title',''),post_param('post'),post_param_integer('skip_sig',0),post_param_integer('is_emphasised',0),$intended_solely_for,(post_param_integer('show_as_edited',0)==1),(post_param_integer('mark_as_unread',0)==1),post_param('reason'));

		require_code('fields');
		if (has_tied_catalogue('post'))
		{
			save_form_custom_fields('post',strval($post_id));
		}

		if ($old_validated!=$validated)
		{
			if ($validated==1) ocf_validate_post($post_id);
		}

		if (addon_installed('awards'))
		{
			require_code('awards');
			handle_award_setting('post',strval($post_id));
		}

		require_code('autosave');
		clear_ocp_autosave();

		// Show it worked / Refresh
		$url=get_param('redirect',NULL);
		if (!is_null($url))
			return redirect_screen(get_page_title('EDIT_POST'),$url,do_lang_tempcode('SUCCESS'));

		return $this->redirect_to('EDIT_POST',$topic_id,NULL,$post_id);
	}

	/**
	 * The actualiser to validate a post.
	 *
	 * @return tempcode		The UI
	 */
	function validate_post() // Type
	{
		$post_id=get_param_integer('id');

		require_code('ocf_posts_action');
		require_code('ocf_posts_action2');
		require_code('ocf_posts_action3');
		$topic_id=ocf_validate_post($post_id);

		$redirect=get_param('redirect','');
		if ($redirect!='')
		{
			return redirect_screen(get_page_title('VALIDATE_POST'),$redirect,do_lang_tempcode('SUCCESS'));
		}

		return $this->redirect_to('VALIDATE_POST',$topic_id);
	}

	// ================
	// TOPIC MODERATION
	// ================

	/**
	 * Check there is at least some moderation access over the given topic.
	 *
	 * @param  AUTO_LINK		The topic ID
	 */
	function check_has_mod_access($topic_id) // This is here to prevent snooping into the details of things (the backend provides the true security)
	{
		$topic_info=$GLOBALS['FORUM_DB']->query_select('f_topics',array('*'),array('id'=>$topic_id),'',1);
		if (!array_key_exists(0,$topic_info)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$forum_id=$topic_info[0]['t_forum_id'];
		$personal_topic=is_null($forum_id);

		if (($personal_topic) && ($topic_info[0]['t_pt_from']!=get_member()) && ($topic_info[0]['t_pt_to']!=get_member()) && (!ocf_has_special_pt_access($topic_id)) && (!has_specific_permission(get_member(),'view_other_pt')))
			access_denied('I_ERROR');

		if (!$personal_topic)
		{
			if (!has_category_access(get_member(),'forums',strval($forum_id))) access_denied('I_ERROR');
		}
	}

	/**
	 * The UI to edit a topic.
	 *
	 * @return tempcode		The UI
	 */
	function edit_topic() // Type
	{
		$topic_id=get_param_integer('id');

		$topic_info=$GLOBALS['FORUM_DB']->query_select('f_topics',array('*'),array('id'=>$topic_id),'',1);
		if (!array_key_exists(0,$topic_info)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$forum_id=$topic_info[0]['t_forum_id'];
		$personal_topic=is_null($forum_id);

		$this->handle_topic_breadcrumbs($forum_id,$topic_id,$topic_info[0]['t_cache_first_title'],do_lang_tempcode('EDIT_TOPIC'));

		$this->check_has_mod_access($topic_id);

		$post_url=build_url(array('page'=>'_SELF','type'=>'_edit_topic','id'=>$topic_id),'_SELF');

		// Certain aspects relating to the posting system
		$fields=new ocp_tempcode();
		$fields->attach(form_input_line(do_lang_tempcode('TITLE'),'','title',$topic_info[0]['t_cache_first_title'],false));
		if ((get_option('is_on_topic_descriptions')=='1') && (!$GLOBALS['FORUM_DRIVER']->topic_is_threaded($topic_id)))
			$fields->attach(form_input_line(do_lang_tempcode('DESCRIPTION'),'','description',$topic_info[0]['t_description'],false));
		$fields->attach(form_input_line(do_lang_tempcode('REASON'),do_lang_tempcode('DESCRIPTION_REASON'),'reason','',false));
		if (get_option('is_on_topic_emoticons')=='1')
			$fields->attach($this->choose_topic_emoticon($topic_info[0]['t_emoticon']));
		$options=array();
		$hidden_fields=new ocp_tempcode();
		if (ocf_may_moderate_forum($forum_id,get_member()))
		{
			$moderation_options=array(
				array(do_lang_tempcode('OPEN'),'open',$topic_info[0]['t_is_open']==1,do_lang_tempcode('DESCRIPTION_OPEN')),
				array(do_lang_tempcode('PINNED'),'pinned',$topic_info[0]['t_pinned']==1,do_lang_tempcode('DESCRIPTION_PINNED')),
			);
			if (addon_installed('unvalidated'))
			{
				if ($topic_info[0]['t_validated']==0)
				{
					$topic_info[0]['t_validated']=get_param_integer('validated',0);
					if ($topic_info[0]['t_validated']==1) attach_message(do_lang_tempcode('WILL_BE_VALIDATED_WHEN_SAVING'));
				}
				$moderation_options[]=array(do_lang_tempcode('VALIDATED'),'validated',$topic_info[0]['t_validated']==1,do_lang_tempcode('DESCRIPTION_VALIDATED'));
			}
			if (get_value('disable_sunk')!=='1')
				$moderation_options[]=array(do_lang_tempcode('SUNK'),'sunk',$topic_info[0]['t_sunk']==1,do_lang_tempcode('DESCRIPTION_SUNK'));
			if (!$personal_topic) $options[]=array(do_lang_tempcode('CASCADING'),'cascading',$topic_info[0]['t_cascading']==1,do_lang_tempcode('DESCRIPTION_CASCADING'));
		} else
		{
			$moderation_options=array();
			$hidden_fields->attach(form_input_hidden('validated','1'));
		}
		$fields->attach(form_input_various_ticks($options,''));
		if (count($moderation_options)!=0) $fields->attach(form_input_various_ticks($moderation_options,'',NULL,do_lang_tempcode('MODERATION_OPTIONS')));

		require_code('fields');
		if (has_tied_catalogue('topic'))
		{
			append_form_custom_fields('topic',strval($topic_id),$fields,$hidden_fields);
		}

		// Awards?
		if (addon_installed('awards'))
		{
			require_code('awards');
			$fields->attach(get_award_fields('topic',strval($topic_id)));
		}

		$title=get_page_title('EDIT_TOPIC');
		$submit_name=do_lang_tempcode('SAVE');
		return do_template('FORM_SCREEN',array('_GUID'=>'071b6747a1df1cf8e72f8f542422aa5b','STAFF_HELP_URL'=>brand_base_url().'/docs'.strval(ocp_version()).'/pg/tut_mod','HIDDEN'=>$hidden_fields,'TITLE'=>$title,'FIELDS'=>$fields,'TEXT'=>'','SUBMIT_NAME'=>$submit_name,'URL'=>$post_url));
	}

	/**
	 * The actualiser to edit a topic.
	 *
	 * @return tempcode		The UI
	 */
	function _edit_topic() // Type
	{
		$topic_id=get_param_integer('id');
		$cascading=post_param_integer('cascading',fractional_edit()?INTEGER_MAGIC_NULL:0);
		$pinned=post_param_integer('pinned',fractional_edit()?INTEGER_MAGIC_NULL:0);
		$sunk=post_param_integer('sunk',fractional_edit()?INTEGER_MAGIC_NULL:0);
		$open=post_param_integer('open',fractional_edit()?INTEGER_MAGIC_NULL:0);
		$validated=post_param_integer('validated',fractional_edit()?INTEGER_MAGIC_NULL:0);
		$title=post_param('title');

		require_code('ocf_topics_action');
		require_code('ocf_topics_action2');

		ocf_edit_topic($topic_id,post_param('description',STRING_MAGIC_NULL),post_param('emoticon',STRING_MAGIC_NULL),$validated,$open,$pinned,$sunk,$cascading,post_param('reason',STRING_MAGIC_NULL),$title);

		require_code('fields');
		if (has_tied_catalogue('topic'))
		{
			save_form_custom_fields('topic',strval($topic_id));
		}

		if (addon_installed('awards'))
		{
			require_code('awards');
			handle_award_setting('topic',strval($topic_id));
		}

		return $this->redirect_to('EDIT_TOPIC',$topic_id);
	}

	/**
	 * The UI to delete a topic.
	 *
	 * @return tempcode		The UI
	 */
	function delete_topic() // Type
	{
		$topic_id=get_param_integer('id');
		$post_url=build_url(array('page'=>'_SELF','type'=>'_delete_topic','id'=>$topic_id),'_SELF');

		$topic_info=$GLOBALS['FORUM_DB']->query_select('f_topics',array('*'),array('id'=>$topic_id),'',1);
		if (!array_key_exists(0,$topic_info)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$this->handle_topic_breadcrumbs($topic_info[0]['t_forum_id'],$topic_id,$topic_info[0]['t_cache_first_title'],do_lang_tempcode('DELETE_TOPIC'));

		$this->check_has_mod_access($topic_id);

		// Certain aspects relating to the posting system
		$fields=new ocp_tempcode();
		$hidden=new ocp_tempcode();
		$hidden->attach(build_keep_post_fields());
		$hidden->attach(build_keep_form_fields());
		$fields->attach(form_input_tree_list(do_lang_tempcode('DESTINATION_TOPIC'),do_lang_tempcode('DESCRIPTION_DESTINATION_TOPIC'),'select_topic_id',NULL,'choose_forum_topic',array(),false));
		$fields->attach(form_input_integer(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('DESTINATION_TOPIC_ID')),do_lang_tempcode('DESCRIPTION_DESTINATION_TOPIC'),'manual_topic_id',NULL,false));
		$fields->attach(form_input_line(do_lang_tempcode('REASON'),do_lang_tempcode('DESCRIPTION_REASON'),'reason','',false));

		$topic_title=$GLOBALS['FORUM_DB']->query_value('f_topics','t_cache_first_title',array('id'=>$topic_id));
		$title=get_page_title('_DELETE_TOPIC',true,array(escape_html($topic_title)));
		$submit_name=do_lang_tempcode('DELETE');
		$text=paragraph(do_lang_tempcode('DELETE_TOPIC_TEXT'));
		return do_template('FORM_SCREEN',array('_GUID'=>'00b84f337de3683bfcdb60ea3086afa0','SKIP_VALIDATION'=>true,'STAFF_HELP_URL'=>brand_base_url().'/docs'.strval(ocp_version()).'/pg/tut_mod','HIDDEN'=>$hidden,'TITLE'=>$title,'FIELDS'=>$fields,'TEXT'=>$text,'SUBMIT_NAME'=>$submit_name,'URL'=>$post_url));
	}

	/**
	 * The actualiser to delete a topic.
	 *
	 * @return tempcode		The UI
	 */
	function _delete_topic() // Type
	{
		$topic_id=get_param_integer('id');
		$post_target_topic_id=post_param_integer('select_topic_id',-1);
		if ($post_target_topic_id==-1) $post_target_topic_id=post_param_integer('manual_topic_id',-1);
		if ($post_target_topic_id==-1) $post_target_topic_id=NULL;

		require_code('ocf_topics_action');
		require_code('ocf_topics_action2');
		$forum_id=ocf_delete_topic($topic_id,post_param('reason'),$post_target_topic_id);

		require_code('fields');
		if (has_tied_catalogue('topic'))
		{
			delete_form_custom_fields('topic',strval($topic_id));
		}

		return $this->redirect_to_forum('DELETE_TOPIC',$forum_id);
	}

	/**
	 * The UI to invite a member to a PT.
	 *
	 * @return tempcode		The UI
	 */
	function invite_member()
	{
		$topic_id=get_param_integer('id');

		$fields=new ocp_tempcode();
		$fields->attach(form_input_username(do_lang_tempcode('USERNAME'),do_lang_tempcode('MEMBER_TO_INVITE'),'username','',false));

		$title=get_page_title('INVITE_MEMBER_TO_PT');
		$submit_name=do_lang_tempcode('INVITE_MEMBER_TO_PT');
		$text=paragraph(do_lang_tempcode('INVITE_MEMBER_TO_PT_TEXT'));
		$post_url=build_url(array('page'=>'_SELF','type'=>'_invite_member','topic_id'=>$topic_id),'_SELF');
		return do_template('FORM_SCREEN',array('SKIP_VALIDATION'=>true,'STAFF_HELP_URL'=>brand_base_url().'/docs'.strval(ocp_version()).'/pg/tut_correspondance','HIDDEN'=>'','TITLE'=>$title,'FIELDS'=>$fields,'TEXT'=>$text,'SUBMIT_NAME'=>$submit_name,'URL'=>$post_url));
	}

	/**
	 * The actualiser to invite a member to a PT.
	 *
	 * @return tempcode		The UI
	 */
	function _invite_member()
	{
		$username=trim(post_param('username'));
		$member_id=$GLOBALS['FORUM_DRIVER']->get_member_from_username($username);
		if (is_null($member_id)) warn_exit(do_lang_tempcode('_USER_NO_EXIST',escape_html($username)));
		$topic_id=get_param_integer('topic_id');

		require_code('ocf_topics_action');
		require_code('ocf_topics_action2');
		require_code('notifications');
		enable_notifications('ocf_topic',strval($topic_id),$member_id);
		ocf_invite_to_pt($member_id,$topic_id);

		return $this->redirect_to('EDIT_TOPIC',$topic_id);
	}

	/**
	 * The UI to edit a poll.
	 *
	 * @return tempcode		The UI
	 */
	function edit_poll() // Type
	{
		$topic_id=get_param_integer('id');
		$poll_id=$GLOBALS['FORUM_DB']->query_value_null_ok('f_topics','t_poll_id',array('id'=>$topic_id));
		if (is_null($poll_id)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));

		$this->check_has_mod_access($topic_id);

		$post_url=build_url(array('page'=>'_SELF','type'=>'_edit_poll','id'=>$poll_id),'_SELF');

		$poll_info=$GLOBALS['FORUM_DB']->query_select('f_polls',array('*'),array('id'=>$poll_id),'',1);
		if (!array_key_exists(0,$poll_info)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$poll=$poll_info[0];

		$topic_info=$GLOBALS['FORUM_DB']->query_select('f_topics',array('*'),array('id'=>$topic_id),'',1);
		if (!array_key_exists(0,$topic_info)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$this->handle_topic_breadcrumbs($topic_info[0]['t_forum_id'],$topic_id,$topic_info[0]['t_cache_first_title'],do_lang_tempcode('EDIT_TOPIC_POLL'));

		$answers=collapse_1d_complexity('pa_answer',$GLOBALS['FORUM_DB']->query_select('f_poll_answers',array('pa_answer'),array('pa_poll_id'=>$poll_id)));
		$question=$poll['po_question'];
		$is_private=$poll['po_is_private'];
		$is_open=$poll['po_is_open'];
		$requires_reply=$poll['po_requires_reply'];
		$minimum_selections=$poll['po_minimum_selections'];
		$maximum_selections=$poll['po_maximum_selections'];
		$fields=$this->get_poll_form_fields($question,$answers,$is_private,$is_open,$requires_reply,$minimum_selections,$maximum_selections);
		$fields->attach(form_input_line(do_lang_tempcode('REASON'),do_lang_tempcode('DESCRIPTION_REASON'),'reason','',false));

		$title=get_page_title('EDIT_TOPIC_POLL');
		$submit_name=do_lang_tempcode('SAVE');

		list($warning_details,$ping_url)=handle_conflict_resolution();

		return do_template('FORM_SCREEN',array('_GUID'=>'992a1bfd025e3fabea9d13307cfd2a91','STAFF_HELP_URL'=>brand_base_url().'/docs'.strval(ocp_version()).'/pg/tut_mod','PREVIEW'=>true,'PING_URL'=>$ping_url,'WARNING_DETAILS'=>$warning_details,'HIDDEN'=>'','TITLE'=>$title,'FIELDS'=>$fields,'TEXT'=>'','SUBMIT_NAME'=>$submit_name,'URL'=>$post_url));
	}

	/**
	 * The actualiser to edit a poll.
	 *
	 * @return tempcode		The UI
	 */
	function _edit_poll() // Type
	{
		$poll_id=get_param_integer('id');
		$topic_id=$GLOBALS['FORUM_DB']->query_value_null_ok('f_topics','id',array('t_poll_id'=>$poll_id));
		if (is_null($topic_id)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));

		$question=post_param('question',STRING_MAGIC_NULL);
		$is_private=post_param_integer('is_private',fractional_edit()?INTEGER_MAGIC_NULL:0);
		$is_open=post_param_integer('is_open',fractional_edit()?INTEGER_MAGIC_NULL:0);
		$minimum_selections=post_param_integer('minimum_selections',fractional_edit()?INTEGER_MAGIC_NULL:0);
		$maximum_selections=post_param_integer('maximum_selections',fractional_edit()?INTEGER_MAGIC_NULL:0);
		$reason=post_param('reason',STRING_MAGIC_NULL);
		$requires_reply=post_param_integer('requires_reply',fractional_edit()?INTEGER_MAGIC_NULL:0);

		if (fractional_edit())
		{
			$answers=collapse_1d_complexity('pa_answer',$GLOBALS['FORUM_DB']->query_select('f_poll_answers',array('pa_answer'),array('pa_poll_id'=>$poll_id)));
			foreach ($answers as $i=>$answer)
			{
				$answers[$i]=post_param('answer_'.strval($i),$answer);
			}
		} else
		{
			$answers=array();
			foreach ($_POST as $key=>$val)
			{
				if (!is_string($val)) continue;

				if (substr($key,0,7)=='answer_')
				{
					if (get_magic_quotes_gpc()) $val=stripslashes($val);
					if ($val!='') $answers[]=$val;
				}
			}
		}

		require_code('ocf_polls_action');
		require_code('ocf_polls_action2');
		ocf_edit_poll($poll_id,$question,$is_private,$is_open,$minimum_selections,$maximum_selections,$requires_reply,$answers,$reason);
		return $this->redirect_to('EDIT_TOPIC_POLL',$topic_id);
	}

	/**
	 * The UI to grab a reason for deleting a poll.
	 *
	 * @return tempcode		The UI
	 */
	function delete_poll() // Type
	{
		$topic_id=get_param_integer('id');
		$topic_info=$GLOBALS['FORUM_DB']->query_select('f_topics',array('*'),array('id'=>$topic_id),'',1);
		if (!array_key_exists(0,$topic_info)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$this->handle_topic_breadcrumbs($topic_info[0]['t_forum_id'],$topic_id,$topic_info[0]['t_cache_first_title'],do_lang_tempcode('DELETE_TOPIC_POLL'));

		return $this->relay_with_reason('DELETE_TOPIC_POLL');
	}

	/**
	 * The actualiser to delete a poll.
	 *
	 * @return tempcode		The UI
	 */
	function _delete_poll() // Type
	{
		$topic_id=get_param_integer('id');
		$poll_id=$GLOBALS['FORUM_DB']->query_value_null_ok('f_topics','t_poll_id',array('id'=>$topic_id));
		if (is_null($poll_id)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		require_code('ocf_polls_action');
		require_code('ocf_polls_action2');
		ocf_delete_poll($poll_id,post_param('reason'));
		return $this->redirect_to('DELETE_TOPIC_POLL',$topic_id);
	}

	/**
	 * The UI to move a topic.
	 *
	 * @return tempcode		The UI
	 */
	function move_topic() // Type
	{
		$topic_id=get_param_integer('id');
		$topic_info=$GLOBALS['FORUM_DB']->query_select('f_topics',array('t_forum_id','t_cache_first_title'),array('id'=>$topic_id),'',1);
		if (!array_key_exists(0,$topic_info)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$forum_id=$topic_info[0]['t_forum_id'];

		$this->handle_topic_breadcrumbs($topic_info[0]['t_forum_id'],$topic_id,$topic_info[0]['t_cache_first_title'],do_lang_tempcode('MOVE_TOPIC'));

		$this->check_has_mod_access($topic_id);

		$post_url=build_url(array('page'=>'_SELF','type'=>'_move_topic','id'=>$topic_id),'_SELF');

		require_code('ocf_forums2');

		// Certain aspects relating to the posting system
		$fields=new ocp_tempcode();
		$fields->attach(form_input_line(do_lang_tempcode('TITLE'),'','title',$topic_info[0]['t_cache_first_title'],false));
		$fields->attach(form_input_tree_list(do_lang_tempcode('DESTINATION_FORUM'),do_lang_tempcode('DESCRIPTION_DESTINATION_FORUM'),'to',NULL,'choose_forum',array(),true,strval($forum_id)));
		$fields->attach(form_input_line(do_lang_tempcode('REASON'),do_lang_tempcode('DESCRIPTION_REASON'),'description','',false));

		$fields->attach(do_template('FORM_SCREEN_FIELD_SPACER',array('TITLE'=>do_lang_tempcode('ACTIONS'))));
		$fields->attach(form_input_tick(do_lang_tempcode('REDIRECT_TO_TOPIC'),do_lang_tempcode('DESCRIPTION_REDIRECT_TO_TOPIC'),'redir_topic',false));

		$topic_title=$topic_info[0]['t_cache_first_title'];
		$title=get_page_title('_MOVE_TOPIC',true,array(escape_html($topic_title)));
		$submit_name=do_lang_tempcode('MOVE_TOPIC');
		return do_template('FORM_SCREEN',array('_GUID'=>'313fd175ccd376caa32794fedad21ac6','SKIP_VALIDATION'=>true,'STAFF_HELP_URL'=>brand_base_url().'/docs'.strval(ocp_version()).'/pg/tut_mod','HIDDEN'=>'','TITLE'=>$title,'FIELDS'=>$fields,'TEXT'=>'','SUBMIT_NAME'=>$submit_name,'URL'=>$post_url));
	}

	/**
	 * The actualiser to move a topic.
	 *
	 * @return tempcode		The UI
	 */
	function _move_topic() // Type
	{
		$topic_id=get_param_integer('id');
		$to=post_param_integer('to');
		$from=$GLOBALS['FORUM_DB']->query_value_null_ok('f_topics','t_forum_id',array('id'=>$topic_id));
		require_code('ocf_topics_action');
		require_code('ocf_topics_action2');
		ocf_move_topics($from,$to,array($topic_id));
		ocf_edit_topic($topic_id,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',post_param('title'));
		return (post_param_integer('redir_topic',0)==0)?$this->redirect_to_forum('MOVE_TOPIC',$from):$this->redirect_to('MOVE_TOPIC',$topic_id);
	}

	/**
	 * The actualiser to pin a topic.
	 *
	 * @return tempcode		The UI
	 */
	function pin_topic() // Type
	{
		$topic_id=get_param_integer('id');
		require_code('ocf_topics_action');
		require_code('ocf_topics_action2');
		ocf_edit_topic($topic_id,NULL,NULL,NULL,NULL,1,NULL,NULL,'');
		return $this->redirect_to('PIN_TOPIC',$topic_id);
	}

	/**
	 * The actualiser to unpin a topic.
	 *
	 * @return tempcode		The UI
	 */
	function unpin_topic() // Type
	{
		$topic_id=get_param_integer('id');
		require_code('ocf_topics_action');
		require_code('ocf_topics_action2');
		ocf_edit_topic($topic_id,NULL,NULL,NULL,NULL,0,NULL,NULL,'');
		return $this->redirect_to('UNPIN_TOPIC',$topic_id);
	}

	/**
	 * The actualiser to pin a topic.
	 *
	 * @return tempcode		The UI
	 */
	function sink_topic() // Type
	{
		$topic_id=get_param_integer('id');
		require_code('ocf_topics_action');
		require_code('ocf_topics_action2');
		ocf_edit_topic($topic_id,NULL,NULL,NULL,NULL,NULL,1,NULL,'');
		return $this->redirect_to('SINK_TOPIC',$topic_id);
	}

	/**
	 * The actualiser to unpin a topic.
	 *
	 * @return tempcode		The UI
	 */
	function unsink_topic() // Type
	{
		$topic_id=get_param_integer('id');
		require_code('ocf_topics_action');
		require_code('ocf_topics_action2');
		ocf_edit_topic($topic_id,NULL,NULL,NULL,NULL,NULL,0,NULL,'');
		return $this->redirect_to('UNSINK_TOPIC',$topic_id);
	}

	/**
	 * The actualiser to cascade a topic.
	 *
	 * @return tempcode		The UI
	 */
	function cascade_topic() // Type
	{
		$topic_id=get_param_integer('id');
		require_code('ocf_topics_action');
		require_code('ocf_topics_action2');
		ocf_edit_topic($topic_id,NULL,NULL,NULL,NULL,NULL,NULL,1,'');
		return $this->redirect_to('CASCADE_TOPIC',$topic_id);
	}

	/**
	 * The actualiser to uncascade a topic.
	 *
	 * @return tempcode		The UI
	 */
	function uncascade_topic() // Type
	{
		$topic_id=get_param_integer('id');
		require_code('ocf_topics_action');
		require_code('ocf_topics_action2');
		ocf_edit_topic($topic_id,NULL,NULL,NULL,NULL,NULL,NULL,0,'');
		return $this->redirect_to('UNCASCADE_TOPIC',$topic_id);
	}

	/**
	 * The actualiser to open a topic.
	 *
	 * @return tempcode		The UI
	 */
	function open_topic() // Type
	{
		$topic_id=get_param_integer('id');
		require_code('ocf_topics_action');
		require_code('ocf_topics_action2');
		ocf_edit_topic($topic_id,NULL,NULL,NULL,1,NULL,NULL,NULL,'');
		return $this->redirect_to('OPEN_TOPIC',$topic_id);
	}

	/**
	 * The actualiser to close a topic.
	 *
	 * @return tempcode		The UI
	 */
	function close_topic() // Type
	{
		$topic_id=get_param_integer('id');
		require_code('ocf_topics_action');
		require_code('ocf_topics_action2');
		ocf_edit_topic($topic_id,NULL,NULL,NULL,0,NULL,NULL,NULL,'');
		return $this->redirect_to('CLOSE_TOPIC',$topic_id);
	}

	/**
	 * The UI to run a multi-moderation.
	 *
	 * @return tempcode		The UI
	 */
	function multimod() // Type
	{
		$mm_id=intval(substr(get_param('type','misc'),3));
		$topic_id=get_param_integer('id');

		$this->check_has_mod_access($topic_id);

		$topic_info=$GLOBALS['FORUM_DB']->query_select('f_topics',array('*'),array('id'=>$topic_id),'',1);
		if (!array_key_exists(0,$topic_info)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$topic_title=$topic_info[0]['t_cache_first_title'];
		$this->handle_topic_breadcrumbs($topic_info[0]['t_forum_id'],$topic_id,$topic_info[0]['t_cache_first_title'],do_lang_tempcode('_PERFORM_MULTI_MODERATION',escape_html($topic_title)));

		$title=get_page_title('_PERFORM_MULTI_MODERATION',true,array(escape_html($topic_title)));
		$mm=$GLOBALS['FORUM_DB']->query_select('f_multi_moderations',array('*'),array('id'=>$mm_id),'',1);
		if (!array_key_exists(0,$mm)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$_mm=$mm[0];
		$post_text=$_mm['mm_post_text'];
		$submit_name=do_lang_tempcode('PERFORM_MULTI_MODERATION');
		$post_url=build_url(array('page'=>'_SELF','type'=>'_multimod','id'=>$topic_id,'mm_id'=>$mm_id),'_SELF',NULL,true);
		$fields=new ocp_tempcode();
		$hidden=new ocp_tempcode();
		$hidden->attach(build_keep_post_fields());
		$hidden->attach(build_keep_form_fields());
		$fields->attach(form_input_text(do_lang_tempcode('MM_POST_TEXT'),do_lang_tempcode('DESCRIPTION_MM_POST_TEXT'),'post_text',$post_text,false));
		$options=array();
		if (get_value('disable_skip_sig')!=='1')
		{
			if (addon_installed('ocf_signatures'))
				$options[]=array(do_lang_tempcode('SKIP_SIGNATURE'),'skip_sig',false,do_lang_tempcode('DESCRIPTION_SKIP_SIGNATURE'));
		}
		if (get_value('disable_post_emphasis')!=='1')
			$options[]=array(do_lang_tempcode('EMPHASISED'),'is_emphasised',true,do_lang_tempcode('DESCRIPTION_EMPHASISED'));
		$fields->attach(form_input_various_ticks($options,''));
		$fields->attach(form_input_line(do_lang_tempcode('REASON'),do_lang_tempcode('OPTIONAL_REASON'),'reason','',false));

		$mm_title=get_translated_text($_mm['mm_name'],$GLOBALS['FORUM_DB']);
		$action_list=new ocp_tempcode();
		if ($_mm['mm_open_state']==1)
			$action_list->attach(do_lang_tempcode('MULTI_MODERATION_WILL_OPEN'));
		if ($_mm['mm_open_state']==0)
			$action_list->attach(do_lang_tempcode('MULTI_MODERATION_WILL_CLOSE'));
		if ($_mm['mm_pin_state']==1)
			$action_list->attach(do_lang_tempcode('MULTI_MODERATION_WILL_PIN'));
		if ($_mm['mm_pin_state']==0)
			$action_list->attach(do_lang_tempcode('MULTI_MODERATION_WILL_UNPIN'));
		if ($_mm['mm_sink_state']==1)
			$action_list->attach(do_lang_tempcode('MULTI_MODERATION_WILL_SINK'));
		if ($_mm['mm_sink_state']==0)
			$action_list->attach(do_lang_tempcode('MULTI_MODERATION_WILL_UNSINK'));
		if ($_mm['mm_title_suffix']!='')
			$action_list->attach(do_lang_tempcode('MULTI_MODERATION_WILL_TITLE_SUFFIX',escape_html($_mm['mm_title_suffix'])));
		if (!is_null($_mm['mm_move_to']))
		{
			$action_list->attach(do_lang_tempcode('MULTI_MODERATION_WILL_MOVE',ocf_forum_breadcrumbs($_mm['mm_move_to'])));
		}
		$action_list->attach(do_lang_tempcode('MULTI_MODERATION_WILL_POST'));
		$text=do_lang_tempcode('MULTI_MODERATION_WILL',make_string_tempcode($mm_title),$action_list);

		return do_template('FORM_SCREEN',array('_GUID'=>'2eef0c445d207bb10ff3fd28ea32ef8c','STAFF_HELP_URL'=>brand_base_url().'/docs'.strval(ocp_version()).'/pg/tut_forum_helpdesk','PREVIEW'=>true,'HIDDEN'=>$hidden,'TITLE'=>$title,'TEXT'=>$text,'URL'=>$post_url,'FIELDS'=>$fields,'SUBMIT_NAME'=>$submit_name));
	}

	/**
	 * The actualiser to run a multi moderation.
	 *
	 * @return tempcode		The UI
	 */
	function _multimod() // Type
	{
		$topic_id=get_param_integer('id');
		$mm_id=get_param_integer('mm_id');
		require_code('ocf_moderation_action');
		require_code('ocf_moderation_action2');
		ocf_perform_multi_moderation($mm_id,$topic_id,post_param('reason'),post_param('post_text'),post_param_integer('is_emphasised',0),post_param_integer('skip_sig',0));

		return $this->redirect_to('PERFORM_MULTI_MODERATION',$topic_id);
	}

	/**
	 * A redirect for viewing post history: made like this so the history button can fit into the same URL architecture as the other post buttons.
	 *
	 * @return tempcode		The UI
	 */
	function topic_history() // Type
	{
		$title=get_page_title('POST_HISTORY');

		// We should be somewhere else entirely - it's just our moderator action list took us here
		$url=build_url(array('page'=>'admin_ocf_history','type'=>'misc','topic_id'=>get_param_integer('id')),'adminzone');
		require_code('site2');
		assign_refresh($url->evaluate(),0.0);
		return do_template('REDIRECT_SCREEN',array('_GUID'=>'e2e5a67f066a90afcc53f9730f8bc42b','URL'=>$url,'TITLE'=>$title,'TEXT'=>do_lang_tempcode('REDIRECTING')));
	}

	/**
	 * The actualiser to mark a forum as read.
	 *
	 * @return tempcode		The UI
	 */
	function mark_read() // Type
	{
		$_forum_id=get_param('id');
		if ($_forum_id=='') $forum_id=NULL; else $forum_id=intval($_forum_id);

		require_code('ocf_forums_action2');
		ocf_ping_forum_read_all($forum_id);

		return $this->redirect_to_forum('MARK_READ',$forum_id);
	}

	/**
	 * The UI to make a normal topic a Private Topic.
	 *
	 * @return tempcode		The UI
	 */
	function make_personal()
	{
		$topic_id=get_param_integer('id');

		$this->check_has_mod_access($topic_id);

		$topic_info=$GLOBALS['FORUM_DB']->query_select('f_topics',array('*'),array('id'=>$topic_id),'',1);
		if (!array_key_exists(0,$topic_info)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));

		$a=$topic_info[0]['t_cache_first_username'];
		$b=$GLOBALS['FORUM_DRIVER']->get_username(get_member());

		$title=get_page_title('MAKE_PERSONAL');
		$text=do_lang_tempcode('MAKE_PERSONAL_DESCRIPTION');
		$submit_name=do_lang_tempcode('MAKE_PERSONAL');
		$post_url=build_url(array('page'=>'_SELF','type'=>'_make_personal'),'_SELF');
		$fields=new ocp_tempcode();
		$hidden=form_input_hidden('id',strval($topic_id));
		$fields->attach(form_input_username(do_lang_tempcode('FROM'),'','a',$a,true));
		$fields->attach(form_input_username(do_lang_tempcode('TO'),'','b',$b,true));

		return do_template('FORM_SCREEN',array('STAFF_HELP_URL'=>brand_base_url().'/docs'.strval(ocp_version()).'/pg/tut_correspondance','HIDDEN'=>$hidden,'TITLE'=>$title,'TEXT'=>$text,'URL'=>$post_url,'FIELDS'=>$fields,'SUBMIT_NAME'=>$submit_name));
	}

	/**
	 * The actualiser to make a normal topic a Private Topic.
	 *
	 * @return tempcode		The UI
	 */
	function _make_personal()
	{
		$topic_id=post_param_integer('id');
		$forum_id=$GLOBALS['FORUM_DB']->query_value_null_ok('f_topics','t_forum_id',array('id'=>$topic_id));
		if (is_null($forum_id)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));

		if (!ocf_may_moderate_forum($forum_id,get_member())) access_denied('I_ERROR');

		$_a=post_param('a');
		$_b=post_param('b');
		$a=$GLOBALS['FORUM_DRIVER']->get_member_from_username($_a);
		if (is_null($a)) warn_exit(do_lang_tempcode('_USER_NO_EXIST',$_a));
		$b=$GLOBALS['FORUM_DRIVER']->get_member_from_username($_b);
		if (is_null($b)) warn_exit(do_lang_tempcode('_USER_NO_EXIST',$_b));

		$GLOBALS['FORUM_DB']->query_update('f_topics',array('t_pt_from'=>$a,'t_pt_to'=>$b,'t_forum_id'=>NULL),array('id'=>$topic_id),'',1);

		// Update forum cache view
		require_code('ocf_posts_action2');
		ocf_force_update_forum_cacheing($forum_id,-1);

		return $this->redirect_to('MAKE_PERSONAL',$topic_id);
	}

	/**
	 * Redirect to a screen suitable for celebrating a members birthday (existing topic, if possible).
	 *
	 * @return tempcode		The UI
	 */
	function birthday()
	{
		$id=get_param('id');
		$topic_id=$GLOBALS['FORUM_DB']->query_value_null_ok_full('SELECT id FROM '.$GLOBALS['FORUM_DB']->get_table_prefix().'f_topics WHERE t_cache_first_time>'.strval(time()-60*60*24*3).' AND '.db_string_equal_to('t_cache_first_title',do_lang('HAPPY_BIRTHDAY_PERSON',$id)));
		if (!is_null($topic_id))
		{
			$title=get_page_title('REDIRECTING');
			$url=$GLOBALS['FORUM_DRIVER']->topic_url($topic_id);
			require_code('site2');
			assign_refresh($url,0.0);
			return do_template('REDIRECT_SCREEN',array('_GUID'=>'f457a6d28fd6e494662e5b82e80e9fa2','URL'=>$url,'TITLE'=>$title,'TEXT'=>do_lang_tempcode('REDIRECTING_TO_BIRTHDAY_TOPIC')));
		}
		$_POST['title']=do_lang('HAPPY_BIRTHDAY_PERSON',$id);
		if (get_magic_quotes_gpc()) $_POST['title']=addslashes($_POST['title']);
		$forum_id=$GLOBALS['FORUM_DB']->query_value_null_ok('f_forums','id',array('f_name'=>get_option('main_forum_name')));
		if (is_null($forum_id)) $forum_id=db_get_first_id();
		$_GET['id']=strval($forum_id);
		return $this->new_topic(false,NULL,file_exists(get_file_base().'/themes/default/images/emoticons/index.html')?'emoticons/birthday':'ocf_emoticons/birthday');
	}

}


