<?php

/**
 * <pre>
 * Invision Power Services
 * IP.CCS front end articles interface.  This library sits on top of databases.php
 * and extends it to customize functionality for the article handling specifically.
 * Last Updated: $Date: 2009-09-22 19:34:19 -0400 (Tue, 22 Sep 2009) $
 * </pre>
 *
 * @author 		$Author: bfarber $
 * @copyright	(c) 2001 - 2009 Invision Power Services, Inc.
 * @license		http://www.invisionpower.com/community/board/license.html
 * @package		IP.Content
 * @link		http://www.invisionpower.com
 * @since		9th February 2010
 * @version		$Revision: 93 $
 */

if ( ! defined( 'IN_ACP' ) )
{
	print "<h1>Incorrect access</h1>You cannot access this file directly.";
	exit();
}

class articlesBuilder extends databaseBuilder
{
	/**
	 * Whether to show subcategory articles on category frontpage
	 *
	 * @access	public
	 * @var		bool
	 */
	const AGGREGATE			= true;
	
	/**
	 * Category limiter
	 *
	 * @access	public
	 * @var		int
	 */
	public $categoryLimit	= 0;
	
	/**
	 * Gateway call to get article output
	 *
	 * @access	public
	 * @param	array 		Page data
	 * @return	string		HTML output
	 */
	public function getArticles( $page )
	{
		//-----------------------------------------
		// Load skin file if it hasn't been loaded yet
		//-----------------------------------------
		
		$this->pages->loadSkinFile();
		
		//-----------------------------------------
		// Get the database info
		//-----------------------------------------
		
		$this->database	= $this->_loadArticlesDatabase();
		
		return $this->getDatabase( '', $page );
	}
	
	/**
	 * Limit the article display to a specified category ID and below.
	 * Can be useful to simulate two article systems.
	 *
	 * @access	public
	 * @param	int			Category ID
	 * @return	void
	 */
	public function limitCategory( $categoryId )
	{
		$categoryId	= intval($categoryId);

		if( $categoryId )
		{
			$this->categoryLimit	= $categoryId;
		}
	}

	/**
	 * Get and return database HTML
	 *
	 * @access	public
	 * @param	string		Database key
	 * @param	array 		Page data
	 * @return	string		Database HTML
	 */
	public function getDatabase( $key, $page )
	{
		if( !$this->database['database_id'] )
		{
			return '';
		}
		
		if ( $this->registry->permissions->check( 'view', $this->database ) != TRUE )
		{
			return '';
		}
		
		//-----------------------------------------
		// Fix language strings
		//-----------------------------------------
		
		$this->registry->ccsFunctions->fixStrings( $this->database['database_id'] );
		
		//-----------------------------------------
		// Get plugin functionality
		//-----------------------------------------
		
		$this->_loadPlugin();

		//-----------------------------------------
		// Basic perm checking and init
		//-----------------------------------------
		
		$this->_initDatabase( $page );

		//-----------------------------------------
		// Get possible field types
		//-----------------------------------------
		
		$this->fieldsClass	= $this->registry->ccsFunctions->getFieldsClass();

		$this->fields	= array();

		if( is_array($this->caches['ccs_fields'][ $this->database['database_id'] ]) AND count($this->caches['ccs_fields'][ $this->database['database_id'] ]) )
		{
			foreach( $this->caches['ccs_fields'][ $this->database['database_id'] ] as $_field )
			{
				$this->fields[ $_field['field_id'] ]	= $_field;
			}
		}

		//-----------------------------------------
		// Get category handler
		//-----------------------------------------
		
		$this->categories	= $this->registry->ccsFunctions->getCategoriesClass( $this->database );

		if( $this->categoryLimit )
		{
			$this->categories->resetRootCategory( $this->categoryLimit );
		}
		
		//-----------------------------------------
		// Fix database furls... sigh :(
		//-----------------------------------------
		
		$this->fixDatabaseFurls();

		//-----------------------------------------
		// What action to take
		//-----------------------------------------
		
		switch( $this->request['do'] )
		{
			case 'add':
				return $this->_actionAdd();
			break;
			
			case 'save':
				return $this->_actionSaveAdd();
			break;
			
			case 'edit':
				return $this->_actionEdit();
			break;
			
			case 'save_edit':
				return $this->_actionSaveEdit();
			break;
			
			case 'comment':
				return $this->_actionComment();
			break;
			
			case 'delete':
				return $this->_actionDelete();
			break;
			
			case 'deleteComment':
				return $this->_actionDeleteComment();
			break;
			
			case 'toggleComment':
				return $this->_actionToggleComment();
			break;
			
			case 'lock':
			case 'unlock':
				return $this->_actionToggleLock();
			break;
			
			case 'pin':
			case 'unpin':
				return $this->_actionPin();
			break;
			
			case 'approve':
			case 'unapprove':
				return $this->_actionApprove();
			break;

			case 'watch':
			case 'unwatch':
				return $this->_actionWatch();
			break;

			case 'search':
				$this->_loadTemplates( 'listing' );

				return $this->_getDatabaseListing();
			break;
		}

		//-----------------------------------------
		// If none of the above, view cats, listing or record?
		//-----------------------------------------

		$_content	= '';

		if( $this->request['record'] )
		{
			$_content	.= $this->_getRecordDisplay();
		}
		else if( $this->request['category'] AND $this->request['view'] == 'archive' )
		{
			$this->_loadTemplates( 'listing' );

			$_content	.= $this->_getDatabaseListing();
		}
		else if( $this->request['category'] )
		{
			$_content	.= $this->_getCategoryFrontpage();
		}
		else if( $this->request['view'] == 'categories' )
		{
			$this->_loadTemplates( 'categories' );
			
			$_content	.= $this->_getDatabaseCategories();
		}
		else
		{
			$this->_loadTemplates();
			
			$_content	.= $this->_getDatabaseFrontpage();
		}

		return $_content;
	}
	
	/**
	 * Get listing of categories
	 *
	 * @access	protected
	 * @return	string		HTML
	 */
	protected function _getDatabaseCategories()
	{
		$_result	= parent::_getDatabaseCategories();
		
		$this->pages->setCanonical( $this->database['base_link'] . 'view=categories' );
		
		return $_result;
	}
	
