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

/**
 * Module page class.
 */
class Module_catalogues
{

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

	/**
	 * Standard modular uninstall function.
	 */
	function uninstall()
	{
		$GLOBALS['SITE_DB']->drop_if_exists('catalogues');
		$GLOBALS['SITE_DB']->drop_if_exists('catalogue_fields');
		$GLOBALS['SITE_DB']->drop_if_exists('catalogue_categories');
		$GLOBALS['SITE_DB']->drop_if_exists('catalogue_entries');
		$GLOBALS['SITE_DB']->drop_if_exists('catalogue_efv_long_trans');
		$GLOBALS['SITE_DB']->drop_if_exists('catalogue_efv_short_trans');
		$GLOBALS['SITE_DB']->drop_if_exists('catalogue_efv_long');
		$GLOBALS['SITE_DB']->drop_if_exists('catalogue_efv_short');
		$GLOBALS['SITE_DB']->drop_if_exists('catalogue_efv_float');
		$GLOBALS['SITE_DB']->drop_if_exists('catalogue_efv_integer');
		$GLOBALS['SITE_DB']->drop_if_exists('catalogue_entry_linkage');
		$GLOBALS['SITE_DB']->drop_if_exists('catalogue_cat_treecache');
		$GLOBALS['SITE_DB']->drop_if_exists('catalogue_childcountcache');

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

		$GLOBALS['SITE_DB']->query_delete('trackbacks',array('trackback_for_type'=>'catalogues'));

		deldir_contents(get_custom_file_base().'/uploads/catalogues',true);

		delete_config_option('catalogues_subcat_narrowin');

		delete_specific_permission('high_catalogue_entry_timeout');

		delete_menu_item_simple('_SEARCH:catalogues:type=misc');
		$cf=$GLOBALS['SITE_DB']->query_value_null_ok('menu_items','id',array('i_menu'=>'collab_features','i_url'=>''));
		if (!is_null($cf))
			delete_menu_item($cf);
		delete_menu_item_simple('_SEARCH:catalogues:id=projects:type=index');
		delete_menu_item_simple('_SEARCH:cms_catalogues:catalogue_name=projects:type=add_entry');
	}

