<?php

/**
 * <pre>
 * Invision Power Services
 * IP.CCS miscellaneous functions
 * Last Updated: $Date: 2010-03-30 15:42:07 -0400 (Tue, 30 Mar 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: 234 $
 */

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

if( !class_exists('app_class_ccs' ) )
{
	require_once( IPSLib::getAppDir( 'ccs' ) . '/app_class_ccs.php' );
	$_t = new app_class_ccs( ipsRegistry::instance() );
}

class ccsFunctions
{
	/**#@+
	 * Registry objects
	 *
	 * @access	protected
	 * @var		object
	 */	
	protected $registry;
	protected $DB;
	protected $settings;
	protected $request;
	protected $member;
	protected $caches;
	protected $cache;
	/**#@-*/
	
	/**
	 * Folder/page checked.  We set a property
	 * to indicate this in case there actually
	 * is no folder/page so we don't do the work twice.
	 *
	 * @access	protected
	 * @var		bool
	 */
	protected $folderCheckComplete	= false;
	
	/**
	 * Requested folder
	 *
	 * @access	protected
	 * @var		string
	 */
	protected $folder				= '';
	
	/**
	 * Requested page SEO name
	 *
	 * @access	protected
	 * @var		string
	 */
	protected $page					= '';
	
	/**
	 * Database data from the FURL
	 *
	 * @access	protected
	 * @var		string
	 */
	protected $databaseString		= '';
	
	/**
	 * Categories handlers
	 *
	 * @access	protected
	 * @var		array
	 */
	protected $categories			= array();
	
	/**
	 * Fields class
	 *
	 * @access	protected
	 * @var		object
	 */
	protected $fieldsClass			= null;
	
	/**
	 * Cached page data for articles/database pages
	 *
	 * @access	public
	 * @var		array
	 */
	public $pageData				= array();

	/**
	 * Constructor
	 *
	 * @access	public
	 * @param	object	ipsRegistry
	 * @return	void
	 */
	public function __construct( ipsRegistry $registry )
	{
		/* Make object */
		//-----------------------------------------
		// Do not set memberData or lang
		// It causes issues with session plugin
		//-----------------------------------------
		
		$this->registry		= $registry;
		$this->DB			= $this->registry->DB();
		$this->settings		=& $this->registry->fetchSettings();
		$this->request		=& $this->registry->fetchRequest();
		$this->member		= $this->registry->member();
		$this->cache		= $this->registry->cache();
		$this->caches		=& $this->registry->cache()->fetchCaches();
	}
	
	/**
	 * Retrieve folder
	 *
	 * @access	public
	 * @return	string		Requested folder name
	 */
	public function getFolder()
	{
		if( $this->folderCheckComplete )
		{
			return $this->folder;
		}
		
		$this->_getPageAndFolder();

		return $this->folder;
	}
	
	/**
	 * Retrieve page name
	 *
	 * @access	public
	 * @return	string		Requested page name
	 */
	public function getPageName()
	{
		if( $this->folderCheckComplete )
		{
			return $this->page;
		}
		
		$this->_getPageAndFolder();
		
		return $this->page;
	}
	
	/**
	 * Retrieve database FURL string
	 *
	 * @access	public
	 * @return	string		Database FURL string (if any)
	 */
	public function getDatabaseFurlString()
	{
		if( $this->folderCheckComplete )
		{
			return $this->databaseString;
		}
		
		$this->_getPageAndFolder();
		
		return $this->databaseString;
	}
	
