<?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		cedi
 */

/**
 * Module page class.
 */
class Module_cedi
{

	/**
	 * 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']=8;
		$info['locked']=false;
		$info['update_require_upgrade']=1;
		return $info;
	}

	/**
	 * Standard modular uninstall function.
	 */
	function uninstall()
	{
		$GLOBALS['SITE_DB']->drop_if_exists('seedy_children');
		$GLOBALS['SITE_DB']->drop_if_exists('seedy_pages');
		$GLOBALS['SITE_DB']->drop_if_exists('seedy_changes');

		delete_config_option('is_on_seedy');
		delete_config_option('points_cedi');
		delete_config_option('cedi_show_stats_count_pages');
		delete_config_option('cedi_show_stats_count_posts');

		delete_value('num_seedy_pages');
		delete_value('num_seedy_posts');
		delete_value('num_seedy_files');

		delete_attachments('seedy_page');
		delete_attachments('cedi_page');

		delete_specific_permission('seedy_manage_tree');
		delete_specific_permission('seedy_edit_pages');
		delete_specific_permission('seedy_edit');

		$GLOBALS['SITE_DB']->query_delete('group_category_access',array('module_the_name'=>'seedy_page'));

		$GLOBALS['SITE_DB']->drop_if_exists('seedy_posts');

		delete_menu_item_simple('_SEARCH:cedi:type=misc');
		delete_menu_item_simple('_SEARCH:cedi:type=random');
		delete_menu_item_simple('_SEARCH:cedi:type=changes');
		delete_menu_item_simple('_SEARCH:cedi:type=tree');
	}

	/**
	 * Standard modular install function.
	 *
	 * @param  ?integer	What version we're upgrading from (NULL: new install)
	 * @param  ?integer	What hack version we're upgrading from (NULL: new-install/not-upgrading-from-a-hacked-version)
	 */
	function install($upgrade_from=NULL,$upgrade_from_hack=NULL)
	{
		require_lang('cedi');

		if (($upgrade_from<4) && (!is_null($upgrade_from)))
		{
			delete_specific_permission('seedy_edit');
			delete_specific_permission('seedy_edit_pages');
			$GLOBALS['SITE_DB']->add_table_field('seedy_pages','seedy_views','INTEGER',0);
			$GLOBALS['SITE_DB']->add_table_field('seedy_pages','hide_posts','BINARY',0);
			$GLOBALS['SITE_DB']->add_table_field('seedy_posts','validated','BINARY',1);

			$GLOBALS['SITE_DB']->query_update('seedy_changes',array('the_action'=>'CEDI_MAKE_POST'),array('the_action'=>'SEEDY_MAKE_POST'));
			$GLOBALS['SITE_DB']->query_update('seedy_changes',array('the_action'=>'CEDI_DELETE_POST'),array('the_action'=>'SEEDY_DELETE_POST'));
			$GLOBALS['SITE_DB']->query_update('seedy_changes',array('the_action'=>'CEDI_EDIT_TREE'),array('the_action'=>'SEEDY_EDIT_TREE'));
			$GLOBALS['SITE_DB']->query_update('seedy_changes',array('the_action'=>'CEDI_MOVE_POST'),array('the_action'=>'SEEDY_MOVE_POST'));
			$GLOBALS['SITE_DB']->query_update('seedy_changes',array('the_action'=>'CEDI_EDIT_POST'),array('the_action'=>'SEEDY_EDIT_POST'));
			$GLOBALS['SITE_DB']->query_update('seedy_changes',array('the_action'=>'CEDI_MAKE_POST'),array('the_action'=>'SEEDY_MAKE_POST'));
			$GLOBALS['SITE_DB']->query_update('seedy_changes',array('the_action'=>'CEDI_EDIT_PAGE'),array('the_action'=>'SEEDY_EDIT_PAGE'));
			$GLOBALS['SITE_DB']->query_update('seedy_changes',array('the_action'=>'CEDI_SEEDY_POSTS'),array('the_action'=>'MERGE_SEEDY_POSTS'));
		}

		if (($upgrade_from<3) && (!is_null($upgrade_from)))
		{
			$GLOBALS['SITE_DB']->add_table_field('seedy_children','title','SHORT_TEXT');
		}

		if (($upgrade_from<6) && (!is_null($upgrade_from)))
		{
			$GLOBALS['SITE_DB']->query_update('attachment_refs',array('r_referer_type'=>'cedi_post'),array('r_referer_type'=>'seedy_post'));
			$GLOBALS['SITE_DB']->query_update('attachment_refs',array('r_referer_type'=>'cedi_page'),array('r_referer_type'=>'seedy_page'));
		}

		if (($upgrade_from<7) && (!is_null($upgrade_from)))
		{
			$GLOBALS['SITE_DB']->query_delete('db_meta_indices',array('i_table'=>'seedy_children','i_name'=>'child_find','i_fields'=>'parent_id'));
			$GLOBALS['SITE_DB']->query('DROP INDEX child_find ON '.$GLOBALS['SITE_DB']->get_table_prefix().'seedy_children');
		}

		if (($upgrade_from<8) && (!is_null($upgrade_from)))
		{
			delete_config_option('is_on_seedy');

			$GLOBALS['SITE_DB']->add_table_field('seedy_pages','submitter','USER');
		}

		if (($upgrade_from<8) || (is_null($upgrade_from)))
		{
			add_config_option('CEDI_MAKE_POST','points_cedi','integer','return addon_installed(\'points\')?\'10\':NULL;','POINTS','COUNT_POINTS_GIVEN');

			add_config_option('CEDI_PAGES','cedi_show_stats_count_pages','tick','return addon_installed(\'stats_block\')?\'0\':NULL;','BLOCKS','STATISTICS');
			add_config_option('CEDI_POSTS','cedi_show_stats_count_posts','tick','return addon_installed(\'stats_block\')?\'0\':NULL;','BLOCKS','STATISTICS');
		}

		if (is_null($upgrade_from))
		{
			$GLOBALS['SITE_DB']->create_table('seedy_changes',array(
				'id'=>'*AUTO',
				'the_action'=>'ID_TEXT',
				'the_page'=>'AUTO_LINK',
				'date_and_time'=>'TIME',
				'ip'=>'IP',
				'the_user'=>'USER'
			));

			$GLOBALS['SITE_DB']->create_table('seedy_children',array(
				'parent_id'=>'*AUTO_LINK',
				'child_id'=>'*AUTO_LINK',
				'the_order'=>'INTEGER',
				'title'=>'SHORT_TEXT'
			));

			//$GLOBALS['SITE_DB']->create_index('seedy_children','child_find',array('parent_id'));

			$GLOBALS['SITE_DB']->create_table('seedy_pages',array(
				'id'=>'*AUTO',
				'title'=>'SHORT_TRANS',
				'notes'=>'LONG_TEXT',
				'description'=>'LONG_TRANS',	// Comcode
				'add_date'=>'TIME',
				'seedy_views'=>'INTEGER',
				'hide_posts'=>'BINARY',
				'submitter'=>'USER'
			));

			$GLOBALS['SITE_DB']->create_index('seedy_pages','seedy_views',array('seedy_views'));
			$GLOBALS['SITE_DB']->create_index('seedy_pages','sps',array('submitter'));
			$GLOBALS['SITE_DB']->create_index('seedy_pages','sadd_date',array('add_date'));

			$lang_key=lang_code_to_default_content('CEDI_HOME',false,1);
			$GLOBALS['SITE_DB']->query_insert('seedy_pages',array('submitter'=>$GLOBALS['FORUM_DRIVER']->get_guest_id()+1,'hide_posts'=>0,'seedy_views'=>0,'add_date'=>time(),'description'=>insert_lang_comcode('',2),'notes'=>'','title'=>$lang_key));
			$groups=$GLOBALS['FORUM_DRIVER']->get_usergroup_list(false,true);
			foreach (array_keys($groups) as $group_id)
			{
				$GLOBALS['SITE_DB']->query_insert('group_category_access',array('module_the_name'=>'seedy_page','category_name'=>strval(db_get_first_id()),'group_id'=>$group_id));
			}

			add_specific_permission('SEEDY','seedy_manage_tree',false);

			$GLOBALS['SITE_DB']->create_table('seedy_posts',array(
				'id'=>'*AUTO',
				'page_id'=>'AUTO_LINK',
				'the_message'=>'LONG_TRANS',	// Comcode
				'date_and_time'=>'TIME',
				'validated'=>'BINARY',
				'seedy_views'=>'INTEGER',
				'the_user'=>'USER',
				'edit_date'=>'?TIME'
			));

			$GLOBALS['SITE_DB']->create_index('seedy_posts','seedy_views',array('seedy_views'));
			$GLOBALS['SITE_DB']->create_index('seedy_posts','spos',array('the_user'));
			$GLOBALS['SITE_DB']->create_index('seedy_posts','posts_on_page',array('page_id'));
			$GLOBALS['SITE_DB']->create_index('seedy_posts','cdate_and_time',array('date_and_time'));
			$GLOBALS['SITE_DB']->create_index('seedy_posts','svalidated',array('validated'));

			$GLOBALS['FORUM_DRIVER']->install_create_custom_field('points_gained_seedy',20,1,0,0,0,'','integer');

			require_lang('cedi');
			//add_menu_item_simple('main_content',NULL,'CEDI','_SEARCH:cedi:type=misc');
			add_menu_item_simple('wiki_features',NULL,'HOME','_SEARCH:cedi:type=misc');
			add_menu_item_simple('wiki_features',NULL,'RANDOM_PAGE','_SEARCH:cedi:type=random');
			add_menu_item_simple('wiki_features',NULL,'CEDI_CHANGELOG','_SEARCH:cedi:type=changes');
			add_menu_item_simple('wiki_features',NULL,'TREE','_SEARCH:cedi:type=tree');

			$GLOBALS['SITE_DB']->create_index('seedy_posts','ftjoin_spm',array('the_message'));
			$GLOBALS['SITE_DB']->create_index('seedy_pages','ftjoin_spt',array('title'));
			$GLOBALS['SITE_DB']->create_index('seedy_pages','ftjoin_spd',array('description'));
		}
	}

