<?php
/**
 * Database feed blocks
 *
 * @author 		$author$
 * @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
 * @version		$Rev: 102 $ 
 * @since		1st March 2009
 **/

class feed_databases implements feedBlockInterface
{
	/**#@+
	 * Registry Object Shortcuts
	 *
	 * @access	protected
	 * @var		object
	 */
	protected $DB;
	protected $settings;
	protected $lang;
	protected $member;
	protected $memberData;
	protected $cache;
	protected $registry;
	protected $caches;
	protected $request;
	/**#@-*/
	
	/**
	 * Constructor
	 *
	 * @access	public
	 * @param	object		Registry reference
	 * @return	void
	 */
	public function __construct( ipsRegistry $registry )
	{
		//-----------------------------------------
		// Make shortcuts
		//-----------------------------------------
		
		$this->registry		= $registry;
		$this->DB			= $registry->DB();
		$this->settings		= $registry->fetchSettings();
		$this->member		= $registry->member();
		$this->memberData	=& $this->registry->member()->fetchMemberData();
		$this->cache		= $registry->cache();
		$this->caches		=& $registry->cache()->fetchCaches();
		$this->request		= $registry->fetchRequest();
		$this->lang 		= $registry->class_localization;
		
		if ( !array_key_exists( 'ccs_databases', $this->caches ) )
		{
			$this->caches['ccs_databases']	= $this->cache->getCache('ccs_databases');
		}
		
		if ( !array_key_exists( 'ccs_fields', $this->caches ) )
		{
			$this->caches['ccs_fields']		= $this->cache->getCache('ccs_fields');
		}
		
		if( !$registry->isClassLoaded( 'ccsFunctions' ) )
		{
			require_once( IPSLib::getAppDir('ccs') . '/sources/functions.php' );
			$registry->setClass( 'ccsFunctions', new ccsFunctions( $registry ) );
		}
	}
	
	/**
	 * Return the plugin meta data
	 *
	 * @access	public
	 * @return	array 			Plugin data (key (folder name), associated app, name, description, hasFilters, templateBit)
	 */
	public function returnFeedInfo()
	{
		$count	= count($this->caches['ccs_databases']);
		
		if( !$count )
		{
			return array();
		}
		
		return array(
					'key'			=> 'databases',
					'app'			=> 'ccs',
					'name'			=> $this->lang->words['feed_name__databases'],
					'description'	=> $this->lang->words['feed_description__databases'],
					'hasFilters'	=> true,
					'templateBit'	=> 'feed__generic'
					);
	}
	
	/**
	 * Get the feed's available content types.  Returns form elements and data
	 *
	 * @access	public
	 * @param	array 			Session data
	 * @return	array 			Form data
	 */
	public function returnContentTypes( $session )
	{
		$options	= array();

		if( count($this->caches['ccs_databases']) AND is_array($this->caches['ccs_databases']) )
		{
			foreach( $this->caches['ccs_databases'] as $database_id => $database )
			{
				if( $database['database_is_articles'] )
				{
					continue;
				}

				$options[]		= array( $database_id, $database['database_name'] );
			}
		}
		
		$_database	= explode( ';', $session['config_data']['content_type']	);
		
		return array(
					array(
						'label'			=> $this->lang->words['generic__select_db'],
						'description'	=> $this->lang->words['generic__desc_db'],
						'field'			=> $this->registry->output->formDropdown( 'content_type', $options, $_database[0] ),
						),
					array(
						'label'			=> $this->lang->words['feed_db__type'],
						'description'	=> $this->lang->words['feed_db__type_db'],
						'field'			=> $this->registry->output->formDropdown( 'content_type_2', array( array( 'db', $this->lang->words['feed_db__db'] ), array( 'categories', $this->lang->words['feed_db__categories'] ), array( 'comments', $this->lang->words['feed_db__comments'] ) ), $_database[1] ),
						),
					);
	}
	
