<?php

/**
 * <pre>
 * Invision Power Services
 * IP.CCS page templates
 * Last Updated: $Date: 2010-03-23 12:22:19 -0400 (Tue, 23 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: 226 $
 */

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

class admin_ccs_templates_pages extends ipsCommand
{
	/**
	 * Shortcut for url
	 *
	 * @access	private
	 * @var		string			URL shortcut
	 */
	private $form_code;
	
	/**
	 * Shortcut for url (javascript)
	 *
	 * @access	private
	 * @var		string			JS URL shortcut
	 */
	private $form_code_js;
	
	/**
	 * HTML library
	 *
	 * @access	public
	 * @var		object
	 */
	public $html;

	/**
	 * Main class entry point
	 *
	 * @access	public
	 * @param	object		ipsRegistry reference
	 * @return	void		[Outputs to screen]
	 */
	public function doExecute( ipsRegistry $registry ) 
	{
		//-----------------------------------------
		// Load HTML
		//-----------------------------------------
		
		$this->html = $this->registry->output->loadTemplate( 'cp_skin_templates' );
		
		//-----------------------------------------
		// Set up stuff
		//-----------------------------------------
		
		$this->form_code	= $this->html->form_code	= 'module=templates&amp;section=pages';
		$this->form_code_js	= $this->html->form_code_js	= 'module=templates&section=pages';
		
		$this->request['type']	= $this->request['type'] ? $this->request['type'] : 'page';

		//-----------------------------------------
		// Load Language
		//-----------------------------------------
		
		ipsRegistry::getClass('class_localization')->loadLanguageFile( array( 'admin_lang' ) );

		//-----------------------------------------
		// Grab extra CSS
		//-----------------------------------------
		
		$this->registry->output->addToDocumentHead( 'importcss', $this->settings['skin_app_url'] . 'css/ccs.css' );
		
		$_global = $this->registry->output->loadTemplate( 'cp_skin_ccsglobal' );
		
		$this->registry->output->addToDocumentHead( 'inlinecss', $_global->getCss() );
		
		//-----------------------------------------
		// What to do?
		//-----------------------------------------
		
		switch( $this->request['do'] )
		{
			case 'add':
			case 'edit':
				$this->_form( $this->request['do'] );
			break;			

			case 'doAdd':
			case 'doEdit':
				$this->_save( strtolower( str_replace( 'do', '', $this->request['do'] ) ) );
			break;
			
			case 'delete':
				$this->_delete();
			break;
			
			case 'addCategory':
				$this->_categoryForm( 'add' );
			break;
			case 'editCategory':
				$this->_categoryForm( 'edit' );
			break;
			
			case 'doAddCategory':
				$this->_categorySave( 'add' );
			break;
			case 'doEditCategory':
				$this->_categorySave( 'edit' );
			break;
			
			case 'deleteCategory':
				$this->_deleteCategory();
			break;

			default:
				$this->_list();
			break;
		}
		
		//-----------------------------------------
		// Pass to CP output hander
		//-----------------------------------------
		
		$this->registry->getClass('output')->html_main .= $this->registry->getClass('output')->global_template->global_frame_wrapper();
		$this->registry->getClass('output')->sendOutput();
	}
	
	/**
	 * Delete a category
	 *
	 * @access	protected
	 * @return	void
	 */
	protected function _deleteCategory()
	{
		$id	= intval($this->request['id']);
		
		$this->DB->update( 'ccs_page_templates', array( 'template_category' => 0 ), 'template_category=' . $id );
		$this->DB->delete( 'ccs_containers', 'container_id=' . $id );
		
		$this->registry->output->global_message = $this->lang->words['template_cat_deleted'];

		$this->registry->output->silentRedirectWithMessage( $this->settings['base_url'] . $this->form_code . '&amp;type=' . $this->request['type'] );
	}

