| // +----------------------------------------------------------------------+ // // $Id: Filesystem.php,v 1.3 2003/01/04 11:56:28 mj Exp $ require_once('Tree/Error.php'); /** * the Filesystem interface to the tree class * this is a bit different, as id we use the entire path, since we know * this is unique in a filesystem and an integer id could only be created * virtually, it doesnt have a tight connection to the actual directory * i.e. using 'add' with ids could fail since we dont know if we get the same * id when we call 'add' with a parentId to create a new folder under since our id would be made up. * so we use the complete path as id, which takes up a lot of memory, i know * but since php is typeless its possible and it makes life easier when * we want to create another dir, since we get the dir as parentId passed to the * 'add' method, whcih makes it easy to create a new dir there :-) * i also thought about hashing the path name but then the add method is not that * easy to implement ... may be one day :-) * * @access public * @author Wolfram Kriesing * @version 2001/06/27 * @package Tree */ class Tree_Memory_Filesystem { /** * @access public * @var array saves the options passed to the constructor */ var $options = array( 'order' =>'', // which column to order by when reading the data from the DB, this sorts the data even inside every level // the column-name maps are used for the "as" in the select queries // so you can use any column name in the table and "map" it to the name that shall be used in the // internal array, that is built, see the examples (in comments) 'columnNameMaps'=>array( /* 'id' => 'tree_id', // use "tree_id" as "id" 'parentId' => 'parent_id', 'prevId' => 'previous_id', 'name' => 'nodeName' */ ), ); /** * set up this object * * @version 2002/08/23 * @access public * @author Wolfram Kriesing * @param string $dsn the path on the filesystem * @param array $options additional options you can set */ function Tree_Memory_Filesystem( $path , $options=array() ) { $this->_path = $path; $this->_options = $options; // not in use currently /* $this->Tree_OptionsDB( $dsn , $options ); // instanciate DB if( is_string($options) ) // just to be backward compatible, or to make the second paramter shorter { $this->setOption( 'order' , $options ); } $this->table = $this->getOption('table'); */ } // end of function /** * retreive all the navigation data from the db and call build to build the * tree in the array data and structure * * @version 2001/11/20 * @access public * @author Wolfram Kriesing * @return boolean true on success */ function setup() { unset($this->data); // unset the data to be sure to get the real data again, no old data if( is_dir($this->_path) ) { $this->data[$this->_path] = array('id'=>$this->_path,'name'=>$this->_path,'parentId'=>0); $this->_setup($this->_path,$this->_path); } return $this->data; } function _setup( $path , $parentId=0 ) { if ($handle = opendir($path)) { while (false !== ($file = readdir($handle))) { if( $file != '.' && $file != '..' && is_dir("$path/$file")) { #$id = sizeof($this->data); $this->data[] = array('id'=>"$path/$file",'name'=>$file,'parentId'=>$parentId); $this->_setup( "$path/$file" , "$path/$file" ); } } closedir($handle); } } /** * this is tricky on a filesystem, since we are working with id's * as identifiers and we need to be sure, the parentId to create a node under * is the same as when the tree was last read, but this might be tricky * */ function add( $newValues , $parent=0 , $prevId=0 ) { if( !$parent ) $parent = $this->path; # FIXXME do the mapping if( !@mkdir( "$parent/{$newValues['name']}" , 0700 ) ) return $this->_throwError('couldnt create dir '.$newValues['name'].' under '.$parent,__LINE__); return "$parent/{$newValues['name']}"; } function remove( $id ) { if( !@rmdir( $id ) ) return $this->_throwError('couldnt remove dir '.$id,__LINE__); return true; } function copy( $srcId , $destId ) { # if( !@copy( $srcId , $destId ) ) this would only be for files :-) # FIXXME loop through the directory to copy the children too !!! $dest = $destId.'/'.preg_replace('/^.*\//','',$srcId); if( is_dir( $dest ) ) return $this->_throwError("couldnt copy, $destId already exists in $srcId " , __LINE__ ); if( !@mkdir( $dest , 0700 ) ) return $this->_throwError("couldnt copy dir from $srcId to $destId " , __LINE__ ); return true; } /** * * * @access private * @version 2002/03/02 * @author Wolfram Kriesing * @param * @return */ function _throwError( $msg , $line , $mode=null ) { return new Tree_Error( $msg , $line , __FILE__ , $mode , $this->db->last_query ); } /** * prepare multiple results * * @see _prepareResult() * @access private * @version 2002/03/03 * @author Wolfram Kriesing * @param * @return */ function _prepareResults( $results ) { $newResults = array(); foreach( $results as $aResult ) $newResults[] = $this->_prepareResult($aResult); return $newResults; } /** * map back the index names to get what is expected * * @access private * @version 2002/03/03 * @author Wolfram Kriesing * @param * @return */ function _prepareResult( $result ) { $map = $this->getOption('columnNameMaps'); if( $map ) foreach( $map as $key=>$columnName ) { $result[$key] = $result[$columnName]; unset($result[$columnName]); } return $result; } } // end of class ?>