	/**
	 * Check the feed content type selection
	 *
	 * @access	public
	 * @param	array 			Submitted data to check (usually $this->request)
	 * @return	array 			Array( (bool) Ok or not, (array) Content type data to use )
	 */
	public function checkFeedContentTypes( $data )
	{
		$types	= array();

		if( count($this->caches['ccs_databases']) AND is_array($this->caches['ccs_databases']) )
		{
			foreach( $this->caches['ccs_databases'] as $database_id => $database )
			{
				$types[]		= $database_id;
			}
		}
		
		$return	= true;
		
		if( !in_array( $data['content_type'], $types ) )
		{
			$return	= false;
		}
		
		if( $data['content_type_2'] )
		{
			$data['content_type']	= $data['content_type'] . ';' . $data['content_type_2'];
		}

		return array( $return, $data['content_type'] );
	}
	
	/**
	 * Get the feed's available filter options.  Returns form elements and data
	 *
	 * @access	public
	 * @param	array 			Session data
	 * @return	array 			Form data
	 */
	public function returnFilters( $session )
	{
		$filters	= array();

		$session['config_data']['filters']['filter_status']		= $session['config_data']['filters']['filter_status'] ? $session['config_data']['filters']['filter_status'] : 'either';
		$session['config_data']['filters']['filter_visibility']	= $session['config_data']['filters']['filter_visibility'] ? $session['config_data']['filters']['filter_visibility'] : 'approved';
		$session['config_data']['filters']['filter_pinned']		= $session['config_data']['filters']['filter_pinned'] ? $session['config_data']['filters']['filter_pinned'] : 'either';
		$session['config_data']['filters']['filter_starter']	= $session['config_data']['filters']['filter_starter'] ? $session['config_data']['filters']['filter_starter'] : '';
		$session['config_data']['filters']['filter_rating']		= $session['config_data']['filters']['filter_rating'] ? $session['config_data']['filters']['filter_rating'] : 0;
		$session['config_data']['filters']['filter_category']	= $session['config_data']['filters']['filter_category'] ? explode( ',', $session['config_data']['filters']['filter_category'] ) : array();
		
		$_database	= explode( ';', $session['config_data']['content_type'] );
		
		//-----------------------------------------
		// Category filter
		//-----------------------------------------
		
		$_cats	= $this->registry->ccsFunctions->getCategoriesClass( $this->caches['ccs_databases'][ $_database[0] ] );

		$filters[]	= array(
							'label'			=> $this->lang->words['feed_db__cat'],
							'description'	=> $_database[1] != 'comments' ? $this->lang->words['feed_db__cat_desc'] : $this->lang->words['feed_dbc__cat_desc'],
							'field'			=> "<select name='filter_category[]' class='dropdown' multiple='multiple' size='5'>" . $_cats->getSelectMenu() . "</select>",
							);

		if( $_database[1] == 'db' OR !$_database[1] )
		{
			$status		= array( array( 'open', $this->lang->words['status__open'] ), array( 'closed', $this->lang->words['status__closed'] ), array( 'either', $this->lang->words['status__either'] ) );
			$filters[]	= array(
								'label'			=> $this->lang->words['feed_db__status'],
								'description'	=> $this->lang->words['feed_db__status_desc'],
								'field'			=> $this->registry->output->formDropdown( 'filter_status', $status, $session['config_data']['filters']['filter_status'] ),
								);

			$visibility	= array( array( 'approved', $this->lang->words['approved__yes'] ), array( 'unapproved', $this->lang->words['approved__no'] ), array( 'either', $this->lang->words['approved__either'] ) );
			$filters[]	= array(
								'label'			=> $this->lang->words['feed_db__visibility'],
								'description'	=> $this->lang->words['feed_db__visibility_desc'],
								'field'			=> $this->registry->output->formDropdown( 'filter_visibility', $visibility, $session['config_data']['filters']['filter_visibility'] ),
								);
	
			$pinned		= array( array( 'pinned', $this->lang->words['pinned__yes'] ), array( 'unpinned', $this->lang->words['pinned__no'] ), array( 'either', $this->lang->words['pinned__either'] ) );
			$filters[]	= array(
								'label'			=> $this->lang->words['feed_db__pinned'],
								'description'	=> '',
								'field'			=> $this->registry->output->formDropdown( 'filter_pinned', $pinned, $session['config_data']['filters']['filter_pinned'] ),
								);
	
			$filters[]	= array(
								'label'			=> $this->lang->words['feed_db__starter'],
								'description'	=> $this->lang->words['feed_db__starter_desc'],
								'field'			=> $this->registry->output->formInput( 'filter_starter', $session['config_data']['filters']['filter_starter'] ),
								);
	
			$filters[]	= array(
								'label'			=> $this->lang->words['feed_db__rating'],
								'description'	=> $this->lang->words['feed_db__rating_desc'],
								'field'			=> $this->registry->output->formInput( 'filter_rating', $session['config_data']['filters']['filter_rating'] ),
								);

			//-----------------------------------------
			// Allow to filter based on custom fields
			// (Yes, let the fun begin...sigh)
			//-----------------------------------------

			$fieldsClass	= $this->registry->ccsFunctions->getFieldsClass();
	
			$fields			= array();
			$_fieldOptions	= array();

			if( is_array($this->caches['ccs_fields'][ $_database[0] ]) AND count($this->caches['ccs_fields'][ $_database[0] ]) )
			{
				foreach( $this->caches['ccs_fields'][ $_database[0] ] as $_field )
				{
					$fields[ $_field['field_id'] ]	= $_field;
					
					if( !in_array( $_field['field_type'], array( 'input', 'textarea', 'radio', 'select', 'editor' ) ) )
					{
						continue;
					}
					
					$_fieldOptions[]	= array( $_field['field_id'], $_field['field_name'] );
				}
			}

			for( $j=1; $j < 6; $j++ )
			{
				$filters[]	= array(
									'label'			=> sprintf( $this->lang->words['feed_db__custom'], $j ),
									'description'	=> $this->lang->words['feed_db__custom_desc'],
									'field'			=> $this->registry->output->formDropdown( 'filter_ct_' . $j, $_fieldOptions, $session['config_data']['filters']['filter_ct_' . $j ] ) . ' ' . $this->registry->output->formInput( 'filter_cv_' . $j, $session['config_data']['filters']['filter_cv_' . $j ] ),
									);
			}
		}
		else if( $_database[1] == 'categories' )
		{
			return array();
		}
		else if( $_database[1] == 'comments' )
		{
			$visibility	= array( array( 'approved', $this->lang->words['approved__yes'] ), array( 'unapproved', $this->lang->words['approved__no'] ), array( 'either', $this->lang->words['approved__either'] ) );
			$filters[]	= array(
								'label'			=> $this->lang->words['feed_dbc__visibility'],
								'description'	=> $this->lang->words['feed_dbc__visibility_desc'],
								'field'			=> $this->registry->output->formDropdown( 'filter_visibility', $visibility, $session['config_data']['filters']['filter_visibility'] ),
								);

			$filters[]	= array(
								'label'			=> $this->lang->words['feed_dbc__starter'],
								'description'	=> $this->lang->words['feed_dbc__starter_desc'],
								'field'			=> $this->registry->output->formInput( 'filter_starter', $session['config_data']['filters']['filter_starter'] ),
								);
		}

		return $filters;
	}
	