	/**
	 * Get listing of categories
	 *
	 * @access	protected
	 * @return	string		HTML
	 */
	protected function _getDatabaseListing()
	{
		//-----------------------------------------
		// Do we have children?
		//-----------------------------------------
		
		$category					= $this->categories->getCategory( $this->request['category'] );
		$category['category_link']	= $this->categories->getCategoryUrl( $this->database['base_link'], $category['category_id'], true ) . 'view=archive';
		
		$this->checkPermalink( $this->categories->getCategoryUrl( $this->database['base_link'], $category['category_id'] ) );
		
		$this->pages->setMetaKeywords( $category['category_meta_keywords'] );
		$this->pages->setMetaDescription( $category['category_meta_description'] );
		$this->pages->setCanonical( $category['category_link'] );


		if( $this->request['category'] AND !$category['category_id'] )
		{
			$this->registry->output->showError( $this->lang->words['no_view_perm_cat'], '10CCS18' );
		}
		else if( $this->request['category'] )
		{
			if ( $category['category_has_perms'] AND $this->registry->permissions->check( 'add', $category ) != TRUE )
			{
				$this->database['_can_add']	= false;
			}
		}
		
		$categories	= $this->categories->catcache[ $this->request['category'] ];
		
		if( count($categories) )
		{
			foreach( $categories as $id => $data )
			{
				$categories[ $id ]					= $this->categories->getCategory( $id );
				$categories[ $id ]['category_link']	= $this->categories->getCategoryUrl( $this->database['base_link'], $id );
				$_children							= $this->categories->getChildren( $id );
				$categories[ $id ]['children']		= array();
				
				if( count($_children) )
				{
					foreach( $_children as $_child )
					{
						$categories[ $id ]['children'][]							= $this->categories->getCategory( $_child );
						$categories[ $id ]['children'][ $_child ]['category_link']	= $this->categories->getCategoryUrl( $this->database['base_link'], $_child );
					}
				}
				
				//-----------------------------------------
				// Latest record display
				//-----------------------------------------

				if( in_array( $this->database['database_field_title'], array( 'primary_id_field', 'member_id', 'record_saved', 'record_updated', 'rating_real' ) ) )
				{
					$categories[ $id ][ $this->database['database_field_title'] . '_value' ]	= ( $this->database['database_field_title'] == 'record_saved' OR $this->database['database_field_title'] == 'record_updated' ) ? $this->registry->class_localization->getDate( $categories[ $id ][ $this->database['database_field_title'] ], 'LONG' ) : $categories[ $id ][ $this->database['database_field_title'] ];
				}
				else
				{
					$categories[ $id ][ $this->database['database_field_title'] . '_value' ]	= $this->fieldsClass->getFieldValue( $this->fields[ str_replace( 'field_', '', $this->database['database_field_title'] ) ], $categories[ $id ], $this->fields[ str_replace( 'field_', '', $this->database['database_field_title'] ) ]['field_truncate'] );
				}
				
				if( in_array( $this->database['database_field_content'], array( 'primary_id_field', 'member_id', 'record_saved', 'record_updated', 'rating_real' ) ) )
				{
					$categories[ $id ][ $this->database['database_field_content'] . '_value' ]	= ( $this->database['database_field_content'] == 'record_saved' OR $this->database['database_field_content'] == 'record_updated' ) ? $this->registry->class_localization->getDate( $categories[ $id ][ $this->database['database_field_content'] ], 'LONG' ) : $categories[ $id ][ $this->database['database_field_content'] ];
				}
				else
				{
					$categories[ $id ][ $this->database['database_field_content'] . '_value' ]	= $this->fieldsClass->getFieldValue( $this->fields[ str_replace( 'field_', '', $this->database['database_field_content'] ) ], $categories[ $id ], $this->fields[ str_replace( 'field_', '', $this->database['database_field_content'] ) ]['field_truncate'] );
				}

				$categories[ $id ]['record_link']	= $this->getRecordUrl( array( 'primary_id_field' => $categories[ $id ]['category_last_record_id'], 'category_id' => $categories[ $id ]['category_last_record_cat'] ? $categories[ $id ]['category_last_record_cat'] : $id, $this->database['database_field_title'] . '_value' => $categories[ $id ][ $this->database['database_field_title'] . '_value' ] ) );
			}
		}

		//-----------------------------------------
		// Breadcrumbs
		//-----------------------------------------

		if( count($categories) OR $this->request['category'] )
		{
			$crumbies	= $this->categories->getBreadcrumbs( $this->request['category'], $this->database['base_link'] );
	
			if( !$this->settings['use_friendly_urls'] AND !$this->settings['ccs_root_url'] )
			{
				array_unshift( $crumbies, array( 0 => $this->database['database_name'], 1 => substr( $this->database['base_link'], 0, -5 ) ) );
			}
			else
			{
				array_unshift( $crumbies, array( 0 => $this->database['database_name'], 1 => substr( $this->database['base_link'], 0, -1 ) ) );
			}
		}
		else if( !$this->request['category'] )
		{
			if( !$this->settings['use_friendly_urls'] AND !$this->settings['ccs_root_url'] )
			{
				$crumbies	= array( array( 0 => $this->database['database_name'], 1 => substr( $this->database['base_link'], 0, -5 ) ) );
			}
			else
			{
				$crumbies	= array( array( 0 => $this->database['database_name'], 1 => substr( $this->database['base_link'], 0, -1 ) ) );
			}
		}

		$this->pages->addNavigation( $this->registry->output->getTemplate('ccs_global')->databaseNavigation( $crumbies ) );
		
		define( 'CCS_NAV_DONE', true );
		
		if( $category['category_name'] )
		{
			$this->registry->output->setTitle( $category['category_name'] );
		}
		
		//-----------------------------------------
		// Showing records?
		//-----------------------------------------
		
		$_show	= true;
		
		if( $category['category_id'] )
		{
			if( !$category['category_show_records'] )
			{
				$_show	= false;
			}
		}

		$records	= array();
		$pages		= '';
		
		if( $_show )
		{
			//-----------------------------------------
			// Sorting and limiting
			//-----------------------------------------
			
			$perPage	= intval($this->request['per_page']) ? intval($this->request['per_page']) : $this->database['database_field_perpage'];
			$perPage	= intval($perPage) > 0 ? $perPage : 25;
			$start		= intval($this->request['st']) ? intval($this->request['st']) : 0;
			
			$_col		= $this->request['sort_col'];
			$_useCol	= $this->database['database_field_sort'];
			$_numeric	= false;
	
			foreach( $this->fields as $_field )
			{
				if( $_col == 'field_' . $_field['field_id'] )
				{
					$_useCol	= $_col;
					$_numeric	= $_field['field_is_numeric'];
				}
			}
			
			if( in_array( $_col, array( 'rating_real', 'record_views', 'primary_id_field', 'member_id', 'record_saved', 'record_updated' ) ) )
			{
				$_useCol	= $_col;
			}
	
			$_dir		= ( $this->request['sort_order'] && in_array( $this->request['sort_order'], array( 'asc', 'desc' ) ) ) ? $this->request['sort_order'] : $this->database['database_field_direction'];
			
			$this->request['sort_col']		= $_useCol;
			$this->request['sort_order']	= $_dir;
			$this->request['per_page']		= $perPage;
		
			//-----------------------------------------
			// Search
			//-----------------------------------------
	
			$_where	= '';
			
			if( $this->request['search_value'] )
			{
				$_where	= $this->fieldsClass->getSearchWhere( $this->fields, $this->request['search_value'] );
			}
			
			if( $category['category_id'] )
			{
				$_where		= $_where ? "category_id=" . intval($this->request['category']) . " AND (" . $_where . ")" : "category_id=" . intval($this->request['category']);
			}
			else
			{
				if( count($this->categories->categories) )
				{
					$_catIds	= array();
					
					foreach( $this->categories->categories as $_catId => $_cat )
					{
						$_catIds[]	= $_catId;
					}
					
					$_where		= $_where ? "category_id IN(" . implode( ',', $_catIds ) . ") AND (" . $_where . ")" : "category_id IN(" . implode( ',', $_catIds ) . ")";
				}
			}
			
			//-----------------------------------------
			// Only show approved records if we can't mod
			//-----------------------------------------
			
			if( !$this->database['moderate_approve'] )
			{
				if( $_where )
				{
					$_where	= "record_approved=1 AND " . $_where;
				}
				else
				{
					$_where	= "record_approved=1";
				}
			}
			
			$count		= $this->DB->buildAndFetch( array( 'select' => 'COUNT(*) as total', 'from' => $this->database['database_database'], 'where' => $_where ) );
			
			//-----------------------------------------
			// Query string
			//-----------------------------------------
			
			$baseUrl	= $this->request['category'] ? $this->categories->getCategoryUrl( $this->database['base_link'], $this->request['category'], true ) : $this->database['base_link'];
			$_qs		= 'search_value=' . urlencode($this->request['search_value']) . '&amp;sort_col=' . $_useCol . '&amp;sort_order=' . $_dir . '&amp;per_page=' . $perPage;
			
			if( $this->request['do'] == 'search' )
			{
				$_qs	= "do=search&amp;" . $_qs;
			}
			
			//-----------------------------------------
			// Page links
			//-----------------------------------------
			
			$pages		= $this->registry->output->generatePagination( array( 
																	'totalItems'		=> $count['total'],
																	'itemsPerPage'		=> $perPage,
																	'currentStartValue'	=> $start,
																	'baseUrl'			=> $baseUrl . $_qs,
																	'base'				=> 'none',
											 				)	);

			//-----------------------------------------
			// Count for search results
			//-----------------------------------------
			
			if( $this->request['search_value'] )
			{
				$this->database['keyword']		= $this->request['search_value'];
				$this->database['result_cnt']	= $count['total'];
			}

			//-----------------------------------------
			// Records
			//-----------------------------------------
			
			$_memberIds	= array();
			
			$this->DB->build( array( 'select' => '*', 'from' => $this->database['database_database'], 'order' => 'record_pinned DESC, ' . ( $_numeric ? $_useCol . '+0' : $_useCol ) . ' ' . $_dir, 'where' => $_where, 'limit' => array( $start, $perPage ) ) );
			$outer	= $this->DB->execute();
			
			while( $r = $this->DB->fetch($outer) )
			{
				foreach( $r as $k => $v )
				{
					if( preg_match( "/^field_(\d+)$/", $k, $matches ) )
					{
						$r[ $k . '_value' ]	= $this->fieldsClass->getFieldValue( $this->fields[ $matches[1] ], $r, $this->fields[ $matches[1] ]['field_truncate'] );
					}
				}
				
				$r['_isRead']		= $this->registry->classItemMarking->isRead( array( 'catID' => $r['category_id'], 'itemID' => $r['primary_id_field'], 'itemLastUpdate' => $r['record_updated'] ), 'ccs' );
				$r['record_link']	= $this->getRecordUrl( $r );
	
				$records[]						= $r;
				$memberIds[ $r['member_id'] ]	= $r['member_id'];
			}
			
			if( count($memberIds) )
			{
				$_members	= IPSMember::load( $memberIds );
				$_mems		= array();
				
				foreach( $_members as $k => $v )
				{
					foreach( $v as $_k => $_v )
					{
						if( strpos( $_k, 'field_' ) === 0 )
						{
							$_k	= str_replace( 'field_', 'user_field_', $_k );
						}
						
						$_mems[ $k ][ $_k ]	= $_v;
					}
				}
				
				$_members	= $_mems;
				
				foreach( $records as $key => $record )
				{
					$records[ $key ]	= array_merge( $record, IPSMember::buildDisplayData( $_members[ $record['member_id'] ] ) );
				}
			}
		}
		
		//-----------------------------------------
		// Hide fields
		//-----------------------------------------
		
		$showFields	= array();
		
		foreach( $this->fields as $field )
		{
			if( $field['field_display_listing'] )
			{
				$showFields[]	= $field;
			}
		}
		
		$specialFields	= $this->_getSpecialFields();

		$template	= 'template_' . $this->database['template_key'];
		$_content	.= $this->registry->output->getTemplate('ccs')->$template( array( 'database' => $this->database, 'fields' => $showFields, 'records' => $records, 'pages' => $pages, 'categories' => $categories, 'parent' => $category, 'show' => $_show, 'special' => $specialFields ) );
		
		return $_content;
	}
	
