<?php

/**
 * @package FlutterDatabaseObjects
 */

/**
 * Create/edit/delete modules 
 * @package FlutterDatabaseObjects
 */

class RCCWP_CustomWriteModule
{
	
	/**
	 * Get all modules
	 *
	 * @return array of objects containing all modules.
	 */
	function GetCustomModules()
	{
		global $wpdb;
	
		$sql = "SELECT * FROM " . RC_CWP_TABLE_MODULES;
		
		$sql .= " ORDER BY name ASC";
		$results = $wpdb->get_results($sql);
		if (!isset($results)) 
			$results = array();

		return $results;
	}
	
	
	/**
	 * Create a new module
	 *
	 * @param string $name module name, the name will be sanitized.
	 * @param string $description module description
	 * @param boolean $create_folders whether to create a folder for the module containing sample template
	 * @return the id of the module or -1 if the module name already exist
	 */

	function Create($name, $description, $create_folders = true)
	{
		require_once('RC_Format.php');
		global $wpdb;
		
		$special_chars = array (' ','`','"','\'','\\','/'," ","#","$","%","^","&","*","!","~","‘","\"","’","'","=","?","/","[","]","(",")","|","<",">",";","\\",",");
		$name = str_replace($special_chars,'',$name);

		//Make sure the module doesn't already exist
		$sql = "SELECT * FROM " . RC_CWP_TABLE_MODULES .
			" WHERE name = '" . $name . "'";
		if ($wpdb->get_row($sql))	return -1;

		$sql = sprintf(
			"INSERT INTO " . RC_CWP_TABLE_MODULES .
			" (name, description)" .
			" values" .
			" (%s, %s)", 
			RC_Format::TextToSql($name),
			RC_Format::TextToSql($description)
		);
			
		$wpdb->query($sql);
		$customWriteModuleId = $wpdb->insert_id;

		if ($create_folders == false)
			return $customWriteModuleId;

		// Create template folder
		$moduleTemplateFolder = dirname(__FILE__)."/modules/".$name;
		if (@mkdir($moduleTemplateFolder, 0777)){
			@chmod($moduleTemplateFolder, 0777);
			if (mkdir($moduleTemplateFolder.'/templates', 0777)){
				@chmod($moduleTemplateFolder.'/templates', 0777);
				if (mkdir($moduleTemplateFolder.'/templates/default', 0777)){	
					@chmod($moduleTemplateFolder.'/templates/default', 0777);
					RCCWP_CustomWriteModule::CreateTemplateFiles($moduleTemplateFolder.'/templates/default/small', $name);
				}
			}

			//Create basic configuration file 
			$configurationFileContent = 
<<<EOF
	<?xml version="1.0"?>
	<canvas>
		<function>
			<author>
			Flutter
			</author>
			<description>
			This is module $name.
			</description>
			<variables>
				<variable>
					<name>
					the_text
					</name>
					<description>
					Text to display (HTML allowed)
					</description>
					<type>
					Textarea
					</type>
					<default>
					<![CDATA[<p>This is some text generated by $name module. </p>]]>
					</default>
				</variable>
			</variables>
		</function>
	</canvas>
EOF;

	
			file_put_contents ($moduleTemplateFolder."/configure.xml", $configurationFileContent);	
			@chmod($moduleTemplateFolder."/configure.xml", 0666);
		}
		
		return $customWriteModuleId;
	}

	/**
	 * @access private 
	 */
	function CreateTemplateFiles($templatePath, $name){
			$defaultFileContent = 
<<<EOF
	<?php
		echo '<div class="block">';
		echo mod_var('the_text');
		echo '</div>';
	?>
EOF;

		if (mkdir($templatePath, 0777)){
			@chmod($templatePath, 0777);
			file_put_contents ($templatePath."/default.php", $defaultFileContent);
			@chmod($templatePath."/default.php", 0666);
		}
	}
	
	/**
	 * Deletes a module and all its child fields as well as the module folder.
	 *
	 * @param integer $customWriteModuleId module id.
	 */
	
	function Delete($customWriteModuleId = null)
	{
		include_once ('RCCWP_CustomGroup.php');
		if (isset($customWriteModuleId))
		{
			global $wpdb;
			
			$customWriteModule = RCCWP_CustomWriteModule::Get($customWriteModuleId);
			$customWriteModuleName = $customWriteModule->name;
		  	
  			$sql = sprintf(
				"DELETE FROM " . RC_CWP_TABLE_MODULES .
				" WHERE id = %d",
				$customWriteModuleId
				);
			$wpdb->query($sql);

			// Remove template folder
			if (!empty($customWriteModuleName)){
				$moduleTemplateFolder = dirname(__FILE__)."/modules/".$customWriteModuleName;
				RCCWP_CustomWriteModule::remove_dir($moduleTemplateFolder);
			}

			// Remove canvas info
			include_once "canvas-import_functions.php";
			canvas_delete_block_by_mod_ID($customWriteModuleId);
			
		}
		
	}

	/**
	 * @access private 
	 */
	function remove_dir($dir)
	{
		if(is_dir($dir))
		{
		$dir = (substr($dir, -1) != "/")? $dir."/":$dir;
		$openDir = opendir($dir);
		while($file = readdir($openDir))
		{
			if(!in_array($file, array(".", "..")))
			{
			if(!is_dir($dir.$file))
				@unlink($dir.$file);
			else
				RCCWP_CustomWriteModule::remove_dir($dir.$file);
			}
		}
		closedir($openDir);
		@rmdir($dir);
		}
	}
	