	/**
	 * Check the feed filters selection
	 *
	 * @access	public
	 * @param	array 			Session data
	 * @param	array 			Submitted data to check (usually $this->request)
	 * @return	array 			Array( (bool) Ok or not, (array) Content type data to use )
	 */
	public function checkFeedFilters( $session, $data )
	{
		//-----------------------------------------
		// Filters are same for records and comments,
		// they're just labeled different on the form
		//-----------------------------------------
		
		$filters	= array();

		$filters['filter_status']		= $data['filter_status'] ? $data['filter_status'] : 'either';
		$filters['filter_visibility']	= $data['filter_visibility'] ? $data['filter_visibility'] : 'approved';
		$filters['filter_pinned']		= $data['filter_pinned'] ? $data['filter_pinned'] : 'either';
		$filters['filter_starter']		= $data['filter_starter'] ? $data['filter_starter'] : '';
		$filters['filter_rating']		= $data['filter_rating'] ? $data['filter_rating'] : 0;
		$filters['filter_category']		= ( is_array($data['filter_category']) AND count($data['filter_category']) ) ? implode( ',', $data['filter_category'] ) : 0;

		for( $j=1; $j < 6; $j++ )
		{
			$filters['filter_ct_' . $j ]	= ( $data['filter_ct_' . $j ] AND $data['filter_cv_' . $j ] ) ? $data['filter_ct_' . $j ] : '';
			$filters['filter_cv_' . $j ]	= $data['filter_cv_' . $j ] ? $data['filter_cv_' . $j ] : '';
		}

		return array( true, $filters );
	}
	