	/**
	 * Get the frontpage for the articles
	 *
	 * @access	protected
	 * @return	string		HTML
	 */
	protected function _getDatabaseFrontpage()
	{
		$this->checkPermalink( $this->database['base_link'] );
		
		//-----------------------------------------
		// Init
		//-----------------------------------------
		
		$_orderBy	= $this->caches['ccs_frontpage']['sort'];
		$_direction	= $this->caches['ccs_frontpage']['order'];
		$_limit		= array( 0, $this->caches['ccs_frontpage']['limit'] );
		$_numeric	= false;
		$_where		= '';

		foreach( $this->fields as $_field )
		{
			if( $_orderBy == 'field_' . $_field['field_id'] )
			{
				$_numeric	= $_field['field_is_numeric'];
			}
			
			if( $_field['field_key'] == 'article_homepage' )
			{
				$_where	= "field_{$_field['field_id']}=',1,'";
			}
		}
		
		//-----------------------------------------
		// Restrict to categories we can view
		//-----------------------------------------
		
		if( count($this->categories->categories) )
		{
			$_catIds	= array();
			
			foreach( $this->categories->categories as $_catId => $_cat )
			{
				$_catIds[]	= $_catId;
			}
			
			$_where		= $_where ? "category_id IN(" . implode( ',', $_catIds ) . ") AND (" . $_where . ")" : "category_id IN(" . implode( ',', $_catIds ) . ")";
		}
		
		$records	= array();
		$_memberIds	= array();

		//-----------------------------------------
		// Retrieve records
		//-----------------------------------------
		
		$this->DB->build( array( 'select' => '*', 'from' => $this->database['database_database'], 'order' => ( $_numeric ? $_orderBy . '+0' : $_orderBy ) . ' ' . $_direction, 'where' => $_where, 'limit' => $_limit ) );
		$outer	= $this->DB->execute();
		
		while( $r = $this->DB->fetch($outer) )
		{
			foreach( $r as $k => $v )
			{
				if( preg_match( "/^field_(\d+)$/", $k, $matches ) )
				{
					$r[ $k . '_value' ]	= $this->fieldsClass->getFieldValue( $this->fields[ $matches[1] ], $r, $this->fields[ $matches[1] ]['field_truncate'] );
				}
			}
			
			$r['category_name']	= $this->categories->categories[ $r['category_id'] ]['category_name'];
			$r['category_link']	= $this->categories->getCategoryUrl( $this->database['base_link'], $r['category_id'] );
			
			$r['_isRead']		= $this->registry->classItemMarking->isRead( array( 'catID' => $r['category_id'], 'itemID' => $r['primary_id_field'], 'itemLastUpdate' => $r['record_updated'] ), 'ccs' );
			$r['record_link']	= $this->getRecordUrl( $r );

			$records[]						= $r;
			$memberIds[ $r['member_id'] ]	= $r['member_id'];
		}

		//-----------------------------------------
		// Get the author data too
		//-----------------------------------------
		
		if( count($memberIds) )
		{
			$_members	= IPSMember::load( $memberIds );
			$_mems		= array();
			
			foreach( $_members as $k => $v )
			{
				foreach( $v as $_k => $_v )
				{
					if( strpos( $_k, 'field_' ) === 0 )
					{
						$_k	= str_replace( 'field_', 'user_field_', $_k );
					}
					
					$_mems[ $k ][ $_k ]	= $_v;
				}
			}
			
			$_members	= $_mems;
			
			foreach( $records as $key => $record )
			{
				$records[ $key ]	= array_merge( $record, IPSMember::buildDisplayData( $_members[ $record['member_id'] ] ) );
			}
		}
		
		$specialFields	= $this->_getSpecialFields();
		
		//-----------------------------------------
		// Hide fields
		//-----------------------------------------
		
		$showFields	= array();
		
		foreach( $this->fields as $field )
		{
			if( $field['field_display_display'] )
			{
				$showFields[]	= $field;
			}
		}
			
		//-----------------------------------------
		// Output
		//-----------------------------------------

		$this->registry->output->setTitle( $this->database['database_name'] );
		$this->pages->setCanonical( rtrim( $this->database['base_link'], '?' ) );
		
		$template	= 'template_' . $this->database['template_key'];
		$_content	.= $this->registry->output->getTemplate('ccs')->$template( array( 'database' => $this->database, 'fields' => $showFields, 'records' => $records, 'special' => $specialFields ) );
		
		return $_content;
	}
	