	/**
	 * Save a category
	 *
	 * @access	protected
	 * @param	string		Type (add or edit)
	 * @return	void
	 */
	protected function _categorySave( $type='add' )
	{
		$category	= array();
		
		if( $type == 'edit' )
		{
			$id			= intval($this->request['id']);
			$category	= $this->DB->buildAndFetch( array( 'select' => '*', 'from' => 'ccs_containers', 'where' => "container_type IN('template','dbtemplate','arttemplate') AND container_id=" . $id ) );
			
			if( !$category['container_id'] )
			{
				$this->registry->output->showError( $this->lang->words['category__cannotfind'], '11CCS144' );
			}
		}
		
		$save	= array( 'container_name' => $this->request['category_title'] );
		
		if( $type == 'add' )
		{
			$save['container_type']		= $this->request['type'] == 'database' ? 'dbtemplate' : ( $this->request['type'] == 'article' ? 'arttemplate' : 'template' );
			$save['container_order']	= 100;
			
			$this->DB->insert( 'ccs_containers', $save );
		}
		else
		{
			$this->DB->update( 'ccs_containers', $save, "container_id=" . $category['container_id'] );
		}
		
		$this->registry->output->global_message = $this->lang->words['template_cat_save__good'];

		$this->registry->output->silentRedirectWithMessage( $this->settings['base_url'] . $this->form_code . '&amp;type=' . $this->request['type'] );
	}
	
	/**
	 * Form to add/edit a category
	 *
	 * @access	protected
	 * @param	string		Type (add or edit)
	 * @return	void
	 */
	protected function _categoryForm( $type='add' )
	{
		$category	= array();
		
		if( $type == 'edit' )
		{
			$id			= intval($this->request['id']);
			$category	= $this->DB->buildAndFetch( array( 'select' => '*', 'from' => 'ccs_containers', 'where' => "container_type IN('template','dbtemplate','arttemplate') AND container_id=" . $id ) );
			
			if( !$category['container_id'] )
			{
				$this->registry->output->showError( $this->lang->words['category__cannotfind'], '11CCS145' );
			}
		}
		
		$this->registry->output->html .= $this->html->categoryForm( $type, $category );
	}

	/**
	 * List the current page templates
	 *
	 * @access	protected
	 * @return	void
	 */
	protected function _list()
	{
		//-----------------------------------------
		// Get current templates
		//-----------------------------------------
		
		$templateIds	= array( 0 );
		$templates		= array();

		if( $this->request['type'] == 'database' )
		{
			$this->DB->build( array(
									'select'	=> 't.template_id, t.template_category', 
									'from'		=> array( 'ccs_page_templates' => 't' ), 
									'order'		=> 't.template_position ASC',
									'where'		=> 't.template_database > 0',	// 1-3 is regular databases
									'group'		=> 't.template_id, t.template_category, t.template_position',
									'add_join'	=> array(
														array(
															'select'	=> 'COUNT(d.database_id) as dbs',
															'from'		=> array( 'ccs_databases' => 'd' ),
															'where'		=> 'd.database_template_categories=t.template_id OR d.database_template_listing=t.template_id OR d.database_template_display=t.template_id',
															'type'		=> 'left',
															)
														)
							)		);
		}
		else if( $this->request['type'] == 'article' )
		{
			$this->DB->build( array(
									'select'	=> 't.template_id, t.template_category', 
									'from'		=> array( 'ccs_page_templates' => 't' ), 
									'order'		=> 't.template_position ASC',
									'where'		=> 't.template_database > 3',	// 4-7 is for articles
							)		);
		}
		else
		{
			$this->DB->build( array(
									'select'	=> 't.template_id, t.template_category', 
									'from'		=> array( 'ccs_page_templates' => 't' ), 
									'order'		=> 't.template_position ASC',
									'where'		=> 't.template_database = 0',
									'group'		=> 't.template_id, t.template_category, t.template_position',
									'add_join'	=> array(
														array(
															'select'	=> 'COUNT(p.page_id) as pages',
															'from'		=> array( 'ccs_pages' => 'p' ),
															'where'		=> 'p.page_template_used=t.template_id',
															'type'		=> 'left',
															)
														)
							)		);
		}
		
		$this->DB->execute();
		
		while( $r = $this->DB->fetch() )
		{
			$templates[ intval($r['template_category']) ][ $r['template_id'] ]	= $r;
			
			$templateIds[]	= $r['template_id'];
		}

		$this->DB->build( array(
								'select'	=> '*', 
								'from'		=> 'ccs_page_templates', 
								'where'		=> 'template_id IN(' . implode( ',', $templateIds ) . ')',
						)		);
		$this->DB->execute();
		
		while( $r = $this->DB->fetch() )
		{
			$r['template_updated_formatted']	= $this->lang->getDate( $r['template_updated'], 'SHORT', 1 );
			
			$templates[ intval($r['template_category']) ][ $r['template_id'] ]	= array_merge( $templates[ intval($r['template_category']) ][ $r['template_id'] ], $r );
		}
		
		//-----------------------------------------
		// Get template categories
		//-----------------------------------------
		
		$categories	= array();

		if( $this->request['type'] == 'database' )
		{
			$this->DB->build( array( 'select' => '*', 'from' => 'ccs_containers', 'where' => "container_type='dbtemplate'", 'order' => 'container_order ASC' ) );
		}
		else if( $this->request['type'] == 'article' )
		{
			$this->DB->build( array( 'select' => '*', 'from' => 'ccs_containers', 'where' => "container_type='arttemplate'", 'order' => 'container_order ASC' ) );
		}
		else
		{
			$this->DB->build( array( 'select' => '*', 'from' => 'ccs_containers', 'where' => "container_type='template'", 'order' => 'container_order ASC' ) );
		}
		
		$this->DB->execute();
		
		while( $r = $this->DB->fetch() )
		{
			$categories[]	= $r;
		}

		//-----------------------------------------
		// Output
		//-----------------------------------------
		
		if( $this->request['type'] == 'database' )
		{
			$this->registry->output->html .= $this->html->listTemplatesDatabase( $templates, $categories );
		}
		else if( $this->request['type'] == 'article' )
		{
			$this->registry->output->html .= $this->html->listTemplatesArticles( $templates, $categories );
		}
		else
		{
			$this->registry->output->html .= $this->html->listTemplatesPage( $templates, $categories );
		}
	}
	