	/**
	 * Get the feed's available ordering options.  Returns form elements and data
	 *
	 * @access	public
	 * @param	array 			Session data
	 * @return	array 			Form data
	 */
	public function returnOrdering( $session )
	{
		$_database								= explode( ';', $session['config_data']['content_type'] );
		
		$session['config_data']['sortorder']	= $session['config_data']['sortorder'] ? $session['config_data']['sortorder'] : 'desc';
		$session['config_data']['offset_start']	= $session['config_data']['offset_start'] ? $session['config_data']['offset_start'] : 0;
		$session['config_data']['offset_end']	= $session['config_data']['offset_end'] ? $session['config_data']['offset_end'] : 10;
		$session['config_data']['sortby']		= $session['config_data']['sortby'] ? $session['config_data']['sortby'] : 'record_saved';

		$filters	= array();
		
		if( $_database[1] == 'comments' )
		{
			$fields		= array(  
								array( 
									'special_key'	=> 'comment_user',
									'field_name'	=> $this->lang->words['field__member'],
									), 
								array( 
									'special_key'	=> 'comment_date',
									'field_name'	=> $this->lang->words['field__saved'],
									),
								);
		}
		else if( $_database[1] == 'categories' )
		{
			return array();
		}
		else
		{
			$fields		= array( 
								array( 
									'special_key'	=> 'primary_id_field',
									'field_name'	=> $this->lang->words['field__id'],
									), 
								array( 
									'special_key'	=> 'member_id',
									'field_name'	=> $this->lang->words['field__member'],
									), 
								array( 
									'special_key'	=> 'record_saved',
									'field_name'	=> $this->lang->words['field__saved'],
									), 
								array( 
									'special_key'	=> 'record_updated',
									'field_name'	=> $this->lang->words['field__updated'],
									), 
								array( 
									'special_key'	=> 'record_approved',
									'field_name'	=> $this->lang->words['field__approved'],
									), 
								array( 
									'special_key'	=> 'record_locked',
									'field_name'	=> $this->lang->words['field__locked'],
									), 
								array( 
									'special_key'	=> 'record_comments',
									'field_name'	=> $this->lang->words['field__comments'],
									),
								array( 
									'special_key'	=> 'rating_real',
									'field_name'	=> $this->lang->words['field__rating'],
									), 
								array( 
									'special_key'	=> 'record_views',
									'field_name'	=> $this->lang->words['field__views'],
									), 
								);
		}
	
		$sortby	= array();
		
		foreach( $fields as $_field )
		{
			$sortby[]	= array( $_field['special_key'], $_field['field_name'] );
		}
		
		$_database	= explode( ';', $session['config_data']['content_type'] );
		
		if( is_array($this->caches['ccs_fields'][ $_database[0] ]) AND count($this->caches['ccs_fields'][ $_database[0] ]) )
		{
			foreach( $this->caches['ccs_fields'][ $_database[0] ] as $_field )
			{
				$sortby[]	= array( 'field_' . $_field['field_id'], $_field['field_name'] );
			}
		}
		
		$sortby[]	= array( 'RAND()', $this->lang->words['sort_generic__rand'] );

		$filters[]	= array(
							'label'			=> $this->lang->words['feed_sort_by'],
							'description'	=> $this->lang->words['feed_sort_by_desc'],
							'field'			=> $this->registry->output->formDropdown( 'sortby', $sortby, $session['config_data']['sortby'] ),
							);
		
		$filters[]	= array(
							'label'			=> $this->lang->words['feed_order_direction'],
							'description'	=> $this->lang->words['feed_order_direction_desc'],
							'field'			=> $this->registry->output->formDropdown( 'sortorder', array( array( 'desc', 'DESC' ), array( 'asc', 'ASC' ) ), $session['config_data']['sortorder'] ),
							);

		$filters[]	= array(
							'label'			=> $this->lang->words['feed_limit_offset_start'],
							'description'	=> $this->lang->words['feed_limit_offset_start_desc'],
							'field'			=> $this->registry->output->formInput( 'offset_start', $session['config_data']['offset_start'] ),
							);

		$filters[]	= array(
							'label'			=> $this->lang->words['feed_limit_offset_end'],
							'description'	=> $this->lang->words['feed_limit_offset_end_desc'],
							'field'			=> $this->registry->output->formInput( 'offset_end', $session['config_data']['offset_end'] ),
							);
		
		return $filters;
	}
	