	/**
	 * Get the frontpage for the category
	 *
	 * @access	protected
	 * @return	string		HTML
	 */
	protected function _getCategoryFrontpage()
	{
		//-----------------------------------------
		// Category data
		//-----------------------------------------
		
		$category					= $this->categories->getCategory( $this->request['category'] );
		$category['category_link']	= $this->categories->getCategoryUrl( $this->database['base_link'], $category['category_id'] );
		
		$this->checkPermalink( $category['category_link'] );
		
		$this->pages->setMetaKeywords( $category['category_meta_keywords'] );
		$this->pages->setMetaDescription( $category['category_meta_description'] );
		$this->pages->setCanonical( $category['category_link'] );

		if( $this->request['category'] AND !$category['category_id'] )
		{
			$this->registry->output->showError( $this->lang->words['no_view_perm_cat'], '10CCS19' );
		}
		else if( $this->request['category'] )
		{
			if ( $category['category_has_perms'] AND $this->registry->permissions->check( 'add', $category ) != TRUE )
			{
				$this->database['_can_add']	= false;
			}
		}

		$this->_loadTemplates( 'category_frontpage', $category['category_template'] );

		//-----------------------------------------
		// Init
		//-----------------------------------------
		
		$_orderBy		= $this->caches['ccs_frontpage']['sort'];
		$_direction		= $this->caches['ccs_frontpage']['order'];
		$_limit			= array( 0, $this->caches['ccs_frontpage']['limit'] );
		$_numeric		= false;
		$specialFields	= $this->_getSpecialFields();
		
		if( self::AGGREGATE )
		{
			$_subCats	= $this->categories->getChildren( $category['category_id'] );
			$_subCats[]	= $category['category_id'];
			
			$_where		= "category_id IN(" . implode( ',', $_subCats ) . ")";
		}
		else
		{
			$_where		= 'category_id=' . $category['category_id'];
		}
		
		//-----------------------------------------
		// Limit by expiry date
		// category_id IN(9,10,8) AND (field_33=0 OR field_33 > 1266424982)
		//-----------------------------------------
		
		if( $specialFields['expiry'] )
		{
			$_where	.= " AND ({$specialFields['expiry']}=0 OR {$specialFields['expiry']} > " . time() . ")";
		}

		foreach( $this->fields as $_field )
		{
			if( $_orderBy == 'field_' . $_field['field_id'] )
			{
				$_numeric	= $_field['field_is_numeric'];
			}
		}
		
		$records	= array();
		$_memberIds	= array();

		//-----------------------------------------
		// Retrieve records
		//-----------------------------------------
		
		$this->DB->build( array( 'select' => '*', 'from' => $this->database['database_database'], 'order' => ( $_numeric ? $_orderBy . '+0' : $_orderBy ) . ' ' . $_direction, 'where' => $_where, 'limit' => $_limit ) );
		$outer	= $this->DB->execute();
		
		while( $r = $this->DB->fetch($outer) )
		{
			foreach( $r as $k => $v )
			{
				if( preg_match( "/^field_(\d+)$/", $k, $matches ) )
				{
					$r[ $k . '_value' ]	= $this->fieldsClass->getFieldValue( $this->fields[ $matches[1] ], $r, $this->fields[ $matches[1] ]['field_truncate'] );
				}
			}
			
			$r['category_name']	= $this->categories->categories[ $r['category_id'] ]['category_name'];
			$r['category_link']	= $this->categories->getCategoryUrl( $this->database['base_link'], $r['category_id'] );
			
			$r['_isRead']		= $this->registry->classItemMarking->isRead( array( 'catID' => $r['category_id'], 'itemID' => $r['primary_id_field'], 'itemLastUpdate' => $r['record_updated'] ), 'ccs' );
			$r['record_link']	= $this->getRecordUrl( $r );

			$records[]						= $r;
			$memberIds[ $r['member_id'] ]	= $r['member_id'];
		}

		//-----------------------------------------
		// Get the author data too
		//-----------------------------------------
		
		if( count($memberIds) )
		{
			$_members	= IPSMember::load( $memberIds );
			$_mems		= array();
			
			foreach( $_members as $k => $v )
			{
				foreach( $v as $_k => $_v )
				{
					if( strpos( $_k, 'field_' ) === 0 )
					{
						$_k	= str_replace( 'field_', 'user_field_', $_k );
					}
					
					$_mems[ $k ][ $_k ]	= $_v;
				}
			}
			
			$_members	= $_mems;
			
			foreach( $records as $key => $record )
			{
				$records[ $key ]	= array_merge( $record, IPSMember::buildDisplayData( $_members[ $record['member_id'] ] ) );
			}
		}

		//-----------------------------------------
		// Other schtuff (breadcrumbs/title)
		//-----------------------------------------

		if( count($categories) OR $this->request['category'] )
		{
			$crumbies	= $this->categories->getBreadcrumbs( $this->request['category'], $this->database['base_link'] );
	
			if( !$this->settings['use_friendly_urls'] AND !$this->settings['ccs_root_url'] )
			{
				array_unshift( $crumbies, array( 0 => $this->database['database_name'], 1 => substr( $this->database['base_link'], 0, -5 ) ) );
			}
			else
			{
				array_unshift( $crumbies, array( 0 => $this->database['database_name'], 1 => substr( $this->database['base_link'], 0, -1 ) ) );
			}
		}
		else if( !$this->request['category'] )
		{
			if( !$this->settings['use_friendly_urls'] AND !$this->settings['ccs_root_url'] )
			{
				$crumbies	= array( array( 0 => $this->database['database_name'], 1 => substr( $this->database['base_link'], 0, -5 ) ) );
			}
			else
			{
				$crumbies	= array( array( 0 => $this->database['database_name'], 1 => substr( $this->database['base_link'], 0, -1 ) ) );
			}
		}

		$this->pages->addNavigation( $this->registry->output->getTemplate('ccs_global')->databaseNavigation( $crumbies ) );
		
		define( 'CCS_NAV_DONE', true );
		
		if( $category['category_name'] )
		{
			$this->registry->output->setTitle( $category['category_name'] );
		}
		else
		{
			$this->registry->output->setTitle( $this->database['database_name'] );
		}
		
		//-----------------------------------------
		// Hide fields
		//-----------------------------------------
		
		$showFields	= array();
		
		foreach( $this->fields as $field )
		{
			if( $field['field_display_display'] )
			{
				$showFields[]	= $field;
			}
		}
		
		//-----------------------------------------
		// Output
		//-----------------------------------------

		$template	= 'template_' . $this->database['template_key'];
		$_content	.= $this->registry->output->getTemplate('ccs')->$template( array( 'database' => $this->database, 'fields' => $showFields, 'category' => $category, 'records' => $records, 'special' => $specialFields ) );
		
		return $_content;
	}
	