	/**
	 * Retrieves the basic information of the module. 
	 *
	 * @param integer $customWriteModuleId module id
	 * @return an object containing id, name and description
	 */
	function Get($customWriteModuleId)
	{
		global $wpdb;
	
		$sql = "SELECT * FROM " . RC_CWP_TABLE_MODULES .
			" WHERE id = " . (int)$customWriteModuleId;
		
		$results = $wpdb->get_row($sql);
		
		return $results;
	}

	/**
	 * Retrieves the basic information of the module given module name.
	 *
	 * @param string $customWriteModuleName module name
	 * @return an object containing id, name and description
	 */
	function GetByName($customWriteModuleName)
	{
		global $wpdb;
	
		$sql = "SELECT * FROM " . RC_CWP_TABLE_MODULES .
			" WHERE name = '$customWriteModuleName'";
		
		$results = $wpdb->get_row($sql);
		
		return $results;
	}
	
	/**
	 * Updates the basic information of a module
	 *
	 * @param integer $customWriteModuleId the id of the module that will be updated
	 * @param string $name new name
	 * @param string $description new description
	 * @return the id of the module or -1 if the module name already exist
	 */
	
	function Update($customWriteModuleId, $name, $description)
	{
		require_once('RC_Format.php');
		global $wpdb;
		
		//$capabilityName = RCCWP_CustomWriteModule::GetCapabilityName($name);
		$special_chars = array (' ','`','"','\'','\\','/'," ","#","$","%","^","&","*","!","~","‘","\"","’","'","=","?","/","[","]","(",")","|","<",">",";","\\",",");
		$name = str_replace($special_chars,'',$name);

		//Make sure the module doesn't already exist
		$sql = "SELECT * FROM " . RC_CWP_TABLE_MODULES .
			" WHERE name = '" . $name . "' AND id <> $customWriteModuleId";
		if ($wpdb->get_row($sql))	return -1;

		//Get old name
		$sql = "SELECT name FROM " . RC_CWP_TABLE_MODULES .
			" WHERE id = $customWriteModuleId";
		$originalModName = $wpdb->get_var($sql);
		$oldModuleTemplateFolder = dirname(__FILE__)."/modules/".$originalModName;

		// Update name
		$sql = sprintf(
			"UPDATE " . RC_CWP_TABLE_MODULES .
			" SET name = %s,".
			"     description = %s".
			" where id = %d",
			RC_Format::TextToSql($name),
			RC_Format::TextToSql($description),
			$customWriteModuleId );
		
		$wpdb->query($sql);

		//Rename module folder
		$newModuleTemplateFolder = dirname(__FILE__)."/modules/".$name;
		rename($oldModuleTemplateFolder, $newModuleTemplateFolder);
		
		return $customWriteModuleId;
		
	}

	
	/**
	 * Import a module given the zip file path. Importing a module means inserting it in
	 * the database and copying its folder to modules folder. If a module with the same
	 * name already exists, the function will append a number to the module name. You must 
	 * have either php ZipArchive extension or unzip program installed.
	 *
	 * @param string $zipFilePath the full path of the zip file
	 * @param string $moduleName the module name, if this value if false, the function will
	 * 							use the zip filename as the module name. The default value is false
	 * @return the module id, or false in case of error.
	 */

	function Import($zipFilePath, $moduleName = false)
	{
		include_once('RCCWP_CustomGroup.php');
		include_once('RCCWP_CustomField.php');
		include_once('RCCWP_CustomWritePanel.php');
		include_once('RCCWP_Application.php');
		include_once('RCCWP_CustomWritePanel.php');

		if (!$moduleName)
			//use zip filename
			$moduleName = basename($zipFilePath, ".zip");

		if ($moduleName == '') return false;

		// Append a number if the module already exists,
		$i = 1;
		$newModuleName = $moduleName;
		while (file_exists(FLUTTER_MODULES_DIR.$newModuleName)){
			$newModuleName = $moduleName. "_" . $i++;
		}
		$moduleName = $newModuleName;


		mkdir(FLUTTER_MODULES_DIR.$moduleName);
		chmod(FLUTTER_MODULES_DIR.$moduleName, 0777);

		$destPath = FLUTTER_MODULES_DIR.$moduleName.DIRECTORY_SEPARATOR;

		if (class_exists('ZipArchive')){
			$zip = new ZipArchive() ;

			// open archive
			if ($zip->open($zipFilePath) !== TRUE) {
				die ("Could not open archive");
			}
			
			// extract contents to destination directory
			$zip->extractTo($destPath);
			
			// close archive
			$zip->close();
		}else{
			if (RCCWP_Application::CheckDecompressionProgramUnzip()) 
				$command = "unzip $zipFilePath -d ". $destPath;
			else{
				die("Cannot find unzip program!");
			}
			exec($command, $out, $err);
		}
		$moduleInfo_imported_data = unserialize(file_get_contents($destPath.'module_info.exp'));
		
		//Import module
		$moduleID = RCCWP_CustomWriteModule::Create($moduleName, $moduleInfo_imported_data['moduleinfo']->description, false);
		
		//Import any panels
		if ($handle = @opendir($destPath)) {
			while (false !== ($file = readdir($handle))) { 
				if (substr($file, 0, 1) == "_"){
					$panelName = basename(substr($file, 1), ".pnl");
					RCCWP_CustomWritePanel::Import($destPath.$file, $panelName);
				}
			}
		}
		
		//Create Duplicates
		foreach($moduleInfo_imported_data['duplicates'] as $moduleDuplicate){
			RCCWP_ModuleDuplicate::Create($moduleID, $moduleDuplicate->duplicate_name);
		}		
		
		return $moduleID;
	}
}
?>
