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

/**
 * Module page class.
 */
class Module_cms_comcode_pages
{

	/**
	 * 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']=4;
		$info['update_require_upgrade']=1;
		$info['locked']=true;
		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 array('misc'=>'COMCODE_PAGE_MANAGEMENT');
	}

	/**
	 * 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()
	{
		return array('submit_highrange_content'=>array(0,'COMCODE_PAGE_ADD'),'edit_highrange_content'=>array(0,'COMCODE_PAGE_EDIT'),'edit_own_highrange_content'=>array(0,'COMCODE_PAGE_OWN_EDIT'));
	}

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

		delete_config_option('store_revisions');
		delete_config_option('number_revisions_show');
		delete_config_option('points_COMCODE_PAGE_ADD');

		/*$zones=find_all_zones(true);
		$langs=find_all_langs(true);
		foreach ($zones as $zone)
		{
			foreach (array_keys($langs) as $lang)
			{
				deldir_contents(zone_black_magic_filterer(get_custom_file_base().(($zone=='')?'':'/').$zone.'/pages/comcode_custom/'.$lang,true),true);
			}
		}*/

		delete_attachments('comcode_page');
	}

	/**
	 * 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)
	{
		if ($GLOBALS['SITE_DB']->table_exists('comcode_pages')) return; // We moved this install code from another file. Now, upgrade.php should have dealt with this issue but if people didn't run it, detected

		require_code('zones2');

		if (($upgrade_from<4) || (is_null($upgrade_from)))
		{
			$GLOBALS['SITE_DB']->create_table('comcode_pages',array(
				'the_zone'=>'*ID_TEXT',
				'the_page'=>'*ID_TEXT',
				'p_parent_page'=>'ID_TEXT',
				'p_validated'=>'BINARY',
				'p_edit_date'=>'?TIME',
				'p_add_date'=>'TIME',
				'p_submitter'=>'USER',
				'p_show_as_edit'=>'BINARY'
			));
			$GLOBALS['SITE_DB']->create_index('comcode_pages','p_submitter',array('p_submitter'));
			$GLOBALS['SITE_DB']->create_index('comcode_pages','p_add_date',array('p_add_date'));
			$GLOBALS['SITE_DB']->create_index('comcode_pages','p_validated',array('p_validated'));
			add_config_option('COMCODE_PAGE_ADD','points_COMCODE_PAGE_ADD','integer','return addon_installed(\'points\')?\'10\':NULL;','POINTS','COUNT_POINTS_GIVEN');
		}

		if (($upgrade_from<3) && (!is_null($upgrade_from)))
		{
			$GLOBALS['SITE_DB']->add_table_field('cached_comcode_pages','cc_page_title','?SHORT_TRANS');
			return;
		}

		if (is_null($upgrade_from))
		{
			$GLOBALS['SITE_DB']->create_table('cached_comcode_pages',array(
				'the_zone'=>'*ID_TEXT',
				'the_page'=>'*ID_TEXT',
				'string_index'=>'LONG_TRANS',	// Comcode
				'the_theme'=>'*ID_TEXT',
				'cc_page_title'=>'?SHORT_TRANS'
			));

			//update_comcode_page_cache(); Lets not force the installer to know comcode. The cache will be generated on first page view

			add_config_option('STORE_REVISIONS','store_revisions','tick','return \'1\';','ADMIN','COMCODE_PAGE_MANAGEMENT');
			add_config_option('SHOW_REVISIONS','number_revisions_show','integer','return \'5\';','ADMIN','COMCODE_PAGE_MANAGEMENT');

			$GLOBALS['SITE_DB']->create_index('cached_comcode_pages','ftjoin_ccpt',array('cc_page_title'));
			$GLOBALS['SITE_DB']->create_index('cached_comcode_pages','ftjoin_ccsi',array('string_index'));
			$GLOBALS['SITE_DB']->create_index('cached_comcode_pages','ccp_join',array('the_page','the_zone'));
		}
	}

	/**
	 * Standard modular run function.
	 *
	 * @return tempcode	The result of execution.
	 */
	function run()
	{
		require_code('zones2');
		require_code('zones3');
		require_lang('zones');

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

		if ($type=='__ed') return $this->__ed();
		if ($type=='export') return $this->export();
		if ($type=='_ed') return $this->_ed();
		if ($type=='misc') return $this->ed();

		return new ocp_tempcode();
	}

	/**
	 * The do-next manager for after content management.
	 *
	 * @param  tempcode		The title (output of get_screen_title)
	 * @param  ?ID_TEXT		The name of the page just handled (NULL: none)
	 * @param  ID_TEXT		The name of the zone just handled (blank: none/welcome-zone)
	 * @param  tempcode		The text to show (blank: default)
	 * @return tempcode		The UI
	 */
	function do_next_manager($title,$page,$zone,$completion_text)
	{
		if (!addon_installed('page_management'))
		{
			return redirect_screen($title,build_url(array('page'=>'_SELF','type'=>'misc'),'_SELF'),$completion_text);
		}

		require_code('zones2');
		require_code('zones3');
		return site_tree_do_next_manager($title,$page,$zone,$completion_text);
	}

	/**
	 * Get all pages.
	 *
	 * @param  LANGUAGE_NAME	The language we are searching for pages of
	 * @return array				The map (page name => path/time)
	 */
	function get_comcode_files_array($lang)
	{
		$zones=find_all_zones();
		$out=array();
		foreach ($zones as $zone)
		{
			$_out=array();
			if ($lang!=get_site_default_lang())
			{
				$_out+=find_all_pages($zone,'comcode_custom/'.get_site_default_lang(),'txt',false,NULL,FIND_ALL_PAGES__NEWEST);
				$_out+=find_all_pages($zone,'comcode/'.get_site_default_lang(),'txt',false,NULL,FIND_ALL_PAGES__NEWEST);
			}
			$_out+=find_all_pages($zone,'comcode_custom/'.$lang,'txt',false,NULL,FIND_ALL_PAGES__NEWEST);
			$_out+=find_all_pages($zone,'comcode/'.$lang,'txt',false,NULL,FIND_ALL_PAGES__NEWEST);

			foreach ($_out as $page=>$subdir)
			{
				if (is_integer($page)) $page=strval($page);

				$resource_owner=$GLOBALS['SITE_DB']->query_value_null_ok('comcode_pages','p_submitter',array('the_zone'=>$zone,'the_page'=>$page));
				if (!has_edit_permission('high',get_member(),$resource_owner,'cms_comcode_pages'))
					continue;

				$out[$zone.':'.$page]=array($zone.'/pages/'.$subdir.'/'.$page,NULL);
			}
		}

		return $out;
	}

	/**
	 * Get a map of page names to paths, under the given specifications.
	 *
	 * @param  ID_TEXT		The zone we are searching in
	 * @param  PATH			The subdirectory to search for pages in
	 * @param  string			The file stub to find for
	 * @param  boolean		Whether we are doing a multi-site check on the base directory
	 * @return array			The map (page name => path/time)
	 */
	function get_comcode_revisions($zone,$subdir,$find_for,$also_checking_base=false)
	{
		$filesarray=array();
		$dir=(((substr($subdir,0,14)=='comcode_custom') && (!$also_checking_base))?get_custom_file_base():get_file_base()).'/'.filter_naughty($zone).(($zone=='')?'':'/').'pages/'.filter_naughty($subdir);
		$_dir=function_exists('glob')?@glob($dir.'/'.$find_for.'*'):@opendir($dir);
		if (($_dir===false) && (function_exists('glob'))) $_dir=array();
		if ($_dir===false)
		{
			if (@mkdir($dir,0777,true)===false)
			{
				if (substr($subdir,0,14)!='comcode_custom') return array();
				warn_exit(do_lang_tempcode('WRITE_ERROR_DIRECTORY_REPAIR',escape_html($dir)));
			}
			fix_permissions($dir,0777);
			sync_file($dir);
			$_dir=opendir($dir);
		}
		if ((get_custom_file_base()!=get_file_base()) && (substr($subdir,0,14)=='comcode_custom') && (!$also_checking_base))
		{
			$filesarray=$this->get_comcode_revisions($zone,$subdir,$find_for,true);
		}

		// Find all the comcode pages
		if (function_exists('glob'))
		{
			foreach ($_dir as $file)
			{
				$temp=explode('.',basename($file));
				if (isset($temp[2]))
					$filesarray[$zone.':'.$file]=array($zone.'/pages/'.$subdir.'/'.basename($file),intval($temp[2]));
			}
		} else
		{
			while (false!==($file=readdir($_dir)))
			{
				if (substr($file,0,strlen($find_for)+1)==$find_for.'.')
				{
					$temp=explode('.',$file);
					if ((isset($temp[2])) && (is_numeric($temp[2])))
						$filesarray[$zone.':'.$file]=array($zone.'/pages/'.$subdir.'/'.$file,intval($temp[2]));
				}
			}

			closedir($_dir);
		}

		if (($zone=='') && (get_option('collapse_user_zones')=='1'))
			$filesarray+=$this->get_comcode_revisions('site',$subdir,$find_for,$also_checking_base);

		return $filesarray;
	}

	/**
	 * The UI to choose a page to edit.
	 *
	 * @return tempcode		The UI
	 */
	function ed()
	{
		$title=get_screen_title('COMCODE_PAGE_EDIT');
		$lang=choose_language($title,true);
		if (is_object($lang)) return $lang;

		require_code('form_templates');

		$add_new_permission=has_specific_permission(get_member(),'submit_highrange_content');
		if ((!$add_new_permission) && (!has_specific_permission(get_member(),'edit_highrange_content')) && (!has_specific_permission(get_member(),'edit_own_highrange_content')))
			check_edit_permission('high',NULL);

		$fields=new ocp_tempcode();
		if ($add_new_permission)
		{
			$fields->attach(form_input_line(do_lang_tempcode('NEW'),do_lang_tempcode('DESCRIPTION_NEW_COMCODE_PAGE'),'page_link_2','',true));
			$submit_name=do_lang_tempcode('ADD');
		} else
		{
			$submit_name=NULL;
		}

		$hidden=new ocp_tempcode();
		$hidden->attach(form_input_hidden('lang',$lang));
		$hidden->attach(form_input_hidden('type','_ed'));
		$hidden->attach(build_keep_form_fields('_SELF'));

		$map=array('page'=>'_SELF','type'=>'_ed','lang'=>$lang);
		$post_url=build_url($map,'_SELF',NULL,false,true);

		breadcrumb_set_self(do_lang_tempcode('COMCODE_PAGES'));

		$search_url=build_url(array('page'=>'search','id'=>'comcode_pages'),get_module_zone('search'));
		$sitemap_zone=get_page_zone('sitemap',false);
		if ($sitemap_zone!==NULL)
		{
			$archive_url=build_url(array('page'=>'sitemap'),$sitemap_zone);
		} else
		{
			$archive_url=build_url(array('page'=>''),'');
		}
		$text=paragraph(do_lang_tempcode('CHOOSE_EDIT_LIST_EXTRA',escape_html($search_url->evaluate()),escape_html($archive_url->evaluate())));
		if (addon_installed('page_management'))
		{
			if (has_actual_page_access(get_member(),'admin_sitetree'))
			{
				$page_wizard=build_url(array('page'=>'admin_sitetree','type'=>'pagewizard'),get_module_zone('admin_sitetree'));
				$site_tree_editor=build_url(array('page'=>'admin_sitetree','type'=>'site_tree'),get_module_zone('admin_sitetree'));
				attach_message(do_lang_tempcode('SUGGEST_PAGE_WIZARD',escape_html($page_wizard->evaluate()),escape_html($site_tree_editor->evaluate())),'inform');
			}
		}

		require_code('templates_results_table');

		$current_ordering=get_param('sort','page_title ASC');
		if (strpos($current_ordering,' ')===false) warn_exit(do_lang_tempcode('INTERNAL_ERROR'));
		list($sortable,$sort_order)=explode(' ',$current_ordering,2);
		$sortables=array(
			'page_title'=>do_lang_tempcode('TITLE'),
			'page'=>do_lang_tempcode('PAGE'),
			'zone_name'=>do_lang_tempcode('ZONE'),
			'pagelink'=>do_lang_tempcode('PAGE_LINK'),
		);
		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';

		$header_row=results_field_title(array(
			do_lang_tempcode('TITLE'),
			do_lang_tempcode('PAGE'),
			do_lang_tempcode('ZONE'),
			do_lang_tempcode('PAGE_LINK'),
			//do_lang_tempcode('PARENT_PAGE'),
			//do_lang_tempcode('OWNER'),
			//do_lang_tempcode('ADDED'),
			//do_lang_tempcode('VALIDATED'),
			do_lang_tempcode('ACTIONS'),
		),$sortables,'sort',$sortable.' '.$sort_order);

		$all_zones=find_all_zones(false,true);

		$number_pages_parsed_for_titles=0;

		$GLOBALS['NO_QUERY_LIMIT']=true;

		$start=get_param_integer('start',0);
		$max=get_param_integer('max',50);

		$filesarray=$this->get_comcode_files_array($lang);
		if (count($filesarray)>=300) // Oh dear, limits reached, try another tact
		{
			$orderer='p_add_date ASC';
			switch ($sortable)
			{
				case 'page_title':
					$orderer='t.text_original '.$sort_order;
					break;
				case 'page':
					$orderer='c.the_page '.$sort_order;
					break;
				case 'zone_name':
					$orderer='c.the_zone '.$sort_order;
					break;
				case 'pagelink':
					$orderer='c.the_zone '.$sort_order.',c.the_page '.$sort_order;
					break;
			}
			$group_by='';
			if (can_arbitrary_groupby())
				$group_by='GROUP BY c.the_zone,c.the_page';

			$where_map='('.db_string_equal_to('language',$lang).' OR language IS NULL)';
			if (!has_specific_permission(get_member(),'edit_highrange_content'))
				$where_map.=' AND submitter='.strval(get_member());
			$ttable=get_table_prefix().'comcode_pages c LEFT JOIN '.get_table_prefix().'cached_comcode_pages a ON c.the_page=a.the_page AND c.the_zone=a.the_zone LEFT JOIN '.get_table_prefix().'translate t ON t.id=a.cc_page_title';
			$page_rows=$GLOBALS['SITE_DB']->query('SELECT c.*,cc_page_title FROM '.$ttable.' WHERE '.$where_map.$group_by.' ORDER BY '.$orderer,$max,$start);
			$max_rows=$GLOBALS['SITE_DB']->query_value_null_ok_full('SELECT COUNT(DISTINCT c.the_zone,c.the_page) FROM '.$ttable.' WHERE '.$where_map);

			$filesarray=array();
			foreach ($page_rows as $row)
			{
				$located=_request_page($row['the_page'],$row['the_zone'],NULL,$lang);
				if ($located!==false)
				{
					$filesarray[$row['the_zone'].':'.$row['the_page']]=array(
						$row['the_zone'].'/pages/'.strtolower($located[0]).'/'.$row['the_page'],
						NULL,
						$row
					);
				}
			}

			$found_via_query=true;
		} else
		{
			$max_rows=0;
			ksort($filesarray);

			$found_via_query=false;
		}

		// Render table rows
		$_table_rows=array();
		foreach ($filesarray as $pagelink=>$path_bits)
		{
			list($zone,$page)=explode(':',$pagelink,2);
			if (!is_string($page)) $page=strval($page);

			$edit_link=build_url(array('page'=>'_SELF','type'=>'_ed','page_link'=>$pagelink,'lang'=>$lang),'_SELF');

			$clone_link=build_url(array('page'=>'_SELF','type'=>'_ed','page_link'=>$zone.':','restore_from'=>$path_bits[0].'.txt','lang'=>$lang),'_SELF');

			$zone_name=array_key_exists($zone,$all_zones)?$all_zones[$zone][1]:$zone;

			// We need to separately read from DB to work out meta data?
			$row=mixed();
			if (!array_key_exists(2,$path_bits))
			{
				$rows=$GLOBALS['SITE_DB']->query_select('comcode_pages c LEFT JOIN '.get_table_prefix().'cached_comcode_pages a ON c.the_page=a.the_page AND c.the_zone=a.the_zone',array('c.*','cc_page_title'),array('c.the_zone'=>$zone,'c.the_page'=>$page),'',1);
				if ((!array_key_exists(0,$rows)) && ($number_pages_parsed_for_titles<15))
				{
					$result=request_page($page,false,$zone,'comcode_custom',true);
					$rows=$GLOBALS['SITE_DB']->query_select('comcode_pages c LEFT JOIN '.get_table_prefix().'cached_comcode_pages a ON c.the_page=a.the_page AND c.the_zone=a.the_zone',array('c.*','cc_page_title'),array('c.the_zone'=>$zone,'c.the_page'=>$page),'',1);
					$number_pages_parsed_for_titles++;
				}
				$row=array_key_exists(0,$rows)?$rows[0]:NULL;
			} else // Ah, no we got everything from DB in one go
			{
				$row=$path_bits[2];
			}

			// Work out meta data
			$page_title=do_lang_tempcode('NA_EM');
			if (!is_null($row))
			{
				$username=protect_from_escaping($GLOBALS['FORUM_DRIVER']->member_profile_hyperlink($row['p_submitter']));

				$parent_page=$row['p_parent_page'];
				$add_date=get_timezoned_date($row['p_add_date']);
				$validated=($row['p_validated']==1)?do_lang_tempcode('YES'):do_lang_tempcode('YES');

				if (!is_null($row['cc_page_title']))
				{
					$_page_title=get_translated_text($row['cc_page_title'],NULL,NULL,true);
					if (!is_null($_page_title))
					{
						if ($_page_title!='')
							$page_title=make_string_tempcode($_page_title);
					}
				}
			} else
			{
				$username=do_lang('UNKNOWN');
				$parent_page='';
				$add_date=get_timezoned_date(filectime(get_file_base().'/index.php'));
				$validated=do_lang_tempcode('YES');
			}

			$wrappable_pagelink=preg_replace('#([^ ]):([\w\-]{10,})$#','${1}: ${2}',preg_replace('#(^[\w\-]{10,}):#','${1}: ',$pagelink));

			$actions=do_template('COMCODE_PAGE_EDIT_ACTIONS',array('_GUID'=>'6cc8c492ba9ae4035c394fbe28a56c26','EDIT_URL'=>$edit_link,'CLONE_URL'=>$clone_link));

			$_table_rows[]=array(
				'page_title'=>$page_title,
				'page'=>$page,
				'zone'=>$zone,
				'zone_name'=>$zone_name,
				'pagelink'=>$pagelink,
				'wrappable_pagelink'=>$wrappable_pagelink,
				'actions'=>$actions,
			);
		}

		// Manual sorting
		global $M_SORT_KEY;
		$M_SORT_KEY=$sortable;
		usort($_table_rows,'multi_sort');
		if ($sort_order=='DESC') $_table_rows=array_reverse($_table_rows);

		$table_rows=new ocp_tempcode();
		if (!$found_via_query)
		{
			$max_rows=count($_table_rows);
		}
		foreach ($_table_rows as $i=>$table_row)
		{
			if (!$found_via_query)
			{
				if ($i<$start) continue;
				if ($i>$max+$start) break;
			}

			$table_rows->attach(results_entry(array(
				protect_from_escaping(hyperlink(build_url(array('page'=>$table_row['page']),$table_row['zone']),$table_row['page_title'])),
				protect_from_escaping(do_template('COMCODE_TELETYPE',array('CONTENT'=>preg_replace('#([\w\d\_]{22})#','${1}<br />',escape_html($table_row['page']))))),
				protect_from_escaping(hyperlink(build_url(array('page'=>''),$table_row['zone']),$table_row['zone_name'],false,true)),
				protect_from_escaping(do_template('COMCODE_TELETYPE',array('CONTENT'=>preg_replace('#([\w\d\_]{22})#','${1}<br />',escape_html($table_row['wrappable_pagelink']))))),
				//$parent_page,
				//$username,
				//$add_date,
				//$validated,
				protect_from_escaping($table_row['actions']),
			),true));
		}

		$table=results_table(do_lang('COMCODE_PAGES'),$start,'start',$max,'max',$max_rows,$header_row,$table_rows,$sortables,$sortable,$sort_order,'sort',NULL,NULL,NULL,8,'fdgfdfdfdggfd',true);

		return do_template('COLUMNED_TABLE_SCREEN',array('_GUID'=>'0b7285c14eb632ab50d0a497a240cf7a','TITLE'=>$title,'TEXT'=>$text,'TABLE'=>$table,'FIELDS'=>$fields,'POST_URL'=>$post_url,'GET'=>true,'HIDDEN'=>$hidden,'SUBMIT_NAME'=>$submit_name));
	}

	/**
	 * Find the filebase-relative path of a Comcode page. Allows override via restore_from parameter.
	 *
	 * @param  LANGUAGE_NAME	The language most preferable
	 * @param  ID_TEXT			The page name
	 * @param  ID_TEXT			The zone
	 * @return PATH				The path (blank: not found)
	 */
	function find_comcode_page($lang,$file,$zone)
	{
		$restore_from=zone_black_magic_filterer(filter_naughty(get_param('restore_from',$zone.'/'.'pages/comcode_custom/'.$lang.'/'.$file.'.txt')),true);
		if (((!is_file(get_file_base().'/'.$restore_from)) && (!is_file(get_custom_file_base().'/'.$restore_from))) || ((!is_null(get_param('restore_from',NULL))) && (!$GLOBALS['FORUM_DRIVER']->is_staff(get_member()))))
		{
			$page_request=_request_page($file,$zone);
			if (strpos($page_request[0],'COMCODE')===false) return '';
			$restore_from=$page_request[count($page_request)-1];
		}

		return $restore_from;
	}

	/**
	 * The UI to edit a page.
	 *
	 * @return tempcode		The UI
	 */
	function _ed()
	{
		$GLOBALS['HELPER_PANEL_PIC']='pagepics/comcode_page_edit';
		require_lang('menus');
		$GLOBALS['HELPER_PANEL_TEXT']=comcode_lang_string('DOC_WRITING');
		$GLOBALS['HELPER_PANEL_TUTORIAL']='tut_comcode_pages';

		$simple_add=(get_param_integer('simple_add',0)==1);

		$lang=choose_language(get_screen_title($simple_add?'COMCODE_PAGE_ADD':'COMCODE_PAGE_EDIT'),true);
		if (is_object($lang)) return $lang;

		if (addon_installed('page_management'))
		{
			// Add to menu
			if ((get_param('menu',STRING_MAGIC_NULL)!=STRING_MAGIC_NULL) && (has_actual_page_access(get_member(),'admin_sitetree')))
			{
				require_code('menus2');
				add_menu_item_simple(get_param('menu'),NULL,get_param('title'),get_param('page_link'),0,0,false);
			}
		}

		// Work out what we're editing, and where it's coming from (support for two pagelink specifying parameters for destination, with addition of restore_from to override source if different from destination)
		$page_link=filter_naughty(get_param('page_link',''));
		if ($page_link=='') $page_link=get_param('page_link_2');
		if (strpos($page_link,':')===false) $page_link=':'.$page_link;
		$page_link_parts=explode(':',$page_link);
		if (count($page_link_parts)!=2) warn_exit(do_lang_tempcode('ZONE_COLON_FILE'));
		$zone=$page_link_parts[0];
		if (($zone!='') && (!file_exists(get_file_base().'/'.$zone.'/pages'))) warn_exit(do_lang_tempcode('NO_SUCH_ZONE'));
		$file=$page_link_parts[1];
		require_code('type_validation');
		if (!is_alphanumeric($file,true)) warn_exit(do_lang_tempcode('BAD_CODENAME'));

		$resource_owner=$GLOBALS['SITE_DB']->query_value_null_ok('comcode_pages','p_submitter',array('the_zone'=>$zone,'the_page'=>$file));
		check_edit_permission('high',$resource_owner);
		if (is_null($resource_owner))
			check_submit_permission('high');

		$restore_from=$this->find_comcode_page($lang,$file,$zone);

		// Check no redirects in our way
		if (addon_installed('redirects_editor'))
		{
			$test=$GLOBALS['SITE_DB']->query_value_null_ok('redirects','r_to_zone',array('r_from_page'=>$file,'r_from_zone'=>$zone));
			if (!is_null($test))
			{
				$redirect_url=build_url(array('page'=>'admin_redirects'),get_module_zone('admin_redirects'));
				attach_message(do_lang_tempcode('BLOCKING_REDIRECT_IN_PLACE',escape_html($redirect_url->evaluate())),'notice');
			}
		}

		$title=get_screen_title(($simple_add || ($file==''))?'COMCODE_PAGE_ADD':'_COMCODE_PAGE_EDIT',true,array(escape_html($zone),escape_html($file)));
		if (!$simple_add && ($file!='')) breadcrumb_set_self(do_lang_tempcode('COMCODE_PAGE_EDIT'));

		if (!has_actual_page_access(get_member(),$file,$zone)) access_denied('PAGE_ACCESS');

		// Default file contents
		$contents=post_param('new','');
		$parsed=NULL;
		if ($contents=='')
		{
			$file_base=strpos($restore_from,'comcode_custom/')?get_custom_file_base():get_file_base();
			if (!is_file($file_base.'/'.$restore_from))
				$file_base=get_file_base();
			if (is_file($file_base.'/'.$restore_from))
			{
				$tmp=fopen($file_base.'/'.$restore_from,'rb');
				flock($tmp,LOCK_SH);
				$contents=file_get_contents($file_base.'/'.$restore_from);
				flock($tmp,LOCK_UN);
				fclose($tmp);
				if (is_null(get_param('restore_from',NULL)))
				{
					$string_index=$GLOBALS['SITE_DB']->query_value_null_ok('cached_comcode_pages','string_index',array('the_zone'=>$zone,'the_page'=>$file));
					if (!is_null($string_index)) $parsed=get_translated_tempcode($string_index,NULL,$lang);
				}

				$new=false;
			} elseif (get_param('title','')!='') // If this came from the 'add new page wizard', then we make a simple template
			{
				$page_pretty_title=get_param('title','');
				$contents='[title]'.$page_pretty_title."[/title]\n\n".do_lang('PAGE_DEFAULT_TEXT');

				$new=true;
			} else
			{
				$contents='[title]'.do_lang('PAGE_DEFAULT_TITLE')."[/title]\n\n";

				$new=true;
			}

			if (($new) && (get_option('is_on_comcode_page_children')=='1') && (has_specific_permission(get_member(),'comcode_dangerous')))
			{
				$contents.=chr(10).chr(10).'[block]main_comcode_page_children[/block]';
			}

			// Pre-process default pages with Tempcode, to make easier to understand
			if ((strpos($restore_from,'/comcode/')!==false) && (($file=='start') || ($file=='panel_left') || ($file=='panel_right')))
			{
				require_code('tempcode_compiler');
				$contents=template_to_tempcode($contents);
				$contents=$contents->evaluate();
			}
		} else
		{
			$new=false;
		}

		$map=array('page'=>'_SELF','type'=>'__ed','wide'=>1);
		if ($simple_add) $map['simple_add']='1';
		$post_url=build_url($map,'_SELF');

		// Revision history
		$filesarray=$this->get_comcode_revisions($zone,'comcode_custom/'.$lang,$file.'.txt');
		rsort($filesarray);
		$i=0;
		$revision_history=new ocp_tempcode();
		$max=intval(get_option('number_revisions_show'));
		$last_path=$file_base.'/'.$restore_from;
		if (is_file($last_path))
		{
			foreach ($filesarray as $iterator=>$stuff)
			{
				list($filepath,$time)=$stuff;

				// Find who did the revision
				$editor=$GLOBALS['SITE_DB']->query_value_null_ok('adminlogs','the_user',array('date_and_time'=>$time,'the_type'=>'COMCODE_PAGE_EDIT','param_a'=>$file));
				if ((has_specific_permission(get_member(),'view_revision_history')) || ($editor==get_member()))
				{
					if (is_null($editor))
					{
						$editor=do_lang('UNKNOWN');
					}
					else
					{
						$editor=$GLOBALS['FORUM_DRIVER']->get_username($editor);
						if (is_null($editor)) $editor=do_lang('UNKNOWN');
					}
					$old_file=(strpos($filepath,'_custom/')?get_custom_file_base():get_file_base()).'/'.$filepath;
					$size=filesize($old_file);
					$date=get_timezoned_date($time);
					$url=get_custom_base_url().'/'.$zone.'/'.'pages/comcode_custom/'.$lang.'/'.$file.'.txt.'.strval($time);
					$restore_url=build_url(array('page'=>'_SELF','type'=>'_ed','page_link'=>$zone.':'.$file,'restore_from'=>zone_black_magic_filterer($zone.(($zone!='')?'/':'').'pages/comcode_custom/'.$lang.'/'.$file.'.txt.'.strval($time),true)),'_SELF');
					require_code('diff');
					if (function_exists('diff_simple'))
					{
						$rendered_diff=diff_simple($old_file,$last_path);
						$last_path=$old_file;
						if (($rendered_diff=='') && ($iterator==0)) continue; // the version records are often saved on create not replace
						$revision_history->attach(do_template('REVISION_HISTORY_LINE',array('_GUID'=>'57e2c81fd621d1c8d6e283a5a4991001','REFERENCE_POINT_EXACT'=>true,'RENDERED_DIFF'=>$rendered_diff,'EDITOR'=>$editor,'DATE'=>$date,'DATE_RAW'=>strval($time),'RESTORE_URL'=>$restore_url,'URL'=>$url,'SIZE'=>clean_file_size($size))));
						$i++;
					}

					if ($i==$max) break;
				}
			}
			if ((strpos($restore_from,'/comcode_custom/')!==false) && (zone_black_magic_filterer($zone.'/'.'pages/comcode/'.$lang.'/'.$file.'.txt',true)!=$restore_from) && (is_file(zone_black_magic_filterer(get_file_base().'/'.$zone.'/'.'pages/comcode/'.$lang.'/'.$file.'.txt'))))
			{
				$url=get_base_url().'/'.$zone.'/'.'pages/comcode/'.$lang.'/'.$file.'.txt';
				$size=filesize(zone_black_magic_filterer(get_file_base().'/'.$zone.'/'.'pages/comcode/'.$lang.'/'.$file.'.txt'));
				$restore_url=build_url(array('page'=>'_SELF','type'=>'_ed','page_link'=>$zone.':'.$file,'restore_from'=>$zone.(($zone=='')?'':'/').'pages/comcode/'.$lang.'/'.$file.'.txt'),'_SELF');
				require_code('diff');
				if (function_exists('diff_simple'))
				{
					$rendered_diff=diff_simple(zone_black_magic_filterer(get_file_base().'/'.$zone.'/'.'pages/comcode/'.$lang.'/'.$file.'.txt'),$last_path);
					$revision_history->attach(do_template('REVISION_HISTORY_LINE',array('_GUID'=>'ed0b29f26cf93d4d6e0348a7e75d259d','REFERENCE_POINT_EXACT'=>true,'RENDERED_DIFF'=>$rendered_diff,'RESTORE_URL'=>$restore_url,'URL'=>$url,'SIZE'=>clean_file_size($size))));
					$i++;
				}
			}
		}
		if ((!$revision_history->is_empty()) && (get_param('restore_from','')==''))
			$revision_history=do_template('REVISION_HISTORY_WRAP',array('_GUID'=>'2349ee62cae037ec3cf1766403c92b39','CONTENT'=>$revision_history));
		elseif (!$revision_history->is_empty()) $revision_history=do_template('REVISION_RESTORE');

		$meta_keywords=post_param('meta_keywords','');
		$meta_description=post_param('meta_description','');
		if (($meta_keywords=='') && ($meta_description==''))
		{
			list($meta_keywords,$meta_description)=seo_meta_get_for('comcode_page',$zone.':'.$file);
		}

		$hidden_fields=new ocp_tempcode();

		if ((addon_installed('page_management')) && (has_actual_page_access(get_member(),'adminzone')))
		{
			$delete_url=build_url(array('page'=>'admin_sitetree','type'=>'_delete','page__'.$file=>1,'zone'=>$zone),get_module_zone('admin_sitetree'));
		} else
		{
			$delete_url=new ocp_tempcode();
		}

		$fields=new ocp_tempcode();
		$fields2=new ocp_tempcode();
		require_code('form_templates');
		if (addon_installed('page_management'))
		{
			if (has_actual_page_access(get_member(),'admin_sitetree'))
			{
				if ($simple_add)
				{
					$hidden_fields->attach(form_input_hidden('title',$file));
				} else
				{
					$fields->attach(form_input_codename(do_lang_tempcode('CODENAME'),do_lang_tempcode('DESCRIPTION_CODENAME'),'title',$file,true));
				}
			}
		}
		$rows=$GLOBALS['SITE_DB']->query_select('comcode_pages',array('*'),array('the_zone'=>$zone,'the_page'=>$file));
		if (array_key_exists(0,$rows))
		{
			$validated=$rows[0]['p_validated']==1;
			$parent_page=$rows[0]['p_parent_page'];
			$show_as_edit=$rows[0]['p_show_as_edit']==1;
			$owner=$rows[0]['p_submitter'];
		} else
		{
			global $NON_CANONICAL_PARAMS;
			$NON_CANONICAL_PARAMS[]='parent_page';

			$validated=true;
			$parent_page=get_param('parent_page','');
			$show_as_edit=false;
			$owner=get_member();
		}
		$_pages=find_all_pages($zone,'comcode/'.$lang,'txt',false,NULL,FIND_ALL_PAGES__NEWEST);
		$_pages+=find_all_pages($zone,'comcode_custom/'.$lang,'txt',false,NULL,FIND_ALL_PAGES__NEWEST);
		$_pages+=find_all_pages($zone,'comcode/'.get_site_default_lang(),'txt',false,NULL,FIND_ALL_PAGES__NEWEST);
		$_pages+=find_all_pages($zone,'comcode_custom/'.get_site_default_lang(),'txt',false,NULL,FIND_ALL_PAGES__NEWEST);
		ksort($_pages);
		$pages=form_input_list_entry('',false,do_lang_tempcode('NA_EM'));
		foreach (array_keys($_pages) as $page)
		{
			if (!is_string($page)) $page=strval($page);
			if ($page!=$file) $pages->attach(form_input_list_entry($page,$parent_page==$page));
		}
		if (!$simple_add) // We don't want to imply the 'validated' has an effect on the menu addition for the add new page wizard, so we don't show validation for that wizard at all
		{
			if (!$validated) $validated=(get_param_integer('validated',0)==1);
			if (has_specific_permission(get_member(),'bypass_validation_highrange_content'))
				if (addon_installed('unvalidated'))
					$fields2->attach(form_input_tick(do_lang_tempcode('VALIDATED'),do_lang_tempcode('DESCRIPTION_VALIDATED'),'validated',$validated));

			if (!$new)
			{
				if ($delete_url->is_empty())
				{
					$fields2->attach(form_input_tick(do_lang_tempcode('DELETE'),do_lang_tempcode('DESCRIPTION_DELETE'),'delete',false));
				}
			}
		} else
		{
			$hidden_fields->attach(form_input_hidden('validated','1'));
		}
		if (get_option('is_on_comcode_page_children')=='1')
		{
			$fields2->attach(form_input_list(do_lang_tempcode('PARENT_PAGE'),do_lang_tempcode('DESCRIPTION_PARENT_PAGE'),'parent_page',$pages,NULL,false,false));
		}
		if (!$simple_add)
		{
			$fields2->attach(form_input_tick(do_lang_tempcode('SHOW_AS_EDITED'),do_lang_tempcode('DESCRIPTION_SHOW_AS_EDITED'),'show_as_edit',$show_as_edit));
			if ($GLOBALS['FORUM_DRIVER']->is_super_admin(get_member())) // TODO: Make a proper permission
			{
				$fields2->attach(form_input_username(do_lang_tempcode('OWNER'),do_lang_tempcode('DESCRIPTION_OWNER'),'owner',$GLOBALS['FORUM_DRIVER']->get_username($owner),true));
			}

			$fields2->attach(do_template('FORM_SCREEN_FIELD_SPACER',array('TITLE'=>do_lang_tempcode('SEO'),'SECTION_HIDDEN'=>true,'HELP'=>(get_option('show_docs')=='0')?NULL:protect_from_escaping(symbol_tempcode('URLISE_LANG',array(do_lang('TUTORIAL_ON_THIS'),brand_base_url().'/docs'.strval(ocp_version()).'/pg/tut_seo','tut_seo','1'))))));
			$fields2->attach(form_input_line_multi(do_lang_tempcode('KEYWORDS'),do_lang_tempcode('DESCRIPTION_META_KEYWORDS'),'meta_keywords[]',array_map('trim',explode(',',preg_replace('#,+#',',',$meta_keywords))),0));
			$fields2->attach(form_input_line(do_lang_tempcode('META_DESCRIPTION'),do_lang_tempcode('DESCRIPTION_META_DESCRIPTION'),'meta_description',$meta_description,false));
		}

		// Awards?
		if (addon_installed('awards'))
		{
			require_code('awards');
			$fields2->attach(get_award_fields('comcode_page',$zone.':'.$file));
		}

		require_code('permissions2');
		$fields2->attach(get_page_permissions_for_environment($zone,$file));

		$hidden_fields->attach(form_input_hidden('file',$file));
		$hidden_fields->attach(form_input_hidden('lang',$lang));
		$hidden_fields->attach(form_input_hidden('zone',$zone));
		$hidden_fields->attach(form_input_hidden('redirect',get_param('redirect','')));

		$posting_form=get_posting_form(do_lang($simple_add?'COMCODE_PAGE_ADD':'SAVE'),$contents,$post_url,$hidden_fields,$fields,do_lang_tempcode('COMCODE_PAGE'),'',$fields2,$parsed,NULL,NULL,false);

		$export_url=build_url(array('page'=>'_SELF','type'=>'export','page_link'=>$page_link,'export'=>$restore_from,'lang'=>$lang),'_SELF');

		$text=new ocp_tempcode();
		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)));
		}

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

		if (!$simple_add)
			breadcrumb_set_parents(array(array('_SELF:_SELF:misc:lang='.$lang,do_lang_tempcode('CHOOSE'))));

		return do_template('COMCODE_EDIT_SCREEN',array('_GUID'=>'ec1d773684757f5bf6f39cf931555bf2','NEW'=>$new,'PING_URL'=>$ping_url,'WARNING_DETAILS'=>$warning_details,'TEXT'=>$text,'TITLE'=>$title,'DELETE_URL'=>$delete_url,'ZONE'=>$zone,'FILE'=>$file,'EXPORT_URL'=>$export_url,'POSTING_FORM'=>$posting_form,'REVISION_HISTORY'=>$revision_history));
	}

	/**
	 * The actualiser to edit a comcode page.
	 *
	 * @return tempcode		The UI
	 */
	function __ed()
	{
		$simple_add=get_param_integer('simple_add',0)==1;

		$title=get_screen_title($simple_add?'COMCODE_PAGE_ADD':'COMCODE_PAGE_EDIT');

		$GLOBALS['HELPER_PANEL_PIC']='pagepics/comcode_page_edit';

		$file=filter_naughty(post_param('file'));
		$lang=filter_naughty(post_param('lang'));
		$zone=filter_naughty(post_param('zone'));

		if (addon_installed('page_management'))
		{
			$new_file=filter_naughty(has_actual_page_access(get_member(),'admin_sitetree')?post_param('title',$file):$file);
		} else $new_file=filter_naughty($file);
		if ($file=='') $file=$new_file;

		require_code('type_validation');
		if (!is_alphanumeric($file,true)) warn_exit(do_lang_tempcode('BAD_CODENAME'));

		$fullpath=zone_black_magic_filterer(get_custom_file_base().'/'.$zone.'/pages/comcode_custom/'.$lang.'/'.$file.'.txt');

		$renaming_page=($new_file!=$file);

		if ($renaming_page)
		{
			if (!is_alphanumeric($new_file,true)) warn_exit(do_lang_tempcode('BAD_CODENAME'));

			$langs=find_all_langs(true);
			$rename_map=array();
			$afm_needed=false; // Actually will stay false as we don't allow renaming original-pages at the moment
			foreach (array_keys($langs) as $lang)
			{
				$path=zone_black_magic_filterer(filter_naughty($zone).(($zone!='')?'/':'').'pages/comcode_custom/'.$lang.'/'.$file.'.txt',true);
				if (is_file(get_file_base().'/'.$path))
				{
					$new_path=zone_black_magic_filterer(filter_naughty($zone).(($zone!='')?'/':'').'pages/comcode_custom/'.$lang.'/'.$new_file.'.txt',true);
					if (is_file($new_path)) warn_exit(do_lang_tempcode('ALREADY_EXISTS',escape_html($zone.':'.$new_file)));
					$rename_map[$path]=$new_path;
				}
				if (is_file(get_file_base().'/'.str_replace('/comcode_custom/','/comcode/',$path)))
				{
					$completion_text=do_lang_tempcode('ORIGINAL_PAGE_NO_RENAME');
				}
			}

			if ($afm_needed)
			{
				require_code('abstract_file_manager');
				force_have_afm_details();
			}
		}

		$validated=post_param_integer('validated',0);
		inject_action_spamcheck();
		if (!has_specific_permission(get_member(),'bypass_validation_highrange_content')) $validated=0;
		$parent_page=post_param('parent_page','');
		$show_as_edit=post_param_integer('show_as_edit',0);

		$resource_owner=$GLOBALS['SITE_DB']->query_value_null_ok('comcode_pages','p_submitter',array('the_zone'=>$zone,'the_page'=>$file));
		check_edit_permission('high',$resource_owner);
		if ($GLOBALS['FORUM_DRIVER']->is_super_admin(get_member())) // TODO: Make a proper permission
		{
			$_owner=post_param('owner',$GLOBALS['FORUM_DRIVER']->get_username(get_member()));
			$owner=$GLOBALS['FORUM_DRIVER']->get_member_from_username($_owner);
			if (is_null($owner)) $owner=get_member();
		} else $owner=get_member();
		if (is_null($resource_owner)) // Add
		{
			check_submit_permission('high');

			require_code('submit');
			give_submit_points('COMCODE_PAGE_ADD');

			if (!addon_installed('unvalidated')) $validated=1;
			$GLOBALS['SITE_DB']->query_insert('comcode_pages',array(
				'the_zone'=>$zone,
				'the_page'=>$file,
				'p_parent_page'=>$parent_page,
				'p_validated'=>$validated,
				'p_edit_date'=>NULL,
				'p_add_date'=>time(),
				'p_submitter'=>$owner,
				'p_show_as_edit'=>0
			));
		} else // Edit
		{
			if (!has_actual_page_access(get_member(),$file,$zone)) access_denied('PAGE_ACCESS');

			require_code('submit');
			$just_validated=(!content_validated('comcode_page',$zone.':'.$file)) && ($validated==1);
			if ($just_validated)
			{
				send_content_validated_notification('comcode_page',$zone.':'.$file);
			}

			if (!addon_installed('unvalidated')) $validated=1;
			$GLOBALS['SITE_DB']->query_update('comcode_pages',array(
				'p_parent_page'=>$parent_page,
				'p_validated'=>$validated,
				'p_edit_date'=>time(),
				'p_submitter'=>$owner,
				'p_show_as_edit'=>$show_as_edit
			),array('the_zone'=>$zone,'the_page'=>$file),'',1);
		}

		if ($validated==0)
		{
			require_code('submit');
			$edit_url=build_url(array('page'=>'_SELF','type'=>'_ed','page_link'=>$zone.':'.$new_file),'_SELF',NULL,false,false,true);
			if (addon_installed('unvalidated'))
				send_validation_request('COMCODE_PAGE_EDIT','comcode_pages',true,$zone.':'.$new_file,$edit_url);
		}

		$new=post_param('post');

		require_code('attachments2');
		$_new=do_comcode_attachments($new,'comcode_page',$zone.':'.$file);
		$new=$_new['comcode'];
		if ((!is_file($fullpath)) || ($new!=file_get_contents($fullpath)))
		{
			$myfile=@fopen($fullpath,'at');
			if ($myfile===false) intelligent_write_error($fullpath);
			flock($myfile,LOCK_EX);
			ftruncate($myfile,0);
			final_attachments_from_preview($zone.':'.$file);
			if (fwrite($myfile,$new)<strlen($new)) warn_exit(do_lang_tempcode('COULD_NOT_SAVE_FILE'));
			flock($myfile,LOCK_UN);
			fclose($myfile);
			sync_file($fullpath);

			$file_changed=true;
		} else
		{
			$file_changed=false;
		}
		require_code('seo2');
		$new_keywords=post_param('meta_keywords','');
		$new_description=post_param('meta_description','');
		if (($new_keywords=='') && ($new_description==''))
		{
			seo_meta_set_for_implicit('comcode_page',$zone.':'.$file,array($new),$new);
		} else
		{
			seo_meta_set_for_explicit('comcode_page',$zone.':'.$file,$new_keywords,$new_description);
		}

		$completion_text=($validated==0)?do_lang_tempcode('SUBMIT_UNVALIDATED'):do_lang_tempcode('SUCCESS');

		// Update cache  NO WE CAN'T - THEY'RE MULTI-THEME NOW
	/*	$string_index=$GLOBALS['SITE_DB']->query_value_null_ok('cached_comcode_pages','string_index',array('the_zone'=>$zone,'the_page'=>$file));
		if (!is_null($string_index))
		{
			lang_remap_comcode($string_index,$new);
		} else
		{
			$string_index=insert_lang_comcode($new,1,NULL,false,NULL,NULL,false,NULL,NULL,60,true,true);
			$GLOBALS['SITE_DB']->query_insert('cached_comcode_pages',array('the_zone'=>$zone,'the_page'=>$file,'string_index'=>$string_index));
		}*/

		require_code('permissions2');
		set_page_permissions_from_environment($zone,$file);

		$caches=$GLOBALS['SITE_DB']->query_select('cached_comcode_pages',array('string_index'),array('the_zone'=>$zone,'the_page'=>$file));
		$GLOBALS['SITE_DB']->query_delete('cached_comcode_pages',array('the_zone'=>$zone,'the_page'=>$file));
		foreach ($caches as $cache)
		{
			delete_lang($cache['string_index']);
		}
		persistent_cache_empty();
		persistent_cache_delete(array('PAGE_INFO'));
		decache('main_comcode_page_children');

		fix_permissions($fullpath);

		if ((is_file($fullpath)) && (get_option('store_revisions')=='1') && ($file_changed))
		{
			$time=time();
			@copy($fullpath,$fullpath.'.'.strval($time)) OR intelligent_write_error($fullpath.'.'.strval($time));
			fix_permissions($fullpath.'.'.strval($time));
			sync_file($fullpath.'.'.strval($time));
		}

		log_it('COMCODE_PAGE_EDIT',$file,$zone);
		require_code('autosave');
		clear_ocp_autosave();

		if ($renaming_page)
		{
			$GLOBALS['SITE_DB']->query_delete('comcode_pages',array('the_zone'=>$zone,'the_page'=>$new_file),'',1);
			$GLOBALS['SITE_DB']->query_update('comcode_pages',array(
				'the_page'=>$new_file,
			),array('the_zone'=>$zone,'the_page'=>$file),'',1);
			$GLOBALS['SITE_DB']->query_update('comcode_pages',array(
				'p_parent_page'=>$new_file,
			),array('the_zone'=>$zone,'p_parent_page'=>$file));

			if (addon_installed('catalogues'))
			{
				update_catalogue_content_ref('comcode_page',$file,$new_file);
			}

			foreach ($rename_map as $path=>$new_path)
			{
				if ($afm_needed)
				{
					afm_move($path,$new_path);
				} else
				{
					rename(get_custom_file_base().'/'.$path,get_custom_file_base().'/'.$new_path);
				}
			}

			if (addon_installed('awards'))
			{
				$types=$GLOBALS['SITE_DB']->query_select('award_types',array('id'),array('a_content_type'=>'comcode_page'));
				foreach ($types as $type)
				{
					$GLOBALS['SITE_DB']->query_update('award_archive',array('content_id'=>$new_file),array('content_id'=>$file,'a_type_id'=>$type['id']));
				}
			}

			$file=$new_file;
		}

		if (post_param_integer('delete',0)==1)
		{
			unlink(get_custom_file_base().'/'.$path);
		}

		if (addon_installed('awards'))
		{
			require_code('awards');
			handle_award_setting('comcode_page',$zone.':'.$file);
		}

		decache('main_sitemap');

		breadcrumb_set_self(do_lang_tempcode('DONE'));

		// Look for bad title semantics
		$_new['html']=$_new['tempcode']->evaluate();
		if ((substr($file,0,1)!='_') && (substr($file,0,6)!='panel_') && (trim($_new['html'])!=''))
		{
			if ((strpos($_new['html'],'<h1')===false) && (strpos($_new['comcode'],'[title]')===false) && (strpos($_new['comcode'],'[title="1"]')===false))
			{
				attach_message(do_lang_tempcode('NO_LEVEL_1_HEADERS'),'notice');
			}
			$matches=array();
			if ((strpos($_new['html'],'<h2')===false) && (preg_match_all('#\n\[(b|font|size)\][^\.]+\[/(b|font|size)\]\n#',$_new['comcode'],$matches)>=2))
			{
				attach_message(do_lang_tempcode('NO_LEVEL_2_HEADERS'),'inform');
			}
		}

		// Show it worked / Refresh
		$url=post_param('redirect','');
		if ($url!='')
		{
			return redirect_screen($title,$url,$completion_text);
		}
		return $this->do_next_manager($title,$file,$zone,$completion_text);
	}

	/**
	 * The actualiser to export a comcode page.
	 *
	 * @return tempcode		The UI
	 */
	function export()
	{
		$title=get_screen_title('EXPORT_COMCODE_PAGE');

		$lang=choose_language($title);
		if (is_object($lang)) return $lang;

		$path=filter_naughty(get_param('export',''));
		$page_link=filter_naughty(get_param('page_link'));
		if ($path=='')
		{
			$page_link_parts=explode(':',$page_link);
			if (count($page_link_parts)!=2) warn_exit(do_lang_tempcode('ZONE_COLON_FILE'));

			$path=$this->find_comcode_page($lang,$page_link_parts[1],$page_link_parts[0]);
		}
		$file_base=strpos($path,'comcode_custom/')?get_custom_file_base():get_file_base();
		if (!is_file($file_base.'/'.$path))
		{
			$path=str_replace('comcode/','comcode_custom/',$path);
			$file_base=get_custom_file_base();
		}
		if (!is_file($file_base.'/'.$path)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$export=file_get_contents($file_base.'/'.$path);

		$matches=array();
		preg_match_all('#\[attachment(.*)\](\d+)\[/attachment\]#',$export,$matches);
		for ($i=0;$i<count($matches[0]);$i++)
		{
			$attachment=$GLOBALS['SITE_DB']->query_select('attachments',array('a_url','a_original_filename'),array('id'=>$matches[2][$i]),'',1);
			$file=file_get_contents(get_custom_file_base().'/'.filter_naughty(rawurldecode($attachment[0]['a_url'])));
			$replace='[attachment filename="'.$attachment[0]['a_original_filename'].'"'.$matches[1][$i].']'.chunk_split(base64_encode($file)).'[/attachment]';
			$export=str_replace($matches[0][$i],$replace,$export);
		}

		breadcrumb_set_parents(array(array('_SELF:_SELF:misc',do_lang_tempcode('CHOOSE')),array('_SELF:_SELF:_ed:pagelink='.$page_link,do_lang_tempcode('COMCODE_PAGE_EDIT'))));

		return do_template('COMCODE_PAGE_EXPORT_SCREEN',array('_GUID'=>'2bbae0dad2dd559b68b628cecdf610fc','TITLE'=>$title,'EXPORT'=>$export));
	}

}