	/**
	 * Standard modular entry-point finder function.
	 *
	 * @return ?array	A map of entry points (type-code=>language-code) (NULL: disabled).
	 */
	function get_entry_points()
	{
		return array('misc'=>'CEDI_HOME','random'=>'RANDOM_PAGE','changes'=>'CEDI_CHANGELOG','tree'=>'TREE');
	}

	/**
	 * Standard modular page-link finder function (does not return the main entry-points that are not inside the tree).
	 *
	 * @param  ?integer  The number of tree levels to computer (NULL: no limit)
	 * @param  boolean	Whether to not return stuff that does not support permissions (unless it is underneath something that does).
	 * @param  ?string	Position to start at in the tree. Does not need to be respected. (NULL: from root)
	 * @param  boolean	Whether to avoid returning categories.
	 * @return ?array	 	A tuple: 1) full tree structure [made up of (pagelink, permission-module, permissions-id, title, children, ?entry point for the children, ?children permission module, ?whether there are children) OR a list of maps from a get_* function] 2) permissions-page 3) optional base entry-point for the tree 4) optional permission-module 5) optional permissions-id (NULL: disabled).
	 */
	function get_page_links($max_depth=NULL,$require_permission_support=false,$start_at=NULL,$dont_care_about_categories=false)
	{
		$permission_page='cms_cedi';

//		if ($require_permission_support) return array(array(),$permission_page,'_SELF:_SELF:type=misc:id=!');

		require_code('cedi');
		$category_id=NULL;
		if (!is_null($start_at))
		{
			$matches=array();
			if (preg_match('#[^:]*:cedi:type=misc:id=(.*)#',$start_at,$matches)!=0) $category_id=intval($matches[1]);
		}

		$cedi_seen=array();
		$adjusted_max_depth=is_null($max_depth)?NULL:(is_null($category_id)?($max_depth-1):$max_depth);
		return array($dont_care_about_categories?array():get_cedi_page_tree($cedi_seen,$category_id,NULL,NULL,false,false,$adjusted_max_depth),$permission_page,'_SELF:_SELF:type=misc:id=!','seedy_page');
	}

	/**
	 * Standard modular new-style deep page-link finder function (does not return the main entry-points).
	 *
	 * @param  string  	Callback function to send discovered page-links to.
	 * @param  MEMBER		The member we are finding stuff for (we only find what the member can view).
	 * @param  integer	Code for how deep we are tunnelling down, in terms of whether we are getting entries as well as categories.
	 * @param  string		Stub used to create page-links. This is passed in because we don't want to assume a zone or page name within this function.
	 * @param  ?string	Where we're looking under (NULL: root of tree). We typically will NOT show a root node as there's often already an entry-point representing it.
	 * @param  integer	Our recursion depth (used to calculate importance of page-link, used for instance by Google sitemap). Deeper is typically less important.
	 * @param  ?array		Non-standard for API [extra parameter tacked on] (NULL: yet unknown). Contents of database table for performance.
	 */
	function get_sitemap_pagelinks($callback,$member_id,$depth,$pagelink_stub,$parent_pagelink=NULL,$recurse_level=0,$category_data=NULL)
	{
		// This is where we start
		if (is_null($parent_pagelink))
		{
			$parent_pagelink=$pagelink_stub.':misc'; // This is the entry-point we're under
			$parent_attributes=array('id'=>strval(db_get_first_id()));
		} else
		{
			list(,$parent_attributes,)=page_link_decode($parent_pagelink);
		}

		// We read in all data for efficiency
		if (is_null($category_data))
		{
			$category_data=$GLOBALS['SITE_DB']->query_select('seedy_pages c LEFT JOIN '.get_table_prefix().'seedy_children x ON x.child_id=c.id LEFT JOIN '.get_table_prefix().'translate t ON '.db_string_equal_to('language',user_lang()).' AND t.id=c.title',array('c.title AS _title','c.id','t.text_original AS title','parent_id','add_date'));
			$category_data=remove_duplicate_rows($category_data,'id');
		}

		// Subcategories
		foreach ($category_data as $row)
		{
			if (is_null($row['title'])) $row['title']=get_translated_text($row['_title']);

			if ((!is_null($row['parent_id'])) && (strval($row['parent_id'])==$parent_attributes['id']))
			{
				$pagelink=$pagelink_stub.'misc:'.strval($row['id']);
				if (__CLASS__!='')
				{
					$this->get_sitemap_pagelinks($callback,$member_id,$depth,$pagelink_stub,$pagelink,$recurse_level+1,$category_data); // Recurse
				} else
				{
					call_user_func_array(__FUNCTION__,array($callback,$member_id,$depth,$pagelink_stub,$pagelink,$recurse_level+1,$category_data)); // Recurse
				}
				if (has_category_access($member_id,'seedy_page',strval($row['id'])))
				{
					call_user_func_array($callback,array($pagelink,$parent_pagelink,$row['add_date'],NULL,max(0.7-$recurse_level*0.1,0.3),$row['title'])); // Callback
				} else // Not accessible: we need to copy the node through, but we will flag it 'Unknown' and say it's not accessible.
				{
					call_user_func_array($callback,array($pagelink,$parent_pagelink,$row['add_date'],NULL,max(0.7-$recurse_level*0.1,0.3),do_lang('UNKNOWN'),false)); // Callback
				}
			}
		}
	}