	/**
	 * Show a record.  Used this to get the special fields, then calls parent.
	 *
	 * @access	protected
	 * @return	string		HTML output
	 */
	protected function _getRecordDisplay()
	{
		//-----------------------------------------
		// Get record
		//-----------------------------------------
		
		$record	= $this->_getRecord();

		if( !$record['primary_id_field'] )
		{
			$this->registry->output->showError( $this->lang->words['couldnot_find_record'], '10CCS20' );
		}
		
		if( $record['category_id'] )
		{
			$category	= $this->categories->categories[ $record['category_id'] ];
			
			$category['category_link']	= $this->categories->getCategoryUrl( $this->database['base_link'], $category['category_id'] );
			
			if( !$category['category_id'] )
			{
				$this->registry->output->showError( $this->lang->words['couldnot_find_record'], '10CCS21' );
			}

			if ( $category['category_has_perms'] AND $this->registry->permissions->check( 'show', $category ) != TRUE )
			{
				$this->registry->output->showError( $this->lang->words['no_view_perm_rec'], '10CCS22' );
			}
			
			if ( $category['category_has_perms'] AND $this->registry->permissions->check( 'rate', $category ) != TRUE )
			{
				$this->database['_can_rate']	= false;
			}
			
			if ( $category['category_has_perms'] AND $this->registry->permissions->check( 'comment', $category ) != TRUE )
			{
				$this->database['_can_comment']	= false;
			}
		}
		
		$this->_loadTemplates( 'record', $record['record_template'] );
		
		//-----------------------------------------
		// Format fields
		//-----------------------------------------
		
		$specialFields	= $this->_getSpecialFields();
		
		foreach( $record as $k => $v )
		{
			if( preg_match( "/^field_(\d+)$/", $k, $matches ) )
			{
				$record[ $k . '_value' ]	= $this->fieldsClass->getFieldValue( $this->fields[ $matches[1] ], $record );
			}
		}
		
		$record	= $this->parseAttachments( $this->database, $this->fields, $record );
		
		$record['record_link']	= $this->getRecordUrl( $record, true );
		
		$this->checkPermalink( $record['record_link'] );
		
		//-----------------------------------------
		// Get member data
		//-----------------------------------------
		
		$member	= IPSMember::load( $record['member_id'] );

		$_mem	= array();
		
		if( count($member) AND is_array($member) )
		{
			foreach( $member as $k => $v )
			{
				if( strpos( $k, 'field_' ) === 0 )
				{
					$k	= str_replace( 'field_', 'user_field_', $k );
				}
				
				$_mem[ $k ]	= $v;
			}
		}
		
		$member	= $_mem;
		
		$record	= array_merge( $member ? $member : array( 'members_display_name' => $this->lang->words['global_guestname'] ), $record );
		
		//-----------------------------------------
		// User editable
		//-----------------------------------------
		
		if( $this->database['database_user_editable'] )
		{
			if ( $this->registry->permissions->check( 'edit', $this->database ) == TRUE )
			{
				if( $this->database['database_all_editable'] OR $record['member_id'] == $this->memberData['member_id'] OR $this->database['moderate_edit'] )
				{
					$this->database['_can_edit']		= true;
				}
			}
			
			if( $record['category_id'] )
			{
				if ( $category['category_has_perms'] AND $this->registry->permissions->check( 'edit', $category ) != TRUE )
				{
					$this->database['_can_edit']	= false;
				}
			}
			
			if( $this->database['moderate_edit'] )
			{
				$this->database['_can_edit']		= true;
			}
		}
		
		if( $record['record_locked'] AND !$this->database['moderate_edit'] )
		{
			$this->database['_can_edit']		= false;
		}
		
		//-----------------------------------------
		// Breadcrumbs
		//-----------------------------------------

		$crumbies	= $this->categories->getBreadcrumbs( $record['category_id'], $this->database['base_link'] );

		if( !$this->settings['use_friendly_urls'] AND !$this->settings['ccs_root_url'] )
		{
			array_unshift( $crumbies, array( 0 => $this->database['database_name'], 1 => substr( $this->database['base_link'], 0, -5 ) ) );
		}
		else
		{
			array_unshift( $crumbies, array( 0 => $this->database['database_name'], 1 => substr( $this->database['base_link'], 0, -1 ) ) );
		}

		array_push( $crumbies, array( 0 => $this->lang->words['navigation_prefix'] . $record[ $this->database['database_field_title'] . '_value' ], 1 => '' ) );
		
		$this->pages->addNavigation( $this->registry->output->getTemplate('ccs_global')->databaseNavigation( $crumbies ) );
		
		define( 'CCS_NAV_DONE', true );
		
		$this->registry->output->setTitle( $record[ $this->database['database_field_title'] . '_value' ] );
		
		//-----------------------------------------
		// Mark read
		//-----------------------------------------

		$this->registry->classItemMarking->markRead( array( 'catID' => $record['category_id'], 'itemID' => $record['primary_id_field'] ), 'ccs' );
		
		//-----------------------------------------
		// Meta tags
		//-----------------------------------------
		
		if( $record['record_meta_keywords'] )
		{
			$this->pages->setMetaKeywords( $record['record_meta_keywords'] );
		}
		else
		{
			$text	= $record[ $this->database['database_field_title'] . '_value' ];
			$text	.= "\n " . $record[ $this->database['database_field_content'] . '_value' ];
			
			//-----------------------------------------
			// Mostly copied from output class
			//-----------------------------------------
			
			$text = str_replace( array( '.', ',', '!', ':', ';', "'", "'", '@', '%', '*', '(', ')' ), '', preg_replace( "/&([^;]+?);/", "", strip_tags($text) ) );
			$_vals   = preg_split( "/\s+?/", $text, -1, PREG_SPLIT_NO_EMPTY );
			$_sw     = explode( ',', $this->lang->words['_stopwords_'] );
			$_fvals  = array();
			$_limit  = 30;
			$_c      = 0;
			
			if ( is_array( $_vals ) )
			{
				foreach( $_vals as $_v )
				{
					if ( strlen( $_v ) >= 3 AND ! in_array( $_v, array_values( $_fvals ) ) AND ! in_array( $_v, $_sw ) )
					{
						$_fvals[] = $_v;
					}
					
					if ( $_c >= $_limit )
					{
						break;
					}
					
					$_c++;
				}
			}

			$this->pages->setMetaKeywords( implode( ',', $_fvals ) );
		}
		
		if( $record['record_meta_description'] )
		{
			$this->pages->setMetaDescription( $record['record_meta_description'] );
		}
		else
		{
			$text	= $record[ $this->database['database_field_title'] . '_value' ];
			$text	.= "\n " . $record[ $this->database['database_field_content'] . '_value' ];
			
			$this->pages->setMetaDescription( IPSText::truncate( strip_tags($text), 247 ) );
		}
		
		$this->pages->setCanonical( $this->getRecordUrl( $record ) );
		
		/**
		 * @see	http://wiki.developers.facebook.com/index.php/Facebook_Share/Specifying_Meta_Tags
		 */
		if( $record[ $specialFields['image'] . '_value' ] )
		{
			$this->pages->setHeadLink( '<link rel="image_src" href="' . $record[ $specialFields['image'] . '_value' ] . '" / >' );
			$this->pages->setHeadLink( '<meta name="medium" content="news" />' );
		}
		
		//-----------------------------------------
		// Parse attachments, if promoted
		//-----------------------------------------
		
		$record[ $this->database['database_field_content'] . '_value' ]	= $this->_parsePromotedAttachments( $record[ $this->database['database_field_content'] . '_value' ] );

		//-----------------------------------------
		// Comments
		// Make sure article allows them too
		//-----------------------------------------
		
		$commentHtml	= '';

	    $forumIntegration	= $this->categories->categories[ $record['category_id'] ]['category_forum_override'] ? $this->categories->categories[ $record['category_id'] ]['category_forum_record'] : $this->database['database_forum_record'];
	    $commentsToo		= $this->categories->categories[ $record['category_id'] ]['category_forum_override'] ? $this->categories->categories[ $record['category_id'] ]['category_forum_comments'] : $this->database['database_forum_comments'];

	    if( $this->database['database_comments'] AND $record[ $specialFields['comments_allowed'] ] AND $forumIntegration AND $commentsToo )
	    {
			//-----------------------------------------
			// Post topic if configured to do so
			//-----------------------------------------

			require_once( IPSLib::getAppDir( 'ccs' ) . '/sources/databases/topics.php' );
			$_topics	= new topicsLibrary( $this->registry, $this->fieldsClass, $this->categories, $this->fields );
			$commentHtml	= $_topics->getComments( $record, $this->categories->categories[ $record['category_id'] ], $this->database, 'topicArticleComments' );
	    }
		else if( $this->database['database_comments'] AND $record[ $specialFields['comments_allowed'] ] )
		{
			$comments	= array();
			$perPage	= 30;
			$start		= intval($this->request['st']) > 0 ? intval($this->request['st']) : 0;
			$where		= $this->database['moderate_approvec'] ? '' : "comment_approved=1 AND ";
			$count		= $this->DB->buildAndFetch( array( 'select' => 'count(*) as total', 'from' => 'ccs_database_comments', 'where' => $where . "comment_database_id={$this->database['database_id']} AND comment_record_id={$record['primary_id_field']}" ) );
			
			$pages		= $this->registry->output->generatePagination( array( 
																	'totalItems'		=> $count['total'],
																	'itemsPerPage'		=> $perPage,
																	'currentStartValue'	=> $start,
																	'baseUrl'			=> $this->database['base_link'],
																	'base'				=> 'none',
											 				)	);

			//-----------------------------------------
			// Joins
			//-----------------------------------------
			
			$_post_joins = array(
								array(
										'type'		=> 'left',
										'select'	=> 'm.*',
										'where'		=> 'm.member_id=c.comment_user',
										'from'		=> array( 'members' => 'm' )
									),
								array(
										'type'		=> 'left',
										'select'	=> 'pp.*',
										'where'		=> 'pp.pp_member_id=m.member_id',
										'from'		=> array( 'profile_portal' => 'pp' )
									),
								array(
										'select'	=> 'pd.*',
										'from'		=> array( 'pfields_content' => 'pd' ),
										'where'		=> 'pd.member_id=m.member_id',
										'type'		=> 'left',
									),
								);
			
			//-----------------------------------------
			// Reputation system joins
			//-----------------------------------------
			
			if( $this->settings['reputation_enabled'] )
			{
				require_once( IPS_ROOT_PATH . 'sources/classes/class_reputation_cache.php' );
				$this->registry->setClass( 'repCache', new classReputationCache() );
			
				/* Add the join to figure out if the user has already rated the post */
				$_post_joins[] = $this->registry->repCache->getUserHasRatedJoin( 'comment_id', 'c.comment_id', 'ccs' );
				
				/* Add the join to figure out the total ratings for each post */
				if( $this->settings['reputation_show_content'] )
				{
					$_post_joins[] = $this->registry->repCache->getTotalRatingJoin( 'comment_id', 'c.comment_id', 'ccs' );
				}
			}

			if( $count['total'] )
			{
				$this->DB->build( array(
										'select'	=> 'c.*',
										'from'		=> array( 'ccs_database_comments' => 'c' ),
										'where'		=> ( $where ? "c." . $where : '' ) . "c.comment_database_id={$this->database['database_id']} AND c.comment_record_id={$record['primary_id_field']}",
										'order'		=> 'c.comment_date ASC',
										'limit'		=> array( $start, $perPage ),
										'add_join'	=> $_post_joins
								)		);
				$outer	= $this->DB->execute();
	
				IPSText::getTextClass( 'bbcode' )->parse_html		= 0;
				IPSText::getTextClass( 'bbcode' )->parse_smilies	= 1;
				IPSText::getTextClass( 'bbcode' )->parse_bbcode		= 1;
				IPSText::getTextClass( 'bbcode' )->parsing_section	= 'ccs_comment';
				
				while( $comment = $this->DB->fetch($outer) )
				{
					//-----------------------------------------
					// Basics
					//-----------------------------------------
	
					$comment	= IPSMember::buildDisplayData( $comment );
					
					IPSText::getTextClass( 'bbcode' )->parsing_mgroup			= $comment['member_group_id'];
					IPSText::getTextClass( 'bbcode' )->parsing_mgroup_others	= $comment['mgroup_others'];
					$comment['comment_post']	= IPSText::getTextClass( 'bbcode' )->preDisplayParse( $comment['comment_post'] );
					
					//-----------------------------------------
					// Reputation
					//-----------------------------------------
					
					if( $this->settings['reputation_enabled'] )
					{
						$comment['pp_reputation_points']	= $comment['pp_reputation_points'] ? $comment['pp_reputation_points'] : 0;
						$comment['has_given_rep']			= $comment['has_given_rep'] ? $comment['has_given_rep'] : 0;
						$comment['rep_points']				= $comment['rep_points'] ? $comment['rep_points'] : 0;
					}
					
					$comment['_repignored']	= 0;
	
					$this->memberData['_cache']['rep_filter'] = isset( $this->memberData['_cache']['rep_filter'] ) ? $this->memberData['_cache']['rep_filter'] : '*';
	
					if( $this->settings['reputation_enabled'] )
					{
						if( ! ( $this->settings['reputation_protected_groups'] && 
							    in_array( $comment['member_group_id'], explode( ',', $this->settings['reputation_protected_groups'] ) ) 
							   ) &&
						 	$this->memberData['_members_cache']['rep_filter'] !== '*' 
						)
						{
							if( $this->settings['reputation_show_content'] && $comment['rep_points'] < $this->memberData['_cache']['rep_filter'] )
							{
								$comment['_repignored'] = 1;
							}
						}
					}
					
					$_link	= $this->registry->getClass('output')->formatUrl( $this->registry->getClass('output')->buildUrl( "showuser={$comment['member_id']}", "public" ), $comment['members_seo_name'], "showuser" );
					$_temp	= $this->registry->getClass('output')->getTemplate('global')->user_popup( $comment['member_id'], $comment['members_seo_name'] );
					
					$comment['author_link']	= "<a href='{$_link}'>{$comment['members_display_name']}</a> {$_temp}";
				
					//-----------------------------------------
					// Store
					//-----------------------------------------
					
					$comments[]	= $comment;
				}
			}
			
			$this->lang->loadLanguageFile( array( 'public_editors' ), 'core' );
			
			$commentHtml	= $this->registry->output->getTemplate('ccs_global')->article_comments( $this->database, $record, $comments, $pages );
		}
		
		//-----------------------------------------
		// Get contributer/revision data
		//-----------------------------------------
		
		$record['contributers']		= array();
		
		if( $this->database['database_revisions'] )
		{
			$contributors	= array();
			$contributions	= array();
			
			$this->DB->build( array( 'select' => 'revision_date, revision_member_id', 'from' => 'ccs_database_revisions', 'where' => 'revision_database_id=' . $this->database['database_id'] . ' AND revision_record_id=' . $record['primary_id_field'] . ' AND revision_member_id <> ' . $record['member_id'] ) );
			$this->DB->execute();
			
			while( $r = $this->DB->fetch() )
			{
				$contributions[ $r['revision_member_id'] ]	= ( isset($contributions[ $r['revision_member_id'] ]) AND $contributions[ $r['revision_member_id'] ] > $r['revision_date'] ) ? $contributions[ $r['revision_member_id'] ] : $r['revision_date'];
				$contributors[ $r['revision_member_id'] ]	= $r['revision_member_id'];
			}
			
			if( count($contributors) )
			{
				$members	= IPSMember::load( $contributors );
				
				foreach( $contributions as $mid => $date )
				{
					$member	= IPSMember::buildDisplayData( $members[ $mid ] );
					
					$contributions[ $mid ]	= array( 'date' => $date, 'member' => $member );
				}
			}
			
			$record['contributers']	= $contributions;
		}

		//-----------------------------------------
		// Update views count
		//-----------------------------------------
		
		$this->DB->update( $this->database['database_database'], "record_views=record_views+1", "primary_id_field={$record['primary_id_field']}", true, true );
		
		//-----------------------------------------
		// Hide fields
		//-----------------------------------------
		
		$showFields	= array();
		
		foreach( $this->fields as $field )
		{
			if( $field['field_display_display'] )
			{
				$showFields[]	= $field;
			}
		}
		
		//-----------------------------------------
		// Output
		//-----------------------------------------

		$template	= 'template_' . $this->database['template_key'];
		$_content	.= $this->registry->output->getTemplate('ccs')->$template( array( 'database' => $this->database, 'fields' => $showFields, 'record' => $record, 'comments' => $commentHtml, 'special' => $specialFields, 'category' => $category ) );
		
		return $_content;
	}


