<?php
defined('WikyBlog') or die("Not an entry point...");

includeFile('admin/PluginAdd.php');

class directoryFunctions extends pluginAdd{
	var $spaces;
	var $currentSpaces;
	
	////////////////////////////////////////////////////////////////////////////////////
	//
	//				Exporting
	//
	
	function exportAsPlugin($nameSpace){
		global $wbTables,$dbInfo,$packageVersion;
		
		if( !isset($dbInfo[$nameSpace]) || !isset($dbInfo[$nameSpace]['class']) ){
			message('INVALID_REQUEST');
			return false;
		}
		if( !function_exists('var_export') ){
			message('INVALID_REQUEST');
			return false;
		}
			
		$class = $dbInfo[$nameSpace]['class'];
		$info = $dbInfo[$nameSpace];
		
		$installAs = $nameSpace;
		if( isset($info['alias']) ){
			$installAs = $info['alias'];
		}
		$similar = false;
		if( isset($info['similar']) ){
			$similar = var_export($info['similar'],true);
		}
		
		
		$query = 'SELECT `data` FROM '.$wbTables['ad_objects'].' WHERE `selector` = "class:'. wbDB::escape($class) .'" LIMIT 1;';
		$result = wbDB::runQuery($query);
		$row = mysql_fetch_assoc($result);
		if( !$row ){
			message('Invalid database entry.');
			return;
		}
		
		$this->exportHeader(false);
		
		//
		//	config.php
		//
		unset($info['dbPlugin']);
		unset($info['alias']);
		unset($info['similar']);
		
		if( !isset($info['useInfo']) ){
			if( isset($info['dirs']) ){
				$info['useInfo'] = $info['dirs'];
				
			}elseif( isset($info['keySpace']) ){
				$info['useInfo'] = $info['keySpace'];
			}
		}
		unset($info['dirs']);
		unset($info['keySpace']);
		
		echo '<h3>config.php</h3>';
		echo '<div style="margin:0 3em 0 3em;">';
		echo '<textarea wrap="off" style="width:100%;margin:0;" rows="7">';
		echo '<'.'?php';
		echo "\n";
		echo 'defined(\'WikyBlog\') or die(\'Not an entry point...\');';
		echo "\n";
		echo "\n";
		
		foreach($info as $var => $value){
			echo '$installInfo[\''.$var.'\'] = '.wbHtmlspecialchars(var_export($value,true)).';';
			echo "\n";
		}
		
		//	Optional
		echo "\n// Optional";
		echo "\n";
		echo '//$installAs = '.$this->escape($installAs).';';
		if( is_string($similar) ){
			echo "\n";
			echo '//$installInfo[\'similar\'] = '.str_replace(array("\n","\r"),array(''),$similar).';';
		}
			
		echo '</textarea>';
		echo '</div>';
				
		
		//
		//	class.php
		//
		echo '<h3>class.php</h3>';
		echo '<div style="margin:0 3em 0 3em;">';
		echo '<textarea wrap="off" style="width:100%;margin:0;" rows="20">';
		echo '<'.'?'."php\n";
		echo 'defined(\'WikyBlog\') or die(\'Not an entry point...\');';
		
		echo "\n";
		echo "\n";
		echo wbHtmlspecialchars($row['data']);
		echo '</textarea>';
		echo '</div>';

		
		echo '<p>';
		echo ' <input type="submit" name="cmd" value="Back" />';
		echo '</p>';
	}
	
	
	////////////////////////////////////////////////////////////////////////////////////
	//
	//				Checking
	//
	
	function checkDirName(){
		global $dbInfo,$wbTables;
		
		if( empty($_POST['name']) ){
			message('You must provide a name.');
			return false;
		}		
		if( !isset($this->spaces[$_POST['space']]) ){
			message('Invalid space requested.');
			return false;
		}
		
		$_POST['name'] = toStorage($_POST['name']);
		$lowerName = wbStrtolower($_POST['name']);
		if( !parent::checkName($_POST['name']) ){
			return false;
		}
		$this->space = $_POST['space'];
		return true;
	}
	