	/**
	 * 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('catalogues');
		require_code('catalogues');
		require_code('catalogues2');

		if (is_null($upgrade_from))
		{
			$GLOBALS['SITE_DB']->create_table('catalogues',array(
				'c_name'=>'*ID_TEXT',
				'c_title'=>'SHORT_TRANS',
				'c_description'=>'LONG_TRANS',	// Comcode
				'c_display_type'=>'SHORT_INTEGER', // C_DT_*
				'c_is_tree'=>'BINARY',
				'c_notes'=>'LONG_TEXT',
				'c_add_date'=>'TIME',
				'c_submit_points'=>'INTEGER',
				'c_ecommerce'=>'BINARY',
				'c_send_view_reports'=>'ID_TEXT' // never,daily,weekly,monthly,quarterly
			));

			$GLOBALS['SITE_DB']->create_table('catalogue_categories',array(
				'id'=>'*AUTO',
				'c_name'=>'ID_TEXT',
				'cc_title'=>'SHORT_TRANS',
				'cc_description'=>'LONG_TRANS',	// Comcode
				'rep_image'=>'URLPATH',
				'cc_notes'=>'LONG_TEXT',
				'cc_add_date'=>'TIME',
				'cc_parent_id'=>'?AUTO_LINK',
				'cc_move_target'=>'?AUTO_LINK',
				'cc_move_days_lower'=>'INTEGER',
				'cc_move_days_higher'=>'INTEGER',
			));
			$GLOBALS['SITE_DB']->create_index('catalogue_categories','catstoclean',array('cc_move_target'));
			$GLOBALS['SITE_DB']->create_index('catalogue_categories','cataloguefind',array('c_name'));
		}

		if ((is_null($upgrade_from)) || ($upgrade_from<6))
		{
			$GLOBALS['SITE_DB']->create_index('catalogue_categories','cc_parent_id',array('cc_parent_id'));
		}

		if (is_null($upgrade_from))
		{
			$GLOBALS['SITE_DB']->create_table('catalogue_fields',array(
				'id'=>'*AUTO',
				'c_name'=>'ID_TEXT',
				'cf_name'=>'SHORT_TRANS',
				'cf_description'=>'LONG_TRANS',
				'cf_type'=>'ID_TEXT', /* can be short_text,long_text,short_trans,long_trans,integer,float,picture,upload,url,email,user */
				'cf_order'=>'INTEGER',
				'cf_defines_order'=>'SHORT_INTEGER', // 0, 1, or 2
				'cf_visible'=>'BINARY',
				'cf_searchable'=>'BINARY',
				'cf_default'=>'LONG_TEXT',
				'cf_required'=>'BINARY',
				'cf_put_in_category'=>'BINARY',
				'cf_put_in_search'=>'BINARY',
			));

			$GLOBALS['SITE_DB']->create_table('catalogue_entries',array(
				'id'=>'*AUTO',
				'c_name'=>'ID_TEXT',
				'cc_id'=>'AUTO_LINK',
				'ce_submitter'=>'USER',
				'ce_add_date'=>'TIME',
				'ce_edit_date'=>'?TIME',
				'ce_views'=>'INTEGER',
				'ce_views_prior'=>'INTEGER',
				'ce_validated'=>'BINARY',
				'notes'=>'LONG_TEXT',
				'allow_rating'=>'BINARY',
				'allow_comments'=>'SHORT_INTEGER',
				'allow_trackbacks'=>'BINARY',
				'ce_last_moved'=>'INTEGER',
			));
			$GLOBALS['SITE_DB']->create_index('catalogue_entries','ce_views',array('ce_views'));
			$GLOBALS['SITE_DB']->create_index('catalogue_entries','ces',array('ce_submitter'));
			$GLOBALS['SITE_DB']->create_index('catalogue_entries','ce_validated',array('ce_validated'));

			$GLOBALS['SITE_DB']->create_table('catalogue_efv_long_trans',array(
				'id'=>'*AUTO', // NEVER use this column: cf_id and ce_id also provide a key. This only exists for the SQL-server fulltext indexing. This column doesn't exist on upgraded old installs.
				'cf_id'=>'AUTO_LINK',
				'ce_id'=>'AUTO_LINK',
				'cv_value'=>'LONG_TRANS', /* does your CV have value? */	// often Comcode
			));

			$GLOBALS['SITE_DB']->create_table('catalogue_efv_long',array(
				'id'=>'*AUTO', // NEVER use this column: cf_id and ce_id also provide a key. This only exists for the SQL-server fulltext indexing. This column doesn't exist on upgraded old installs.
				'cf_id'=>'AUTO_LINK',
				'ce_id'=>'AUTO_LINK',
				'cv_value'=>'LONG_TEXT',
			));

			$GLOBALS['SITE_DB']->create_table('catalogue_efv_short_trans',array(
				'id'=>'*AUTO', // NEVER use this column: cf_id and ce_id also provide a key. This only exists for the SQL-server fulltext indexing. This column doesn't exist on upgraded old installs.
				'cf_id'=>'AUTO_LINK',
				'ce_id'=>'AUTO_LINK',
				'cv_value'=>'SHORT_TRANS', // often Comcode
			));

			$GLOBALS['SITE_DB']->create_table('catalogue_efv_short',array(
				'id'=>'*AUTO', // NEVER use this column: cf_id and ce_id also provide a key. This only exists for the SQL-server fulltext indexing. This column doesn't exist on upgraded old installs.
				'cf_id'=>'AUTO_LINK',
				'ce_id'=>'AUTO_LINK',
				'cv_value'=>'SHORT_TEXT',
			));
		}

		if ((is_null($upgrade_from)) || ($upgrade_from<6))
		{
			$GLOBALS['SITE_DB']->create_table('catalogue_entry_linkage',array(
				'catalogue_entry_id'=>'*AUTO_LINK',
				'content_type'=>'ID_TEXT',
				'content_id'=>'ID_TEXT',
			));
			$GLOBALS['SITE_DB']->create_index('catalogue_entry_linkage','custom_fields',array('content_type','content_id'));

			// This caches ancestor relationships. It is redundant to doing tree traversals on catalogue_categories.cc_id, allowing normal efficient SQL joins to be done instead
			// Note that self relationships (cc_id=cc_ancestor_id) are stored too, so that a single join covers that too.
			$GLOBALS['SITE_DB']->create_table('catalogue_cat_treecache',array(
				'cc_id'=>'*AUTO_LINK',
				'cc_ancestor_id'=>'*AUTO_LINK',
			));
			$GLOBALS['SITE_DB']->create_table('catalogue_childcountcache',array(
				'cc_id'=>'*AUTO_LINK',
				'c_num_rec_children'=>'INTEGER',
				'c_num_rec_entries'=>'INTEGER',
			));
			$GLOBALS['SITE_DB']->create_index('catalogue_cat_treecache','cc_ancestor_id',array('cc_ancestor_id'));

			$GLOBALS['SITE_DB']->create_table('catalogue_efv_float',array(
				'id'=>'*AUTO', // NEVER use this column: cf_id and ce_id also provide a key. This only exists for the SQL-server fulltext indexing. This column doesn't exist on upgraded old installs.
				'cf_id'=>'AUTO_LINK',
				'ce_id'=>'AUTO_LINK',
				'cv_value'=>'?REAL',
			));

			$GLOBALS['SITE_DB']->create_table('catalogue_efv_integer',array(
				'id'=>'*AUTO', // NEVER use this column: cf_id and ce_id also provide a key. This only exists for the SQL-server fulltext indexing. This column doesn't exist on upgraded old installs.
				'cf_id'=>'AUTO_LINK',
				'ce_id'=>'AUTO_LINK',
				'cv_value'=>'?INTEGER',
			));

			$GLOBALS['SITE_DB']->create_index('catalogue_efv_float','fcv_value',array('cv_value'));
			$GLOBALS['SITE_DB']->create_index('catalogue_efv_integer','itv_value',array('cv_value'));

			$GLOBALS['SITE_DB']->create_index('catalogue_efv_float','fcf_id',array('cf_id'),'id');
			$GLOBALS['SITE_DB']->create_index('catalogue_efv_integer','icf_id',array('cf_id'),'id');
			$GLOBALS['SITE_DB']->create_index('catalogue_efv_float','fce_id',array('ce_id'),'id');
			$GLOBALS['SITE_DB']->create_index('catalogue_efv_integer','ice_id',array('ce_id'),'id');

			$GLOBALS['SITE_DB']->create_index('catalogue_efv_float','cefv_f_combo',array('ce_id','cf_id'),'id');
			$GLOBALS['SITE_DB']->create_index('catalogue_efv_integer','cefv_i_combo',array('ce_id','cf_id'),'id');
			$GLOBALS['SITE_DB']->create_index('catalogue_efv_long','cefv_l_combo',array('ce_id','cf_id'),'id');
			$GLOBALS['SITE_DB']->create_index('catalogue_efv_short','cefv_s_combo',array('ce_id','cf_id'),'id');
			$GLOBALS['SITE_DB']->create_index('catalogue_efv_long_trans','cefv_lt_combo',array('ce_id','cf_id'),'id');
			$GLOBALS['SITE_DB']->create_index('catalogue_efv_short_trans','cefv_st_combo',array('ce_id','cf_id'),'id');
		}

		if (is_null($upgrade_from))
		{
			// Add the default catalogues
			// ==========================

			$groups=$GLOBALS['FORUM_DRIVER']->get_usergroup_list(false,true);

			// Projects
			actual_add_catalogue('projects',lang_code_to_default_content('DEFAULT_CATALOGUE_PROJECTS_TITLE',false,2),lang_code_to_default_content('DEFAULT_CATALOGUE_PROJECTS_DESCRIPTION',true,3),C_DT_FIELDMAPS,0,'',30);
			$fields=array(
				array('NAME','DESCRIPTION_NAME','short_trans',1,1),
				array('MAINTAINER','DESCRIPTION_MAINTAINER','user',0,1),
				array('DESCRIPTION','DESCRIPTION_DESCRIPTION','long_trans',0,1),
				array('PROJECT_PROGRESS','DESCRIPTION_PROJECT_PROGRESS','integer',0,1)
			);
			foreach ($fields as $i=>$field)
				actual_add_catalogue_field('projects',lang_code_to_default_content($field[0],false,3),lang_code_to_default_content($field[1],true,3),$field[2],$i,$field[3],1,1,'',$field[4]);
			$cat_id=actual_add_catalogue_category('projects',lang_code_to_default_content('DEFAULT_CATALOGUE_PROJECTS_TITLE',false,2),lang_code_to_default_content('DEFAULT_CATALOGUE_PROJECTS_DESCRIPTION',true,3),'',NULL,'');
			foreach (array_keys($groups) as $group_id)
			{
				$GLOBALS['SITE_DB']->query_insert('group_category_access',array('module_the_name'=>'catalogues_category','category_name'=>strval($cat_id),'group_id'=>$group_id));
				$GLOBALS['SITE_DB']->query_insert('group_category_access',array('module_the_name'=>'catalogues_catalogue','category_name'=>'projects','group_id'=>$group_id));
			}
			//add_menu_item_simple('main_content',NULL,'DEFAULT_CATALOGUE_PROJECTS_TITLE','_SEARCH:catalogues:type=index:id=projects');
			$projects=add_menu_item_simple('collab_features',NULL,'_DEFAULT_CATALOGUE_PROJECTS_TITLE');
			add_menu_item_simple('collab_features',$projects,'VIEW','_SEARCH:catalogues:type=index:id=projects',0,0,true,do_lang('ZONE_BETWEEN'),1);
			add_menu_item_simple('collab_features',$projects,'ADD','_SEARCH:cms_catalogues:type=add_entry:catalogue_name=projects',0,0,true,do_lang('ZONE_BETWEEN'),1);

			// Modifications
			actual_add_catalogue('modifications',lang_code_to_default_content('DEFAULT_CATALOGUE_MODIFICATIONS_TITLE',false,2),lang_code_to_default_content('DEFAULT_CATALOGUE_MODIFICATIONS_DESCRIPTION',true,3),C_DT_TITLELIST,0,'',60);
			$fields=array(
				array('NAME','DESCRIPTION_NAME','short_trans',1,1),
				array('IMAGE','DESCRIPTION_MODIFICATION_IMAGE_URL','picture',0,0),
				array('STATUS','DESCRIPTION_MODIFICATION_STATUS','short_trans',0,1),
				array('URL','DESCRIPTION_URL','url',0,0),
				array('DESCRIPTION','DESCRIPTION_DESCRIPTION','long_trans',0,1),
				array('AUTHOR','DESCRIPTION_AUTHOR','short_text',0,1)
			);
			foreach ($fields as $i=>$field)
				actual_add_catalogue_field('modifications',lang_code_to_default_content($field[0],false,3),lang_code_to_default_content($field[1],true,3),$field[2],$i,$field[3],1,1,'',$field[4]);
			foreach (array_keys($groups) as $group_id)
				$GLOBALS['SITE_DB']->query_insert('group_category_access',array('module_the_name'=>'catalogues_catalogue','category_name'=>'modifications','group_id'=>$group_id));
			add_menu_item_simple('collab_features',NULL,'DEFAULT_CATALOGUE_MODIFICATIONS_TITLE','_SEARCH:catalogues:type=index:id=modifications');

			// Hosted-sites
			actual_add_catalogue('hosted',lang_code_to_default_content('DEFAULT_CATALOGUE_HOSTED_TITLE',false,2),lang_code_to_default_content('DEFAULT_CATALOGUE_HOSTED_DESCRIPTION',true,3),C_DT_FIELDMAPS,0,'',0);
			$fields=array(
				array('NAME','DESCRIPTION_NAME','short_trans',1,1),
				array('URL','DESCRIPTION_URL','url',0,0),
				array('DESCRIPTION','DESCRIPTION_DESCRIPTION','long_trans',0,0)
			);
			foreach ($fields as $i=>$field)
				actual_add_catalogue_field('hosted',lang_code_to_default_content($field[0],false,2),lang_code_to_default_content($field[1],true,3),$field[2],$i,$field[3],1,1,'',$field[4]);
			$cat_id=actual_add_catalogue_category('hosted',lang_code_to_default_content('DEFAULT_CATALOGUE_HOSTED_TITLE',false,2),lang_code_to_default_content('DEFAULT_CATALOGUE_HOSTED_DESCRIPTION',true,3),'',NULL,'');
			foreach (array_keys($groups) as $group_id)
			{
				$GLOBALS['SITE_DB']->query_insert('group_category_access',array('module_the_name'=>'catalogues_category','category_name'=>strval($cat_id),'group_id'=>$group_id));
				$GLOBALS['SITE_DB']->query_insert('group_category_access',array('module_the_name'=>'catalogues_catalogue','category_name'=>'hosted','group_id'=>$group_id));
			}
			add_menu_item_simple('collab_features',NULL,'DEFAULT_CATALOGUE_HOSTED_TITLE','_SEARCH:catalogues:type=index:id=hosted');

			// Links
			$links_category=actual_add_catalogue('links',lang_code_to_default_content('DEFAULT_CATALOGUE_LINKS_TITLE',false,2),lang_code_to_default_content('DEFAULT_CATALOGUE_LINKS_DESCRIPTION',true,3),C_DT_TABULAR,1,'',0);
			$fields=array(
				// Name, Description, Type, Defines order, Required, Put in category
				array('TITLE','DESCRIPTION_TITLE','short_trans',1,1,1),
				array('URL','DESCRIPTION_URL','url',0,1,0),
				array('DESCRIPTION','DESCRIPTION_DESCRIPTION','long_trans',0,0,1)
			);
			foreach ($fields as $i=>$field)
				actual_add_catalogue_field('links',lang_code_to_default_content($field[0],false,2),lang_code_to_default_content($field[1],true,3),$field[2],$i,$field[3],1,1,'',$field[4],$field[5]);
			foreach (array_keys($groups) as $group_id)
			{
				$GLOBALS['SITE_DB']->query_insert('group_category_access',array('module_the_name'=>'catalogues_category','category_name'=>strval($links_category),'group_id'=>$group_id));
				$GLOBALS['SITE_DB']->query_insert('group_category_access',array('module_the_name'=>'catalogues_catalogue','category_name'=>'links','group_id'=>$group_id));
			}
			add_menu_item_simple('main_content',NULL,'DEFAULT_CATALOGUE_LINKS_TITLE','_SEARCH:catalogues:type=index:id=links');

			// FAQs
			actual_add_catalogue('faqs',lang_code_to_default_content('DEFAULT_CATALOGUE_FAQS_TITLE',false,2),lang_code_to_default_content('DEFAULT_CATALOGUE_FAQS_DESCRIPTION',true,3),C_DT_FIELDMAPS,0,'',0);
			$fields=array(
				array('QUESTION','DESCRIPTON_QUESTION','short_trans',0,1,1),
				array('ANSWER','_DESCRIPTION_ANSWER','long_trans',0,1,1),
				array('ORDER','DESCRIPTION_ORDER','auto_increment',1,0,0)
			);
			foreach ($fields as $i=>$field)
				actual_add_catalogue_field('faqs',lang_code_to_default_content($field[0],false,2),lang_code_to_default_content($field[1],true,3),$field[2],$i,$field[3],$field[5],1,'',$field[4]);
			$cat_id=actual_add_catalogue_category('faqs',lang_code_to_default_content('DEFAULT_CATALOGUE_FAQS_TITLE',false,2),lang_code_to_default_content('DEFAULT_CATALOGUE_FAQS_DESCRIPTION',true,3),'',NULL,'');
			foreach (array_keys($groups) as $group_id)
			{
				$GLOBALS['SITE_DB']->query_insert('group_category_access',array('module_the_name'=>'catalogues_category','category_name'=>strval($cat_id),'group_id'=>$group_id));
				$GLOBALS['SITE_DB']->query_insert('group_category_access',array('module_the_name'=>'catalogues_catalogue','category_name'=>'faqs','group_id'=>$group_id));
			}
			add_menu_item_simple('main_content',NULL,'_DEFAULT_CATALOGUE_FAQS_TITLE','_SEARCH:catalogues:type=index:id=faqs',0,0,true,do_lang('DEFAULT_CATALOGUE_FAQS_TITLE'));

			// Contacts
			actual_add_catalogue('contacts',lang_code_to_default_content('CONTACTS',false,2),lang_code_to_default_content('DEFAULT_CATALOGUE_CONTACTS_DESCRIPTION',true,3),C_DT_FIELDMAPS,0,'',30);
			$fields=array(
				array('CONTACT_FIRST_NAME','','short_text',0,1),
				array('CONTACT_LAST_NAME','','short_text',1,1),
				array('EMAIL_ADDRESS','','short_text',0,1),
				array('CONTACT_COMPANY','','short_text',0,1),
				array('CONTACT_HOMEADDRESS','','short_text',0,1),
				array('CONTACT_CITY','','short_text',0,1),
				array('CONTACT_HOMEPHONE','','short_text',0,1),
				array('CONTACT_WORKPHONE','','short_text',0,1),
				array('CONTACT_HOMEPAGE','','short_text',0,1),
				array('CONTACT_IM','','short_text',0,1),
				array('CONTACT_EVENTS','','long_text',0,1),
				array('CONTACT_NOTES','','long_text',0,1),
				array('CONTACT_PHOTO','','picture',0,1)
			);
			foreach ($fields as $i=>$field)
				actual_add_catalogue_field('contacts',lang_code_to_default_content($field[0],false,3),insert_lang('',2),$field[2],$i,$field[3],1,1,'',$field[4]);
			actual_add_catalogue_category('contacts',lang_code_to_default_content('CONTACTS',false,2),'','',NULL,'');
			add_menu_item_simple('main_content',NULL,'CONTACTS','_SEARCH:catalogues:type=index:id=contacts');
		}

		if ((is_null($upgrade_from)) || ($upgrade_from<6))
		{
			$GLOBALS['SITE_DB']->create_index('catalogue_entries','ce_add_date',array('ce_add_date'),'id');
			$GLOBALS['SITE_DB']->create_index('catalogue_entries','ce_c_name',array('c_name'),'id');
		}

		if ((!is_null($upgrade_from)) && ($upgrade_from<4))
		{
			$GLOBALS['SITE_DB']->delete_table_field('catalogues','c_own_template');
			$GLOBALS['SITE_DB']->add_table_field('catalogues','c_cat_tab','BINARY',0);
			$GLOBALS['SITE_DB']->add_table_field('catalogues','c_ecommerce','BINARY',0);
			$GLOBALS['SITE_DB']->add_table_field('catalogue_entries','ce_views_prior','INTEGER');
			$GLOBALS['SITE_DB']->add_table_field('catalogues','c_send_view_reports','ID_TEXT','never');
			$GLOBALS['SITE_DB']->add_table_field('catalogue_categories','cc_move_target','?AUTO_LINK',NULL);
			$GLOBALS['SITE_DB']->add_table_field('catalogue_categories','cc_move_days_lower','INTEGER',30);
			$GLOBALS['SITE_DB']->add_table_field('catalogue_categories','cc_move_days_higher','INTEGER',60);
			$GLOBALS['SITE_DB']->add_table_field('catalogue_entries','ce_last_moved','INTEGER',0);
			$GLOBALS['SITE_DB']->query('UPDATE '.$GLOBALS['SITE_DB']->get_table_prefix().'catalogue_entries SET ce_last_moved=ce_add_date');
		}

		if ((is_null($upgrade_from)) || ($upgrade_from<3))
		{
			$cat_id=actual_add_catalogue('products',lang_code_to_default_content('DEFAULT_CATALOGUE_PRODUCTS_TITLE',false,2),lang_code_to_default_content('DEFAULT_CATALOGUE_PRODUCTS_DESCRIPTION',false,2),C_DT_GRID,1,'',0,1);

			$fields=array(
				//		Name							 Description			Type			  Defines order  Required  Visible  Searchable
				array('ECOM_CAT_product_title','DESCRIPTION_TITLE','short_trans',1,1,1,1),
				array('ECOM_CAT_item_code','ECOM_CATD_item_code','random',0,1,1,1),
				array('ECOM_CAT_price_pre_tax','ECOM_CATD_price_pre_tax','float',0,1,1,1),
				array('ECOM_CAT_stock_level','ECOM_CATD_stock_level','integer',0,0,1,0),
				array('ECOM_CAT_stock_level_warn_at','ECOM_CATD_stock_level_warn_at','integer',0,0,0,0),
				array('ECOM_CAT_stock_level_maintain','ECOM_CATD_stock_level_maintain','tick',0,1,0,0),
				array('ECOM_CAT_tax_type','ECOM_CATD_tax_type','list',0,1,0,0,"0%|5%|17.5%",0),
				array('ECOM_CAT_image','ECOM_CATD_image','picture',0,0,1,1),
				array('ECOM_CAT_weight','ECOM_CATD_weight','float',0,1,0,0),
				array('ECOM_CAT_description','DESCRIPTION_DESCRIPTION','long_trans',0,1,1,1)
			);

			foreach ($fields as $i=>$field)
			{
				actual_add_catalogue_field('products', // $c_name
													lang_code_to_default_content($field[0],false,3), // $name
													lang_code_to_default_content($field[1],true,3), // $description
													($field[2]=='tick')?'list':$field[2], // $type
													$i, // $order
													$field[3], // $defines_order
													$field[5], // $visible
													$field[6], // $searchable
													($field[2]=='tick')?(do_lang('NO').'|'.do_lang('YES')):(array_key_exists(7,$field)?$field[7]:''), // $default
													$field[4], // $required
													array_key_exists(5,$field)?$field[5]:0, // $put_in_category
													array_key_exists(5,$field)?$field[5]:0 // $put_in_search
												);
			}

			foreach (array_keys($groups) as $group_id)
			{
				$GLOBALS['SITE_DB']->query_insert('group_category_access',array('module_the_name'=>'catalogues_category','category_name'=>strval($cat_id),'group_id'=>$group_id));
				$GLOBALS['SITE_DB']->query_insert('group_category_access',array('module_the_name'=>'catalogues_catalogue','category_name'=>'products','group_id'=>$group_id));
			}

			add_menu_item_simple('main_content',NULL,'DEFAULT_CATALOGUE_PRODUCTS_TITLE','_SEARCH:catalogues:type=category:catalogue_name=products');

			add_specific_permission('CATALOGUES','high_catalogue_entry_timeout',false);
		}

		if ((is_null($upgrade_from)) || ($upgrade_from<3))
		{
			$GLOBALS['SITE_DB']->create_index('catalogue_efv_long','#lcv_value',array('cv_value'),'id');
			$GLOBALS['SITE_DB']->create_index('catalogue_efv_short','#scv_value',array('cv_value'),'id');
		}

		if ((!is_null($upgrade_from)) && ($upgrade_from<3))
		{
			$GLOBALS['SITE_DB']->add_table_field('catalogue_entries','allow_trackbacks','BINARY',1);
			$GLOBALS['SITE_DB']->add_table_field('catalogue_entries','c_name','ID_TEXT');
			$GLOBALS['SITE_DB']->add_table_field('catalogue_categories','rep_image','URLPATH');
			$GLOBALS['SITE_DB']->add_table_field('catalogue_fields','cf_default','LONG_TEXT');
			$GLOBALS['SITE_DB']->add_table_field('catalogue_fields','cf_searchable','BINARY',1);
			$entries=$GLOBALS['SITE_DB']->query_select('catalogue_entries e LEFT JOIN '.$GLOBALS['SITE_DB']->get_table_prefix().'catalogue_categories c ON e.cc_id=c.id',array('e.id','c.c_name'));
			foreach ($entries as $entry)
			{
				$GLOBALS['SITE_DB']->query_update('catalogue_entries',array('c_name'=>$entry['c_name']),array('id'=>$entry['id']),'',1);
			}
		}

		if ((!is_null($upgrade_from)) && ($upgrade_from<4))
		{
			$GLOBALS['SITE_DB']->alter_table_field('catalogues','c_own_pages','SHORT_INTEGER','c_display_type');
			$GLOBALS['SITE_DB']->add_table_field('catalogue_fields','cf_put_in_category','BINARY',1);
			$GLOBALS['SITE_DB']->add_table_field('catalogue_fields','cf_put_in_search','BINARY',1);
		}

		if ((is_null($upgrade_from)) || ($upgrade_from<5))
		{
			//$GLOBALS['SITE_DB']->create_index('catalogue_efv_long','ilcv_value',array('cv_value'),'id');	Not allowed, LONG_TEXT can not be in key. People shouldn't order by this anyway
			$GLOBALS['SITE_DB']->create_index('catalogue_efv_short','iscv_value',array('cv_value'),'id');
			$GLOBALS['SITE_DB']->create_index('catalogue_efv_long','lcf_id',array('cf_id'),'id');
			$GLOBALS['SITE_DB']->create_index('catalogue_efv_short','scf_id',array('cf_id'),'id');
			$GLOBALS['SITE_DB']->create_index('catalogue_efv_long_trans','ltcf_id',array('cf_id'),'id');
			$GLOBALS['SITE_DB']->create_index('catalogue_efv_short_trans','stcf_id',array('cf_id'),'id');
			$GLOBALS['SITE_DB']->create_index('catalogue_efv_long','lce_id',array('ce_id'),'id');
			$GLOBALS['SITE_DB']->create_index('catalogue_efv_short','sce_id',array('ce_id'),'id');
			$GLOBALS['SITE_DB']->create_index('catalogue_efv_long_trans','ltce_id',array('ce_id'),'id');
			$GLOBALS['SITE_DB']->create_index('catalogue_efv_short_trans','stce_id',array('ce_id'),'id');
			$GLOBALS['SITE_DB']->create_index('catalogue_entries','ce_cc_id',array('cc_id'),'id');
			$GLOBALS['SITE_DB']->create_index('catalogue_categories','ftjoin_cctitle',array('cc_title'));
			$GLOBALS['SITE_DB']->create_index('catalogue_categories','ftjoin_ccdescrip',array('cc_description'));
			$GLOBALS['SITE_DB']->create_index('catalogue_efv_long_trans','ltcv_value',array('cv_value'));
			$GLOBALS['SITE_DB']->create_index('catalogue_efv_short_trans','stcv_value',array('cv_value'));
		}

		if ((!is_null($upgrade_from)) && ($upgrade_from<6))
		{
			require_code('catalogues2');
			rebuild_catalogue_cat_treecache();

			// Move floats and integers into their own new tables
			if (function_exists('set_time_limit')) @set_time_limit(0);
			$sql_integer=db_string_equal_to('cf_type','integer').' OR '.db_string_equal_to('cf_type','auto_increment').' OR '.db_string_equal_to('cf_type','random').' OR '.db_string_equal_to('cf_type','user').' OR '.db_string_equal_to('cf_type','tick');
			$sql_float=db_string_equal_to('cf_type','float');
			foreach (array($sql_float=>'float',$sql_integer=>'integer') as $where=>$new_type)
			{
				$fields=$GLOBALS['SITE_DB']->query('SELECT id FROM '.get_table_prefix().'catalogue_fields WHERE '.$where);
				foreach ($fields as $field)
				{
					do
					{
						$or_list='';
						$rows=$GLOBALS['SITE_DB']->query_select('catalogue_efv_short',array('*'),array('cf_id'=>$field['id']),'',100);
						foreach ($rows as $row)
						{
							if ($or_list!='') $or_list.=' OR ';
							$or_list.='ce_id='.strval($row['ce_id']).' AND cf_id='.strval($row['cf_id']);

							unset($row['id']);
							if ($new_type=='float')
							{
								$row['cv_value']=($row['cv_value']=='')?NULL:floatval($row['cv_value']);
							}
							elseif ($new_type=='integer')
							{
								$row['cv_value']=($row['cv_value']=='')?NULL:intval($row['cv_value']);
							}
							$GLOBALS['SITE_DB']->query_insert('catalogue_efv_'.$new_type,$row);
						}
						if ($or_list!='')
						{
							$GLOBALS['SITE_DB']->query('DELETE FROM '.get_table_prefix().'catalogue_efv_short WHERE '.$or_list);
						}
					}
					while (count($rows)!=0);
				}
			}
		}

		if ((is_null($upgrade_from)) || ($upgrade_from<7))
		{
			add_config_option('CATALOGUES_SUBCAT_NARROWIN','catalogues_subcat_narrowin','tick','return \'0\';','FEATURE','CATALOGUES');
		}
	}

	/**
	 * 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'=>'CATALOGUES');
	}

	/**
	 * 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_catalogues';

		require_code('catalogues');
		require_lang('catalogues');

		$category_id=NULL;
		if (!is_null($start_at))
		{
			$matches=array();
			if (preg_match('#[^:]*:catalogues:type=index:id=(.*)#',$start_at,$matches)!=0)
			{
				$category_id=NULL;
				$adjusted_max_depth=is_null($max_depth)?NULL:(is_null($category_id)?$max_depth:$max_depth);
				$children=$dont_care_about_categories?array():get_catalogue_category_tree($matches[1],$category_id,NULL,NULL,$adjusted_max_depth,false);
				return array($children,$permission_page,'_SELF:_SELF:type=category:id=!','catalogues_category');
			}
			elseif (preg_match('#[^:]*:catalogues:type=category:id=(.*)#',$start_at,$matches)!=0)
			{
				$category_id=($matches[1]=='')?NULL:intval($matches[1]);
				$adjusted_max_depth=is_null($max_depth)?NULL:(is_null($category_id)?$max_depth:$max_depth);
				$catalogue_name=$GLOBALS['SITE_DB']->query_value('catalogue_categories','c_name',array('id'=>$category_id));
				$children=$dont_care_about_categories?array():get_catalogue_category_tree($catalogue_name,$category_id,NULL,NULL,$adjusted_max_depth,false);
				return array($children,$permission_page,'_SELF:_SELF:type=category:id=!','catalogues_category');
			}
		}

		$children=array();
		if ($dont_care_about_categories)
		{
			$rows=array();
		} else
		{
			$query='SELECT c.c_title,c.c_name,t.text_original FROM '.get_table_prefix().'catalogues c LEFT JOIN '.$GLOBALS['SITE_DB']->get_table_prefix().'translate t ON '.db_string_equal_to('language',user_lang()).' AND c.c_title=t.id';
//			if (db_has_subqueries($GLOBALS['SITE_DB']->connection_read))		Actually we want empty ones in site trees
//				$query.=' WHERE EXISTS (SELECT * FROM '.get_table_prefix().'catalogue_entries e WHERE e.c_name=c.c_name)';
			$rows=$GLOBALS['SITE_DB']->query($query);
		}
		foreach ($rows as $row)
		{
			if (substr($row['c_name'],0,1)=='_') continue;

			if (is_null($row['text_original'])) $row['text_original']=get_translated_text($row['c_title']);
			$kids=array();
			if ((!is_null($max_depth)) || ($max_depth>1))
			{
				$adjusted_max_depth=is_null($max_depth)?NULL:(is_null($category_id)?($max_depth-2):($max_depth-1));
				$kids=get_catalogue_category_tree($row['c_name'],$category_id,NULL,NULL,$adjusted_max_depth,false);
			}
			$children[]=array('_SELF:_SELF:type=index:id='.$row['c_name'],'catalogues_catalogue',$row['c_name'],$row['text_original'],$kids,'_SELF:_SELF:type=category:id=!','catalogues_category',true);
			if (!$require_permission_support)
			{
				$children[]=array('_SELF:_SELF:type=atoz:catalogue_name='.$row['c_name'],'catalogues_catalogue',$row['c_name'],do_lang('DEFAULT__CATALOGUE_CATEGORY_ATOZ',$row['text_original']));
			}
		}

		return array($children,$permission_page,'_SELF:_SELF:type=misc:id=!');
	}

	/**
	 * 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();
		if (preg_match('#^([^:]*):([^:]*):type=index:id=(.*)$#',$page_link,$matches)!=0)
			return array($matches[3],'catalogues_catalogue');
		preg_match('#^([^:]*):([^:]*):type=category:id=(.*)$#',$page_link,$matches);
		return array($matches[3],'catalogues_category');
	}

	/**
	 * 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.
	 * @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,$entry_data=NULL)
	{
		$parent_pagelink_orig=$parent_pagelink;

		// 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'=>NULL,'c_name'=>'');
		} else
		{
			list(,$parent_attributes,)=page_link_decode($parent_pagelink);
		}

		// We read in all data for efficiency
		if (is_null($category_data))
		{
			$query='SELECT c_name,d.id,t.text_original AS title,cc_add_date AS edit_date';
			$lots=($GLOBALS['SITE_DB']->query_value_null_ok('catalogue_categories','COUNT(*)')>1000) && (db_has_subqueries($GLOBALS['SITE_DB']->connection_read));
			if ($lots)
			{
				$query.=',NULL AS parent_id';
			} else
			{
				$query.=',cc_parent_id AS parent_id';
			}
			$query.=' FROM '.get_table_prefix().'catalogue_categories d LEFT JOIN '.get_table_prefix().'translate t ON '.db_string_equal_to('language',user_lang()).' AND t.id=d.cc_title';
			$query.=' WHERE d.c_name NOT LIKE \''.db_encode_like('\_%').'\'';
			if ($lots)
			{
				$query.=' AND EXISTS (SELECT * FROM '.get_table_prefix().'catalogue_entries e WHERE e.cc_id=d.id)';
			}
			$category_data=list_to_map('id',$GLOBALS['SITE_DB']->query($query));
		}
		$query='SELECT c.* FROM '.get_table_prefix().'catalogues c';
		if (can_arbitrary_groupby())
			$query.=' JOIN '.get_table_prefix().'catalogue_entries e ON c.c_name=e.c_name';
		$query.=' WHERE c.c_name NOT LIKE \''.db_encode_like('\_%').'\'';
		if (can_arbitrary_groupby())
			$query.=' GROUP BY e.cc_id';
		$catalogues=list_to_map('c_name',$GLOBALS['SITE_DB']->query($query));

		if (!is_null($parent_pagelink_orig))
		{
			$parent_attributes['c_name']=$category_data[intval($parent_attributes['id'])]['c_name'];
		}

		// Subcategories
		foreach ($category_data as $row)
		{
			if (((!is_null($row['parent_id'])) && (strval($row['parent_id'])==$parent_attributes['id'])) || ((is_null($parent_pagelink_orig)) && (is_null($row['parent_id']))))
			{
				$pagelink=$pagelink_stub.'category:'.strval($row['id']);
				if (__CLASS__!='')
				{
					$this->get_sitemap_pagelinks($callback,$member_id,$depth,$pagelink_stub,$pagelink,$recurse_level+1,$category_data,$entry_data); // Recurse
				} else
				{
					call_user_func_array(__FUNCTION__,array($callback,$member_id,$depth,$pagelink_stub,$pagelink,$recurse_level+1,$category_data,$entry_data)); // Recurse
				}
				if ((has_category_access($member_id,'catalogues_catalogue',$row['c_name'])) && ((get_value('disable_cat_cat_perms')==='1') || (has_category_access($member_id,'catalogues_category',strval($row['id'])))))
				{
					call_user_func_array($callback,array($pagelink,$parent_pagelink,NULL,$row['edit_date'],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,NULL,$row['edit_date'],max(0.7-$recurse_level*0.1,0.3),do_lang('UNKNOWN'),false)); // Callback
				}
			}
		}

		// Entries
		if (($depth>=DEPTH__ENTRIES) && (has_category_access($member_id,'catalogues_catalogue',$parent_attributes['c_name'])) && ((get_value('disable_cat_cat_perms')==='1') || (has_category_access($member_id,'catalogues_category',$parent_attributes['id']))))
		{
			require_code('catalogues');

			$start=0;
			do
			{
				$entry_data=$GLOBALS['SITE_DB']->query_select('catalogue_entries d',array('c_name','id','cc_id AS category_id','ce_add_date AS add_date','ce_edit_date AS edit_date','d.*'),array('cc_id'=>intval($parent_attributes['id'])),'',500,$start);

				foreach ($entry_data as $row)
				{
					$map=get_catalogue_entry_map($row,$catalogues[$row['c_name']],'CATEGORY','DEFAULT',NULL,NULL,array(0));

					$row['title']=is_object($map['FIELD_0_PLAIN'])?$map['FIELD_0_PLAIN']->evaluate():$map['FIELD_0_PLAIN'];

					$pagelink=$pagelink_stub.'entry:'.strval($row['id']);
					call_user_func_array($callback,array($pagelink,$parent_pagelink,$row['add_date'],$row['edit_date'],0.2,$row['title'])); // Callback
				}

				$start+=500;
			}
			while (array_key_exists(0,$entry_data));
		}
	}

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

		$GLOBALS['NO_QUERY_LIMIT']=true;

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

		if ($type=='category') return $this->view_catalogue_category();
		if ($type=='atoz') return $this->view_catalogue_category_entries();
		if ($type=='entry') return $this->view_catalogue_entry();
		if ($type=='index') return $this->view_catalogue_index();
		if ($type=='tree') return $this->tree_view_screen();
		if ($type=='misc') return $this->list_catalogues();

		return new ocp_tempcode();
	}

	/**
	 * The UI to show a catalogue category.
	 *
	 * @return tempcode		The UI
	 */
	function view_catalogue_category()
	{
		require_code('feedback');
		require_code('images');

		$id=get_param_integer('id',-1);
		if ($id==-1)
		{
			$id=$GLOBALS['SITE_DB']->query_value('catalogue_categories','MIN(id)',array('c_name'=>get_param('catalogue_name'),'cc_parent_id'=>NULL));
		}
		$GLOBALS['FEED_URL']=find_script('backend').'?mode=catalogues&filter='.strval($id);

		$categories=$GLOBALS['SITE_DB']->query_select('catalogue_categories',array('*'),array('id'=>$id),'',1);
		if (!array_key_exists(0,$categories))
		{
			return warn_screen(get_screen_title('CATALOGUES'),do_lang_tempcode('MISSING_RESOURCE'));
		}
		$category=$categories[0];

		// Permission for here?
		if (!has_category_access(get_member(),'catalogues_catalogue',$category['c_name']))
		{
			access_denied('CATALOGUE_ACCESS');
		}
		if ((get_value('disable_cat_cat_perms')!=='1') && (!has_category_access(get_member(),'catalogues_category',strval($id))))
		{
			access_denied('CATEGORY_ACCESS');
		}

		$catalogue_name=$category['c_name'];
		$root=get_param_integer('root',NULL);

		$_title=get_translated_text($category['cc_title']);
		$catalogues=$GLOBALS['SITE_DB']->query_select('catalogues',array('*'),array('c_name'=>$catalogue_name),'',1);
		if (!array_key_exists(0,$catalogues)) warn_exit(do_lang_tempcode('CATALOGUE_NOT_FOUND',$catalogue_name));

		$catalogue=$catalogues[0];
		$tpl_set=$catalogue_name;

		if (is_ecommerce_catalogue($catalogue_name))
		{
			$is_ecommerce=true;
			$tpl_set='products';
		} else
		{
			$is_ecommerce=false;
		}

		$title_to_use=do_lang_tempcode($catalogue_name.'__CATALOGUE_CATEGORY',escape_html($_title));
		$title_to_use_2=do_lang($catalogue_name.'__CATALOGUE_CATEGORY',$_title,NULL,NULL,NULL,false);
		if (is_null($title_to_use_2))
		{
			$title_to_use=do_lang_tempcode('DEFAULT__CATALOGUE_CATEGORY',escape_html($_title));
			$title_to_use_2=do_lang('DEFAULT__CATALOGUE_CATEGORY',$_title);
		}
		$awards=array();
		if (addon_installed('awards'))
		{
			require_code('awards');
			$awards=array_merge($awards,find_awards_for('catalogue',$catalogue_name));
			$awards=array_merge($awards,find_awards_for('catalogue_category',strval($id)));
		}
		$title=get_screen_title($title_to_use,false,NULL,NULL,$awards);

		if (is_object($title_to_use_2)) $title_to_use_2=$title_to_use_2->evaluate();
		seo_meta_load_for('catalogue_category',strval($id),$title_to_use_2);

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

		list($entry_buildup,$sorting,$entries,$max_rows)=get_catalogue_category_entry_buildup($id,$catalogue_name,$catalogue,'CATEGORY',$tpl_set,$max,$start,NULL,$root,NULL,true,NULL,either_param('active_filter',''));

		// Build up subcategories
		$rows_subcategories=$GLOBALS['SITE_DB']->query_select('catalogue_categories',array('*'),array('cc_parent_id'=>$id),'',600);
		if (count($rows_subcategories)==300) $rows_subcategories=array(); // Performance issue, manual browsing will be needed
		foreach ($rows_subcategories as $i=>$subcategory) // Dereference language
		{
			$rows_subcategories[$i]['cc_title']=get_translated_text($subcategory['cc_title']);
		}
		for ($i=0;$i<count($rows_subcategories);$i++) // Sort
		{
			for ($j=$i+1;$j<count($rows_subcategories);$j++)
			{
				if ($rows_subcategories[$i]['cc_title']>$rows_subcategories[$j]['cc_title'])
				{
					$temp=$rows_subcategories[$j];
					$rows_subcategories[$j]=$rows_subcategories[$i];
					$rows_subcategories[$i]=$temp;
				}
			}
		}
		$subcategories=new ocp_tempcode();
		$uses_rep_image=false;
		foreach ($rows_subcategories as $sc)
		{
			if ($sc['rep_image']!='') $uses_rep_image=true;
		}
		foreach ($rows_subcategories as $sc)
		{
			if ((get_value('disable_cat_cat_perms')!=='1') && (!has_category_access(get_member(),'catalogues_category',strval($sc['id'])))) continue;

			$child_counts=count_catalogue_category_children($sc['id']);
			$num_children=$child_counts['num_children'];
			$num_entries=$child_counts['num_entries_children'];
			$map=array('page'=>'_SELF','id'=>$sc['id'],'type'=>'category');
			if (!is_null($root)) $map['root']=$root;
			if (get_page_name()=='catalogues') $map+=propagate_ocselect();
			$url=build_url($map,'_SELF');
			if ($uses_rep_image || $is_ecommerce)
			{
				$display_string=do_lang_tempcode(($catalogue['c_is_tree']==1)?'CATEGORY_SUBORDINATE':'CATEGORY_SUBORDINATE_2',integer_format($num_entries),integer_format($num_children));
				if ($sc['rep_image'])
					$rep_image=do_image_thumb($sc['rep_image'],$sc['cc_title'],$sc['cc_title'],false);
				else
					$rep_image=new ocp_tempcode();

				$description=$sc['cc_description'];
				$description=get_translated_tempcode($description);
				$ajax_edit_url='_SEARCH:cms_catalogues:type=__edit_category:id='.strval($sc['id']);
				$subcategories->attach(do_template('CATEGORY_'.$tpl_set.'_ENTRY',array('_GUID'=>'871f5f5195fcb426fac716e35569d6a3','ID'=>strval($sc['id']),'NAME_FIELD'=>'title','AJAX_EDIT_URL'=>$ajax_edit_url,'URL'=>$url,'REP_IMAGE'=>$rep_image,'CHILDREN'=>$display_string,'NAME'=>$sc['cc_title'],'NAME_PLAIN'=>$sc['cc_title'],'DESCRIPTION'=>$description,'NUM_CHILDREN'=>integer_format($num_children),'NUM_CHILDREN_RECURSIVE'=>integer_format($child_counts['num_children_children']),'NUM_ENTRIES'=>integer_format($num_entries),'NUM_ENTRIES_DIRECT'=>integer_format($child_counts['num_entries'])),NULL,false,'CATEGORY_ENTRY'));
			} else
			{	
				$subcategories->attach(do_template('CATALOGUE_'.$tpl_set.'_SUBCATEGORY',array('ID'=>strval($sc['id']),'CATALOGUE'=>$catalogue_name,'URL'=>$url,'NUM_CHILDREN'=>integer_format($num_children),'NUM_CHILDREN_RECURSIVE'=>integer_format($child_counts['num_children_children']),'NUM_ENTRIES'=>integer_format($num_entries),'NUM_ENTRIES_DIRECT'=>integer_format($child_counts['num_entries']),'NAME'=>$sc['cc_title']),NULL,false,'CATALOGUE_DEFAULT_SUBCATEGORY'));
			}
		}
		if (!$subcategories->is_empty())
		{
			if ($uses_rep_image)
			{
				$subcategories=do_template('CATEGORY_LIST',array('_GUID'=>'3041620a953e52229f752b1bccfbeee3','CONTENT'=>$subcategories));
			} else
			{
				$subcategories=do_template('CATALOGUE_'.$tpl_set.'_SUBCATEGORY_WRAP',array('CATALOGUE'=>$catalogue_name,'CONTENT'=>$subcategories),NULL,false,'CATALOGUE_DEFAULT_SUBCATEGORY_WRAP');
			}
		}

		// Links to add to catalogue category etc
		if (has_actual_page_access(NULL,'cms_catalogues',NULL,(get_value('disable_cat_cat_perms')==='1')?array('catalogues_catalogue',$catalogue_name):array('catalogues_catalogue',$catalogue_name,'catalogues_category',strval($id)),'submit_midrange_content'))
		{
			$add_link=build_url(array('page'=>'cms_catalogues','type'=>'add_entry','catalogue_name'=>$catalogue_name,'category_id'=>$id),get_module_zone('cms_catalogues'));
		} else $add_link=new ocp_tempcode();
		if (has_actual_page_access(NULL,'cms_catalogues',NULL,(get_value('disable_cat_cat_perms')==='1')?array('catalogues_catalogue',$catalogue_name):array('catalogues_catalogue',$catalogue_name,'catalogues_category',strval($id)),'submit_cat_midrange_content'))
		{
			$add_cat_url=build_url(array('page'=>'cms_catalogues','type'=>'add_category','catalogue_name'=>$catalogue_name,'parent_id'=>$id),get_module_zone('cms_catalogues'));
		} else $add_cat_url=new ocp_tempcode();
		if (has_actual_page_access(NULL,'cms_catalogues',NULL,(get_value('disable_cat_cat_perms')==='1')?array('catalogues_catalogue',$catalogue_name):array('catalogues_catalogue',$catalogue_name,'catalogues_category',strval($id)),'edit_cat_midrange_content'))
		{
			$edit_cat_url=build_url(array('page'=>'cms_catalogues','type'=>'_edit_category','catalogue_name'=>$catalogue_name,'id'=>$id),get_module_zone('cms_catalogues'));
		} else $edit_cat_url=new ocp_tempcode();
		if (has_actual_page_access(NULL,'cms_catalogues',NULL,(get_value('disable_cat_cat_perms')==='1')?array('catalogues_catalogue',$catalogue_name):array('catalogues_catalogue',$catalogue_name),'edit_cat_highrange_content'))
		{
			$edit_catalogue_url=build_url(array('page'=>'cms_catalogues','type'=>'_edit_catalogue','id'=>$catalogue_name),get_module_zone('cms_catalogues'));
		} else $edit_catalogue_url=new ocp_tempcode();

		require_code('templates_pagination');
		$pagination=pagination(do_lang_tempcode('ENTRIES'),$id,$start,'start',$max,'max',$max_rows,$root,'category',true);

		if ($catalogue['c_is_tree']==1)
		{
			$breadcrumbs=catalogue_category_breadcrumbs($id,$root);
			if (!$breadcrumbs->is_empty()) $breadcrumbs->attach(do_template('BREADCRUMB_SEPARATOR'));
			if (has_specific_permission(get_member(),'open_virtual_roots'))
			{
				$url=get_self_url(false,false,(is_null(get_param('root',NULL)))?array('root'=>$id):array('root'=>($id==-1)?NULL:$id));
				$breadcrumbs->attach(hyperlink($url,escape_html($_title),false,false,do_lang_tempcode('VIRTUAL_ROOT')));
			} else $breadcrumbs->attach('<span>'.escape_html($_title).'</span>');
		} else
		{
			$breadcrumbs=new ocp_tempcode();
			$url=build_url(array('page'=>'_SELF','type'=>'index','id'=>$catalogue_name),'_SELF');
			$catalogue_title=get_translated_text($catalogue['c_title']);
			$breadcrumbs->attach(hyperlink($url,escape_html($catalogue_title),false,false,do_lang_tempcode('GO_BACKWARDS_TO',escape_html($catalogue_name))));
			$breadcrumbs->attach(do_template('BREADCRUMB_SEPARATOR'));
			$breadcrumbs->attach('<span>'.escape_html($_title).'</span>');
		}

		breadcrumb_add_segment($breadcrumbs);
		if (is_null($root)) breadcrumb_set_parents(array(array('_SELF:_SELF:misc'.($is_ecommerce?':ecommerce=1':''),do_lang('CATALOGUES'))));

		$GLOBALS['META_DATA']+=array(
			'created'=>date('Y-m-d',$category['cc_add_date']),
			'creator'=>'',
			'publisher'=>'', // blank means same as creator
			'modified'=>'',
			'type'=>get_translated_text($catalogue['c_title']).' category',
			'title'=>$_title,
			'identifier'=>'_SEARCH:catalogues:category:'.strval($id),
			'description'=>get_translated_text($category['cc_description']),
		);

		$rep_image_str=$category['rep_image'];
		if ($rep_image_str!='')
		{
			$GLOBALS['META_DATA']+=array(
				'image'=>(url_is_local($rep_image_str)?(get_custom_base_url().'/'):'').$rep_image_str,
			);
		}

		$cart_link=new ocp_tempcode();

		if ($is_ecommerce)
		{
			if (get_forum_type()!='ocf') warn_exit(do_lang_tempcode('NO_OCF'));

			require_code('shopping');
			require_lang('shopping');

			$cart_link=show_cart_image();
		}

		$display_type='';
		switch ($catalogue['c_display_type'])
		{
			case C_DT_FIELDMAPS:
				$display_type='FIELDMAPS';
				break;
			case C_DT_TITLELIST:
				$display_type='TITLELIST';
				break;
			case C_DT_TABULAR:
				$display_type='TABULAR';
				break;
			case C_DT_GRID:
				$display_type='GRID';
				break;
		}

		return do_template('CATALOGUE_'.$tpl_set.'_CATEGORY_SCREEN',array('ID'=>strval($id),'DISPLAY_TYPE'=>$display_type,'ADD_DATE_RAW'=>strval($category['cc_add_date']),'TITLE'=>$title,'_TITLE'=>$_title,'TAGS'=>get_loaded_tags('catalogue_categories'),'CATALOGUE'=>$catalogue_name,'PAGINATION'=>$pagination,'SORTING'=>$sorting,'ADD_ENTRY_URL'=>$add_link,'ADD_CAT_URL'=>$add_cat_url,'EDIT_CAT_URL'=>$edit_cat_url,'EDIT_CATALOGUE_URL'=>$edit_catalogue_url,'ENTRIES'=>$entry_buildup,'SUBCATEGORIES'=>$subcategories,'DESCRIPTION'=>get_translated_tempcode($category['cc_description']),'CART_LINK'=>$cart_link,'BREADCRUMBS'=>$breadcrumbs),NULL,false,'CATALOGUE_DEFAULT_CATEGORY_SCREEN');
	}

	/**
	 * The UI to show a catalogue A-Z screen.
	 *
	 * @return tempcode		The UI
	 */
	function view_catalogue_category_entries()
	{
		$id=get_param_integer('id',-1);

		if ($id==-1)
		{
			$id=$GLOBALS['SITE_DB']->query_value('catalogue_categories','MIN(id)',array('c_name'=>get_param('catalogue_name'),'cc_parent_id'=>NULL));
		}
		$GLOBALS['FEED_URL']=find_script('backend').'?mode=catalogues&filter='.strval($id);

		$categories=$GLOBALS['SITE_DB']->query_select('catalogue_categories',array('*'),array('id'=>$id),'',1);
		if (!array_key_exists(0,$categories))
		{
			return warn_screen(get_screen_title('CATALOGUES'),do_lang_tempcode('MISSING_RESOURCE'));
		}
		$category=$categories[0];

		// Permission for here?
		if (!has_category_access(get_member(),'catalogues_catalogue',$category['c_name']))
		{
			access_denied('CATALOGUE_ACCESS');
		}

		$catalogue_name=$category['c_name'];

		$root=get_param_integer('root',NULL);

		$category=$GLOBALS['SITE_DB']->query_value('catalogue_categories','cc_title',array('id'=>$id));

		$category_name=get_translated_text($category);

		$catalogues=$GLOBALS['SITE_DB']->query_select('catalogues',array('*'),array('c_name'=>$catalogue_name),'',1);

		if (!array_key_exists(0,$catalogues)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));

		$catalogue=$catalogues[0];

		$tpl_set=$catalogue_name;

		$category_buildup=new ocp_tempcode();

		$max=NULL;
		$start=NULL;

		require_code('ocfiltering');
		$sql_filter=ocfilter_to_sqlfragment(strval($id).'*','cc_id','catalogue_categories','cc_parent_id','cc_id','id'); // Note that the parameters are fiddled here so that category-set and record-set are the same, yet SQL is returned to deal in an entirely different record-set (entries' record-set)

		if ($GLOBALS['SITE_DB']->query_value_null_ok_full('SELECT COUNT(*) FROM '.get_table_prefix().'catalogue_entries p WHERE ce_validated=1 AND ('.$sql_filter.')')>1000)
			warn_exit(do_lang_tempcode('TOO_MANY_TO_CHOOSE_FROM'));
		$cats=array();

		$rows=$GLOBALS['SITE_DB']->query('SELECT * FROM '.get_table_prefix().'catalogue_entries p WHERE ce_validated=1 AND ('.$sql_filter.')');
		foreach ($rows as $row)
		{
			$entry_map=get_catalogue_entry_map($row,$catalogue,'CATEGORY','DEFAULT',$root,NULL,array(0),false,false);
			$letter=strtoupper(substr(is_object($entry_map['FIELD_0_PLAIN'])?$entry_map['FIELD_0_PLAIN']->evaluate():$entry_map['FIELD_0_PLAIN'],0,1));

			if ((get_value('disable_cat_cat_perms')!=='1') && (!has_category_access(get_member(),'catalogues_category',strval($row['id'])))) continue;

			if (!array_key_exists($letter,$cats)) $cats[$letter]=array();
			$cats[$letter][]=$row;
		}
		unset($rows);

		ksort($cats);
		foreach ($cats as $letter=>$entries)
		{
			list($entry_buildup)=get_catalogue_category_entry_buildup(NULL,$catalogue_name,$catalogue,'CATEGORY',$tpl_set,$max,$start,NULL,$root,NULL,true,$entries);

			$category_buildup->attach(do_template('CATALOGUE_CATEGORY_HEADING',array('LETTER'=>is_integer($letter)?strval($letter):$letter,'ENTRIES'=>escape_html($entry_buildup)),NULL,false,'CATALOGUE_CATEGORY_HEADING'));				
		}

		$_title=get_translated_text($category);

		$title_to_use=do_lang_tempcode('DEFAULT__CATALOGUE_CATEGORY_ATOZ',escape_html($_title));

		$title=get_screen_title($title_to_use,false);

		//Link to add to catalogue category
		if (has_actual_page_access(NULL,'cms_catalogues',NULL,(get_value('disable_cat_cat_perms')==='1')?array('catalogues_catalogue',$catalogue_name):array('catalogues_catalogue',$catalogue_name,'catalogues_category',strval($id)),'submit_midrange_content'))
		{
			$add_link=build_url(array('page'=>'cms_catalogues','type'=>'add_entry','catalogue_name'=>$catalogue_name,'category_id'=>$id),get_module_zone('cms_catalogues'));
		} else $add_link=new ocp_tempcode();
		if (has_actual_page_access(NULL,'cms_catalogues',NULL,(get_value('disable_cat_cat_perms')==='1')?array('catalogues_catalogue',$catalogue_name):array('catalogues_catalogue',$catalogue_name,'catalogues_category',strval($id)),'submit_cat_midrange_content'))
		{
			$add_cat_url=build_url(array('page'=>'cms_catalogues','type'=>'add_category','catalogue_name'=>$catalogue_name,'parent_id'=>$id),get_module_zone('cms_catalogues'));
		} else $add_cat_url=new ocp_tempcode();
		if (has_actual_page_access(NULL,'cms_catalogues',NULL,(get_value('disable_cat_cat_perms')==='1')?array('catalogues_catalogue',$catalogue_name):array('catalogues_catalogue',$catalogue_name,'catalogues_category',strval($id)),'edit_cat_midrange_content'))
		{
			$edit_cat_url=build_url(array('page'=>'cms_catalogues','type'=>'_edit_category','catalogue_name'=>$catalogue_name,'id'=>$id),get_module_zone('cms_catalogues'));
		} else $edit_cat_url=new ocp_tempcode();
		if (has_actual_page_access(NULL,'cms_catalogues',NULL,(get_value('disable_cat_cat_perms')==='1')?array('catalogues_catalogue',$catalogue_name):array('catalogues_catalogue',$catalogue_name),'edit_cat_highrange_content'))
		{
			$edit_catalogue_url=build_url(array('page'=>'cms_catalogues','type'=>'_edit_catalogue','id'=>$catalogue_name),get_module_zone('cms_catalogues'));
		} else $edit_catalogue_url=new ocp_tempcode();

		breadcrumb_set_parents(array(array('_SELF:_SELF:misc'.(($catalogue['c_ecommerce']==1)?':ecommerce=1':''),do_lang_tempcode('CATALOGUES'))));

		return do_template('CATALOGUE_'.$tpl_set.'_CATEGORY_SCREEN',array('TITLE'=>$title,'ID'=>'','CART_LINK'=>'','_TITLE'=>$_title,'TAGS'=>get_loaded_tags('catalogue_categories'),'CATALOGUE'=>$catalogue_name,'PAGINATION'=>'','SORTING'=>'','ADD_ENTRY_URL'=>$add_link,'ADD_CAT_URL'=>$add_cat_url,'EDIT_CAT_URL'=>$edit_cat_url,'EDIT_CATALOGUE_URL'=>$edit_catalogue_url,'ENTRIES'=>$category_buildup,'SUBCATEGORIES'=>'','DESCRIPTION'=>''),NULL,false,'CATALOGUE_DEFAULT_CATEGORY_SCREEN');
	}

	/**
	 * The UI to show a catalogue entry.
	 *
	 * @return tempcode		The UI
	 */
	function view_catalogue_entry()
	{
		$id=get_param_integer('id');
		return render_catalogue_entry_screen($id);
	}

	/**
	 * The UI to show the index of a catalogue.
	 *
	 * @return tempcode		The UI
	 */
	function view_catalogue_index()
	{
		$catalogue_name=get_param('id');
		$GLOBALS['FEED_URL']=find_script('backend').'?mode=catalogues&filter='.$catalogue_name;
		$catalogue_rows=$GLOBALS['SITE_DB']->query_select('catalogues',array('*'),array('c_name'=>$catalogue_name),'',1);
		if (!array_key_exists(0,$catalogue_rows)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$catalogue=$catalogue_rows[0];
		$description=get_translated_tempcode($catalogue['c_description']);
		$description_2=get_translated_text($catalogue['c_description']);
		$title_to_use=do_lang_tempcode($catalogue_name.'__CATALOGUE_INDEX',escape_html(get_translated_text($catalogue['c_title'])));
		$title_to_use_2=do_lang($catalogue_name.'__CATALOGUE_INDEX',escape_html(get_translated_text($catalogue['c_title'])),NULL,NULL,NULL,false);
		if (is_null($title_to_use_2))
			$title_to_use=do_lang_tempcode('DEFAULT__CATALOGUE_INDEX',escape_html(get_translated_text($catalogue['c_title'])));
		if (addon_installed('awards'))
		{
			require_code('awards');
			$awards=find_awards_for('catalogue',$catalogue_name);
		} else $awards=array();
		$title=get_screen_title($title_to_use,false,NULL,NULL,$awards);

		if (!has_category_access(get_member(),'catalogues_catalogue',$catalogue_name))
		{
			access_denied('CATALOGUE_ACCESS');
		}

		if ($GLOBALS['SITE_DB']->query_value('catalogue_categories','COUNT(*)',array('c_name'=>$catalogue_name))>1000)
			warn_exit(do_lang_tempcode('TOO_MANY_TO_CHOOSE_FROM'));
		$rows_subcategories=$GLOBALS['SITE_DB']->query_select('catalogue_categories',array('*'),array('c_name'=>$catalogue_name));
		foreach ($rows_subcategories as $i=>$subcategory) // Dereference language
		{
			$rows_subcategories[$i]['cc_title']=get_translated_text($subcategory['cc_title']);
		}
		global $M_SORT_KEY;
		$M_SORT_KEY='cc_title';
		usort($rows_subcategories,'multi_sort');
		$out=new ocp_tempcode();
		foreach ($rows_subcategories as $myrow)
		{
			if ((get_value('disable_cat_cat_perms')!=='1') && (!has_category_access(get_member(),'catalogues_category',strval($myrow['id'])))) continue;

			$url=build_url(array('page'=>'_SELF','id'=>$myrow['id'],'type'=>'category'),'_SELF');
			$name=$myrow['cc_title'];
			$description=get_translated_tempcode($myrow['cc_description']);
			$child_counts=count_catalogue_category_children($myrow['id']);
			$num_children=$child_counts['num_children'];
			$num_entries=$child_counts['num_entries_children'];
			$display_string=do_lang_tempcode(($catalogue['c_is_tree']==1)?'CATEGORY_SUBORDINATE':'CATEGORY_SUBORDINATE_2',integer_format($num_entries),integer_format($num_children));

			$out->attach(do_template('INDEX_SCREEN_FANCIER_ENTRY',array('_GUID'=>'f2550f5be8765b5d0349ee5523f739cb','NAME'=>$name,'DESCRIPTION'=>$description,'URL'=>$url,'TITLE'=>'','COUNT'=>$display_string)));
		}

		breadcrumb_set_parents(array(array('_SELF:_SELF:misc'.(($catalogue['c_ecommerce']==1)?':ecommerce=1':''),do_lang_tempcode('CATALOGUES'))));
		breadcrumb_set_self(make_string_tempcode(escape_html(get_translated_text($catalogue['c_title']))));

		$edit_url=build_url(array('page'=>'cms_catalogues','type'=>'_edit_catalogue','id'=>$catalogue_name),get_module_zone('cms_catalogues'));

		if (has_actual_page_access(NULL,'cms_catalogues',NULL,array('catalogues_catalogue',$catalogue_name),'submit_cat_midrange_content'))
		{
			$add_cat_url=build_url(array('page'=>'cms_catalogues','type'=>'add_category','catalogue_name'=>$catalogue_name),get_module_zone('cms_catalogues'));
		} else $add_cat_url=new ocp_tempcode();

		$GLOBALS['META_DATA']+=array(
			'created'=>date('Y-m-d',$catalogue['c_add_date']),
			'creator'=>'',
			'publisher'=>'', // blank means same as creator
			'modified'=>'',
			'type'=>'Catalogue',
			'title'=>get_translated_text($catalogue['c_title']),
			'identifier'=>'_SEARCH:catalogues:index:'.$catalogue_name,
			'description'=>$description_2,
		);

		$catalogue_description=get_translated_tempcode($catalogue['c_description']);

		return do_template('INDEX_SCREEN_FANCIER_SCREEN',array('_GUID'=>'9ac6f5967177b020bebfe8b4ace35eff','PRE'=>$catalogue_description,'POST'=>'','TITLE'=>$title,'CATALOGUE'=>$catalogue_name,'DESCRIPTION'=>$description,'ADD_CAT_URL'=>$add_cat_url,'CONTENT'=>$out,'EDIT_URL'=>$edit_url));
	}

	/**
	 * The UI to show a list of catalogues to choose from.
	 *
	 * @return tempcode		The UI
	 */
	function list_catalogues()
	{
		$title=get_screen_title('CATALOGUES');

		$GLOBALS['FEED_URL']=find_script('backend').'?mode=catalogues&filter=';

		$ecommerce=get_param_integer('ecommerce',NULL);

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

		$query='FROM '.get_table_prefix().'catalogues c';
		if (can_arbitrary_groupby())
			$query.=' JOIN '.get_table_prefix().'catalogue_entries e ON e.c_name=c.c_name';
		$query.=' WHERE ';
		$query.=is_null($ecommerce)?'1=1':('c_ecommerce='.strval($ecommerce));
		$query.=' AND c.c_name NOT LIKE \''.db_encode_like('\_%').'\'';
		$rows=$GLOBALS['SITE_DB']->query('SELECT c.* '.$query.(can_arbitrary_groupby()?' GROUP BY c.c_name':''),$max,$start);
		$max_rows=$GLOBALS['SITE_DB']->query_value_null_ok_full('SELECT COUNT(DISTINCT c.c_name) '.$query);
		$out=new ocp_tempcode();
		foreach ($rows as $myrow)
		{
			$first_category=$GLOBALS['SITE_DB']->query_value_null_ok('catalogue_categories','MIN(id)',array('c_name'=>$myrow['c_name'],'cc_parent_id'=>NULL));
			if (is_null($first_category)) continue;

			if (!has_category_access(get_member(),'catalogues_catalogue',$myrow['c_name'])) continue;

			if ($myrow['c_is_tree']==1) // Point to root
			{
				$url=build_url(array('page'=>'_SELF','catalogue_name'=>$myrow['c_name'],'type'=>'category','id'=>$first_category),'_SELF');
			} else
			{
				$url=build_url(array('page'=>'_SELF','id'=>$myrow['c_name'],'type'=>'index'),'_SELF');
			}
			$name=get_translated_text($myrow['c_title']);

			$num_entries=$GLOBALS['SITE_DB']->query_value('catalogue_entries','COUNT(*)',array('c_name'=>$myrow['c_name'],'ce_validated'=>1));
			$num_children=$GLOBALS['SITE_DB']->query_value('catalogue_categories','COUNT(*)',array('c_name'=>$myrow['c_name']));
			if ($myrow['c_is_tree']==1) $num_children--;

			$description=get_translated_tempcode($myrow['c_description']);

			$display_string=do_lang_tempcode(($myrow['c_is_tree']==1)?'CATEGORY_SUBORDINATE':'CATEGORY_SUBORDINATE_2',integer_format($num_entries),integer_format($num_children));

			$out->attach(do_template('INDEX_SCREEN_FANCIER_ENTRY',array('_GUID'=>'082993547f051894a6b70eea8194df5f','NAME'=>$name,'DESCRIPTION'=>$description,'URL'=>$url,'TITLE'=>'','COUNT'=>$display_string)));
		}

		require_code('templates_pagination');
		$pagination=pagination(do_lang_tempcode('CATALOGUES'),NULL,$start,'start',$max,'max',$max_rows,NULL,'misc');

		return do_template('INDEX_SCREEN_FANCIER_SCREEN',array('_GUID'=>'5af7dcb5bd26550ca6f26c2f9108f478','PRE'=>'','POST'=>'','PAGINATION'=>$pagination,'TITLE'=>$title,'CONTENT'=>$out));
	}

	/**
	 * The UI to view a catalogue category tree.
	 *
	 * @return tempcode		The UI
	 */
	function tree_view_screen()
	{
		require_code('splurgh');

		$catalogue_name=get_param('id');

		if ($GLOBALS['SITE_DB']->query_value('catalogue_categories','COUNT(*)',array('c_name'=>$catalogue_name))>1000)
			warn_exit(do_lang_tempcode('TOO_MANY_TO_CHOOSE_FROM'));

		$GLOBALS['FEED_URL']=find_script('backend').'?mode=catalogues&filter=';

		$url_stub=build_url(array('page'=>'_SELF','type'=>'category'),'_SELF',NULL,false,false,true);
		$last_change_time=$GLOBALS['SITE_DB']->query_value_null_ok('catalogue_categories','MAX(cc_add_date)');

		if (!has_category_access($GLOBALS['FORUM_DRIVER']->get_guest_id(),'catalogues_catalogue',$catalogue_name))
		{
			access_denied('CATALOGUE_ACCESS');
		}

		$category_rows=$GLOBALS['SITE_DB']->query_select('catalogue_categories',array('id','cc_title','cc_parent_id'),array('c_name'=>$catalogue_name));
		$map=array();
		foreach ($category_rows as $i=>$category)
		{
			if ($i!=0)
			{
				if (!has_category_access($GLOBALS['FORUM_DRIVER']->get_guest_id(),'catalogues_category',strval($category['id']))) continue;
			}

			$id=$category['id'];

			$map[$id]['title']=get_translated_text($category['cc_title']);
			$children=array();
			foreach ($category_rows as $child)
			{
				if ($child['cc_parent_id']==$id) $children[]=$child['id'];
			}
			$map[$id]['children']=$children;
		}
		if (count($map)==0) inform_exit(do_lang_tempcode('NO_ENTRIES'));

		$content=splurgh_master_build('id',$map,$url_stub->evaluate(),'catalogue_'.$catalogue_name.'_tree_made',$last_change_time,$category_rows[0]['id']);

		$title=get_screen_title('CATEGORIES');

		breadcrumb_set_parents(array(array('_SELF:_SELF:misc'.(is_ecommerce_catalogue($catalogue_name)?':ecommerce=1':''),do_lang_tempcode('CATALOGUES'))));

		return do_template('SPLURGH_SCREEN',array('_GUID'=>'7cbb5d410887e3834a01265e133a9b33','TITLE'=>$title,'CONTENT'=>$content));
	}

}