	/**
	 * Save comment to a record.  
	 * Verify article allows comments and that cutoff hasn't passed.
	 *
	 * @access	protected
	 * @return	mixed		void (output an error) or HTML to print
	 */
	protected function _actionComment()
	{
		//-----------------------------------------
		// Get record
		//-----------------------------------------
		
		if( !$this->request['record_id'] )
		{
			$this->registry->output->showError( 'couldnot_comment_record', '10CCS23' );
		}
		
		$_approved	= !$this->database['moderate_approve'] ? "record_approved=1 AND " : '';
		
		$record	= $this->DB->buildAndFetch( array( 'select' => '*', 'from' => $this->database['database_database'], 'where' => $_approved . 'primary_id_field=' . intval($this->request['record_id']) ) );

		foreach( $record as $k => $v )
		{
			if( preg_match( "/^field_(\d+)$/", $k, $matches ) )
			{
				$record[ $k . '_value' ]	= $this->fieldsClass->getFieldValue( $this->fields[ $matches[1] ], $record );
			}
		}

		//-----------------------------------------
		// Store so we don't have to requery
		//-----------------------------------------
		
		$this->_record	= $record;
		
		//-----------------------------------------
		// Verify comments allowed, and not past cutoff
		//-----------------------------------------
		
		$specialFields	= $this->_getSpecialFields();
		
		if( !$record[ $specialFields['comments_allowed'] ] )
		{
			$this->registry->output->showError( $this->lang->words['comment__notallowed'], '10CCS24' );
		}
		
		if( $record[ $specialFields['comments_cutoff'] ] AND time() > $record[ $specialFields['comments_cutoff'] ] )
		{
			$this->registry->output->showError( $this->lang->words['comment__pastcutoff'], '10CCS25' );
		}
		
		return parent::_actionComment();
	}
	