	/**
	 * Convert a page link to a category ID and category permission module type.
	 *
	 * @param  string	The page link
	 * @return array	The pair
	 */
	function extract_page_link_permissions($page_link)
	{
		$matches=array();
		preg_match('#^([^:]*):([^:]*):type=misc:id=(.*)$#',$page_link,$matches);
		return array($matches[3],'seedy_page');
	}

	/**
	 * Standard modular run function.
	 *
	 * @return tempcode	The result of execution.
	 */
	function run()
	{
		$GLOBALS['FEED_URL']=find_script('backend').'?mode=cedi&filter=';

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

		require_code('cedi');
		require_lang('cedi');
		require_css('wiki');

		// Decide what to do
		if ($type=='findpost')
		{
			$post_id=get_param_integer('id');
			$page_id=$GLOBALS['SITE_DB']->query_select('seedy_posts','page_id',array('id'=>$post_id));
			$redirect=build_url(array('page'=>'_SELF','type'=>'misc','id'=>$page_id),'_SELF',NULL,false,false,false,'post_'.strval($post_id));
			require_code('site2');
			assign_refresh($redirect,0.0);
			return do_template('REDIRECT_SCREEN',array('_GUID'=>'ec38429b79fff8b311d45e7d8126cb48','URL'=>$redirect,'TITLE'=>get_screen_title('CEDI'),'TEXT'=>do_lang_tempcode('REDIRECTING')));
		}
		if ($type=='misc') return $this->page();
		if ($type=='random') return $this->random();
		if ($type=='changes') return $this->changes();
		if ($type=='tree') return $this->tree();
		if ($type=='do') return $this->do_cedi_merge();
		if ($type=='mg') return $this->do_cedi_merge_interface();
		if ($type=='move') return $this->move();
		if ($type=='_move') return $this->_move();
		if ($type=='post') return $this->post();
		if ($type=='_post') return $this->_post();

		return new ocp_tempcode();
	}

	/**
	 * Redirect to a random page.
	 *
	 * @return tempcode		The UI
	 */
	function random()
	{
		attach_message(do_lang_tempcode('TAKEN_RANDOM_WIKI_PAGE'),'inform');

		$num_pages=$GLOBALS['SITE_DB']->query_value('seedy_pages','MAX(id)');
		if ($num_pages<=db_get_first_id())
		{
			$id=$num_pages;
		} else
		{
			$pages=array();
			do // Loop. picking random pages between 0 and max-id till we find one that exists
			{
				$id=mt_rand(db_get_first_id(),$num_pages);
				$pages=$GLOBALS['SITE_DB']->query_select('seedy_pages',array('*'),array('id'=>$id),'',1);
			}
			while (!array_key_exists(0,$pages));
		}
		$redir_url=build_url(array('page'=>'_SELF','type'=>'misc','id'=>$id),'_SELF');
		return redirect_screen(get_screen_title('RANDOM_PAGE'),$redir_url,'');
	}