	/**
	 * Check the feed ordering options
	 *
	 * @access	public
	 * @param	array 			Submitted data to check (usually $this->request)
	 * @return	array 			Array( (bool) Ok or not, (array) Ordering data to use )
	 */
	public function checkFeedOrdering( $data )
	{
		$limits		= array();

		$limits['sortby']			= $data['sortby'];
		$limits['sortorder']		= in_array( $data['sortorder'], array( 'desc', 'asc' ) ) ? $data['sortorder'] : 'desc';
		$limits['offset_start']		= intval($data['offset_start']);
		$limits['offset_end']		= intval($data['offset_end']);

		return array( true, $limits );
	}
	
	/**
	 * Modify the template
	 *
	 * @access	public
	 * @param	array 			Feed configuration
	 * @param	string			Template HTML
	 * @return	string			Template HTML
	 */
	public function modifyTemplate( $config, $template )
	{
		if( $config['config_data']['block_id'] )
		{
			return $template;
		}
		
		$_database	= explode( ';', $config['config_data']['content_type'] );

		if( $_database[1] == 'categories' )
		{
			$_template	= $this->DB->buildAndFetch( array( 'select' => '*', 'from' => 'ccs_template_blocks', 'where' => "tpb_name='feed__database_categories'" ) );
			
			if( $_template['tpb_content'] )
			{
				return $_template['tpb_content'];
			}
		}
		//else
		//{
		//	return str_replace( '<span class=\'desctext\'>{IPSText::truncate( strip_tags($r[\'content\']), 32 )}</span>', '', $template );
		//}
		
		return $template;
	}
	
	/**
	 * Execute the feed and return the HTML to show on the page.  
	 * Can be called from ACP or front end, so the plugin needs to setup any appropriate lang files, skin files, etc.
	 *
	 * @access	public
	 * @param	array 				Block data
	 * @return	string				Block HTML to display or cache
	 */
	public function executeFeed( $block )
	{
		$this->lang->loadLanguageFile( array( 'public_ccs' ), 'ccs' );
		
		$config		= unserialize( $block['block_config'] );
		$where		= array();
		$_database	= explode( ';', $config['content'] );
		
		//-----------------------------------------
		// Fix language strings
		//-----------------------------------------
		
		$this->registry->ccsFunctions->fixStrings( $_database[0] );

		if( $_database[1] == 'comments' )
		{
			return $this->_getComments( $block, $config, $_database );
		}
		else if( $_database[1] == 'categories' )
		{
			return $this->_getCategories( $block, $config, $_database );
		}
		else
		{
			return $this->_getRecords( $block, $config, $_database );
		}
	}
	
	/**
	 * Get the categories
	 *
	 * @access	protected
	 * @param	array 		Block config
	 * @param	array 		Config data for this feed
	 * @param	array 		Database info
	 * @return	string		Output HTML
	 */
	protected function _getCategories( $block, $config, $_database )
	{
		//-----------------------------------------
		// Get DB
		//-----------------------------------------
		
		$database	= $this->caches['ccs_databases'][ $_database[0] ];

		//-----------------------------------------
		// Now get categories....
		//-----------------------------------------
		
		$records	= $this->registry->ccsFunctions->getCategoriesClass( $database )->getCategoriesWithDepth();

		//-----------------------------------------
		// Return formatted content
		//-----------------------------------------
		
		$feedConfig		= $this->returnFeedInfo();
		$templateBit	= $feedConfig['templateBit'] . '_' . $block['block_id'];

		if( $config['hide_empty'] AND !count($records) )
		{
			return '';
		}

		$return	= $this->registry->output->getTemplate('ccs')->$templateBit( $block['block_name'], $records );

		return $return;
	}
	
