<?php

/**
 * <pre>
 * Invision Power Services
 * RSS output plugin :: ccs
 * Last Updated: $Date: 2010-02-25 18:01:12 -0500 (Thu, 25 Feb 2010) $
 * </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		1st March 2009
 * @version		$Revision: 213 $
 */

if ( ! defined( 'IN_IPB' ) )
{
	print "<h1>Incorrect access</h1>You cannot access this file directly. If you have recently upgraded, make sure you upgraded all the relevant files.";
	exit();
}

class rss_output_ccs
{
	/**
	 * Expiration date
	 *
	 * @access	private
	 * @var		integer			Expiration timestamp
	 */
	private $expires			= 0;

	/**
	 * Category lib
	 *
	 * @access	private
	 * @var		obj				Category library
	 */
	private $categories;
	
	/**
	 * Constructor
	 *
	 * @access	public
	 * @return	void
	 */
	public function __construct()
	{
		$registry	= ipsRegistry::instance();
		
		if( !$registry->isClassLoaded( 'ccsFunctions' ) )
		{
			require_once( IPSLib::getAppDir('ccs') . '/app_class_ccs.php' );
			$_tmp	= new app_class_ccs( $registry );
		}
	}

	/**
	 * Grab the RSS links
	 *
	 * @access	public
	 * @return	string		RSS document
	 */
	public function getRssLinks()
	{		
		if( !IPSLib::appIsInstalled('ccs') )
		{
			return array();
		}

		$return			= array();
		
		//-----------------------------------------
		// Database feeds
		//-----------------------------------------
		
		$databases		= ipsRegistry::cache()->getCache('ccs_databases');
		
		foreach( $databases as $_dbId => $_db )
		{
			if( !$_db['database_open'] )
			{
				continue;
			}
			
			if ( ipsRegistry::getClass('permissions')->check( 'view', $_db ) != TRUE )
			{
				continue;
			}
			
			$_rss	= explode( ';', $_db['database_rss'] );

			if( !$_rss[0] )
			{
				continue;
			}
			
			$return[] = array( 'title' => $_db['database_name'], 'url' => ipsRegistry::getClass('output')->formatUrl( ipsRegistry::$settings['board_url'] . "/index.php?app=core&amp;module=global&amp;section=rss&amp;type=ccs&amp;id=" . $_db['database_id'], '%%' . $_db['database_name'] . '%%', 'section=rss2' ) );
		}
		
		//-----------------------------------------
		// Category feeds
		//-----------------------------------------
		
		require_once( IPSLib::getAppDir( 'ccs' ) . '/sources/databases/categories.php' );
		$this->categories	= new ccs_categories( ipsRegistry::instance() );
		
		foreach( $databases as $_dbId => $_db )
		{
			$this->categories->init( $_db );

			if( count($this->categories->categories) )
			{
				foreach( $this->categories->categories as $_catId => $_cat )
				{
					if( !$databases[ $_cat['category_database_id'] ]['database_open'] )
					{
						continue;
					}
	
					if ( ipsRegistry::getClass('permissions')->check( 'view', $databases[ $_cat['category_database_id'] ] ) != TRUE )
					{
						continue;
					}

					if ( $_cat['category_has_perms'] AND ipsRegistry::getClass('permissions')->check( 'view', $_cat ) != TRUE )
					{
						continue;
					}
					
					$_rss	= explode( ';', $_cat['category_rss'] );
					
					if( !$_rss[0] )
					{
						continue;
					}
					
					$return[] = array( 'title' => $databases[ $_cat['category_database_id'] ]['database_name'] . ': ' . $_cat['category_name'], 'url' => ipsRegistry::getClass('output')->formatUrl( ipsRegistry::$settings['board_url'] . "/index.php?app=core&amp;module=global&amp;section=rss&amp;type=ccs&amp;id=" . $_cat['category_database_id'] . 'c' . $_cat['category_id'], '%%' . $_cat['category_name'] . '%%', 'section=rss2' ) );
				}
			}
		}

		return $return;
	}
	