	/**
	 * The UI to show a page.
	 *
	 * @return tempcode		The UI
	 */
	function page()
	{
		require_code('feedback');

		// We will use OCF styling
		require_lang('ocf');

		// Find our page by whatever means
		$find=get_param('find','');
		if ($find!='')	// Allow quick 'find' remapping to a real id
		{
			$id=$GLOBALS['SITE_DB']->query_value_null_ok('seedy_pages p LEFT JOIN '.get_table_prefix().'translate t ON p.title=t.id','p.id',array('text_original'=>$find));
			if (is_null($id))
			{
				$title=get_screen_title('ERROR_OCCURRED');
				$add_access=(has_submit_permission('low',get_member(),get_ip_address(),'cms_cedi'));
				require_lang('zones');
				$add_url=$add_access?build_url(array('page'=>'cms_cedi','type'=>'add_page','id'=>$find,'redirect'=>get_self_url(true,true)),get_module_zone('cms_cedi')):new ocp_tempcode();
				return do_template('MISSING_SCREEN',array('_GUID'=>'ba778c816860a9594983ed9ef03d0c42','TITLE'=>$title,'ADD_URL'=>$add_url,'PAGE'=>$find));
			}
			$chain=cedi_derive_chain($id);
		} else
		{
			list($id,$chain)=get_param_cedi_chain('id',strval(db_get_first_id()));
		}
		$pages=$GLOBALS['SITE_DB']->query_select('seedy_pages',array('*'),array('id'=>$id),'',1);

		// Display title
		if (!array_key_exists(0,$pages))
		{
			return warn_screen(get_screen_title('CEDI'),do_lang_tempcode('MISSING_RESOURCE'));
		}
		$page=$pages[0];
		$current_title=get_translated_text($page['title']);
		$title_to_use=do_lang_tempcode('CEDI_PAGE',escape_html($current_title));
		$title_to_use_2=do_lang('CEDI_PAGE',$current_title);
		if (addon_installed('awards'))
		{
			require_code('awards');
			$awards=find_awards_for('cedi_page',strval($page['id']));
		} else $awards=array();
		$title=get_screen_title($title_to_use,false,NULL,NULL,$awards);

		if (!has_category_access(get_member(),'seedy_page',strval($page['id']))) access_denied('CATEGORY_ACCESS');

		// Views
		if (get_db_type()!='xml')
		{
			$page['seedy_views']++;
			if (!$GLOBALS['SITE_DB']->table_is_locked('seedy_pages')) // TODO: Update for v10
				$GLOBALS['SITE_DB']->query_update('seedy_pages',array('seedy_views'=>$page['seedy_views']),array('id'=>$id),'',1,NULL,false,true);
		}

		seo_meta_load_for('seedy_page',strval($id),$title_to_use_2);

		// Description
		$description=get_translated_tempcode($page['description']);
		$description_comcode=get_translated_text($page['description']);

		// Build up navigation tree
		$breadcrumbs=cedi_breadcrumbs($chain,$current_title,has_specific_permission(get_member(),'open_virtual_roots'),true,true);

		// Children Links
		$dbchildren=$GLOBALS['SITE_DB']->query('SELECT child_id,c.title,hide_posts,description FROM '.get_table_prefix().'seedy_children c JOIN '.get_table_prefix().'seedy_pages p ON c.child_id=p.id WHERE c.parent_id='.strval((integer)$id).' ORDER BY c.the_order');
		$num_children=0;
		$children=new ocp_tempcode();
		foreach ($dbchildren as $myrow)
		{
			$child_id=$myrow['child_id'];
			$child_title=$myrow['title'];
			$child_description=get_translated_text($myrow['description']);

			$my_child_posts=$GLOBALS['SITE_DB']->query_value('seedy_posts','COUNT(*)',array('page_id'=>$child_id));
			$my_child_children=$GLOBALS['SITE_DB']->query_value('seedy_children','COUNT(*)',array('parent_id'=>$child_id));

			$my_child_posts_string=do_lang_tempcode('POST_PLU',integer_format($my_child_posts));
			$my_child_children_string=do_lang_tempcode('CHILD_PLU',integer_format($my_child_children));
			if ((!($my_child_posts>0)) && (!($my_child_children>0))) $sup=($myrow['hide_posts']==1)?new ocp_tempcode():do_lang_tempcode('EMPTY');
			if (($my_child_posts>0) || ($my_child_children>0) || (trim($child_description)!=''))
			{
				$sup=do_template('WIKI_SUBCATEGORY_CHILDREN',array(
					'_GUID'=>'90e9f1647fdad0cacccecca3cbf12888',
					'MY_CHILD_POSTS'=>integer_format($my_child_posts),
					'MY_CHILD_CHILDREN'=>integer_format($my_child_children),
					'BODY_CONTENT'=>(trim($child_description)!='')?strval(strlen($child_description)):NULL,
				));
			}

			$url=build_url(array('page'=>'_SELF','type'=>'misc','id'=>$chain.'/'.strval($child_id)),'_SELF');
			$children->attach(do_template('WIKI_SUBCATEGORY_LINK',array('_GUID'=>'e9f9b504093220dc23a1ab59b3e8e5df','URL'=>$url,'CHILD'=>$child_title,'SUP'=>$sup)));

			$num_children++;
		}

		$staff_access=has_specific_permission(get_member(),'edit_lowrange_content','cms_cedi',array('seedy_page',$id));

		// Main text (posts)
		$where_map=array('page_id'=>$id);
		if (!has_specific_permission(get_member(),'see_unvalidated')) $where_map['validated']=1;
		$dbposts=$GLOBALS['SITE_DB']->query_select('seedy_posts',array('*'),$where_map,'ORDER BY date_and_time',300);
		$num_posts=0;
		$posts=new ocp_tempcode();
		$include_expansion=(strpos($description_comcode,'[attachment')!==false);
		foreach ($dbposts as $myrow)
		{
			// Work out posters details
			$poster=$myrow['the_user'];
			$username=$GLOBALS['FORUM_DRIVER']->get_username($poster);
			if (is_null($username)) $username=do_lang('UNKNOWN');

			$post_id=$myrow['id'];

			// Date post was made
			$post_date_raw=$myrow['date_and_time'];
			$post_date=get_timezoned_date($myrow['date_and_time']);

			// Rating
			actualise_rating(true,'seedy_post',strval($post_id),build_url(array('page'=>'_SELF','type'=>'misc','id'=>$chain),'_SELF'),$current_title);
			$rating_array=get_rating_simple_array(build_url(array('page'=>'_SELF','type'=>'misc','id'=>$chain),'_SELF'),$current_title,'seedy_post',strval($post_id),'WIKI_RATING_FORM',$poster);
			if (!is_null($rating_array))
			{
				$rating=do_template('WIKI_RATING',$rating_array);
			} else $rating=new ocp_tempcode();

			// Display the post then ;)
			$post_comcode=get_translated_text($myrow['the_message']);
			$include_expansion_here=(strpos($post_comcode,'[attachment')!==false);
			if ($include_expansion_here) $include_expansion=true;
			$post=get_translated_tempcode($myrow['the_message']);
			if ((has_edit_permission('low',get_member(),$poster,'cms_cedi',array('seedy_page',$id))) && (($id!=db_get_first_id()) || (has_specific_permission(get_member(),'feature'))))
			{
				$edit_url=build_url(array('page'=>'_SELF','type'=>'post','id'=>$chain,'post_id'=>$post_id),'_SELF');
				$extra=do_template('SCREEN_ITEM_BUTTON',array('_GUID'=>'37404e2e5cf7e4cb806f796e9df90898','REL'=>'edit','IMMEDIATE'=>false,'URL'=>$edit_url,'TITLE'=>do_lang_tempcode('EDIT'),'IMG'=>'edit'));
				$move_url=build_url(array('page'=>'_SELF','type'=>'move','id'=>$chain,'post_id'=>$post_id),'_SELF');
				$extra->attach(do_template('SCREEN_ITEM_BUTTON',array('_GUID'=>'b4325cd1bac924cc83771d4c3c41be8b','REL'=>'move','IMMEDIATE'=>false,'URL'=>$move_url,'TITLE'=>do_lang_tempcode('MOVE'),'IMG'=>'move')));
			} else $extra=new ocp_tempcode();
			$poster_url=is_guest($poster)?'':$GLOBALS['FORUM_DRIVER']->member_profile_url($poster,false,true);
			$rate_url=get_self_url(true);
			$posts->attach(do_template('WIKI_POST',array('_GUID'=>'a29b107abfaf7689c8392676c63093f5','INCLUDE_EXPANSION'=>$include_expansion_here,'UNVALIDATED'=>($myrow['validated']==0)?do_lang_tempcode('UNVALIDATED'):new ocp_tempcode(),'STAFF_ACCESS'=>$staff_access,'RATE_URL'=>$rate_url.'#post_'.strval($post_id),'RATING'=>$rating,'ID'=>strval($myrow['id']),'POSTER_URL'=>$poster_url,'POSTER'=>$username,'POST_DATE_RAW'=>strval($post_date_raw),'POST_DATE'=>$post_date,'POST'=>$post,'BUTTONS'=>$extra)));

			$num_posts++;
		}

		if (count($dbposts)>=300)
		{
			attach_message(do_lang_tempcode('TOO_MANY_CEDI_POSTS'),'warn');
		}

		$menu=$this->do_menu($chain,$id,$include_expansion,count($dbposts)<300);

		$GLOBALS['META_DATA']+=array(
			'created'=>date('Y-m-d',$page['add_date']),
			'creator'=>$GLOBALS['FORUM_DRIVER']->get_username($page['submitter']),
			'publisher'=>'', // blank means same as creator
			'modified'=>'',
			'type'=>'Wiki+ Page',
			'title'=>comcode_escape(get_translated_text($page['title'])),
			'identifier'=>'_SEARCH:cedi:misc:'.strval($page['id']),
			'description'=>(strlen($description_comcode)<200)?$description_comcode:'',
			'numposts'=>strval($num_posts),
			'image'=>find_theme_image('bigicons/cedi'),
		);

		breadcrumb_add_segment($breadcrumbs);

		// Re-defined canonical URL
		global $CANONICAL_URL,$NON_CANONICAL_PARAMS;
		$non_canonical=array();
		if (is_array($NON_CANONICAL_PARAMS)) foreach ($NON_CANONICAL_PARAMS as $n) $non_canonical[$n]=NULL;
		$CANONICAL_URL=get_self_url(true,false,$non_canonical+array('id'=>$id,'type'=>'misc','find'=>NULL));

		return do_template('WIKI_PAGE_SCREEN',array('_GUID'=>'1840d6934be3344c4f93a159fc737a45','TAGS'=>get_loaded_tags('cedi_pages'),'HIDE_POSTS'=>$page['hide_posts']==1,'ID'=>strval($id),'VIEWS'=>integer_format($page['seedy_views']),'STAFF_ACCESS'=>$staff_access,'DESCRIPTION'=>$description,'TITLE'=>$title,'CHILDREN'=>$children,'POSTS'=>$posts,'NUM_POSTS'=>integer_format($num_posts),'MENU'=>$menu));
	}