	/**
	 * Sort out page and folder
	 *
	 * @access	protected
	 * @return	void
	 */
	protected function _getPageAndFolder()
	{
		$page	= '';
		$folder	= '';
		
		//-----------------------------------------
		// What page?
		//-----------------------------------------

		if( !$this->request['page'] AND !$this->request['id'] )
		{
			$page	= $this->settings['ccs_default_page'];
		}
		else
		{
			$page	= urldecode($this->request['page']);
		}

		//-----------------------------------------
		// Fix folder, page and db
		//-----------------------------------------

		$_http			= ( $_SERVER['HTTPS'] and $_SERVER['HTTPS'] != 'off' ) ? "https://" : "http://";
		$_default		= $this->settings['ccs_root_url'] ? $this->settings['ccs_root_url'] : $this->settings['board_url'];
		$_default		= rtrim( str_replace( parse_url( $_default, PHP_URL_SCHEME ) . '://www.', $_http, $_default ), '/' );
		// Here we were force adding the /, but then we removed it from requestUri, 
		// so if you visited http://domain.com (without trailing slash) it may not get removed from $_default
		//$_default		= ( substr( $_default, -1 ) == '/' ) ? $_default : $_default . '/';
		$_requestUri	= rtrim( $_SERVER['REQUEST_URI'] ? $_SERVER['REQUEST_URI'] : @getenv('REQUEST_URI'), '/' );
		$_reconstructed	= $_http . preg_replace( '/^www\./', '', $_SERVER['HTTP_HOST'] ) . ( substr( $_requestUri, 0, 1 ) == '/' ? $_requestUri : '/' . $_requestUri );
		$_path			= str_replace( strtolower($_default), '', $_reconstructed );

		if( IPS_DEFAULT_PUBLIC_APP == 'ccs' )
		{
			$_path	= preg_replace( "/^\/index\.php($|\?|\/)/i", '', $_path );
		}

		//-----------------------------------------
		// Does URI have db marker in it
		//-----------------------------------------
		
		if( strpos( $_path, '/' . DATABASE_FURL_MARKER . '/' ) !== false )
		{
			$_rest	= substr( $_path, ( strpos( $_path, '/' . DATABASE_FURL_MARKER . '/' ) + ( strlen(DATABASE_FURL_MARKER) + 2 ) ) );
			$_path	= substr( $_path, 0, ( strpos( $_path, '/' . DATABASE_FURL_MARKER . '/' ) ) );
			
			if( strpos( $_rest, '?' ) )
			{
				$this->databaseString	= rtrim( substr( $_rest, 0, strpos( $_rest, '?' ) ), '/' );
			}
			else
			{
				$this->databaseString	= $_rest;
			}
		}

		//-----------------------------------------
		// Accessing URL dynamically (thru IPB)?
		//-----------------------------------------
		
		if( strpos( $_path, 'app=ccs' ) !== false )
		{
			$_folder	= ( strpos( urldecode($this->request['folder']), '/' ) === 0 ) ? substr( urldecode($this->request['folder']), 1 ) : urldecode($this->request['folder']);
			
			$_path	= $_folder . '/' . $this->request['page'];
		}
		
		//-----------------------------------------
		// Accessing through IPB friendly urls?
		//-----------------------------------------
		
		if( strpos( $_reconstructed, str_replace( 'http://www.', 'http://', strtolower( $this->settings['board_url'] ) ) ) !== false )
		{
			include( IPSLib::getAppDir('ccs') . '/extensions/furlTemplates.php' );
			$_path = preg_replace( $_PATHFIX, "\\1", $_path );
		}

		//-----------------------------------------
		// Accessing through main gateway
		//-----------------------------------------
		
		if( $this->settings['ccs_root_filename'] AND strpos( $_path, $this->settings['ccs_root_filename'] . '/' ) !== false )
		{
			$_path	= substr( $_path, ( strpos( $_path, $this->settings['ccs_root_filename'] . '/' ) + ( strlen($this->settings['ccs_root_filename']) + 1 ) ) );
		}

		$uriBits	= explode( '/', $_path );
		$myFolder	= '';

		if( count($uriBits) > 1 )
		{
			$page		= array_pop($uriBits); // Retrieve the file name
			$myFolder	= count($uriBits) ? '/' . implode( '/', $uriBits ) : '';
			$myFolder	= ( $myFolder == '/' ) ? '' : $myFolder;
		}
		else
		{
			$page		= $_path;
		}

		$folder	= $myFolder;

		if( strpos( $page, '?' ) !== false )
		{
			$page	= substr( $page, 0, strpos( $page, '?' ) );
		}
		
		if( strpos( $page, '/' ) !== false )
		{
			$page	= substr( $page, 0, strpos( $page, '/' ) );
		}
		
		if( strpos( $page, '&' ) !== false )
		{
			$page	= substr( $page, 0, strpos( $page, '&' ) );
		}

		$page	= IPSText::parseCleanValue( $page );
		$folder	= IPSText::parseCleanValue( preg_replace( "#^//(.*?)$#", "/$1", $folder ) );

		$this->folder	= $folder;
		$this->page		= $page;
		
		$this->folderCheckComplete	= true;
	}