	/**
	 * Delete a template
	 *
	 * @access	protected
	 * @return	void
	 */
	protected function _delete()
	{
		$id	= intval($this->request['template']);
		
		//-----------------------------------------
		// If template is used, warn user
		//-----------------------------------------
		
		if( !$this->request['confirm'] )
		{
			$template	= $this->DB->buildAndFetch( array( 'select' => '*', 'from' => 'ccs_page_templates', 'where' => 'template_id=' . $id ) );
			$check		= $this->DB->buildAndFetch( array( 'select' => "COUNT(*) as total", 'from' => 'ccs_pages', 'where' => 'page_template_used=' . $id ) );
			
			if( $check['total'] )
			{
				$this->registry->output->html .= $this->html->confirmDelete( $id, $template, $check['total'] );
				return;
			}
		}

		//-----------------------------------------
		// Deletes
		//-----------------------------------------
		
		$this->DB->delete( 'ccs_page_templates', 'template_id=' . $id );
		$this->DB->delete( 'ccs_template_cache', "cache_type='template' AND cache_type_id=" . $id );
		
		//-----------------------------------------
		// Recache the "skin" file
		//-----------------------------------------
		
		require_once( IPSLib::getAppDir( 'ccs' ) . '/sources/pages.php' );
		$_pagesClass	= new pageBuilder( $this->registry );
		$_pagesClass->recacheTemplateCache();
		
		//-----------------------------------------
		// Also clear any cache using this template..
		//-----------------------------------------
		
		$this->DB->update( 'ccs_pages', array( 'page_cache' => null ), 'page_template_used=' . $id );
		
		$this->registry->output->global_message = $this->lang->words['template_deleted'];

		$this->registry->output->silentRedirectWithMessage( $this->settings['base_url'] . $this->form_code . '&amp;type=' . $this->request['type'] );
	}