	function checkWhere(){
		global $wbTables;
		
		if( !empty($_POST['where']) ){
			$table = wbData::dbInfo($_POST['space'],'dbTable');
			$query = 'EXPLAIN SELECT * FROM '.$table;
			$query .= ' INNER JOIN '.$wbTables['all_files'];
			$query .= ' ON '.$wbTables['all_files'].'.`file_id` = '.$table.'.`file_id` ';
			$query .= ' WHERE 1 AND '.$_POST['where'];
			$result = @mysql_query($query);
			if( !$result ){
				message('"Where" must be valid sql.');
				return false;
			}
		}
		return true;
	}

	
	////////////////////////////////////////////////////////////////////////////////////
	//
	//				Saving
	//
	function finish(){
		global $dbObject, $wbDisableFeatures;
		
		if( isset($wbDisableFeatures) && $wbDisableFeatures ){
			message('<b>Sorry, this feature was disabled.');
			return false;
		}		
		
		
		//
		//	Check
		//
			if( !$this->check() ){
				return false;
			}
			$this->className = $this->getClassName( wbStrtolower($_POST['name']) );
			$class = $this->createClass();
			if( !$class ){
				return false;
			}
			$newInfo = $this->newDbInfo();
			
		//
		//	Save
		//
			if( !$this->saveNew($class,$newInfo) ){
				return false;
			}
			return true;
	}
	
	function saveNew($code,$newInfo){
		global $dbObject,$dbInfo;
		
		//
		//	dbInfo
		//
		
			$name = wbStrtolower($_POST['name']);
			if( !is_array($newInfo) ){
				message('Directory creation failed.');
				return false;
			}
			
			$testCode = $code.'$TEST="hello";';
			eval($testCode);
			if( $TEST !== "hello"){
				message('The PHP code did not evaluate.');
				return false;
			}
			
			if( !$this->ad_object('class:'.$this->className,$code) ){
				message('Couldn\'t save object.');
				return false;
			}
			
			$data = $dbObject->getConfiguration();
			$data['dbInfo'][$name] = $dbInfo[$name] = $newInfo;
			
			if( method_exists($this,'addSimilar') ){
				$this->addSimilar($data,$name);
			}
			
			if( !$dbObject->updateConfig($data) ){
				echo 'Oops, the space wasn\'t created successfully, please try again.';
				return false;
			}
			
			$this->savePostData($name);
			
		message('Space created.');
		$this->currentSpaces[$name] = $_POST['space'];
		return true;		
	}
	
	function update(){
		global $dbObject,$dbInfo;
		//change class
		$name = wbStrtolower($_POST['name']);
		$this->className = $dbInfo[$name]['class'];
		
		if( !$this->check() ){
			return false;
		}
		
		$code = $this->createClass();
		if( !$code ){
			return false;
		}
		if( !$this->ad_object('class:'.$this->className,$code) ){
			message('Couldn\'t save object.');
			return false;
		}
		$this->savePostData($name);
		
		//update similar
		$data = $dbObject->getConfiguration();
		
		if( method_exists($this,'addSimilar') ){
			$this->removeSimilar($data,$name);
			$this->addSimilar($data,$name);
		}
		$dbObject->updateConfig($data);
		
		
		message('Space updated.');
		return true;
	}
	
	
	
	function savePostData($name){
		$serialized = serialize($_POST);
		$this->ad_object('dirEdit:'.$name,$serialized);
	}
	
	
	////////////////////////////////////////////////////////////////////////////////////
	//
	//				Removing/Deleting
	//
	
	function removeDirCheck(){
		echo '<div style="text-align:center;padding:3em;">';
		echo 'Are you sure you want to remove <tt>'.$_GET['name'].'</tt>?<br/>';
		echo '<input type="submit" value="Cancel" /> ';
		echo ' &nbsp; <input type="submit" name="cmd['.$_GET['name'].']" value="Confirm Removal" /> ';
		echo '</div>';
	}