	/**
	 * Return the records for database feed
	 *
	 * @access	protected
	 * @param	array 		Block config
	 * @param	array 		Config data for this feed
	 * @param	array 		Database info
	 * @return	string		Output HTML
	 */
	protected function _getRecords( $block, $config, $_database )
	{
		//-----------------------------------------
		// Set up filtering clauses
		//-----------------------------------------

		$where		= array();
		
		if( $config['filters']['filter_status'] != 'either' )
		{
			$where[]	= "p.record_locked=" . ( $config['filters']['filter_status'] == 'open' ? 0 : 1 );
		}
		
		if( $config['filters']['filter_visibility'] != 'either' )
		{
			$where[]	= "p.record_approved=" . ( $config['filters']['filter_visibility'] == 'approved' ? 1 : 0 );
		}

		if( $config['filters']['filter_pinned'] != 'either' )
		{
			$where[]	= "p.record_pinned=" . ( $config['filters']['filter_pinned'] == 'pinned' ? 1 : 0 );
		}
		
		if( $config['filters']['filter_category'] )
		{
			$where[]	= "p.category_id IN(" . $config['filters']['filter_category'] . ")";
		}

		if( $config['filters']['filter_starter'] == 'myself' )
		{
			$where[]	= "p.member_id = " . $this->memberData['member_id'];
		}
		else if( $config['filters']['filter_starter'] == 'friends' )
		{
			//-----------------------------------------
			// Get page builder for friends
			//-----------------------------------------
			
			require_once( IPSLib::getAppDir('ccs') . '/sources/pages.php' );
			$pageBuilder	= new pageBuilder( $this->registry );
			$friends		= $pageBuilder->getFriends();
			
			if( count($friends) )
			{
				$where[]	= "p.member_id IN( " . implode( ',', $friends ) . ")";
			}
			else
			{
				return '';
			}
		}
		else if( $config['filters']['filter_starter'] != '' )
		{
			$member	= IPSMember::load( $config['filters']['filter_starter'], 'basic', 'displayname' );
			
			if( $member['member_id'] )
			{
				$where[]	= "p.member_id = " . $member['member_id'];
			}
			else
			{
				return '';
			}
		}
		
		if( $config['filters']['filter_rating'] )
		{
			$where[]	= "p.rating_real >= " . $config['filters']['filter_rating'];
		}
		
		//-----------------------------------------
		// Get DB
		//-----------------------------------------
		
		$database	= $this->caches['ccs_databases'][ $_database[0] ];
		
		//-----------------------------------------
		// Custom filtering
		//-----------------------------------------

		$fieldsClass	= $this->registry->ccsFunctions->getFieldsClass();

		$fields		= array();
		$_numeric	= 0;

		if( count($this->caches['ccs_fields'][ $database['database_id'] ]) AND is_array($this->caches['ccs_fields'][ $database['database_id'] ]) )
		{
			foreach( $this->caches['ccs_fields'][ $database['database_id'] ] as $r )
			{
				$fields[ $r['field_id'] ]	= $r;
				
				if( 'field_' . $r['field_id'] == $config['sortby'] )
				{
					$_numeric	= $r['field_is_numeric'];
				}
			}
		}

		for( $j=1; $j < 6; $j++ )
		{
			$_fieldId	= $config['filters']['filter_ct_' . $j ] ? $config['filters']['filter_ct_' . $j ] : 0;
			
			if( !$_fieldId )
			{
				continue;
			}

			if( $fieldsClass->getSearchWhere( array( $_fieldId => $fields[ $_fieldId ] ) , $config['filters']['filter_cv_' . $j ] ) )
			{
				$where[]	= $fieldsClass->getSearchWhere( array( $_fieldId => $fields[ $_fieldId ] ) , $config['filters']['filter_cv_' . $j ] );
			}
		}

		if( $config['sortby'] == 'RAND()' )
		{
			$order	= $this->DB->buildRandomOrder();
		}
		else
		{
			$order	= $this->DB->checkForField( $config['sortby'], 'ccs_custom_database_' . $_database[0] ) ? $config['sortby'] : 'primary_id_field';
	
			$order	= 'p.' . $order . ( $_numeric ? '+0' : '' ) . ' ' . $config['sortorder'];
		}

		//-----------------------------------------
		// Get database class
		//-----------------------------------------
		
		require_once( IPSLib::getAppDir( 'ccs' ) . '/sources/databases.php' );
		$dbClass		= new databaseBuilder( $this->registry );

		//-----------------------------------------
		// Run the query and get the results
		//-----------------------------------------

		$records	= array();
		$memberIds	= array();
		
		$this->DB->build( array(
								'select'	=> 'p.*',
								'from'		=> array( 'ccs_custom_database_' . $_database[0] => 'p' ),
								'where'		=> implode( ' AND ', $where ),
								'order'		=> $order,
								'limit'		=> array( $config['offset_a'], $config['offset_b'] ),
								'add_join'	=> array(
													array(
														'select'	=> 'c.*',
														'from'		=> array( 'ccs_database_categories' => 'c' ),
														'where'		=> 'c.category_id=p.category_id',
														'type'		=> 'left',
														)
													)
						)		);
		$outer	= $this->DB->execute();
		
		while( $r = $this->DB->fetch($outer) )
		{
			//-----------------------------------------
			// Normalization
			//-----------------------------------------
			
			$r['url']		= $this->registry->ccsFunctions->returnDatabaseUrl( $database['database_id'], 0, $r );
			$r['date']		= $r['record_updated'];
			
			foreach( $r as $k => $v )
			{
				if( preg_match( "/^field_(\d+)$/", $k, $matches ) )
				{
					$r[ $k . '_value' ]	= $fieldsClass->getFieldValue( $fields[ $matches[1] ], $r, $fields[ $matches[1] ]['field_truncate'] );
				}
			}
			
			$r['_title']	= $r[ $database['database_field_title'] . '_value' ];
			$r['content']	= $r[ $database['database_field_content'] . '_value' ];
			$r['_isRead']	= $this->registry->classItemMarking->isRead( array( 'catID' => $r['category_id'], 'itemID' => $r['primary_id_field'], 'itemLastUpdate' => $r['record_updated'] ), 'ccs' );
	
			//-----------------------------------------
			// Parse attachments
			//-----------------------------------------
			
			$r	= $dbClass->parseAttachments( $database, $fields, $r );
			
			$records[]						= $r;
			$memberIds[ $r['member_id'] ]	= $r['member_id'];
		}
		
		//-----------------------------------------
		// Get member info
		//-----------------------------------------
		
		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'] ] ) );
				$records[ $key ]['title']	= $records[ $key ]['_title'];
			}
		}
		
		//-----------------------------------------
		// Return formatted content
		//-----------------------------------------
		
		$feedConfig		= $this->returnFeedInfo();
		$templateBit	= $feedConfig['templateBit'] . '_' . $block['block_id'];

		if( $config['hide_empty'] AND !count($records) )
		{
			return '';
		}

		$return	= $this->registry->output->getTemplate('ccs')->$templateBit( $block['block_name'], $records );

		return $return;
	}
	
	/**
	 * Return the comments for database feed
	 *
	 * @access	protected
	 * @param	array 		Block config
	 * @param	array 		Config data for this feed
	 * @param	array 		Database info
	 * @return	string		Output HTML
	 */
	protected function _getComments( $block, $config, $_database )
	{
		//-----------------------------------------
		// Set up filtering clauses
		//-----------------------------------------

		$where		= array();

		$where[]	= "c.comment_database_id=" . $_database[0];
		
		if( $config['filters']['filter_visibility'] != 'either' )
		{
			$where[]	= "c.comment_approved=" . ( $config['filters']['filter_visibility'] == 'approved' ? 1 : 0 );
		}

		if( $config['filters']['filter_category'] )
		{
			$where[]	= "r.category_id IN(" . $config['filters']['filter_category'] . ")";
		}

		if( $config['filters']['filter_starter'] == 'myself' )
		{
			$where[]	= "c.comment_user = " . $this->memberData['member_id'];
		}
		else if( $config['filters']['filter_starter'] == 'friends' )
		{
			//-----------------------------------------
			// Get page builder for friends
			//-----------------------------------------
			
			require_once( IPSLib::getAppDir('ccs') . '/sources/pages.php' );
			$pageBuilder	= new pageBuilder( $this->registry );
			$friends		= $pageBuilder->getFriends();
			
			if( count($friends) )
			{
				$where[]	= "c.comment_user IN( " . implode( ',', $friends ) . ")";
			}
			else
			{
				return '';
			}
		}
		else if( $config['filters']['filter_starter'] != '' )
		{
			$member	= IPSMember::load( $config['filters']['filter_starter'], 'basic', 'displayname' );
			
			if( $member['member_id'] )
			{
				$where[]	= "c.comment_user = " . $member['member_id'];
			}
			else
			{
				return '';
			}
		}

		if( $config['sortby'] == 'comment_user' OR $config['sortby'] == 'comment_date' )
		{
			$_p	= 'c.';
		}
		else
		{
			$_p	= 'r.';
		}

		if( $config['sortby'] == 'RAND()' )
		{
			$order	= $this->DB->buildRandomOrder();
		}
		else
		{
			$order	.= ' ' . $_p . $config['sortby'] . ' ' . $config['sortorder'];
		}
		
		//-----------------------------------------
		// Get DB
		//-----------------------------------------
		
		$database	= $this->caches['ccs_databases'][ $_database[0] ];
		
		//-----------------------------------------
		// Get possible field types
		//-----------------------------------------
		
		$fieldsClass	= $this->registry->ccsFunctions->getFieldsClass();

		$fields	= array();

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

		//-----------------------------------------
		// Run the query and get the results
		//-----------------------------------------

		$records	= array();
		$memberIds	= array();
		
		$this->DB->build( array(
								'select'	=> 'c.*',
								'from'		=> array( 'ccs_database_comments' => 'c' ),
								'where'		=> implode( ' AND ', $where ),
								'order'		=> $order,
								'limit'		=> array( $config['offset_a'], $config['offset_b'] ),
								'add_join'	=> array(
													array(
														'select'	=> 'r.*',
														'from'		=> array( 'ccs_custom_database_' . $_database[0] => 'r' ),
														'where'		=> "c.comment_record_id=r.primary_id_field",
														'type'		=> 'left',
														)
													)
						)		);
		$outer	= $this->DB->execute();
		
		while( $r = $this->DB->fetch($outer) )
		{
			//-----------------------------------------
			// Normalization
			//-----------------------------------------
			
			$r['url']		= $this->registry->ccsFunctions->returnDatabaseUrl( $database['database_id'], 0, $r, $r['comment_id'] );
			$r['date']		= $r['comment_date'];
			$r['content']	= $r['comment_post'];
			
			foreach( $r as $k => $v )
			{
				if( preg_match( "/^field_(\d+)$/", $k, $matches ) )
				{
					$r[ $k . '_value' ]	= $fieldsClass->getFieldValue( $fields[ $matches[1] ], $r, $fields[ $matches[1] ]['field_truncate'] );
				}
			}
			
			$r['_title']	= $r[ $database['database_field_title'] . '_value' ];
			$r['_isRead']	= $this->registry->classItemMarking->isRead( array( 'catID' => $r['category_id'], 'itemID' => $r['primary_id_field'], 'itemLastUpdate' => $r['record_updated'] ), 'ccs' );
	
			$records[]							= $r;
			$memberIds[ $r['comment_user'] ]	= $r['comment_user'];
		}

		//-----------------------------------------
		// Get member info
		//-----------------------------------------
		
		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;
			
			$_members[0]['members_display_name']	= $this->lang->words['global_guestname'];
			
			foreach( $records as $key => $record )
			{
				$records[ $key ]	= array_merge( $record, IPSMember::buildDisplayData( $_members[ $record['comment_user'] ] ) );
				$records[ $key ]['title']	= $records[ $key ]['_title'];
			}
		}
		
		//-----------------------------------------
		// Return formatted content
		//-----------------------------------------
		
		$feedConfig		= $this->returnFeedInfo();
		$templateBit	= $feedConfig['templateBit'] . '_' . $block['block_id'];

		if( $config['hide_empty'] AND !count($records) )
		{
			return '';
		}

		$return	= $this->registry->output->getTemplate('ccs')->$templateBit( $block['block_name'], $records );

		return $return;
	}
}