	/**
	 * Load the database
	 *
	 * @access	protected
	 * @return	array 		Database info
	 */
	protected function _loadArticlesDatabase()
	{
		$database	= array();
		
		if( count($this->caches['ccs_databases']) AND is_array($this->caches['ccs_databases']) )
		{
			foreach( $this->caches['ccs_databases'] as $dbid => $_database )
			{
				if( $_database['database_is_articles'] )
				{
					$database	= $_database;
				}
			}
		}
		
		//-----------------------------------------
		// Store globally for item marking lib
		//-----------------------------------------
		
		if( $database['database_id'] )
		{
			$this->settings['_currentDatabaseId']	= $database['database_id'];
		}
		
		return $database;
	}
	
	/**
	 * Load the appropriate template data
	 *
	 * @access	protected
	 * @param	string		Override to a specific template type
	 * @param	int			Specific template ID to use
	 * @return	void
	 */
	protected function _loadTemplates( $override='', $templateId=0 )
	{
		//-----------------------------------------
		// Which template we loading?
		//-----------------------------------------

		$templateId		= intval($templateId);
		$templateType	= $override;
		
		if( $this->request['record'] )
		{
			$templateType	= 'record';
		}
		else if( $this->request['view'] == 'archive' )
		{
			$templateType	= 'listing';
		}
		else if( $this->request['category'] )
		{
			$templateType	= 'category_frontpage';
		}
		else if( $this->request['view'] == 'categories' )
		{
			$templateType	= 'categories';
		}
		else if( !$override )
		{
			$templateType	= 'frontpage';
		}

		//-----------------------------------------
		// Get it
		//-----------------------------------------

		switch( $templateType )
		{
			case 'record':
				$template	= $this->DB->buildAndFetch( array( 'select' => '*', 'from' => 'ccs_page_templates', 'where' => "template_id=" . ( $templateId ? $templateId : $this->database['database_template_display'] ) ) );
			break;
			
			case 'category_frontpage':
				$template	= $this->DB->buildAndFetch( array( 'select' => '*', 'from' => 'ccs_page_templates', 'where' => "template_id=" . $templateId ) );
			break;
			
			case 'categories':
				$template	= $this->DB->buildAndFetch( array( 'select' => '*', 'from' => 'ccs_page_templates', 'where' => "template_id=" . $this->database['database_template_categories'] ) );
			break;
			
			case 'listing':
			case 'category':
				$template	= $this->DB->buildAndFetch( array( 'select' => '*', 'from' => 'ccs_page_templates', 'where' => "template_id=" . $this->database['database_template_listing'] ) );
			break;
			
			case 'frontpage':
				$template	= $this->DB->buildAndFetch( array( 'select' => '*', 'from' => 'ccs_page_templates', 'where' => "template_id=" . $this->caches['ccs_frontpage']['template'] ) );
			break;
		}

		//-----------------------------------------
		// Merge into database data and return
		//-----------------------------------------

		$this->database	= array_merge( $this->database, $template );
	}
	