	/**
	 * Show the form to add or edit a page template
	 *
	 * @access	protected
	 * @param	string		[$type]		Type of form (add|edit)
	 * @return	void
	 * @todo 	Update this method for new templates
	 */
	protected function _form( $type='add' )
	{
		$defaults	= array( 'template_content' => '{ccs special_tag="page_content"}' );
		$form		= array();
		
		if( $type == 'edit' )
		{
			$id	= intval($this->request['template']);
			
			if( !$id )
			{
				$this->registry->output->showError( $this->lang->words['ccs_no_template_id'], '11CCS146' );
			}
			
			$defaults	= $this->DB->buildAndFetch( array( 'select' => '*', 'from' => 'ccs_page_templates', 'where' => 'template_id=' . $id ) );
		}
		else
		{
			if( $this->request['database'] )
			{
				$_lookFor	= 0;
				
				switch( $this->request['database'] )
				{
					case 1:
						$_lookFor	= 3;
					break;
					
					case 2:
						$_lookFor	= 1;
					break;
					
					case 3:
						$_lookFor	= 2;
					break;
					
					case 4:
						$_lookFor	= 4;
					break;
					
					case 5:
						$_lookFor	= 5;
					break;
					
					case 6:
						$_lookFor	= 10;
					break;
					
					case 7:
						$_lookFor	= 11;
					break;
				}
				
				if( $_lookFor )
				{
					$content	= file_get_contents( IPSLib::getAppDir('ccs') . '/xml/demosite.xml' );
					
					require_once( IPS_KERNEL_PATH . 'classXML.php' );
			
					$xml = new classXML( IPS_DOC_CHAR_SET );
					$xml->loadXML( $content );
				
					foreach( $xml->fetchElements('template') as $template )
					{
						$_template	= $xml->fetchElementsFromRecord( $template );
	
						if( $_template['template_id'] == $_lookFor )
						{
							$defaults['template_content']	= $_template['template_content'];
						}
					}
					
					$defaults['template_database']	= $this->request['database'];
				}
			}
		}
		
		$form['name']			= $this->registry->output->formInput( 'template_name', $this->request['template_name'] ? $this->request['template_name'] : $defaults['template_name'] );
		$form['key']			= $this->registry->output->formInput( 'template_key', $this->request['template_key'] ? $this->request['template_key'] : $defaults['template_key'] );
		$form['description']	= $this->registry->output->formTextarea( 'template_desc', $this->request['template_desc'] ? $this->request['template_desc'] : $defaults['template_desc'], 75, 3 );
		$form['content']		= $this->registry->output->formTextarea( 'template_content', htmlspecialchars( $_POST['template_content'] ? $_POST['template_content'] : $defaults['template_content'] ), 75, 30, 'template_content', "style='width:100%;'" );
		
		//-----------------------------------------
		// Category, if available
		//-----------------------------------------
		
		$form['category']		= '';
		$categories				= array();
		
		if( $this->request['type'] == 'database' )
		{
			$this->DB->build( array( 'select' => '*', 'from' => 'ccs_containers', 'where' => "container_type='dbtemplate'", 'order' => 'container_order ASC' ) );
		}
		else if( $this->request['type'] == 'article' )
		{
			$this->DB->build( array( 'select' => '*', 'from' => 'ccs_containers', 'where' => "container_type='arttemplate'", 'order' => 'container_order ASC' ) );
		}
		else
		{
			$this->DB->build( array( 'select' => '*', 'from' => 'ccs_containers', 'where' => "container_type='template'", 'order' => 'container_order ASC' ) );
		}
		
		$this->DB->execute();
		
		while( $r = $this->DB->fetch() )
		{
			$categories[]	= array( $r['container_id'], $r['container_name'] );
		}
		
		if( count($categories) )
		{
			array_unshift( $categories, array( '0', $this->lang->words['no_selected_cat'] ) );
			
			$form['category']	= $this->registry->output->formDropdown( 'template_category', $categories, $this->request['template_category'] ? $this->request['template_category'] : $defaults['template_category'] );
		}
		
		//-----------------------------------------
		// Output
		//-----------------------------------------
		
		$this->registry->output->html .= $this->html->templateForm( $type, $defaults, $form );
		
		//-----------------------------------------
		// WYSIWYG editing
		//-----------------------------------------

		$_globalHtml	= $this->registry->output->loadTemplate( 'cp_skin_ccsglobal' );
		
		$this->registry->output->html .= $_globalHtml->getWysiwyg( 'template_content' );
	}
	
