rootDirs = $rootDirs; } public function exists( $file ){ $file = trim( $file, '/' ); foreach ( $this->rootDirs as $rootDir ){ $path = "{$rootDir}/{$file}"; if ( file_exists( $path ) ){ return TRUE; } } return FALSE; } public function get_recent_path( $file ){ $file = trim( $file, '/' ); foreach ( $this->rootDirs as $rootDir ){ $path = "{$rootDir}/{$file}"; if ( file_exists( $path ) ){ return $rootDir; } } return FALSE; } public function make_dir( $dir, $zeroTime = FALSE ){ $dir = trim( $dir, '/' ); if ( $this->exists( $dir ) ){ return FALSE; } $path = "{$this->rootDirs[0]}/{$dir}"; return $this->create_node( $path, NULL, $zeroTime ); } public function make_dir_in_recent( $dir, $zeroTime = FALSE ){ $dir = trim( $dir, '/' ); if ( $this->exists( $dir ) ){ return FALSE; } $path = $this->get_recent_path( dirname( $dir ) ); $path = ( $path ? $path : $this->rootDirs[0] ) . "/{$dir}"; return $this->create_node( $path, NULL, $zeroTime ); } public function put_contents( $file, $data, $zeroTime = FALSE ){ $file = trim( $file, '/' ); if ( $this->exists( $file ) ){ return FALSE; } $path = "{$this->rootDirs[0]}/{$file}"; return $this->create_node( $path, $data, $zeroTime ); } public function put_contents_in_recent( $file, $data, $zeroTime = FALSE ){ $file = trim( $file, '/' ); if ( $this->exists( $file ) ){ return FALSE; } $path = $this->get_recent_path( dirname( $file ) ); $path = ( $path ? $path : $this->rootDirs[0] ) . "/{$file}"; return $this->create_node( $path, $data, $zeroTime ); } public function get_listing( $dir, $pattern = '*', $descending = FALSE ){ $dir = trim( $dir, '/' ); $result = []; foreach ( $this->rootDirs as $rootDir ){ $path = "{$rootDir}/{$dir}"; if ( ! file_exists( $path ) ){ continue; } $listing = glob( "{$path}/{$pattern}", GLOB_NOSORT | GLOB_BRACE ); if ( $listing ){ $listing = array_map( 'basename', $listing ); $result = array_merge( $result, $listing ); } } $result = array_unique( $result ); if ( $descending ){ rsort( $result, SORT_STRING ); } else { sort( $result, SORT_STRING ); } return $result; } public function is_not_empty( $dir ){ $dir = trim( $dir, '/' ); foreach ( $this->rootDirs as $rootDir ){ $iterator = new \FilesystemIterator( $rootDir ); if ( $iterator->valid() ){ return TRUE; } } return FALSE; } public function count_items_in_recent( $dir, $pattern = NULL, $recursively = FALSE ){ $dir = trim( $dir, '/' ); $path = $this->get_recent_path( $dir ); if ( ! $path ){ return 0; } $cmd = "find '{$path}' -mindepth 1" . ( $recursively ? '' : ' -maxdepth 1' ) . ( $pattern ? ' -name ' . $pattern : '' ) . ' -printf x | wc -c'; exec( $cmd, $output, $returnVar ); return $returnVar == 0 ? (int) implode( $output ) : 0; } public function get_contents( $file ){ $file = trim( $file, '/' ); foreach ( $this->rootDirs as $rootDir ){ $path = "{$rootDir}/{$file}"; if ( file_exists( $path ) ){ return file_get_contents( $path ); } } return FALSE; } public function get_recent_contents( $dir, $pattern = '*' ){ $dir = trim( $dir, '/' ); foreach ( $this->rootDirs as $rootDir ){ $path = "{$rootDir}/{$dir}"; if ( file_exists( $path ) ){ $listing = glob( "{$path}/{$pattern}", GLOB_NOSORT | GLOB_BRACE ); if ( empty( $listing ) ){ continue; } rsort( $listing ); foreach ( $listing as $item ){ if ( ! is_dir( $item ) ){ return file_get_contents( $item ); } } } } return FALSE; } private function create_node( $path, $data = NULL, $zeroTime = FALSE ){ $this->lastError = ''; $path = ( $path[0] == '/' ? '' : $this->baseDir ) . $path; if ( file_exists( $path ) ){ $this->lastError = 'File already exists'; return FALSE; } // Automatically set zeroTime option if parent directory has zero date $dir = dirname( $path ); if ( ! $zeroTime && file_exists( $dir ) ){ $zeroTime = filemtime( $dir ) < 86400; } // If zeroTime option is not set, use traditional file system functions if ( ! $zeroTime ){ if ( is_null( $data ) ){ if ( ! mkdir( $path, 0755, TRUE ) ){ $this->lastError = "Could not create directory {$path}"; return FALSE; } } else { $dir = dirname( $path ); if ( ! file_exists( $dir ) && ! mkdir( $dir, 0755, TRUE ) ){ $this->lastError = "Could not create directory {$dir}"; return FALSE; } if ( ! file_put_contents( $path, $data ) ){ $this->lastError = "Could not write file {$path}"; return FALSE; } } return TRUE; } // Otherwise create node and set its modification date to zero (i.e. 1970-01-01 00:00:00) // Zero dates of parent directories must be preserved, so find first path item with zero date ... $startPath = ''; foreach ( explode( '/', ltrim( $path, '/' ) ) as $item ){ $startPath .= "/{$item}"; if ( ! file_exists( $startPath ) || filemtime( $startPath ) < 86400 ){ break; } } if ( is_null( $data ) ){ if ( ! mkdir( $path, 0755, TRUE ) ){ $this->lastError = "Could not create directory {$path}"; return FALSE; } } else { if ( ! file_exists( dirname( $path ) ) && ! $this->create_node( dirname( $path ), NULL, TRUE ) ){ return FALSE; } if ( ! file_put_contents( $path, $data ) ){ $this->lastError = "Could not write file {$path}"; return FALSE; } chmod( $path, 0644 ); } do { touch( $path, 0 ); } while ( $path != $startPath && $path = dirname( $path ) ); return TRUE; } } // end of file file_system.class.php /* $rootDirs = [ '/home/martin/Sandkasten/ParTCP_File_System/data', '/home/martin/Sandkasten/ParTCP_File_System/data2', '/home/martin/Sandkasten/ParTCP_File_System/data3' ]; $FS = new ParTCP_File_System( $rootDirs ); //var_dump( $FS->count_items( 'groups' ) ); var_dump( $FS->get_listing( 'groups' ) ); */