	/**
	 * Show the buttons on the Wiki+ page viewing page.
	 *
	 * @param  SHORT_TEXT	The ID chain being used to get to this page
	 * @param  AUTO_LINK		The ID of the page we are showing the menu on
	 * @param  boolean		Whether to include the expansion/contraction button
	 * @param  boolean		Whether posting is generally allowed (may be passed false if too many posts)
	 * @return tempcode		The button tempcode
	 */
	function do_menu($chain,$id,$include_expansion,$may_post=true)
	{
		$page_url=build_url(array('page'=>'_SELF','type'=>'misc','id'=>$chain),'_SELF');
		$pos=strpos($chain,'/');
		$id=intval(substr($chain,($pos===false)?0:($pos+1)));
		if ((addon_installed('search')) && (has_actual_page_access(get_member(),'search')))
		{
			$search_url=build_url(array('page'=>'search','type'=>'misc','id'=>'cedi_posts','search_under'=>$id),get_module_zone('search'));
			$search_button=do_template('SCREEN_BUTTON',array('_GUID'=>'ad8783a0af3a35f21022b30397f1b03e','IMMEDIATE'=>false,'REL'=>'search','URL'=>$search_url,'TITLE'=>do_lang_tempcode('SEARCH'),'IMG'=>'search'));
		} else $search_button=new ocp_tempcode();
		$changes_url=build_url(array('page'=>'_SELF','type'=>'changes','id'=>$chain),'_SELF');
		$changes_button=do_template('SCREEN_BUTTON',array('_GUID'=>'99ad7faac817326510583a69ac719d58','IMMEDIATE'=>false,'REL'=>'history','URL'=>$changes_url,'TITLE'=>do_lang_tempcode('CEDI_CHANGELOG'),'IMG'=>'changes'));
		if ((has_specific_permission(get_member(),'seedy_manage_tree','cms_cedi',array('seedy_page',$id))) && (has_actual_page_access(get_member(),'cms_cedi')))
		{
			$tree_url=build_url(array('page'=>'cms_cedi','type'=>'edit_tree','id'=>$chain,'redirect'=>get_self_url(true,true)),get_module_zone('cms_cedi'));
			$tree_button=do_template('SCREEN_BUTTON',array('_GUID'=>'e6edc9f39b6b0aff86cffbaa98c51827','REL'=>'edit','IMMEDIATE'=>false,'URL'=>$tree_url,'TITLE'=>do_lang_tempcode('CEDI_EDIT_TREE'),'IMG'=>'edit_tree'));
		} else $tree_button=new ocp_tempcode();
		if ((has_edit_permission('cat_low',get_member(),NULL,'cms_cedi',array('seedy_page',$id))) && (has_actual_page_access(get_member(),'cms_cedi')))
		{
			$edit_url=build_url(array('page'=>'cms_cedi','type'=>'edit_page','id'=>$chain,'redirect'=>get_self_url(true,true)),get_module_zone('cms_cedi'));
			$edit_button=do_template('SCREEN_BUTTON',array('_GUID'=>'5d8783a0af3a35f21022b30397f1b03e','REL'=>'edit','IMMEDIATE'=>false,'URL'=>$edit_url,'TITLE'=>do_lang_tempcode('EDIT'),'IMG'=>'edit'));
		} else $edit_button=new ocp_tempcode();
		if (($may_post) && (has_submit_permission('low',get_member(),get_ip_address(),'cms_cedi',array('seedy_page',$id))) && (($id!=db_get_first_id()) || (has_specific_permission(get_member(),'feature'))))
		{
			$post_url=build_url(array('page'=>'_SELF','type'=>'post','id'=>$chain),'_SELF');
			$post_button=do_template('SCREEN_BUTTON',array('_GUID'=>'c26462f34a64c4bf80c1fb7c40102eb0','IMMEDIATE'=>false,'URL'=>$post_url,'TITLE'=>do_lang_tempcode('_POST'),'IMG'=>'new_post'));
		} else $post_button=new ocp_tempcode();

		$tpl=new ocp_tempcode();
		$tpl->attach($search_button);
		$tpl->attach($changes_button);
		$tpl->attach($tree_button);
		$tpl->attach($edit_button);
		$tpl->attach($post_button);
		return $tpl;
	}