	/**
	 * Return the proper page url
	 *
	 * @access	public
	 * @param	array 	Page data
	 * @return	string	Page URL based on enabled settings
	 */
	public function returnPageUrl( $page=array() )
	{
		$url	= $this->settings['ccs_root_url'];
		
		if( $url )
		{
			if( !$this->settings['ccs_mod_rewrite'] )
			{
				if( substr( $url, -1 ) != '/' )
				{
					$url .= '/';
				}
			
				$url .= $this->settings['ccs_root_filename'];
			}
			else
			{
				$url	= rtrim( $url, "/" );
			}
			
			if( $page['page_folder'] )
			{
				$url .= $page['page_folder'] . '/';
			}
			else
			{
				$url	.= '/';
			}
			
			$url	.= $page['page_seo_name'];
		}
		else if( $this->settings['use_friendly_urls'] )
		{
			$url	= str_replace( 'http:/', 'http://', str_replace( '//', '/', $this->registry->output->formatUrl( $this->settings['board_url'] . '/index.php?app=ccs&amp;module=pages&amp;section=pages&amp;folder=' . $page['page_folder'] . '&amp;id=' . $page['page_id'], $page['page_seo_name'], 'page' ) ) );
		}
		else
		{
			$url	= $this->settings['board_url'] . '/index.php?app=ccs&amp;module=pages&amp;section=pages&amp;id=' . $page['page_id'];
		}
		
		return $url;
	}
	
	/**
	 * Return URL to database/category/record/comment.
	 *
	 * @access	public
	 * @param	int		Database ID
	 * @param	int		Category ID
	 * @param	mixed	Record ID or array of record data
	 * @param	int		Comment ID
	 * @return	string	URL
	 */
	public function returnDatabaseUrl( $database, $category=0, $record=null, $comment=0 )
	{
		$_recordId	= is_array($record) ? $record['primary_id_field'] : $record;
		
		//-----------------------------------------
		// Caching
		//-----------------------------------------
		
		static $builtUrls	= array();
		$_thisKey			= md5( $database . $category . $_recordId . $comment );

		if( array_key_exists( $_thisKey, $builtUrls ) )
		{
			return $builtUrls[ $_thisKey ];
		}
		
		$_database	= $this->caches['ccs_databases'][ $database ];
		
		if( !$_database['database_id'] )
		{
			//return array( $this->lang->words['nopage_id_red'] );
			
			$builtUrls[ $_thisKey ]	= '#';
			
			return '#';
		}
		
		if( $_database['database_is_articles'] )
		{
			$_findWhere		= "page_content LIKE '%\{parse articles\}%'";
			$_findWhereKey	= 'articles';
		}
		else
		{
			$_findWhere		= "page_content LIKE '%parse database=\"{$_database['database_key']}\"%'";
			$_findWhereKey	= $_database['database_key'];
		}
		
		//-----------------------------------------
		// Pull from cache if available, else get from db
		//-----------------------------------------

		if( array_key_exists( $_findWhereKey, $this->pageData ) )
		{
			$page	= $this->pageData[ $_findWhereKey ];
		}
		else
		{
			$page	= $this->DB->buildAndFetch( array( 'select' => '*', 'from' => 'ccs_pages', 'where' => $_findWhere ) );
			
			$this->pageData[ $_findWhereKey ]	= $page;
		}
		
		if( !$page['page_id'] )
		{
			//return array( $this->lang->words['nopage_id_red'] );

			$builtUrls[ $_thisKey ]	= '#';
			
			return '#';
		}
		
		$url	= $this->returnPageUrl( $page );
		
		if( $category )
		{
			if( !$this->settings['use_friendly_urls'] AND !$this->settings['ccs_root_url'] )
			{
				$url	.= '&amp;category=' . $category;
			}
			else
			{
				$url	= $this->getCategoriesClass( $_database )->getCategoryUrl( $url . '?', $category );
			}
		}
		else if( $_recordId )
		{
			if( !$this->settings['use_friendly_urls'] AND !$this->settings['ccs_root_url'] )
			{
				$url	.= '&amp;record=' . $_recordId;
			}
			else
			{
				$_database['base_link']	= $url . '?';

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

				require_once( IPSLib::getAppDir( 'ccs' ) . '/sources/databases.php' );
				$_dbLibrary					= new databaseBuilder( $this->registry );
				$_dbLibrary->categories		= $this->getCategoriesClass( $_database );
				$_dbLibrary->database		= $_database;
				$_dbLibrary->fields			= $_fields;
				$_dbLibrary->fieldsClass	= $this->getFieldsClass();
				
				if( !is_array($record) )
				{
					$record		= $this->DB->buildAndFetch( array( 'select' => '*', 'from' => $_database['database_database'], 'where' => 'primary_id_field=' . $_recordId ) );
				}
				
				$url	= $_dbLibrary->getRecordUrl( $record );
			}
		}
		
		if( $comment )
		{
			$url	.= '#comment' . $comment;
		}
		
		$builtUrls[ $_thisKey ]	= $url;
		
		return $url;
	}

