[ Index ] |
|
Code source de PHP PEAR 1.4.5 |
1 <?php 2 // 3 // +------------------------------------------------------------------------+ 4 // | PEAR :: Package File Manager | 5 // +------------------------------------------------------------------------+ 6 // | Copyright (c) 2003-2004 Gregory Beaver | 7 // | Email cellog@phpdoc.org | 8 // +------------------------------------------------------------------------+ 9 // | This source file is subject to version 3.00 of the PHP License, | 10 // | that is available at http://www.php.net/license/3_0.txt. | 11 // | If you did not receive a copy of the PHP license and are unable to | 12 // | obtain it through the world-wide-web, please send a note to | 13 // | license@php.net so we can mail you a copy immediately. | 14 // +------------------------------------------------------------------------+ 15 // | Portions of this code based on phpDocumentor | 16 // | Web http://www.phpdoc.org | 17 // | Mirror http://phpdocu.sourceforge.net/ | 18 // +------------------------------------------------------------------------+ 19 // $Id: File.php,v 1.21 2005/03/28 06:37:35 cellog Exp $ 20 // 21 /** 22 * Retrieve the files from a directory listing 23 * @package PEAR_PackageFileManager 24 */ 25 /** 26 * Retrieve the files from a directory listing 27 * 28 * This class is used to retrieve a raw directory 29 * listing. Use the {@link PEAR_PackageFileManager_CVS} 30 * class to only retrieve the contents of a cvs 31 * repository when generating the package.xml 32 * @package PEAR_PackageFileManager 33 */ 34 class PEAR_PackageFileManager_File { 35 /** 36 * @var array 37 * @access private 38 */ 39 var $_options = 40 array( 41 ); 42 43 /** 44 * @access private 45 * @var PEAR_PackageFileManager 46 */ 47 var $_parent; 48 49 /** 50 * @access private 51 * @var array|false 52 */ 53 var $_ignore = false; 54 55 /** 56 * Set up the File filelist generator 57 * 58 * 'ignore' and 'include' are the only options that this class uses. See 59 * {@link PEAR_PackageFileManager::setOptions()} for 60 * more information and formatting of this option 61 * @param PEAR_PackageFileManager 62 * @param array 63 */ 64 function PEAR_PackageFileManager_File(&$parent, $options) 65 { 66 $this->_parent = &$parent; 67 $this->_options = array_merge($this->_options, $options); 68 } 69 70 /** 71 * Generate the <filelist></filelist> section 72 * of the package file. 73 * 74 * This function performs the backend generation of the array 75 * containing all files in this package 76 * @return array 77 */ 78 function getFileList() 79 { 80 $package_directory = $this->_options['packagedirectory']; 81 $ignore = $this->_options['ignore']; 82 // implicitly ignore packagefile 83 $ignore[] = $this->_options['packagefile']; 84 if ($this->_options['packagefile'] == 'package.xml') { 85 // ignore auto-generated package2.xml from PEAR 1.4.0 86 $ignore[] = 'package2.xml'; 87 } 88 $include = $this->_options['include']; 89 $this->ignore = array(false, false); 90 $this->_setupIgnore($ignore, 1); 91 $this->_setupIgnore($include, 0); 92 $allfiles = $this->dirList(substr($package_directory, 0, strlen($package_directory) - 1)); 93 if (PEAR::isError($allfiles)) { 94 return $allfiles; 95 } 96 if (!count($allfiles)) { 97 return PEAR_PackageFileManager::raiseError(PEAR_PACKAGEFILEMANAGER_NO_FILES, 98 substr($package_directory, 0, strlen($package_directory) - 1)); 99 } 100 $struc = array(); 101 foreach($allfiles as $file) { 102 $path = substr(dirname($file), strlen(str_replace(DIRECTORY_SEPARATOR, 103 '/', 104 realpath($package_directory))) + 1); 105 if (!$path) { 106 $path = '/'; 107 } 108 $ext = array_pop(explode('.', $file)); 109 if (strlen($ext) == strlen($file)) { 110 $ext = ''; 111 } 112 $struc[$path][] = array('file' => basename($file), 113 'ext' => $ext, 114 'path' => (($path == '/') ? basename($file) : $path . '/' . basename($file)), 115 'fullpath' => $file); 116 } 117 if (!count($struc)) { 118 $newig = implode($this->_options['ignore'], ', '); 119 return PEAR_PackageFileManager::raiseError(PEAR_PACKAGEFILEMANAGER_IGNORED_EVERYTHING, 120 substr($package_directory, 0, strlen($package_directory) - 1), $newig); 121 } 122 uksort($struc,'strnatcasecmp'); 123 foreach($struc as $key => $ind) { 124 usort($ind, array($this, 'sortfiles')); 125 $struc[$key] = $ind; 126 } 127 128 $tempstruc = $struc; 129 if (!isset($tempstruc['/'])) { 130 $tempstruc['/'] = array(); 131 } 132 $struc = array('/' => $tempstruc['/']); 133 $bv = 0; 134 foreach($tempstruc as $key => $ind) { 135 $save = $key; 136 if ($key != '/') 137 { 138 $struc['/'] = $this->_setupDirs($struc['/'], explode('/',$key), $tempstruc[$key]); 139 } 140 } 141 uksort($struc['/'], array($this, 'mystrucsort')); 142 143 return $struc; 144 } 145 146 /** 147 * Retrieve a listing of every file in $directory and 148 * all subdirectories. 149 * 150 * The return format is an array of full paths to files 151 * @access protected 152 * @return array list of files in a directory 153 * @param string $directory full path to the directory you want the list of 154 * @throws PEAR_PACKAGEFILEMANAGER_DIR_DOESNT_EXIST 155 */ 156 function dirList($directory) 157 { 158 $ret = false; 159 if (@is_dir($directory)) { 160 $ret = array(); 161 $d = @dir($directory); // thanks to Jason E Sweat (jsweat@users.sourceforge.net) for fix 162 while($d && false !== ($entry=$d->read())) { 163 if ($this->_testFile($directory, $entry)) { 164 if (is_file($directory . '/' . $entry)) { 165 // if include option was set, then only pass included files 166 if ($this->ignore[0]) { 167 if ($this->_checkIgnore($entry, $directory . '/' . $entry, 0)) { 168 continue; 169 } 170 } 171 // if ignore option was set, then only pass included files 172 if ($this->ignore[1]) { 173 if ($this->_checkIgnore($entry, $directory . '/' . $entry, 1)) { 174 continue; 175 } 176 } 177 $ret[] = $directory . '/' . $entry; 178 } 179 if (is_dir($directory . '/' . $entry)) { 180 $tmp = $this->dirList($directory . '/' . $entry); 181 if (is_array($tmp)) { 182 foreach($tmp as $ent) { 183 $ret[] = $ent; 184 } 185 } 186 } 187 } 188 } 189 if ($d) { 190 $d->close(); 191 } 192 } else { 193 return PEAR_PackageFileManager::raiseError(PEAR_PACKAGEFILEMANAGER_DIR_DOESNT_EXIST, $directory); 194 } 195 return $ret; 196 } 197 198 /** 199 * Test whether an entry should be processed. 200 * 201 * Normally, it ignores all files and directories that begin with "." addhiddenfiles option 202 * instead only ignores "." and ".." entries 203 * @access private 204 * @param string directory name of entry 205 * @param string name 206 */ 207 function _testFile($directory, $entry) 208 { 209 if ($this->_options['addhiddenfiles']) { 210 return is_file($directory . '/' . $entry) || (is_dir($directory . '/' . $entry) && !in_array($entry, array('.', '..'))); 211 } else { 212 return $entry{0} != '.'; 213 } 214 } 215 216 /** 217 * Tell whether to ignore a file or a directory 218 * allows * and ? wildcards 219 * 220 * @param string $file just the file name of the file or directory, 221 * in the case of directories this is the last dir 222 * @param string $path the full path 223 * @param 1|0 $return value to return if regexp matches. Set this to 224 * false to include only matches, true to exclude 225 * all matches 226 * @return bool true if $path should be ignored, false if it should not 227 * @access private 228 */ 229 function _checkIgnore($file, $path, $return = 1) 230 { 231 if (file_exists($path)) { 232 $path = realpath($path); 233 } 234 if (is_array($this->ignore[$return])) { 235 foreach($this->ignore[$return] as $match) { 236 // match is an array if the ignore parameter was a /path/to/pattern 237 if (is_array($match)) { 238 // check to see if the path matches with a path delimiter appended 239 preg_match('/^' . strtoupper($match[0]).'$/', strtoupper($path) . '/',$find); 240 if (!count($find)) { 241 // check to see if it matches without an appended path delimiter 242 preg_match('/^' . strtoupper($match[0]).'$/', strtoupper($path), $find); 243 } 244 if (count($find)) { 245 // check to see if the file matches the file portion of the regex string 246 preg_match('/^' . strtoupper($match[1]).'$/', strtoupper($file), $find); 247 if (count($find)) { 248 return $return; 249 } 250 } 251 // check to see if the full path matches the regex 252 preg_match('/^' . strtoupper($match[0]).'$/', 253 strtoupper($path . DIRECTORY_SEPARATOR . $file), $find); 254 if (count($find)) { 255 return $return; 256 } 257 } else { 258 // ignore parameter was just a pattern with no path delimiters 259 // check it against the path 260 preg_match('/^' . strtoupper($match).'$/', strtoupper($path), $find); 261 if (count($find)) { 262 return $return; 263 } 264 // check it against the file only 265 preg_match('/^' . strtoupper($match).'$/', strtoupper($file), $find); 266 if (count($find)) { 267 return $return; 268 } 269 } 270 } 271 } 272 return !$return; 273 } 274 275 /** 276 * Construct the {@link $ignore} array 277 * @param array strings of files/paths/wildcards to ignore 278 * @param 0|1 0 = files to include, 1 = files to ignore 279 * @access private 280 */ 281 function _setupIgnore($ignore, $index) 282 { 283 $ig = array(); 284 if (is_array($ignore)) { 285 for($i=0; $i<count($ignore);$i++) { 286 $ignore[$i] = strtr($ignore[$i], "\\", "/"); 287 $ignore[$i] = str_replace('//','/',$ignore[$i]); 288 289 if (!empty($ignore[$i])) { 290 if (!is_numeric(strpos($ignore[$i], '/'))) { 291 $ig[] = $this->_getRegExpableSearchString($ignore[$i]); 292 } else { 293 if (basename($ignore[$i]) . '/' == $ignore[$i]) { 294 $ig[] = $this->_getRegExpableSearchString($ignore[$i]); 295 } else { 296 $ig[] = array($this->_getRegExpableSearchString($ignore[$i]), 297 $this->_getRegExpableSearchString(basename($ignore[$i]))); 298 } 299 } 300 } 301 } 302 if (count($ig)) { 303 $this->ignore[$index] = $ig; 304 } else { 305 $this->ignore[$index] = false; 306 } 307 } else $this->ignore[$index] = false; 308 } 309 310 /** 311 * Converts $s into a string that can be used with preg_match 312 * @param string $s string with wildcards ? and * 313 * @return string converts * to .*, ? to ., etc. 314 * @access private 315 */ 316 function _getRegExpableSearchString($s) 317 { 318 $y = '\/'; 319 if (DIRECTORY_SEPARATOR == '\\') { 320 $y = '\\\\'; 321 } 322 $s = str_replace('/', DIRECTORY_SEPARATOR, $s); 323 $x = strtr($s, array('?' => '.','*' => '.*','.' => '\\.','\\' => '\\\\','/' => '\\/', 324 '[' => '\\[',']' => '\\]','-' => '\\-')); 325 if (strpos($s, DIRECTORY_SEPARATOR) !== false && 326 strrpos($s, DIRECTORY_SEPARATOR) === strlen($s) - 1) { 327 $x = "(?:.*$y$x?.*|$x.*)"; 328 } 329 return $x; 330 } 331 332 /** 333 * Recursively move contents of $struc into associative array 334 * 335 * The contents of $struc have many indexes like 'dir/subdir/subdir2'. 336 * This function converts them to 337 * array('dir' => array('subdir' => array('subdir2'))) 338 * @param array struc is array('dir' => array of files in dir, 339 * 'dir/subdir' => array of files in dir/subdir,...) 340 * @param array array form of 'dir/subdir/subdir2' array('dir','subdir','subdir2') 341 * @return array same as struc but with array('dir' => 342 * array(file1,file2,'subdir' => array(file1,...))) 343 * @access private 344 */ 345 function _setupDirs($struc, $dir, $contents) 346 { 347 if (!count($dir)) { 348 foreach($contents as $dir => $files) { 349 if (is_string($dir)) { 350 if (strpos($dir, '/')) { 351 $test = true; 352 $a = $contents[$dir]; 353 unset($contents[$dir]); 354 $b = explode('/', $dir); 355 $c = array_shift($b); 356 if (isset($contents[$c])) { 357 $contents[$c] = $this->_setDir($contents[$c], $this->_setupDirs(array(), $b, $a)); 358 } else { 359 $contents[$c] = $this->_setupDirs(array(), $b, $a); 360 } 361 } 362 } 363 } 364 return $contents; 365 } 366 $me = array_shift($dir); 367 if (!isset($struc[$me])) { 368 $struc[$me] = array(); 369 } 370 $struc[$me] = $this->_setupDirs($struc[$me], $dir, $contents); 371 return $struc; 372 } 373 374 375 /** 376 * Recursively add all the subdirectories of $contents to $dir without erasing anything in 377 * $dir 378 * @param array 379 * @param array 380 * @return array processed $dir 381 * @access private 382 */ 383 function _setDir($dir, $contents) 384 { 385 while(list($one,$two) = each($contents)) { 386 if (isset($dir[$one])) { 387 $dir[$one] = $this->_setDir($dir[$one], $contents[$one]); 388 } else { 389 $dir[$one] = $two; 390 } 391 } 392 return $dir; 393 } 394 395 396 /**#@+ 397 * Sorting functions for the file list 398 * @param string 399 * @param string 400 * @access private 401 */ 402 function sortfiles($a, $b) 403 { 404 return strnatcasecmp($a['file'],$b['file']); 405 } 406 407 function mystrucsort($a, $b) 408 { 409 if (is_numeric($a) && is_string($b)) return 1; 410 if (is_numeric($b) && is_string($a)) return -1; 411 if (is_numeric($a) && is_numeric($b)) 412 { 413 if ($a > $b) return 1; 414 if ($a < $b) return -1; 415 if ($a == $b) return 0; 416 } 417 return strnatcasecmp($a,$b); 418 } 419 /**#@-*/ 420 } 421 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 14:08:00 2007 | par Balluche grâce à PHPXref 0.7 |