	/**
	 * Save the edits to a template
	 *
	 * @access	protected
	 * @param	string		[$type]		Saving of form (add|edit)
	 * @return	void
	 */
	protected function _save( $type='add' )
	{
		//-----------------------------------------
		// Protected links from dashboard
		//-----------------------------------------
		
		if ( $this->request['request_method'] != 'post' )
		{
			return $this->_form( $type );
		}
		
		$id	= 0;

		if( $type == 'edit' )
		{
			$id	= intval($this->request['template']);
			
			if( !$id )
			{
				$this->registry->output->showError( $this->lang->words['ccs_no_template_id'], '11CCS147' );
			}
		}
		
		$save	= array(
						'template_name'		=> trim($this->request['template_name']),
						'template_desc'		=> trim($this->request['template_desc']),
						'template_key'		=> trim( str_replace( '-', '_', IPSText::alphanumericalClean( $this->request['template_key'] ) ) ),
						'template_content'	=> str_replace( '&#46;&#46;/', '../', trim($_POST['template_content']) ),
						'template_updated'	=> time(),
						'template_category'	=> intval($this->request['template_category']),
						'template_database'	=> intval($this->request['template_database']),
						);

		//-----------------------------------------
		// Make sure key is unique
		//-----------------------------------------
		
		if( !$save['template_key'] )
		{
			$this->registry->output->showError( $this->lang->words['template_key_missing'], '11CCS148' );
		}
		
		$check	= $this->DB->buildAndFetch( array( 'select' => 'template_id', 'from' => 'ccs_page_templates', 'where' => "template_key='{$save['template_key']}' AND template_id<>{$id}" ) );
		
		if( $check['template_id'] )
		{
			$this->registry->output->showError( $this->lang->words['template_key_used'], '11CCS149' );
		}

		//-----------------------------------------
		// Test the syntax
		//-----------------------------------------
		
		require_once( IPS_KERNEL_PATH . 'classTemplateEngine.php' );
		$engine					= new classTemplate( IPS_ROOT_PATH . 'sources/template_plugins' );
		
		$_TEST	= $engine->convertHtmlToPhp( 'test__' . $save['template_key'], $save['template_database'] ? '$data' : '', $save['template_content'], '', false, true );

		ob_start();
		eval( $_TEST );
		$_RETURN = ob_get_contents();
		ob_end_clean();

		if( $_RETURN )
		{
			$this->registry->output->global_error	= $this->lang->words['bad_template_syntax'];
			
			$this->_form( $type );
			return;
		}
		
		//-----------------------------------------
		// Save
		//-----------------------------------------
		
		if( $type == 'edit' )
		{
			$this->DB->update( 'ccs_page_templates', $save, 'template_id=' . $id );
			
			$this->DB->update( 'ccs_pages', array( 'page_cache' => null ), 'page_template_used=' . $id );
			
			$this->registry->output->global_message = $this->lang->words['template_edited'];
		}
		else
		{
			$this->DB->insert( 'ccs_page_templates', $save );
			
			$id	= $this->DB->getInsertId();
			
			$this->registry->output->global_message = $this->lang->words['template_added'];
			
			$this->request['template']	= $id;
		}
		
		//-----------------------------------------
		// Recache the template
		//-----------------------------------------
		
		$cache	= array(
						'cache_type'	=> 'template',
						'cache_type_id'	=> $id,
						);

		require_once( IPS_KERNEL_PATH . 'classTemplateEngine.php' );
		$engine					= new classTemplate( IPS_ROOT_PATH . 'sources/template_plugins' );
		$cache['cache_content']	= $engine->convertHtmlToPhp( 'template_' . $save['template_key'], $save['template_database'] ? '$data' : '', $save['template_content'], '', false, true );
		
		$hasIt	= $this->DB->buildAndFetch( array( 'select' => 'cache_id', 'from' => 'ccs_template_cache', 'where' => "cache_type='template' AND cache_type_id={$id}" ) );
		
		if( $hasIt['cache_id'] )
		{
			$this->DB->update( 'ccs_template_cache', $cache, "cache_type='template' AND cache_type_id={$id}" );
		}
		else
		{
			$this->DB->insert( 'ccs_template_cache', $cache );
		}

		//-----------------------------------------
		// Recache the "skin" file
		//-----------------------------------------
		
		require_once( IPSLib::getAppDir( 'ccs' ) . '/sources/pages.php' );
		$_pagesClass	= new pageBuilder( $this->registry );
		$_pagesClass->recacheTemplateCache( $engine );
		
		//-----------------------------------------
		// Show form again?
		//-----------------------------------------
		
		if( $this->request['save_and_reload'] )
		{
			$this->_form( 'edit' );
			return;
		}
		
		//-----------------------------------------
		// Output
		//-----------------------------------------

		$this->registry->output->silentRedirectWithMessage( $this->settings['base_url'] . $this->form_code . '&amp;type=' . $this->request['type'] );
	}
}