	/**
	 * Grab the RSS document content and return it
	 *
	 * @access	public
	 * @return	string		RSS document
	 */
	public function returnRSSDocument()
	{
		if( !IPSLib::appIsInstalled('ccs') )
		{
			return '';
		}
		
		//-----------------------------------------
		// INIT
		//-----------------------------------------
		
		$databases		= ipsRegistry::cache()->getCache('ccs_databases');
		$_input			= explode( 'c', ipsRegistry::$request['id'] );
		$database		= intval($_input[0]);
		$category		= intval($_input[1]);
		$rss_data		= array();
		$to_print		= '';
	
		//-----------------------------------------
		// Can view?
		//-----------------------------------------
		
		if( !$databases[ $database ]['database_open'] )
		{
			return '';
		}
		
		if ( ipsRegistry::getClass('permissions')->check( 'view', $databases[ $database ] ) != TRUE )
		{
			return '';
		}
			
		//-----------------------------------------
		// Category or db feed?
		//-----------------------------------------
		
		if( $category )
		{
			//-----------------------------------------
			// Get category handler
			//-----------------------------------------
			
			require_once( IPSLib::getAppDir( 'ccs' ) . '/sources/databases/categories.php' );
			$this->categories	= new ccs_categories( ipsRegistry::instance() );
			$this->categories->init( $databases[ $database ] );
			
			$thisCategory	= $this->categories->categories[ $category ];
			
			//-----------------------------------------
			// Permissions
			//-----------------------------------------

			if ( $thisCategory['category_has_perms'] AND ipsRegistry::getClass('permissions')->check( 'view', $thisCategory ) != TRUE )
			{
				return '';
			}

			$_rss			= explode( ';', $thisCategory['category_rss'] );
			
			//-----------------------------------------
			// Is RSS enabled?
			//-----------------------------------------
			
			if( !$_rss[0] )
			{
				return '';
			}

			//-----------------------------------------
			// Expiration (default to 24 hours)
			//-----------------------------------------
			
			$this->expires	= time() + ( 60 * 60 * 24 );
			
			if( $_rss[4] AND $_rss[1] )
			{
				$this->expires	= $_rss[4] + ( 60 * 60 * $_rss[1] );
			}
			else if( $_rss[1] )
			{
				$this->expires	= time() + ( 60 * 60 * $_rss[1] );
			}
		
			//-----------------------------------------
			// Get RSS export
			// We don't include RSS cache in normal db cache
			// for resource/efficiency reasons
			//-----------------------------------------
			
			$rss_data	= '';
	
			if( $_rss[1] AND $_rss[4] AND ( time() < $_rss[4] + ( 60 * 60 * $_rss[1] ) ) )
			{
				$rss_data = $thisCategory['category_rss_cache'];
			}
			
			//-----------------------------------------
			// Got a cache??
			//-----------------------------------------
	
			if ( $rss_data )
			{
				return $rss_data;
			}
			else
			{
				//-----------------------------------------
				// Correct expires time
				//-----------------------------------------
				
				$this->expires = time() + ( 60 * 60 * $_rss[1] );
				
				//-----------------------------------------
				// Recache
				//-----------------------------------------
				
				return $this->recacheCategoryRss( $database, $databases, $thisCategory );
			}
		}
		else
		{
			$_rss			= explode( ';', $databases[ $database ]['database_rss'] );
			
			//-----------------------------------------
			// Is RSS enabled?
			//-----------------------------------------
			
			if( !$_rss[0] )
			{
				return '';
			}

			//-----------------------------------------
			// Expiration (default to 24 hours)
			//-----------------------------------------
			
			$this->expires	= time() + ( 60 * 60 * 24 );
			
			if( $_rss[3] AND $_rss[1] )
			{
				$this->expires	= $_rss[3] + ( 60 * 60 * $_rss[1] );
			}
			else if( $_rss[1] )
			{
				$this->expires	= time() + ( 60 * 60 * $_rss[1] );
			}
		
			//-----------------------------------------
			// Get RSS export
			// We don't include RSS cache in normal db cache
			// for resource/efficiency reasons
			//-----------------------------------------
			
			$rss_data	= array();
	
			if( $_rss[1] AND $_rss[3] AND ( time() < $_rss[3] + ( 60 * 60 * $_rss[1] ) ) )
			{
				$rss_data = ipsRegistry::DB()->buildAndFetch( array( 'select'	=> 'database_rss_cache',
																	'from'		=> 'ccs_databases',
																	'where'		=> 'database_id=' . $database ) );
			}
			
			//-----------------------------------------
			// Got a cache??
			//-----------------------------------------
	
			if ( $rss_data['database_rss_cache'] )
			{
				return $rss_data['database_rss_cache'];
			}
			else
			{
				//-----------------------------------------
				// Correct expires time
				//-----------------------------------------
				
				$this->expires = time() + ( 60 * 60 * $_rss[1] );
				
				//-----------------------------------------
				// Recache
				//-----------------------------------------
				
				return $this->recacheRss( $database, $databases );
			}
		}
	}
	
