Location: PHPKode > projects > CubeHenge > CubeHengeServer-v0.1.1/cubehenge/services/Publicity/Publicity.php
<?php
/*
 * Created on May 30, 2009
 *
 * Copyright 2009 Ryan T. Graff
 * 
 */
 
 /*
  * 
  * Publicity
  * 
  * Publicity is a dynamic view management system. It allows for reading and writing of
  * script templates representing views in a web browser. (HTML, CSS, JavaScript or other web browser supported languages.)
  * Each script can contain parameters designated by the following delimters: ${param}.
  * A repeated parameter will result in data being applied to the given view in multiple locations.
  * A view (or list of views) can be access with provided data and will return a view script
  * prepoulated with values from the provided data according to selected property mapping.
  * 
  * Features Include:
  * 1. Functionality for saving/editing/deleting views.
  * 2. Show a list of views.
  * 3. Functionality for saving/editing/deleting property mappings.
  * 4. Show a list of mappings.
  * 5. Functionality for linking from one view to one or many other views.
  * 6. Multi-dimensional view/data provider mappings.
  * 
  * */
 
 class Publicity{
 	
 	// Error constants
 	public static $PUBLICITY_ERROR = "PUBLICITY_ERROR:";
 	public static $VIEW_NOT_FOUND = "VIEW_NOT_FOUND";
 	public static $MAPPING_NOT_FOUND = "MAPPING_NOT_FOUND";
 	public static $ERROR_BAD_PATH = "ERROR_BAD_PATH";
 	public static $FILE_IO_ERROR = "FILE_IO_ERROR";
 	
 	// Linked view constants
 	public static $PARAM_NAME = "PARAM_NAME_INDEX";
 	public static $MAPPING_INDEX = "MAPPING_INDEX";
 	public static $VIEW_INDEX = "VIEW_INDEX";
 	public static $DELIMITER_INDEX = "DELIMITER_INDEX";
 	
 	// Filter array constants
 	public static $FILTER_NAME = "filterName";
 	public static $FILTER_FOLDER = "filterFolder";
 	
 	public function Publicity()
 	{
 		
 		
 		
 	}
 	
 	// Views
 	
 	public function saveView( $name, $script, $folder = "" )
 	{
 		
 		if( $folder == "" ){
 			
 			$folder = ".";
 			
 		}
 		
 		$path = 'views/' . $folder . '/' . $name . '.php';
 		
 		$this->writeFile( $path, $script );
 		
 		return true;
 		
 	}
 	
 	public function readView( $name, $folder = "" )
 	{
 		
 		if( $folder == "" ){
 			
 			$folder = ".";
 			
 		}
 		
 		$path = 'views/' . $folder . "/" . $name . ".php";
 		
 		$view = $this->readFile( $path );
 		
 		return $view;
 		
 	}
 	
 	public function listViews( $folder = "" )
 	{
 		
 		if( $folder == "" ){
 			
 			$folder = ".";
 			
 		}
 		
 		chdir( "views" );
 		
 		$this->validatePath( $folder );
 		
 		//
 		$folderList = array();
 		$viewList = array();
 		
 		// Read list from folder.
		if ($handle = opendir( $folder )) {
		    
		    while (false !== ($file = readdir($handle))) {
		        
		        if( $file == ".." || $file == "." ){
		        	
		        	continue;
		        	
		        }
		        
		        if( strpos( $file, '.php' ) === false ){
		        	
		        	$dir = $folder . "/" . $file;
		        	
		        	$dir = str_replace( "//", "/", $dir );
		        	
		        	$folderList[] = $dir;
		        	
		        }else{
		        	
		        	$viewList[] = str_replace( ".php", "", $file );
		        	
		        }
		        
		    }
		
		    closedir($handle);
		}
		
		$data = array();
		$data['folders'] = $folderList;
		$data['views'] = $viewList;
		
		return $data;
 		
 	}
 	
 	public function deleteView( $name, $folder = "" )
 	{
 		
 		if( $folder == "" ){
 			
 			$folder = ".";
 			
 		}
 		
 		$path = "views/" . $folder . "/" . $name . ".php";
 		
 		return $this->deleteFile( $path );
 		
 	}
 	
 	// Mappings
 	
 	public function buildMappingProperty( $mappingName, $dataIndex, $parameter, $folder = "", $makeViewLink = false, $linkedViewName = "", $linkedViewFolder = "" )
 	{
 		
 		$map = array();
 		
 		if( $makeViewLink ){
 			
 			$linkedViewPath = $linkedViewFolder . '/' . $linkedViewName;
 			
 			$map[ $dataIndex ] = $this->createMultiDimSubMapObject( $parameter, $linkedViewPath, null );
 			
 		}else{
 			
 			$map[ $dataIndex ] = $parameter;
 			
 		}
 		
 		return $this->saveMapping( $mappingName, $map, $folder );
 		
 	}
 	
 	public function nestMappings( $parentMappingName, $childMappingArray, $view, $dataIndex, $parameter, $parentMappingFolder = "", $viewFolder = "", $delimiter = null, $newParentMappingName = null )
 	{
 		
 		$parentMap = $this->readMapping( $parentMappingName, $parentMappingFolder );
 		
 		$viewPath = $viewFolder . "/" . $view;
 		
 		$subMap = $this->createMultiDimSubMapObject( $parameter, $viewPath, $childMappingArray, $delimiter );
 		
 		$parentMap[ $dataIndex ] = $subMap;
 		
 		$parentName = $parentMappingName;
 		
 		if( $newParentMappingName != "" && $newParentMappingName != null ){
 			
 			$parentName .= $newParentMappingName;
 			
 		}
 		
 		return $this->saveMapping( $parentName, $parentMap, $parentMappingFolder );
 		
 	}
 	
 	public function saveMapping( $name, $mappingArray, $folder = "", $overwrite = false )
 	{
 		
 		if( $folder == "" ){
 			
 			$folder = ".";
 			
 		}
 		
 		if( !$overwrite ){
 			
 			$map = array();
 			
 			if( $this->mappingExists( $name, $folder ) ){
 				
 				$map = $this->readMapping( $name, $folder );
 				
 			}
 			
 			$mappingArray = array_merge( $map, $mappingArray );
 			
 		}
 		
 		$data = '<?php  $map = \'' . serialize( $mappingArray ) . '\'; ?>';
 		$path = 'mappings/' . $folder . '/' . $name . '.php';
 		
 		$this->writeFile( $path, $data );
 		
 		return true;
 		
 	}
 	
 	public function readMapping( $name, $folder = "" )
 	{
 		
 		if( $folder == "" ){
 			
 			$folder = ".";
 			
 		}
 		
 		$path = 'mappings/' . $folder . "/" . $name . ".php";
 		
 		$this->validatePath( $path );
 		
 		if( !@include( $path ) ){
 			
 			throw new Exception( Publicity::$PUBLICITY_ERROR . Publicity::$MAPPING_NOT_FOUND );
 			
 		}
 		
 		$data = unserialize( $map );
 		
 		return $data;
 		
 	}
 	
 	public function listMappings( $folder = "" )
 	{
 		
 		if( $folder == "" ){
 			
 			$folder = ".";
 			
 		}
 		
 		chdir( "mappings" );
 		
 		$this->validatePath( $folder );
 		
 		//
 		$folderList = array();
 		$mappingsList = array();
 		
 		// Read list from folder.
		if ($handle = opendir( $folder )) {
		    
		    while (false !== ($file = readdir($handle))) {
		        
		        if( $file == ".." || $file == "." ){
		        	
		        	continue;
		        	
		        }
		        
		        if( strpos( $file, '.php' ) === false ){
		        	
		        	$dir = $folder . "/" . $file;
		        	
		        	$dir = str_replace( "//", "/", $dir );
		        	
		        	$folderList[] = $dir;
		        	
		        }else{
		        	
		        	$mappingsList[] = str_replace( ".php", "", $file );
		        	
		        }
		        
		    }
		
		    closedir($handle);
		}
		
		$data = array();
		$data['folders'] = $folderList;
		$data['mappings'] = $mappingsList;
		
		return $data;
 		
 	}
 	
 	public function deleteMapping( $name, $folder = "" )
 	{
 		
 		if( $folder == "" ){
 			
 			$folder = ".";
 			
 		}
 		
 		$path = "mappings/" . $folder . "/" . $name . ".php";
 		
 		return $this->deleteFile( $path );
 		
 	}
 	
 	// Filters
 	
 	public function saveFilter( $name, $script, $folder = "" )
 	{
 		
 		if( $folder == "" ){
 			
 			$folder = ".";
 			
 		}
 		
 		$path = 'filters/' . $folder . '/' . $name . '.php';
 		
 		$this->writeFile( $path, $script );
 		
 		return true;
 		
 	}
 	
 	public function readFilter( $name, $folder = "" )
 	{
 		
 		if( $folder == "" ){
 			
 			$folder = ".";
 			
 		}
 		
 		$path = 'filters/' . $folder . "/" . $name . ".php";
 		
 		$filter = $this->readFile( $path );
 		
 		return $filter;
 		
 	}
 	
 	public function listFilters( $folder = "" )
 	{
 		
 		if( $folder == "" ){
 			
 			$folder = ".";
 			
 		}
 		
 		chdir( "filters" );
 		
 		$this->validatePath( $folder );
 		
 		//
 		$folderList = array();
 		$filterList = array();
 		
 		// Read list from folder.
		if ($handle = opendir( $folder )) {
		    
		    while (false !== ($file = readdir($handle))) {
		        
		        if( $file == ".." || $file == "." ){
		        	
		        	continue;
		        	
		        }
		        
		        if( strpos( $file, '.php' ) === false ){
		        	
		        	$dir = $folder . "/" . $file;
		        	
		        	$dir = str_replace( "//", "/", $dir );
		        	
		        	$folderList[] = $dir;
		        	
		        }else{
		        	
		        	$filterList[] = str_replace( ".php", "", $file );
		        	
		        }
		        
		    }
		
		    closedir($handle);
		}
		
		$data = array();
		$data['folders'] = $folderList;
		$data['filters'] = $filterList;
		
		return $data;
 		
 	}
 	
 	public function deleteFilter( $name, $folder = "" )
 	{
 		
 		if( $folder == "" ){
 			
 			$folder = ".";
 			
 		}
 		
 		$path = "filters/" . $folder . "/" . $name . ".php";
 		
 		return $this->deleteFile( $path );
 		
 	}
 	
 	// 
 	
 	public function buildSingleView( $view, $data = null, $mapping = null, $viewFolder = "", $mappingFolder = "", $filters = null )
 	{
 		
 		if( $viewFolder == "" ){
 			
 			$viewFolder = ".";
 			
 		}
 		
 		if( $mappingFolder == "" ){
 			
 			$mappingFolder = ".";
 			
 		}
 		
 		$viewPath = $viewFolder . "/" . $view;
 		$mappingPath = $mappingFolder . "/" . $mapping;
 		
 		$this->validatePath( $viewPath );
 		$this->validatePath( $mappingPath );
 		
 		$script = $this->readFile( "views/" . $viewPath . ".php" );
 		
 		if( $data == null && $mapping == null ){
 			
 			return $script;
 			
 		}
 		
 		if( $mapping == null ){
 			
 			// Apply data properties to view parameters directly.
 			foreach( $data as $key => $value ){
 				
 				$value = (string) $value;
 				
 				$filteredValue = $value;
 				
 				if( $filters != null ){
 					
 					if( $filters[ $key ] != null ){
 						
 						$currentFilter = (array) $filters[ $key ];
 						
 						$filteredValue = $this->processFilter( $value, $currentFilter[ Publicity::$FILTER_NAME ], $currentFilter[ Publicity::$FILTER_FOLDER ] );
 						
 					}
 					
 				}
 				
 				$script = str_replace( '${' . $key . '}', $filteredValue, $script );
 				
 			}
 			
 			return $script;
 			
 		}
 		
 		$mapArray = array();
 		
 		if( is_array( $mapping ) ){
 			
 			$mapArray = $mapping;
 			
 		}else{
 			
 			if( !@include( "mappings/" . $mappingPath . ".php" ) ){
	 			
	 			throw new Exception( Publicity::$PUBLICITY_ERROR . Publicity::$MAPPING_NOT_FOUND );
	 			
	 		}
	 		
	 		$mapArray = unserialize( $map );
 			
 		}
 		
 		$dataToArray = (array) $data;
 		
 		foreach( $mapArray as $key => $value ){
 			
 			if( $data != null ){
 				
 				
 				$filteredValue = $dataToArray[ $key ];
				
				if( $filters != null ){
					
					if( $filters[ $key ] != null ){
						
						$currentFilter = (array) $filters[ $key ];
						
						$filteredValue = $this->processFilter( $dataToArray[ $key ], $currentFilter[ Publicity::$FILTER_NAME ], $currentFilter[ Publicity::$FILTER_FOLDER ] );
						
					}
					
				}
 				
 				$script = str_replace( '${' . $this->parseValueParamName( $value ) . '}', $this->parseMultiDimMapping( $filteredValue, $value ), $script );
 				
 			}else{
 				
 				$script = str_replace( '${' . $this->parseValueParamName( $value ) . '}', $this->parseMultiDimMapping( null, $value ), $script );
 				
 			}
 			
 		}
 		
 		return $script;
 		
 	}
 	
 	public function buildViewList( $view, $dataProvider = null, $mapping = null, $viewFolder = "", $mappingFolder = "", $filters = null )
 	{
 		
 		$views = array();
 		
 		for( $i = 0; $i <= count( $dataProvider ) - 1; $i++ ){
 			
 			$views[] = $this->buildSingleView( $view, $dataProvider[ $i ], $mapping, $viewFolder, $mappingFolder, $filters );
 			
 		}
 		
 		return $views;
 		
 	}
 	
 	// Util methods.
 	
 	public function viewExists( $name, $folder = "" )
 	{
 		
 		if( $folder == "" ){
 			
 			$folder = ".";
 			
 		}
 		
 		$path = "views/" . $folder . "/" . $name . ".php";
 		
 		$this->validatePath( $path );
 		
 		return file_exists( $path );
 		
 	}
 	
 	public function mappingExists( $name, $folder = "" )
 	{
 		
 		if( $folder == "" ){
 			
 			$folder = ".";
 			
 		}
 		
 		$path = "mappings/" . $folder . "/" . $name . ".php";
 		
 		$this->validatePath( $path );
 		
 		return file_exists( $path );
 		
 	}
 	
 	public function filterExists( $name, $folder = "" )
 	{
 		
 		if( $folder == "" ){
 			
 			$folder = ".";
 			
 		}
 		
 		$path = "filters/" . $folder . "/" . $name . ".php";
 		
 		$this->validatePath( $path );
 		
 		return file_exists( $path );
 		
 	}
 	
 	// Internal use only.
 	
 	private function processFilter( $data, $filter, $folder = "" )
 	{
 		
 		if( $filter == "" ){
 			
 			return $data;
 			
 		}
 		
 		if( $folder == null ){
 			
 			$folder = "";
 			
 		}
 		
 		if( $folder == "" ){
 			
 			$folder = ".";
 			
 		}
 		
 		$path = "filters/" . $folder . "/" . $filter . ".php";
 		
 		$this->validatePath( $path );
 		
 		if( !@include_once( $path ) ){
 			
 			throw new Exception( Publicity::$PUBLICITY_ERROR . Publicity::$ERROR_BAD_PATH . ":" . $path );
 			
 		}
 		
 		$filterFunction = str_replace( "/", "_", $folder ) . "_" . $filter;
 		
 		return $filterFunction( $data );
 		
 	}
 	
 	private function parseMultiDimMapping( $data, $subMapping )
 	{
 		
 		if( is_string( $subMapping ) ){
 			
 			if( $data == null ){
 				
 				$data = "";
 				
 			}
 			
 			return (string) $data;
 			
 		}
 		
 		$mapInfo = $subMapping[ Publicity::$MAPPING_INDEX ];
 		
 		// Parse multi-dimensional data
 		if( is_array( $data ) ){
 			
 			$delimiter = "";
 			
 			if( $subMapping[ Publicity::$DELIMITER_INDEX ] != null ){
 				
 				$delimiter = $subMapping[ Publicity::$DELIMITER_INDEX ];
 				
 			}
 			
 			return implode( $delimiter, $this->buildViewList( $subMapping[ Publicity::$VIEW_INDEX ], $data, $mapInfo ) );
 			
 		}
 		
 		return $this->buildSingleView( $subMapping[ Publicity::$VIEW_INDEX ], $data, $mapInfo );
 		
 	}
 	
 	private function parseValueParamName( $value )
 	{
 		
 		if( is_string( $value ) ){
 			
 			return $value;
 			
 		}
 		
 		$valArr = (array) $value;
 		
 		return $valArr[ Publicity::$PARAM_NAME ];
 		
 	}
 	
 	private function writeFile( $path, $data )
 	{
 		
 		$this->validatePath( $path );
 		
 		if( !@is_dir( dirname( $path ) ) ){
 			
 			$this->makeDeepDirectories( dirname( $path ) );
 			
 		}
 		
 		$handle = fopen( $path, "w" );
 		
 		if( !@fwrite( $handle, $data ) ){
 			
 			throw new Exception( Publicity::$PUBLICITY_ERROR . Publicity::$FILE_IO_ERROR . ":" . $path );
 			
 		}
 		
 		fclose( $handle );
 		
 	}
 	
 	private function makeDeepDirectories( $directory )
 	{
 		
 		$directory = str_replace( "\\", "/", $directory );
 		$directoryArray = explode( "/", $directory );
 		
 		$path = "";
 		
 		for( $i = 0; $i <= count( $directoryArray ) - 1; $i++ ){
 			
 			if( $directoryArray[ $i ] == "." || $directoryArray[ $i ] == "" ){
 				
 				continue;
 				
 			}
 			
 			$path .= $directoryArray[ $i ] . "/";
 			
 			$this->validatePath( $path );
 			
 			if( @is_dir( $path ) ){
 				
 				continue;
 				
 			}
 			
 			if( !@mkdir( $path ) ){
				
				throw new Exception( Publicity::$PUBLICITY_ERROR . Publicity::$FILE_IO_ERROR . ":" . $path );
				
			}
 			
 		}
 		
 	}
 	
 	private function readFile( $path )
 	{
 		
 		$this->validatePath( $path );
 		
 		if( !file_exists( $path ) ){
 			
 			throw new Exception( Publicity::$PUBLICITY_ERROR . Publicity::$ERROR_BAD_PATH . ":" . $path );
 			
 		}
 		
 		$handle = fopen( $path, "r" );
 		
 		if( !( $contents = @fread( $handle, filesize( $path ) ) ) ){
 			
 			throw new Exception( Publicity::$PUBLICITY_ERROR . Publicity::$FILE_IO_ERROR . ":" . $path );
 			
 		}
 		
 		fclose( $handle );
 		
 		return $contents;
 		
 	}
 	
 	private function deleteFile( $path )
 	{
 		
 		$this->validatePath( $path );
 		
 		if( !@unlink( $path ) ){
 			
 			throw new Exception( Publicity::$PUBLICITY_ERROR . Publicity::$FILE_IO_ERROR . ":" . $path );
 			
 		}
 		
 		return true;
 		
 	}
 	
 	private function createMultiDimSubMapObject( $paramName, $view, $mapping = null, $delimiter = null )
 	{
 		
 		$subMap = array();
 		
 		$this->validatePath( $view );
 		
 		$subMap[ Publicity::$PARAM_NAME ] = $paramName;
 		$subMap[ Publicity::$VIEW_INDEX ] = $view;
 		$subMap[ Publicity::$MAPPING_INDEX ] = $mapping;
 		
 		if( $delimiter != null ){
 			
 			$subMap[ Publicity::$DELIMITER_INDEX ] = $delimiter;
 			
 		}
 		
 		return $subMap;
 		
 	}
 	
 	/** Verify that a path does not contain an instance of "..". */
 	private function validatePath( $path )
 	{
 		
 		$path = str_replace( "\\", "/", $path );
 		
 		if( strpos( $path, ".." ) !== false || strpos( $path, "/" ) === 0 || strpos( $path, ":" ) !== false ){
 			
 			throw new Exception( Publicity::$PUBLICITY_ERROR . Publicity::$ERROR_BAD_PATH . ":" . $path );
 			
 		}
 		
 	}
 	
 }
 
?>
Return current item: CubeHenge