[ Index ] |
|
Code source de SPIP Agora 1.4 |
1 <?php 2 // 3 // +----------------------------------------------------------------------+ 4 // | PHP Version 5 | 5 // +----------------------------------------------------------------------+ 6 // | Copyright (c) 1997-2004 The PHP Group | 7 // +----------------------------------------------------------------------+ 8 // | This source file is subject to version 3.0 of the PHP license, | 9 // | that is bundled with this package in the file LICENSE, and is | 10 // | available through the world-wide-web at the following url: | 11 // | http://www.php.net/license/3_0.txt. | 12 // | If you did not receive a copy of the PHP license and are unable to | 13 // | obtain it through the world-wide-web, please send a note to | 14 // | license@php.net so we can mail you a copy immediately. | 15 // +----------------------------------------------------------------------+ 16 // | Authors: Tomas V.V.Cox <cox@idecnet.com> | 17 // | Stig Bakken <ssb@php.net> | 18 // +----------------------------------------------------------------------+ 19 // 20 // $Id: Dependency.php,v 1.36.4.1 2004/12/27 07:04:19 cellog Exp $ 21 22 require_once "PEAR.php"; 23 24 define('PEAR_DEPENDENCY_MISSING', -1); 25 define('PEAR_DEPENDENCY_CONFLICT', -2); 26 define('PEAR_DEPENDENCY_UPGRADE_MINOR', -3); 27 define('PEAR_DEPENDENCY_UPGRADE_MAJOR', -4); 28 define('PEAR_DEPENDENCY_BAD_DEPENDENCY', -5); 29 define('PEAR_DEPENDENCY_MISSING_OPTIONAL', -6); 30 define('PEAR_DEPENDENCY_CONFLICT_OPTIONAL', -7); 31 define('PEAR_DEPENDENCY_UPGRADE_MINOR_OPTIONAL', -8); 32 define('PEAR_DEPENDENCY_UPGRADE_MAJOR_OPTIONAL', -9); 33 34 /** 35 * Dependency check for PEAR packages 36 * 37 * The class is based on the dependency RFC that can be found at 38 * http://cvs.php.net/cvs.php/pearweb/rfc. It requires PHP >= 4.1 39 * 40 * @author Tomas V.V.Vox <cox@idecnet.com> 41 * @author Stig Bakken <ssb@php.net> 42 */ 43 class PEAR_Dependency 44 { 45 // {{{ constructor 46 /** 47 * Constructor 48 * 49 * @access public 50 * @param object Registry object 51 * @return void 52 */ 53 function PEAR_Dependency(&$registry) 54 { 55 $this->registry = &$registry; 56 } 57 58 // }}} 59 // {{{ callCheckMethod() 60 61 /** 62 * This method maps the XML dependency definition to the 63 * corresponding one from PEAR_Dependency 64 * 65 * <pre> 66 * $opts => Array 67 * ( 68 * [type] => pkg 69 * [rel] => ge 70 * [version] => 3.4 71 * [name] => HTML_Common 72 * [optional] => false 73 * ) 74 * </pre> 75 * 76 * @param string Error message 77 * @param array Options 78 * @return boolean 79 */ 80 function callCheckMethod(&$errmsg, $opts) 81 { 82 $rel = isset($opts['rel']) ? $opts['rel'] : 'has'; 83 $req = isset($opts['version']) ? $opts['version'] : null; 84 $name = isset($opts['name']) ? $opts['name'] : null; 85 $opt = (isset($opts['optional']) && $opts['optional'] == 'yes') ? 86 $opts['optional'] : null; 87 $errmsg = ''; 88 switch ($opts['type']) { 89 case 'pkg': 90 return $this->checkPackage($errmsg, $name, $req, $rel, $opt); 91 break; 92 case 'ext': 93 return $this->checkExtension($errmsg, $name, $req, $rel, $opt); 94 break; 95 case 'php': 96 return $this->checkPHP($errmsg, $req, $rel); 97 break; 98 case 'prog': 99 return $this->checkProgram($errmsg, $name); 100 break; 101 case 'os': 102 return $this->checkOS($errmsg, $name); 103 break; 104 case 'sapi': 105 return $this->checkSAPI($errmsg, $name); 106 break; 107 case 'zend': 108 return $this->checkZend($errmsg, $name); 109 break; 110 default: 111 return "'{$opts['type']}' dependency type not supported"; 112 } 113 } 114 115 // }}} 116 // {{{ checkPackage() 117 118 /** 119 * Package dependencies check method 120 * 121 * @param string $errmsg Empty string, it will be populated with an error message, if any 122 * @param string $name Name of the package to test 123 * @param string $req The package version required 124 * @param string $relation How to compare versions with each other 125 * @param bool $opt Whether the relationship is optional 126 * 127 * @return mixed bool false if no error or the error string 128 */ 129 function checkPackage(&$errmsg, $name, $req = null, $relation = 'has', 130 $opt = false) 131 { 132 if (is_string($req) && substr($req, 0, 2) == 'v.') { 133 $req = substr($req, 2); 134 } 135 switch ($relation) { 136 case 'has': 137 if (!$this->registry->packageExists($name)) { 138 if ($opt) { 139 $errmsg = "package `$name' is recommended to utilize some features."; 140 return PEAR_DEPENDENCY_MISSING_OPTIONAL; 141 } 142 $errmsg = "requires package `$name'"; 143 return PEAR_DEPENDENCY_MISSING; 144 } 145 return false; 146 case 'not': 147 if ($this->registry->packageExists($name)) { 148 $errmsg = "conflicts with package `$name'"; 149 return PEAR_DEPENDENCY_CONFLICT; 150 } 151 return false; 152 case 'lt': 153 case 'le': 154 case 'eq': 155 case 'ne': 156 case 'ge': 157 case 'gt': 158 $version = $this->registry->packageInfo($name, 'version'); 159 if (!$this->registry->packageExists($name) 160 || !version_compare("$version", "$req", $relation)) 161 { 162 $code = $this->codeFromRelation($relation, $version, $req, $opt); 163 if ($opt) { 164 $errmsg = "package `$name' version " . $this->signOperator($relation) . 165 " $req is recommended to utilize some features."; 166 if ($version) { 167 $errmsg .= " Installed version is $version"; 168 } 169 return $code; 170 } 171 $errmsg = "requires package `$name' " . 172 $this->signOperator($relation) . " $req"; 173 return $code; 174 } 175 return false; 176 } 177 $errmsg = "relation '$relation' with requirement '$req' is not supported (name=$name)"; 178 return PEAR_DEPENDENCY_BAD_DEPENDENCY; 179 } 180 181 // }}} 182 // {{{ checkPackageUninstall() 183 184 /** 185 * Check package dependencies on uninstall 186 * 187 * @param string $error The resultant error string 188 * @param string $warning The resultant warning string 189 * @param string $name Name of the package to test 190 * 191 * @return bool true if there were errors 192 */ 193 function checkPackageUninstall(&$error, &$warning, $package) 194 { 195 $error = null; 196 $packages = $this->registry->listPackages(); 197 foreach ($packages as $pkg) { 198 if ($pkg == $package) { 199 continue; 200 } 201 $deps = $this->registry->packageInfo($pkg, 'release_deps'); 202 if (empty($deps)) { 203 continue; 204 } 205 foreach ($deps as $dep) { 206 if ($dep['type'] == 'pkg' && strcasecmp($dep['name'], $package) == 0) { 207 if ($dep['rel'] == 'ne' || $dep['rel'] == 'not') { 208 continue; 209 } 210 if (isset($dep['optional']) && $dep['optional'] == 'yes') { 211 $warning .= "\nWarning: Package '$pkg' optionally depends on '$package'"; 212 } else { 213 $error .= "Package '$pkg' depends on '$package'\n"; 214 } 215 } 216 } 217 } 218 return ($error) ? true : false; 219 } 220 221 // }}} 222 // {{{ checkExtension() 223 224 /** 225 * Extension dependencies check method 226 * 227 * @param string $name Name of the extension to test 228 * @param string $req_ext_ver Required extension version to compare with 229 * @param string $relation How to compare versions with eachother 230 * @param bool $opt Whether the relationship is optional 231 * 232 * @return mixed bool false if no error or the error string 233 */ 234 function checkExtension(&$errmsg, $name, $req = null, $relation = 'has', 235 $opt = false) 236 { 237 if ($relation == 'not') { 238 if (extension_loaded($name)) { 239 $errmsg = "conflicts with PHP extension '$name'"; 240 return PEAR_DEPENDENCY_CONFLICT; 241 } else { 242 return false; 243 } 244 } 245 246 if (!extension_loaded($name)) { 247 if ($relation == 'not') { 248 return false; 249 } 250 if ($opt) { 251 $errmsg = "'$name' PHP extension is recommended to utilize some features"; 252 return PEAR_DEPENDENCY_MISSING_OPTIONAL; 253 } 254 $errmsg = "'$name' PHP extension is not installed"; 255 return PEAR_DEPENDENCY_MISSING; 256 } 257 if ($relation == 'has') { 258 return false; 259 } 260 $code = false; 261 if (is_string($req) && substr($req, 0, 2) == 'v.') { 262 $req = substr($req, 2); 263 } 264 $ext_ver = phpversion($name); 265 $operator = $relation; 266 // Force params to be strings, otherwise the comparation will fail (ex. 0.9==0.90) 267 if (!version_compare("$ext_ver", "$req", $operator)) { 268 $errmsg = "'$name' PHP extension version " . 269 $this->signOperator($operator) . " $req is required"; 270 $code = $this->codeFromRelation($relation, $ext_ver, $req, $opt); 271 if ($opt) { 272 $errmsg = "'$name' PHP extension version " . $this->signOperator($operator) . 273 " $req is recommended to utilize some features"; 274 return $code; 275 } 276 } 277 return $code; 278 } 279 280 // }}} 281 // {{{ checkOS() 282 283 /** 284 * Operating system dependencies check method 285 * 286 * @param string $os Name of the operating system 287 * 288 * @return mixed bool false if no error or the error string 289 */ 290 function checkOS(&$errmsg, $os) 291 { 292 // XXX Fixme: Implement a more flexible way, like 293 // comma separated values or something similar to PEAR_OS 294 static $myos; 295 if (empty($myos)) { 296 include_once "OS/Guess.php"; 297 $myos = new OS_Guess(); 298 } 299 // only 'has' relation is currently supported 300 if ($myos->matchSignature($os)) { 301 return false; 302 } 303 $errmsg = "'$os' operating system not supported"; 304 return PEAR_DEPENDENCY_CONFLICT; 305 } 306 307 // }}} 308 // {{{ checkPHP() 309 310 /** 311 * PHP version check method 312 * 313 * @param string $req which version to compare 314 * @param string $relation how to compare the version 315 * 316 * @return mixed bool false if no error or the error string 317 */ 318 function checkPHP(&$errmsg, $req, $relation = 'ge') 319 { 320 // this would be a bit stupid, but oh well :) 321 if ($relation == 'has') { 322 return false; 323 } 324 if ($relation == 'not') { 325 $errmsg = 'Invalid dependency - "not" is not allowed for php dependencies, ' . 326 'php cannot conflict with itself'; 327 return PEAR_DEPENDENCY_BAD_DEPENDENCY; 328 } 329 if (substr($req, 0, 2) == 'v.') { 330 $req = substr($req,2, strlen($req) - 2); 331 } 332 $php_ver = phpversion(); 333 $operator = $relation; 334 if (!version_compare("$php_ver", "$req", $operator)) { 335 $errmsg = "PHP version " . $this->signOperator($operator) . 336 " $req is required"; 337 return PEAR_DEPENDENCY_CONFLICT; 338 } 339 return false; 340 } 341 342 // }}} 343 // {{{ checkProgram() 344 345 /** 346 * External program check method. Looks for executable files in 347 * directories listed in the PATH environment variable. 348 * 349 * @param string $program which program to look for 350 * 351 * @return mixed bool false if no error or the error string 352 */ 353 function checkProgram(&$errmsg, $program) 354 { 355 // XXX FIXME honor safe mode 356 $exe_suffix = OS_WINDOWS ? '.exe' : ''; 357 $path_elements = explode(PATH_SEPARATOR, getenv('PATH')); 358 foreach ($path_elements as $dir) { 359 $file = $dir . DIRECTORY_SEPARATOR . $program . $exe_suffix; 360 if (@file_exists($file) && @is_executable($file)) { 361 return false; 362 } 363 } 364 $errmsg = "'$program' program is not present in the PATH"; 365 return PEAR_DEPENDENCY_MISSING; 366 } 367 368 // }}} 369 // {{{ checkSAPI() 370 371 /** 372 * SAPI backend check method. Version comparison is not yet 373 * available here. 374 * 375 * @param string $name name of SAPI backend 376 * @param string $req which version to compare 377 * @param string $relation how to compare versions (currently 378 * hardcoded to 'has') 379 * @return mixed bool false if no error or the error string 380 */ 381 function checkSAPI(&$errmsg, $name, $req = null, $relation = 'has') 382 { 383 // XXX Fixme: There is no way to know if the user has or 384 // not other SAPI backends installed than the installer one 385 386 $sapi_backend = php_sapi_name(); 387 // Version comparisons not supported, sapi backends don't have 388 // version information yet. 389 if ($sapi_backend == $name) { 390 return false; 391 } 392 $errmsg = "'$sapi_backend' SAPI backend not supported"; 393 return PEAR_DEPENDENCY_CONFLICT; 394 } 395 396 // }}} 397 // {{{ checkZend() 398 399 /** 400 * Zend version check method 401 * 402 * @param string $req which version to compare 403 * @param string $relation how to compare the version 404 * 405 * @return mixed bool false if no error or the error string 406 */ 407 function checkZend(&$errmsg, $req, $relation = 'ge') 408 { 409 if (substr($req, 0, 2) == 'v.') { 410 $req = substr($req,2, strlen($req) - 2); 411 } 412 $zend_ver = zend_version(); 413 $operator = substr($relation,0,2); 414 if (!version_compare("$zend_ver", "$req", $operator)) { 415 $errmsg = "Zend version " . $this->signOperator($operator) . 416 " $req is required"; 417 return PEAR_DEPENDENCY_CONFLICT; 418 } 419 return false; 420 } 421 422 // }}} 423 // {{{ signOperator() 424 425 /** 426 * Converts text comparing operators to them sign equivalents 427 * 428 * Example: 'ge' to '>=' 429 * 430 * @access public 431 * @param string Operator 432 * @return string Sign equivalent 433 */ 434 function signOperator($operator) 435 { 436 switch($operator) { 437 case 'lt': return '<'; 438 case 'le': return '<='; 439 case 'gt': return '>'; 440 case 'ge': return '>='; 441 case 'eq': return '=='; 442 case 'ne': return '!='; 443 default: 444 return $operator; 445 } 446 } 447 448 // }}} 449 // {{{ codeFromRelation() 450 451 /** 452 * Convert relation into corresponding code 453 * 454 * @access public 455 * @param string Relation 456 * @param string Version 457 * @param string Requirement 458 * @param bool Optional dependency indicator 459 * @return integer 460 */ 461 function codeFromRelation($relation, $version, $req, $opt = false) 462 { 463 $code = PEAR_DEPENDENCY_BAD_DEPENDENCY; 464 switch ($relation) { 465 case 'gt': case 'ge': case 'eq': 466 // upgrade 467 $have_major = preg_replace('/\D.*/', '', $version); 468 $need_major = preg_replace('/\D.*/', '', $req); 469 if ($need_major > $have_major) { 470 $code = $opt ? PEAR_DEPENDENCY_UPGRADE_MAJOR_OPTIONAL : 471 PEAR_DEPENDENCY_UPGRADE_MAJOR; 472 } else { 473 $code = $opt ? PEAR_DEPENDENCY_UPGRADE_MINOR_OPTIONAL : 474 PEAR_DEPENDENCY_UPGRADE_MINOR; 475 } 476 break; 477 case 'lt': case 'le': case 'ne': 478 $code = $opt ? PEAR_DEPENDENCY_CONFLICT_OPTIONAL : 479 PEAR_DEPENDENCY_CONFLICT; 480 break; 481 } 482 return $code; 483 } 484 485 // }}} 486 } 487 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sat Feb 24 14:40:03 2007 | par Balluche grâce à PHPXref 0.7 |