	/**
	 * Grab the RSS document expiration timestamp
	 *
	 * @access	public
	 * @return	integer		Expiration timestamp
	 */
	public function grabExpiryDate()
	{
		return $this->expires ? $this->expires : time();
	}
	
	/**
	 * Recache the RSS feed
	 *
	 * @access	public
	 * @param	integer		Database ID 
	 * @param	array 		Databases cache
	 * @return	string
	 */
	public function recacheRss( $database, $databases )
	{
		//-----------------------------------------
		// Init
		//-----------------------------------------
		
		$settings	= ipsRegistry::instance()->fetchSettings();
		$_rss		= explode( ';', $databases[ $database ]['database_rss'] );
		$cache		= array();
		$where		= array();

		//-----------------------------------------
		// RSS class
		//-----------------------------------------
		
		require_once( IPS_KERNEL_PATH . 'classRss.php' );
		$class_rss				= new classRss();
		$class_rss->use_sockets	= $this->use_sockets;
		$class_rss->doc_type	= IPS_DOC_CHAR_SET;
		
		//-----------------------------------------
		// Field type handler
		//-----------------------------------------
		
		require_once( IPSLib::getAppDir( 'ccs' ) . '/sources/databases/fields.php' );
		$fieldsClass	= new ccs_database_fields( ipsRegistry::instance() );
		$fieldsClass->getHandlers();
		
		//-----------------------------------------
		// Get database class
		//-----------------------------------------
		
		require_once( IPSLib::getAppDir( 'ccs' ) . '/sources/databases.php' );
		$dbClass		= new databaseBuilder( ipsRegistry::instance() );
		
		$fields		= array();
		$fieldCache	= ipsRegistry::cache()->getCache('ccs_fields');

		if( is_array($fieldCache[ $database ]) AND count($fieldCache[ $database ]) )
		{
			foreach( $fieldCache[ $database ] as $_field )
			{
				$fields[ $_field['field_id'] ]	= $_field;
			}
		}
		
		//-----------------------------------------
		// Get category handler
		//-----------------------------------------
		
		require_once( IPSLib::getAppDir( 'ccs' ) . '/sources/databases/categories.php' );
		$this->categories	= new ccs_categories( ipsRegistry::instance() );
		$this->categories->init( $databases[ $database ] );

		if( count($this->categories->categories) )
		{
			$_catIds	= array();
			
			foreach( $this->categories->categories as $_catId => $_cat )
			{
				//-----------------------------------------
				// Permissions
				//-----------------------------------------
				
				if( !$_cat['category_show_records'] )
				{
					continue;
				}
				
				if ( $_cat['category_has_perms'] AND ipsRegistry::getClass('permissions')->check( 'view', $_cat ) != TRUE )
				{
					continue;
				}
			
				//-----------------------------------------
				// Are we excluding category from feed?
				//-----------------------------------------
				
				$_catRss	= explode( ';', $_cat['category_rss'] );

				if( $_catRss[3] )
				{
					continue;
				}
				
				$_catIds[]	= $_catId;
			}
			
			$where[]		= "category_id IN(" . implode( ',', $_catIds ) . ")";
		}
		
		$where[]	= "record_approved=1";

		//-----------------------------------------
		// Start RSS stuff
		//-----------------------------------------
		
		$cache[] = array( 'url' => $settings['board_url'] . '/index.php?app=core&amp;module=global&amp;section=rss&amp;type=ccs&amp;id='.$database, 'title' => $databases[ $database ]['database_name'] );

		/* Create the RSS Channel */
		$channel_id = $class_rss->createNewChannel( array(	'title'			=> $databases[ $database ]['database_name'],
															'link'			=> ipsRegistry::instance()->getClass('ccsFunctions')->returnDatabaseUrl( $database ),
															'pubDate'		=> $class_rss->formatDate( time() ),
															'ttl'			=> $_rss[1] * 60 * 60,
															'description'	=> $databases[ $database ]['database_description']
													)		);
														
		//-----------------------------------------
		// Get the entries to add to the RSS
		//-----------------------------------------

		ipsRegistry::DB()->build( array( 'select' => '*', 'from' => $databases[ $database ]['database_database'], 'order' => 'record_updated DESC', 'where' => implode( " AND ", $where ), 'limit' => array( 0, $_rss[2] ) ) );
		$outer	= ipsRegistry::DB()->execute();
		
		while( $r = ipsRegistry::DB()->fetch($outer) )
		{
			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	= $dbClass->parseAttachments( $databases[ $database ], $fields, $r );

			$class_rss->addItemToChannel( $channel_id, array(	'title'			=> $r[ $databases[ $database ]['database_field_title'] . '_value' ],
																'link'			=> ipsRegistry::instance()->getClass('ccsFunctions')->returnDatabaseUrl( $database, 0, $r['primary_id_field'] ),
																'description'	=> $r[ $databases[ $database ]['database_field_content'] . '_value' ],
																'pubDate'		=> $class_rss->formatDate( $r['record_updated'] ),
																'guid'			=> md5( $database . $r['primary_id_field'] )
										)					);
		}

		//-----------------------------------------
		// Create feed
		//-----------------------------------------
		
		$class_rss->createRssDocument();
		
		//-----------------------------------------
		// Update cache?
		//-----------------------------------------
		
		if( $_rss[1] )
		{
			$_rss[3]	= time();
			$update		= array( 'database_rss' => implode( ';', $_rss ), 'database_rss_cache' => $class_rss->rss_document );

			ipsRegistry::DB()->update( 'ccs_databases', $update, "database_id=" . $database );
			
			ipsRegistry::cache()->rebuildCache( 'ccs_databases' );
		}
		
		return $class_rss->rss_document;
	}
	