	function removeDir($type){
		global $dbInfo,$dbObject,$page;
		
		$name =& $page->cmdArg[0];
		
		if( !isset($dbInfo[$name]) ){
			message($name.' was an invalid argument. ');
			return;
		}
			
		if( !isset($dbInfo[$name][$type]) ){
			message($name.' was an invalid argument.');
			return;
		}
		
		$data = $dbObject->getConfiguration();
		if(isset($data['dbInfo'][$name]['dbPlugin'])){
			$this->removeObject('class:'.$data['dbInfo'][$name]['class']);
		}
		$this->removeObject('dirEdit:'.$data['dbInfo'][$name]['class']);
		

		
		unset($data['dbInfo'][$name]);
		if( method_exists($this,'removeSimilar') ){
			$this->removeSimilar($data,$name);
		}
		if( !$dbObject->updateConfig($data) ){
			echo 'Oops, the space wasn\'t deleted successfully, please try again.';
		}
		message('The selected space was removed.');
		unset($this->currentSpaces[$name]);
	}
	
	////////////////////////////////////////////////////////////////////////////////////
	//
	//				Editing
	//
	
	function setVariables($space){
		global $wbTables,$wbTablePrefix;
			
			
		//
		//	Types
		//	
			$this->types = array();
			$this->types['timestamp'] = array('Year','Quarter','Month','Week of Year','Day of Week','Day of Month','Hour','Year-Month','Month-Day','Whole Value');
			$this->types['datetime'] =& $this->types['timestamp'];
			$this->types['time'] = array('Hour','Minute');
			$this->types['date'] = array('Year','Quarter','Month','Week of Year','Day of Week','Day of Month','Whole Value');
			//$this->types['varchar'] = array('Comma Separated','Whole Value');
			
			$this->types['varchar'] = array('Comma Separated','Comma and Colon Separated','Whole Value');
			$this->types['char'] =& $this->types['varchar'];
			$this->types['string'] =& $this->types['varchar']; //because of mysql_field_type
			$this->types['enum'] =& $this->types['varchar'];
			$this->types['set'] =& $this->types['varchar'];
			
			$this->types['int'] = array('Whole Value');
			$this->types['tinyint'] =& $this->types['int'];
			$this->types['smallint'] =& $this->types['int'];
			$this->types['mediumint'] =& $this->types['int'];
			$this->types['bigint'] =& $this->types['int'];
			
			
			
			//	Results of mysql_field_type
			//
			// CHAR, VARCHAR, TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT, ENUM, SET: string
			// TINYINT, SMALLINT, MEDIUMINT, INT, INTEGER, BIGINT: int
			// FLOAT, DOUBLE, DECIMAL, NUMERIC: real
			// TIMESTAMP: timestamp
			// YEAR: year
			// DATE: date
			// TIME: time
			// DATETIME: datetime
			// TINYBLOB, MEDIUMBLOB, LONGBLOB, BLOB: blob
			
		//
		//	Get detailed information from the table
		//
			$this->variables= array();
			
			$avoid = array(	'file_id'=>1,'owner'=>1,'title'=>1,
							'content'=>1,'ip'=>1,'username'=>1,
							'hitcounter'=>1,'summary'=>1);
			
			
			
			$from = wbData::dbInfo($space,'queryFrom');
			$query = 'SELECT * FROM '.$from;
			$query .= ' LIMIT 1 OFFSET 0';
			
			$result = wbDB::runQuery($query);
			$row = mysql_fetch_row($result);
			$i = 0;
			$prefixLen = strlen($wbTablePrefix);
			while( $i < mysql_num_fields($result) ){
				
				$type = @mysql_field_type($result,$i);
				$field = @mysql_field_name($result,$i);
				
				if( $pos = strpos($type,'(')){
					$type = substr($type,0,$pos);
				}
				if( !isset($this->types[$type]) ){
					$i++;
					//message('skipped: '.$field.' :: '.$type);
					continue;
				}
				
				
				$this->variables[$field] = $type;
				
				$table = mysql_field_table($result,$i);
				$testPrefix = substr($table,0,strlen($wbTablePrefix));
				if( $testPrefix == $wbTablePrefix ){
					$table = substr($table,strlen($wbTablePrefix));
				}
				$this->varTables[$field] = $table;
				$i ++;
			}

			
			//	if the data type uses more than one table in queryFrom .. like events, this won't show all those values
			//
			// $tempObject = null;
			// wbData::newObject($space,$tempObject,true);
			// $table = $tempObject->dbInfo['dbTable'];
			// $query = 'SHOW FULL COLUMNS FROM '.$table;
			
			// $result = wbDB::runQuery($query);
			// while($row = mysql_fetch_assoc($result)){
			// 	if(isset($avoid[$row['Field']])){
			// 		continue;
			// 	}
			// 	$field =& $row['Field'];
			// 	if( $pos = strpos($row['Type'],'(')){
			// 		$type = substr($row['Type'],0,$pos);
			// 	}else{
			// 		$type =& $row['Type'];
			// 	}
			// 	if( !isset($this->types[$type]) ){
			// 		continue;
			// 	}
			// 	
			// 	$this->variables[$field] = $type;
			// }
			
			$this->variables['keywords'] = 'varchar';
			$this->varTables['keywords'] = 'all_files';
			
			$this->variables['modified'] = 'timestamp';
			$this->varTables['modified'] = 'all_files';
			
			$this->variables['posted'] = 'timestamp';
			$this->varTables['posted'] = 'all_files';

			$this->variables['created'] = 'timestamp';
			$this->varTables['created'] = 'all_files';
	}
	