	/**
	 * Get special field mappings (based on field_key)
	 *
	 * @access	protected
	 * @return	array
	 */
	protected function _getSpecialFields()
	{
		$specialFields	= array(
								'title'					=> '',
								'content'				=> '',
								'frontpage'				=> '',
								'date'					=> '',
								'expiry'				=> '',
								'comments_allowed'		=> '',
								'comments_cutoff'		=> '',
								'image'					=> '',
								);

		foreach( $this->fields as $_field )
		{
			switch( $_field['field_key'] )
			{
				case 'article_title':
					$specialFields['title']				= 'field_' . $_field['field_id'];
				break;

				case 'article_body':
					$specialFields['content']			= 'field_' . $_field['field_id'];
				break;

				case 'article_image':
					$specialFields['image']				= 'field_' . $_field['field_id'];
				break;
				
				case 'article_homepage':
					$specialFields['frontpage']			= 'field_' . $_field['field_id'];
				break;
				
				case 'article_date':
					$specialFields['date']				= 'field_' . $_field['field_id'];
				break;
				
				case 'article_expiry':
					$specialFields['expiry']			= 'field_' . $_field['field_id'];
				break;
				
				case 'article_comments':
					$specialFields['comments_allowed']	= 'field_' . $_field['field_id'];
				break;
				
				case 'article_cutoff':
					$specialFields['comments_cutoff']	= 'field_' . $_field['field_id'];
				break;
			}
		}

		return $specialFields;
	}

	/**
	 * Attempt to parse attachments from a promoted post...
	 *
	 * @access	protected
	 * @param	string		Content
	 * @return	string		Content (with attachments parsed)
	 */
	protected function _parsePromotedAttachments( $content )
	{
		//-----------------------------------------
		// Only bother if there is an attachment tag
		//-----------------------------------------
		
		if( strpos( $content, '[attachment=' ) !== false )
		{
			preg_match( "/\[attachment=(\d+):.*?\]/i", $content, $matches );
			
			if( $matches[1] )
			{
				$_attach	= $this->DB->buildAndFetch( array( 'select' => 'attach_rel_id', 'from' => 'attachments', 'where' => 'attach_id=' . intval($matches[1]) ) );
				
				if( $_attach['attach_rel_id'] )
				{
					$this->lang->loadLanguageFile( array( 'public_topic' ), 'forums' );
					
					$classToLoad	= IPSLib::loadLibrary( IPSLib::getAppDir( 'core' ) . '/sources/classes/attach/class_attach.php', 'class_attach' );
					$_attachments   =  new $classToLoad( $this->registry );
					
					$_attachments->type		= 'post';
					$_attachments->init();

					$attachHTML = $_attachments->renderAttachments( $content, array( $_attach['attach_rel_id'] ) );
			
					/* Now parse back in the rendered posts */
					if( is_array($attachHTML) AND count($attachHTML) )
					{
						foreach( $attachHTML as $id => $data )
						{
							/* Get rid of any lingering attachment tags */
							if ( stristr( $data['html'], "[attachment=" ) )
							{
								$data['html'] = IPSText::stripAttachTag( $data['html'] );
							}
							
							if( $data['html'] )
							{
								$content		= $data['html'];
							}
							
							$content		.= $data['attachmentHtml'];
						}
					}
				}
			}
		}
		
		return $content;
	}
}