	/**
	 * Recache the RSS feed
	 *
	 * @access	public
	 * @param	integer		Database ID 
	 * @param	array 		Databases cache
	 * @param	array 		Category data
	 * @return	string
	 */
	public function recacheCategoryRss( $database, $databases, $category )
	{
		//-----------------------------------------
		// Init
		//-----------------------------------------
		
		$settings	= ipsRegistry::instance()->fetchSettings();
		$_rss		= explode( ';', $databases[ $database ]['database_rss'] );
		$cache		= array();
		$where		= array();

		//-----------------------------------------
		// RSS class
		//-----------------------------------------
		
		require_once( IPS_KERNEL_PATH . 'classRss.php' );
		$class_rss				= new classRss();
		$class_rss->use_sockets	= $this->use_sockets;
		$class_rss->doc_type	= IPS_DOC_CHAR_SET;
		
		//-----------------------------------------
		// Field type handler
		//-----------------------------------------
		
		require_once( IPSLib::getAppDir( 'ccs' ) . '/sources/databases/fields.php' );
		$fieldsClass	= new ccs_database_fields( ipsRegistry::instance() );
		$fieldsClass->getHandlers();
		
		//-----------------------------------------
		// Get database class
		//-----------------------------------------
		
		require_once( IPSLib::getAppDir( 'ccs' ) . '/sources/databases.php' );
		$dbClass		= new databaseBuilder( ipsRegistry::instance() );
		
		$fields		= array();
		$fieldCache	= ipsRegistry::cache()->getCache('ccs_fields');

		if( is_array($fieldCache[ $database ]) AND count($fieldCache[ $database ]) )
		{
			foreach( $fieldCache[ $database ] as $_field )
			{
				$fields[ $_field['field_id'] ]	= $_field;
			}
		}
		
		//-----------------------------------------
		// Category where clause
		//-----------------------------------------

		$_children	= $this->categories->getChildren( $category['category_id'] );
		$_cats		= array( $category['category_id'] ) ;
		
		if( count($_children) )
		{
			foreach( $_children as $_child )
			{
				$_cats[]	= $_child;
			}
		}
		
		if( count($_cats) == 1 )
		{
			$where[]	= "category_id=" . $category['category_id'];
		}
		else
		{
			$where[]	= "category_id IN(" . implode( ',', $_cats ) . ")";
		}

		$where[]	= "record_approved=1";

		//-----------------------------------------
		// Start RSS stuff
		//-----------------------------------------
		
		$cache[] = array( 'url' => $settings['board_url'] . '/index.php?app=core&amp;module=global&amp;section=rss&amp;type=ccs&amp;id=' . $database . 'c' . $category['category_id'], 'title' => $databases[ $database ]['database_name'] . ': ' . $category['category_name'] );


		/* Create the RSS Channel */
		$channel_id = $class_rss->createNewChannel( array(	'title'			=> $databases[ $database ]['database_name'],
															'link'			=> ipsRegistry::instance()->getClass('ccsFunctions')->returnDatabaseUrl( $database, $category['category_id'] ),
															'pubDate'		=> $class_rss->formatDate( time() ),
															'ttl'			=> $_rss[1] * 60 * 60,
															'description'	=> $category['category_description']
													)		);
														
		//-----------------------------------------
		// Get the entries to add to the RSS
		//-----------------------------------------

		ipsRegistry::DB()->build( array( 'select' => '*', 'from' => $databases[ $database ]['database_database'], 'order' => 'record_updated DESC', 'where' => implode( " AND ", $where ), 'limit' => array( 0, $_rss[2] ) ) );
		$outer	= ipsRegistry::DB()->execute();
		
		while( $r = ipsRegistry::DB()->fetch($outer) )
		{
			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	= $dbClass->parseAttachments( $databases[ $database ], $fields, $r );

			$class_rss->addItemToChannel( $channel_id, array(	'title'			=> $r[ $databases[ $database ]['database_field_title'] . '_value' ],
																'link'			=> ipsRegistry::instance()->getClass('ccsFunctions')->returnDatabaseUrl( $database, 0, $r['primary_id_field'] ),
																'description'	=> $r[ $databases[ $database ]['database_field_content'] . '_value' ],
																'pubDate'		=> $class_rss->formatDate( $r['record_updated'] ),
																'guid'			=> md5( $database . $r['primary_id_field'] )
										)					);
		}

		//-----------------------------------------
		// Create feed
		//-----------------------------------------
		
		$class_rss->createRssDocument();
		
		//-----------------------------------------
		// Update cache?
		//-----------------------------------------
		
		if( $_rss[1] )
		{
			$_rss[4]	= time();
			$update		= array( 'category_rss' => implode( ';', $_rss ), 'category_rss_cache' => $class_rss->rss_document );

			ipsRegistry::DB()->update( 'ccs_database_categories', $update, "category_id=" . $category['category_id'] );
		}
		
		return $class_rss->rss_document;
	}
}