	/**
	 * Get fields class (prevents instantiating more than once)
	 *
	 * @access	public
	 * @return	object
	 */	
	public function getFieldsClass()
	{
		if( !is_object($this->fieldsClass) )
		{
			require_once( IPSLib::getAppDir( 'ccs' ) . '/sources/databases/fields.php' );
			$this->fieldsClass	= new ccs_database_fields( $this->registry );
			$this->fieldsClass->getHandlers();
		}
		
		return $this->fieldsClass;
	}
	
	/**
	 * Get fields class (prevents instantiating more than once)
	 *
	 * @access	public
	 * @param	mixed 		Database data, or database id
	 * @return	object
	 */	
	public function getCategoriesClass( $database )
	{
		$database	= is_int($database) ? $this->caches['ccs_databases'][ $database ] : $database;

		if( !is_object( $this->categories[ $database['database_id'] ] ) )
		{
			require_once( IPSLib::getAppDir( 'ccs' ) . '/sources/databases/categories.php' );
			$this->categories[ $database['database_id'] ]	= new ccs_categories( $this->registry );
			$this->categories[ $database['database_id'] ]->init( $database );
		}
		
		return $this->categories[ $database['database_id'] ];
	}

	/**
	 * Apply ACP-defined "record" language bits to all language strings.
	 *
	 * @access	public
	 * @param	integer		Database id
	 * @param	bool		Force rebuild
	 * @return	void
	 */
	public function fixStrings( $database, $buildAgain=false )
	{
		//-----------------------------------------
		// Only build once
		//-----------------------------------------
		
		static $stringsFixed	= false;
		
		if( $stringsFixed AND !$buildAgain )
		{
			return;
		}
		
		$stringsFixed	= true;
		
		//-----------------------------------------
		// Fix strings
		//-----------------------------------------
		
		$_database	= $this->caches['ccs_databases'][ $database ];
		
		foreach( $this->registry->class_localization->words as $_k => $_v )
		{
			if( strpos( $_v, '_RUS_' ) !== false OR strpos( $_v, '_RUP_' ) !== false OR strpos( $_v, '_RLS_' ) !== false OR strpos( $_v, '_RLP_' ) !== false )
			{
				$_v	= str_replace( "_RUS_", $_database['database_lang_su'] ? $_database['database_lang_su'] : $this->registry->class_localization->words['database_lang_su'], $_v );
				$_v	= str_replace( "_RUP_", $_database['database_lang_pu'] ? $_database['database_lang_pu'] : $this->registry->class_localization->words['database_lang_pu'], $_v );
				$_v	= str_replace( "_RLS_", $_database['database_lang_sl'] ? $_database['database_lang_sl'] : $this->registry->class_localization->words['database_lang_sl'], $_v );
				$_v	= str_replace( "_RLP_", $_database['database_lang_pl'] ? $_database['database_lang_pl'] : $this->registry->class_localization->words['database_lang_pl'], $_v );
				
				$this->registry->class_localization->words[ $_k ]	= $_v;
			}
		}
	}
	
	/**
	 * Return image dimensions for template plugin
	 *
	 * @access	public
	 * @param	string		Image path/url
	 * @param	int			Max width
	 * @param	int			Max height
	 */
	public function getTemplateDimensions( $image, $width, $height )
	{
		if( empty( $width ) AND empty( $height ) )
		{
			return;
		}

		//-----------------------------------------
		// Dimensions
		// If set maxwidth and no maxheight, then we want the script to
		//	reduce based on width only.  And vice-versa.
		//-----------------------------------------
		
		$maxWidth	= ( $width ) ? intval($width) : 1000000000;
		$maxHeight	= ( $height ) ? intval($height) : 1000000000;
		
		//-----------------------------------------
		// Existing dims
		//-----------------------------------------
		
		$_dims		= @getimagesize( $image );

		if( !$_dims[0] )
		{
			return;
		}
		
		$_newDims	= IPSLib::scaleImage( array( 
												'cur_width'		=> $_dims[0],
												'cur_height'	=> $_dims[1],
												'max_width'		=> $maxWidth,
												'max_height'	=> $maxHeight,
										)		);

		//-----------------------------------------
		// Process the tag and return the data
		//-----------------------------------------

		return " width='{$_newDims['img_width']}' height='{$_newDims['img_height']}'";
	}
}