	/**
	 * The UI to show changes.
	 *
	 * @return tempcode		The UI
	 */
	function changes()
	{
		$title=get_screen_title('CEDI_CHANGELOG');

		breadcrumb_set_parents(array(array('_SELF:_SELF:misc',do_lang_tempcode('CEDI'))));

		require_code('templates_internalise_screen');
		$test_tpl=internalise_own_screen($title);
		if (is_object($test_tpl)) return $test_tpl;

		$start=get_param_integer('start',0);
		$max=get_param_integer('max',25);
		$sortables=array('date_and_time'=>do_lang_tempcode('DATE'));
		$test=explode(' ',get_param('sort','date_and_time DESC'),2);
		if (count($test)==1) $test[1]='DESC';
		list($sortable,$sort_order)=$test;
		if (((strtoupper($sort_order)!='ASC') && (strtoupper($sort_order)!='DESC')) || (!array_key_exists($sortable,$sortables)))
			log_hack_attack_and_exit('ORDERBY_HACK');
		global $NON_CANONICAL_PARAMS;
		$NON_CANONICAL_PARAMS[]='sort';

		$_id=get_param('id',NULL);
		$id=NULL;
		if (!is_null($_id))
		{
			list($id,)=get_param_cedi_chain('id');
		}
		$where=(!is_null($id))?('the_page='.strval($id)):(db_string_equal_to('the_action','CEDI_MAKE_POST').' OR '.db_string_equal_to('the_action','CEDI_EDIT_PAGE'));
		$rows=$GLOBALS['SITE_DB']->query('SELECT * FROM '.get_table_prefix().'seedy_changes WHERE '.$where.' ORDER BY '.$sortable.' '.$sort_order,$max,$start);
		$max_rows=$GLOBALS['SITE_DB']->query_value_null_ok_full('SELECT COUNT(*) FROM '.get_table_prefix().'seedy_changes WHERE '.$where);
		$fields=new ocp_tempcode();
		require_code('templates_results_table');
		foreach ($rows as $myrow)
		{
			if (!has_category_access(get_member(),'seedy_page',strval($myrow['the_page']))) continue;

			$l=$GLOBALS['SITE_DB']->query_value_null_ok('seedy_pages','title',array('id'=>$myrow['the_page']));
			if (!is_null($l))
			{
				$chain=is_null($id)?cedi_derive_chain($myrow['the_page']):$_id;
				$l=cedi_breadcrumbs($chain,get_translated_text($l),true);

				$username=$GLOBALS['FORUM_DRIVER']->get_username($myrow['the_user']);
				if (is_null($username)) $username=do_lang('UNKNOWN');
				$_date_and_time=get_timezoned_date($myrow['date_and_time']);
				$ml=$GLOBALS['FORUM_DRIVER']->member_profile_hyperlink($myrow['the_user']);
				$action=do_lang($myrow['the_action'],NULL,NULL,NULL,NULL,false);
				if (is_null($action)) $action='?';

				$fields->attach(results_entry(array($l,$ml,escape_html($_date_and_time),$action)));
			}
		}
		if ($fields->is_empty()) return inform_screen($title,do_lang_tempcode('NO_ENTRIES'));

		$fields_title=results_field_title(array(do_lang_tempcode('PAGE'),do_lang_tempcode('USERNAME'),do_lang_tempcode('DATE'),do_lang_tempcode('ACTION')),$sortables,'sort',$sortable.' '.$sort_order);
		$out=results_table(do_lang_tempcode('CEDI_CHANGELOG'),$start,'start',$max,'max',$max_rows,$fields_title,$fields,$sortables,$sortable,$sort_order,'sort');

		return do_template('WIKI_CHANGES_SCREEN',array('_GUID'=>'0dea1ed9d31a818cba60f56fc1c8f68f','TITLE'=>$title,'RESULTS'=>$out));
	}

	/**
	 * Get markers of posts from the POST/GET.
	 *
	 * @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;
	}

	/**
	 * The UI for merging Wiki+ posts.
	 *
	 * @return tempcode	The UI.
	 */
	function do_cedi_merge_interface()
	{
		$title=get_screen_title('MERGE_CEDI_POSTS');

		$_redir_url=build_url(array('page'=>'_SELF','type'=>'misc','id'=>get_param('id',false,true)),'_SELF');
		$redir_url=$_redir_url->evaluate();
		$merge_url=build_url(array('page'=>'_SELF','redirect'=>$redir_url,'type'=>'do','id'=>get_param('id',false,true)),'_SELF',NULL,true);

		$merged='';
		$markers=$this->get_markers();
		if (count($markers)==0) warn_exit(do_lang_tempcode('NOTHING_SELECTED'));
		foreach ($markers as $id)
		{
			$rows=$GLOBALS['SITE_DB']->query_select('seedy_posts',array('*'),array('id'=>$id),'',1);
			if (!array_key_exists(0,$rows)) continue;
			$myrow=$rows[0];

			if (!has_category_access(get_member(),'seedy_page',strval($myrow['page_id']))) access_denied('CATEGORY_ACCESS');
			check_edit_permission('low',NULL,array('seedy_page',$myrow['page_id']),'cms_cedi');

			if ($merged!='') $merged.=chr(10).chr(10);
			$merged.=get_translated_text($myrow['the_message']);
		}

		require_code('form_templates');

		$posting_form=get_posting_form(do_lang('MERGE_CEDI_POSTS'),$merged,$merge_url,new ocp_tempcode(),new ocp_tempcode());

		return do_template('POSTING_SCREEN',array('_GUID'=>'4372327fb689ef70a9ac5d275dd454f1','POSTING_FORM'=>$posting_form,'HIDDEN'=>'','TITLE'=>$title,'TEXT'=>do_lang_tempcode('CEDI_MERGE_TEXT')));
	}