	function selectVariables($name,$i){
		echo '<select name="'.$name.'[]">';
		echo '<option value="">-ignore-</option>';
		foreach($this->variables as $field => $type){
			echo '<option value=""></option>';
			echo '<optgroup label="'.$field.'" title="'.$field.'">';
			$this->selectVariables2($name,$i,$field,$type);
			echo '</optgroup>';
		}
		echo '</select>';
	}
	
	function selectVariables2($name,$i,$field,$type){
		$temp = array();
		$temp = $this->types[$type];
		foreach($temp as $how){
			$value = $field.':'.$how;
			if( isset($_POST[$name][$i]) && ($_POST[$name][$i] == $value) ){
				echo '<option value="'.$value.'" selected="selected">'.$field.' &nbsp; - &nbsp; '.$how.'</option>';
			}else{
				echo '<option value="'.$value.'">'.$field.' &nbsp; - &nbsp; '.$how.'</option>';
			}
		}
	}

	
	function createClassOrderBy(){
		
		$variables = array_flip($this->variables);
		if( is_array($_POST['order']) ){
			$tempA = array();
			foreach($_POST['order'] as $i => $column){
				if( empty($column) ){
					continue;
				}
				$temp = $this->columnSQL($column);
				$tempA[] = $temp['sqlOrder'].' '.$_POST['order2'][$i];
			}
			if( count($tempA) > 0){
				return $this->escapeSafe(implode(', ',$tempA));
			}
		}
		return false;
	}
	