	/**
	 * The actualiser for merging Wiki+ posts.
	 *
	 * @return tempcode	The UI.
	 */
	function do_cedi_merge()
	{
		$title=get_screen_title('MERGE_CEDI_POSTS');

		check_edit_permission('low',NULL,array('seedy_page',get_param('id',false,true)),'cms_cedi');

		require_code('comcode_check');

		@ignore_user_abort(true);

		$message=post_param('post');
		check_comcode($message,NULL,false,NULL,true);
		$post_id=$GLOBALS['SITE_DB']->query_insert('seedy_posts',array('edit_date'=>NULL,'the_message'=>0,'the_user'=>get_member(),'date_and_time'=>time(),'page_id'=>get_param_integer('id'),'validated'=>1,'seedy_views'=>0),true);
		require_code('attachments2');
		$the_message=insert_lang_comcode_attachments(2,$message,'cedi_post',strval($post_id));
		$GLOBALS['SITE_DB']->query_update('seedy_posts',array('the_message'=>$the_message),array('id'=>$post_id),'',1);

		@ignore_user_abort(false);

		$markers=$this->get_markers();
		foreach ($markers as $id)
		{
			$GLOBALS['SITE_DB']->query_delete('seedy_posts',array('id'=>$id),'',1);
		}

		$GLOBALS['SITE_DB']->query_insert('seedy_changes',array('the_page'=>get_param_integer('id'),'the_action'=>'MERGE_CEDI_POSTS','date_and_time'=>time(),'ip'=>get_ip_address(),'the_user'=>get_member()));

		require_code('autosave');
		clear_ocp_autosave();

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

	/**
	 * The UI for moving a Wiki+ post.
	 *
	 * @return tempcode	The UI.
	 */
	function move()
	{
		$title=get_screen_title('CEDI_MOVE_POST');

		$_id=get_param_cedi_chain('id');
		$id=$_id[0];
		$post_id=get_param_integer('post_id');

		$original_poster=$GLOBALS['SITE_DB']->query_value('seedy_posts','the_user',array('id'=>$post_id));

		$true_page_id=$GLOBALS['SITE_DB']->query_value('seedy_posts','page_id',array('id'=>$post_id));
		if (!has_category_access(get_member(),'seedy_page',strval($true_page_id))) access_denied('CATEGORY_ACCESS');
		check_edit_permission('low',$original_poster,array('seedy_page',$true_page_id),'cms_cedi');

		$_redir_url=build_url(array('page'=>'_SELF','type'=>'misc','id'=>get_param('id',false,true)),'_SELF');
		$redir_url=$_redir_url->evaluate();
		$move_url=build_url(array('page'=>'_SELF','redirect'=>$redir_url,'type'=>'_move','id'=>get_param('id',false,true)),'_SELF');

		require_code('form_templates');

		$fields=form_input_tree_list(do_lang_tempcode('DESTINATION'),'','target',NULL,'choose_cedi_page',array(),true,strval($id));

		$hidden=form_input_hidden('source',strval($post_id));

		return do_template('FORM_SCREEN',array('_GUID'=>'f231626424aa83d75df571a818665152','SKIP_VALIDATION'=>true,'TITLE'=>$title,'URL'=>$move_url,'TEXT'=>do_lang_tempcode('SELECT_TARGET_POST_DESTINATION'),'FIELDS'=>$fields,'HIDDEN'=>$hidden,'SUBMIT_NAME'=>do_lang_tempcode('MOVE')));
	}

	/**
	 * The actualiser for moving a Wiki+ post.
	 *
	 * @return tempcode	The UI.
	 */
	function _move()
	{
		$title=get_screen_title('CEDI_MOVE_POST');

		$post_id=post_param_integer('source');
		$target=post_param_integer('target');
		$_id=get_param_cedi_chain('id');
		$id=$_id[0];

		$true_page_id=$GLOBALS['SITE_DB']->query_value('seedy_posts','page_id',array('id'=>$post_id));
		if (!has_category_access(get_member(),'seedy_page',strval($true_page_id))) access_denied('CATEGORY_ACCESS');

		$original_poster=$GLOBALS['SITE_DB']->query_value('seedy_posts','the_user',array('id'=>$post_id));
		check_edit_permission('low',$original_poster,array('seedy_page',$true_page_id),'cms_cedi');

		// Check user info
		$member=get_member();
		if ($target==db_get_first_id())
		{
			check_specific_permission('feature');
		}

		if ($id==$target)
		{
			return warn_screen($title,do_lang_tempcode('INVALID_OPERATION'));
		} else
		{
			$GLOBALS['SITE_DB']->query_update('seedy_posts',array('page_id'=>$target),array('id'=>$post_id),'',1);
			$GLOBALS['SITE_DB']->query_insert('seedy_changes',array('the_page'=>$target,'the_action'=>'CEDI_MOVE_POST','date_and_time'=>time(),'ip'=>get_ip_address(),'the_user'=>$member));

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

	/**
	 * The UI for making a Wiki+ post.
	 *
	 * @return tempcode	The UI.
	 */
	function post()
	{
		$post_id=get_param_integer('post_id',-1);
		if ($post_id==-1) $mode='post'; else $mode='edit';

		require_code('form_templates');

		$specialisation=new ocp_tempcode();

		$parsed=NULL;

		if ($mode=='edit')
		{
			$_id=get_param_cedi_chain('id',strval($GLOBALS['SITE_DB']->query_value('seedy_posts','page_id',array('id'=>$post_id))));
			$id=$_id[0];

			$rows=$GLOBALS['SITE_DB']->query_select('seedy_posts',array('*'),array('id'=>$post_id),'',1);
			if (!array_key_exists(0,$rows)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
			$myrow=$rows[0];

			if (!has_category_access(get_member(),'seedy_page',strval($myrow['page_id']))) access_denied('CATEGORY_ACCESS');

			$original_poster=$myrow['the_user'];
			check_edit_permission('low',$original_poster,array('seedy_page',$myrow['page_id']),'cms_cedi');

			$title=get_screen_title('CEDI_EDIT_POST');

			// If we are editing, we need to retrieve the message
			$message=get_translated_text($myrow['the_message']);
			$parsed=get_translated_tempcode($myrow['the_message']);

			if (has_delete_permission('low',get_member(),$original_poster,'cms_cedi',array('seedy_page',$myrow['page_id'])))
			{
				$specialisation->attach(do_template('FORM_SCREEN_FIELD_SPACER',array('TITLE'=>do_lang_tempcode('ACTIONS'))));
				$specialisation->attach(form_input_tick(do_lang_tempcode('DELETE'),do_lang_tempcode('DESCRIPTION_DELETE'),'delete',false));
			}

			$submit_name=do_lang_tempcode('SAVE');

			$validated=$myrow['validated'];

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

			if (has_specific_permission(get_member(),'bypass_validation_lowrange_content','cms_cedi',array('seedy_page',$myrow['page_id'])))
				$specialisation->attach(form_input_tick(do_lang_tempcode('VALIDATED'),do_lang_tempcode('DESCRIPTION_VALIDATED'),'validated',$validated==1));
		} else
		{
			$_id=get_param_cedi_chain('id');
			$id=$_id[0];

			if ($GLOBALS['SITE_DB']->query_value('seedy_posts','COUNT(*)',array('page_id'=>$id))>=300)
			{
				warn_exit(do_lang_tempcode('TOO_MANY_CEDI_POSTS'));
			}

			check_submit_permission('low',array('seedy_page',$id),'cms_cedi');

			$title=get_screen_title('CEDI_MAKE_POST');

			$message='';

			$submit_name=do_lang_tempcode('MAKE_POST');

			$validated=1;

			list($warning_details,$ping_url)=array(NULL,NULL);

			if (has_specific_permission(get_member(),'bypass_validation_lowrange_content','cms_cedi'))
				$specialisation->attach(form_input_tick(do_lang_tempcode('VALIDATED'),do_lang_tempcode('DESCRIPTION_VALIDATED'),'validated',$validated==1));
		}

		$hidden_fields=new ocp_tempcode();

		require_code('fields');
		if (has_tied_catalogue('seedy_post'))
		{
			append_form_custom_fields('seedy_post',($mode=='edit')?strval($post_id):NULL,$specialisation,$hidden_fields);
		}

		$text=new ocp_tempcode();

		list($page_id,)=get_param_cedi_chain('id',strval(db_get_first_id()));
		require_lang('notifications');
		$notify=($GLOBALS['SITE_DB']->query_value_null_ok('seedy_changes','MAX(date_and_time)',array('the_page'=>$page_id))<time()-60*10);
		$radios=form_input_radio_entry('send_notification','0',!$notify,do_lang_tempcode('NO'));
		$radios->attach(form_input_radio_entry('send_notification','1',$notify,do_lang_tempcode('YES')));
		$specialisation->attach(form_input_radio(do_lang_tempcode('SEND_NOTIFICATION'),do_lang_tempcode('DESCRIPTION_SEND_NOTIFICATION'),'send_notification',$radios));

		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)));
		}

		// Awards?
		if (addon_installed('awards'))
		{
			require_code('awards');
			$specialisation->attach(get_award_fields('seedy_post',($post_id==-1)?NULL:strval($post_id)));
		} else $awards=array();

		// Attachment modification=re-entry
		$message=post_param('message',$message);

		$_chain=get_param_cedi_chain('id',strval(db_get_first_id()));
		$chain=$_chain[1];

		$breadcrumbs=cedi_breadcrumbs($chain,NULL,true,true);

		$_redir_url=build_url(array('page'=>'_SELF','type'=>'misc','id'=>get_param('id',strval($id),true)),'_SELF');
		$redir_url=$_redir_url->evaluate();
		$post_url=build_url(array('page'=>'_SELF','id'=>get_param('id',strval(db_get_first_id()),false),'redirect'=>$redir_url,'type'=>'_post'),'_SELF');

		$hidden_fields->attach(form_input_hidden('post_id',strval($post_id)));

		$javascript=(function_exists('captcha_ajax_check')?captcha_ajax_check():'');

		$posting_form=get_posting_form($submit_name,$message,$post_url,$hidden_fields,new ocp_tempcode(),NULL,'',$specialisation,$parsed,$javascript);

		breadcrumb_add_segment($breadcrumbs,protect_from_escaping('<span>'.$submit_name->evaluate().'</span>'));

		return do_template('WIKI_POSTING_SCREEN',array('_GUID'=>'efdea6198cba136eb6809937c2322458','PING_URL'=>$ping_url,'WARNING_DETAILS'=>$warning_details,'TEXT'=>$text,'TITLE'=>$title,'POSTING_FORM'=>$posting_form));
	}

	/**
	 * The actualiser for making a Wiki+ post.
	 *
	 * @return tempcode	The UI.
	 */
	function _post()
	{
		if (addon_installed('captcha'))
		{
			require_code('captcha');
			enforce_captcha();
		}

		$post_id=post_param_integer('post_id',-1);
		if ($post_id==-1) $mode='post'; else $mode='edit';

		require_code('uploads');

		$_id=get_param_cedi_chain('id');
		$id=$_id[0];
		if ($mode=='edit')
		{
			$delete=post_param_integer('delete',0);
			$title=get_screen_title('CEDI_EDIT_POST');
		} else
		{
			$title=get_screen_title('CEDI_MAKE_POST');

			if ($GLOBALS['SITE_DB']->query_value('seedy_posts','COUNT(*)',array('id'=>$id))>=300)
			{
				warn_exit(do_lang_tempcode('TOO_MANY_CEDI_POSTS'));
			}
		}

		// Post Text
		$message=post_param('post');

		$validated=post_param_integer('validated',0);

		if ($id==db_get_first_id())
		{
			check_specific_permission('feature');
		}

		// Do it
		if ($mode=='post')
		{
			inject_action_spamcheck();
			if (!has_specific_permission(get_member(),'bypass_validation_lowrange_content','cms_cedi',array('seedy_page',$id)))
				$validated=0;
			if (!has_category_access(get_member(),'seedy_page',strval($id))) access_denied('CATEGORY_ACCESS');

			check_submit_permission('low',NULL,'cms_cedi');

			$post_id=cedi_add_post($id,$message,$validated);

			if ($validated==0)
			{
				require_code('submit');
				$edit_url=build_url(array('page'=>'cedi','type'=>'post','post_id'=>$post_id,'validated'=>1),'_SELF',NULL,false,false,true);
				if (addon_installed('unvalidated'))
					send_validation_request('CEDI_MAKE_POST','seedy_posts',false,strval($post_id),$edit_url);
			}
		} else
		{
			$rows=$GLOBALS['SITE_DB']->query_select('seedy_posts',array('*'),array('id'=>$post_id),'',1);
			if (!array_key_exists(0,$rows)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
			$myrow=$rows[0];
			if (!has_category_access(get_member(),'seedy_page',strval($myrow['page_id']))) access_denied('CATEGORY_ACCESS');

			$original_poster=$myrow['the_user'];

			if (!has_specific_permission(get_member(),'bypass_validation_lowrange_content','cms_cedi',array('seedy_page',$myrow['page_id'])))
				$validated=0;

			if ($delete==1)
			{
				check_delete_permission('low',$original_poster,array('seedy_page',$myrow['page_id']),'cms_cedi');

				cedi_delete_post($post_id);

				require_code('fields');
				if (has_tied_catalogue('seedy_post'))
				{
					delete_form_custom_fields('seedy_post',strval($post_id));
				}
			} else
			{
				check_edit_permission('low',$original_poster,array('seedy_page',$myrow['page_id']),'cms_cedi');

				cedi_edit_post($post_id,$message,$validated);
			}
		}

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

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

		require_code('autosave');
		clear_ocp_autosave();

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

	/**
	 * The UI to show the Wiki+ tree.
	 *
	 * @return tempcode		The UI
	 */
	function tree()
	{
		require_code('splurgh');

		breadcrumb_set_parents(array(array('_SELF:_SELF:misc',do_lang_tempcode('CEDI'))));

		if ($GLOBALS['SITE_DB']->query_value('seedy_pages','COUNT(*)')>3000)
			warn_exit(do_lang_tempcode('TOO_MANY_TO_CHOOSE_FROM'));

		$url_stub=build_url(array('page'=>'_SELF','type'=>'misc'),'_SELF',NULL,false,false,true);
		$last_change_time=$GLOBALS['SITE_DB']->query_value_null_ok('seedy_changes','date_and_time',NULL,'ORDER BY date_and_time DESC');

		$children_rows=$GLOBALS['SITE_DB']->query_select('seedy_children',array('child_id','parent_id','title'),NULL,'ORDER BY the_order');
		$page_rows=$GLOBALS['SITE_DB']->query_select('seedy_pages',array('id','title'));
		$map=array();
		foreach ($page_rows as $i=>$page)
		{
			if ($i%100==0) echo escape_html(chr(10)); // Fixes weird CGI timeout (some servers only) if there's lots of data. Won't trigger quirks mode. 'escape_html' is just for the XSS detector.

			if ($page['id']!=db_get_first_id())
			{
				if (!has_category_access($GLOBALS['FORUM_DRIVER']->get_guest_id(),'seedy_page',strval($page['id']))) continue;
			}

			$id=$page['id'];

			$map[$id]['title']=get_translated_text($page['title']);
			$children=array();
			foreach ($children_rows as $child)
			{
				if ($child['parent_id']==$id) $children[]=$child['child_id'];
			}
			$map[$id]['children']=$children;
		}

		$root=get_param_integer('keep_cedi_root',NULL);
		$cache_name='cedi_tree_made';
		if (!is_null($root)) $cache_name.=strval($root);
		$content=splurgh_master_build('id',$map,$url_stub->evaluate(),$cache_name,$last_change_time,$root);

		$title=get_screen_title('CEDI_TREE');
		return do_template('SPLURGH_SCREEN',array('_GUID'=>'be1e902d5f4429795f0f4c4e4384071b','TITLE'=>$title,'CONTENT'=>$content));
	}

}