	function columnSQL(&$post){
		global $wbTables,$dbInfo,$wbTablePrefix;
		
		$pos = strpos($post,':');
		$column = substr($post,0,$pos);
		$how = substr($post,$pos+1);
		
		$column = '`{$wbTablePrefix}'.$this->varTables[$column].'`.`'.$column.'` ';
		
		$result = array();
		$result['sqlOrder'] = false;
		$result['sqlShow'] = false;
		$result['instruction'] = false;
		
		$result['instruction'] = false;
		
		switch($how){
			
			//timestamps
			case 'Year':
				$result['sqlOrder'] = 'YEAR('.$column.')';
			break;
			case 'Quarter':
				$result['sqlOrder'] = 'CONCAT("Quarter ",QUARTER('.$column.'))';
			break; 
			case 'Month':
				$result['sqlOrder'] = 'DATE_FORMAT('.$column.',"0%m")';//put a zero in front.. otherwise it won't order correctly
				$result['sqlShow'] = 'DATE_FORMAT('.$column.',"%M")';
			break;
			case 'Week of Year';
				$result['sqlOrder'] = 'CONCAT("Week ",WEEK('.$column.'))';
			break;
			case 'Day of Week':
				$result['sqlOrder'] = 'DATE_FORMAT('.$column.',"0%w")';
				$result['sqlShow'] = 'DATE_FORMAT('.$column.',"%W")';
			break;
			case 'Day of Month':
				$result['sqlOrder'] = 'DATE_FORMAT('.$column.',"0%d")';
				$result['sqlShow'] = 'DATE_FORMAT('.$column.',"%e")';
			break;
			case 'Hour':
				$result['sqlOrder'] = 'Hour('.$column.')';
			break;
			case 'Minute':
				$result['sqlOrder'] = 'Minute('.$column.')';
			break;
			case 'Second':
				$result['sqlOrder'] = 'Second('.$column.')';
			break;
			
			case 'Year-Month':
				$result['sqlOrder'] = 'DATE_FORMAT('.$column.',"0%Y%m")';
				$result['sqlShow'] = 'DATE_FORMAT('.$column.',"%Y %M")';
			break;
			
			case 'Month-Day':
				$result['sqlOrder'] = 'DATE_FORMAT('.$column.',"0%m%e")';
				$result['sqlShow'] = 'DATE_FORMAT('.$column.',"%M %e")';
			break;
			
			
			case 'Whole Value':
				$result['sqlOrder'] = $column;
			break;
			
			case 'Comma Separated':
				$result['sqlOrder'] = $column.' ';
				$result['instruction'] = 'comma';	//special instruction 
			break;
			
			case 'Comma and Colon Separated';
				$result['sqlOrder'] = $column.'  '; //we add a couple of spaces 
				$result['instruction'] = 'commacolon';	//special instruction 
			break;
			
			default:
				trigger_error('No type for : '.$post);
			return;
		
		}
		if( !$result['sqlShow'] ){
			$result['sqlShow'] = $result['sqlOrder'];
		}
		
		return $result;
	}
	
	
	function editVals($name){
		global $wbTables;
		$query = 'SELECT `data` FROM '.$wbTables['ad_objects'];
		$query .= ' WHERE `selector` = "dirEdit:'. wbDB::escape($name) .'"  LIMIT 1 OFFSET 0;';
		$result = wbDB::runQuery($query);
		if( $row = mysql_fetch_assoc($result) ){
			$data = unserialize($row['data']);
			if( is_array($data) ){
				$_POST += $data;
				$this->create(false);
				return true;
			}else{
				message('Invalid data.'); //make sure the `data` column is utf8_general_ci
				//message('Invalid data:<textarea style="width:100%" rows="5">'.htmlspecialchars($row['data']).'</textarea>');
			}
		}
		message('Data not available for this type (2)');
		return false;
	}
		
	function setSpaces(){
		global $dbInfo;
		
		foreach($dbInfo as $space => $info){
			if( !isset($info['dbTable']) ){
				continue;
			}
			$class = wbData::getClass($space,true);
			if( !$class ){
				continue;
			}
			if( is_callable(array($class,'abbrevOutput')) ){
				$this->spaces[$space] = true;
			}
		}
	}
	function setCurrentSpaces($type){
		global $dbInfo;
		foreach($dbInfo as $space => $info){
			if( isset($info[$type]) ){
				$this->currentSpaces[$space] = $info['useInfo'];
			}
		}
	}
	
	function escapeSafe(&$text){
		$text = addcslashes($text,'\"');
		return '"'.str_replace(array("\r","\n"),' ',$text).'"';
	}
	
	function escape(&$text){
		$text = addcslashes($text,"\'");
		return '\''.str_replace(array("\r","\n"),' ',$text).'\'';
	}
	
}