Rev 94 | Blame | Compare with Previous | Last modification | View Log | RSS feed
<?php//// +----------------------------------------------------------------------+// | PHP Version 5 |// +----------------------------------------------------------------------+// | Copyright (c) 1997-2004 The PHP Group |// +----------------------------------------------------------------------+// | This source file is subject to version 3.0 of the PHP license, |// | that is bundled with this package in the file LICENSE, and is |// | available through the world-wide-web at the following url: |// | http://www.php.net/license/3_0.txt. |// | If you did not receive a copy of the PHP license and are unable to |// | obtain it through the world-wide-web, please send a note to |// | license@php.net so we can mail you a copy immediately. |// +----------------------------------------------------------------------+// | Authors: Tomas V.V.Cox <cox@idecnet.com> |// | Stig Bakken <ssb@php.net> |// +----------------------------------------------------------------------+//// THIS FILE IS DEPRECATED IN FAVOR OF DEPENDENCY2.PHP, AND IS NOT USED IN THE INSTALLER// $Id: Dependency.php,v 1.42 2006/03/26 23:25:56 cellog Exp $require_once "PEAR.php";require_once "OS/Guess.php";define('PEAR_DEPENDENCY_MISSING', -1);define('PEAR_DEPENDENCY_CONFLICT', -2);define('PEAR_DEPENDENCY_UPGRADE_MINOR', -3);define('PEAR_DEPENDENCY_UPGRADE_MAJOR', -4);define('PEAR_DEPENDENCY_BAD_DEPENDENCY', -5);define('PEAR_DEPENDENCY_MISSING_OPTIONAL', -6);define('PEAR_DEPENDENCY_CONFLICT_OPTIONAL', -7);define('PEAR_DEPENDENCY_UPGRADE_MINOR_OPTIONAL', -8);define('PEAR_DEPENDENCY_UPGRADE_MAJOR_OPTIONAL', -9);/*** Dependency check for PEAR packages** The class is based on the dependency RFC that can be found at* http://cvs.php.net/cvs.php/pearweb/rfc. It requires PHP >= 4.1** @author Tomas V.V.Vox <cox@idecnet.com>* @author Stig Bakken <ssb@php.net>*/class PEAR_Dependency{// {{{ constructor/*** Constructor** @access public* @param object Registry object* @return void*/function PEAR_Dependency(&$registry){$this->registry = &$registry;}// }}}// {{{ callCheckMethod()/*** This method maps the XML dependency definition to the* corresponding one from PEAR_Dependency** <pre>* $opts => Array* (* [type] => pkg* [rel] => ge* [version] => 3.4* [name] => HTML_Common* [optional] => false* )* </pre>** @param string Error message* @param array Options* @return boolean*/function callCheckMethod(&$errmsg, $opts){$rel = isset($opts['rel']) ? $opts['rel'] : 'has';$req = isset($opts['version']) ? $opts['version'] : null;$name = isset($opts['name']) ? $opts['name'] : null;$channel = isset($opts['channel']) ? $opts['channel'] : 'pear.php.net';$opt = (isset($opts['optional']) && $opts['optional'] == 'yes') ?$opts['optional'] : null;$errmsg = '';switch ($opts['type']) {case 'pkg':return $this->checkPackage($errmsg, $name, $req, $rel, $opt, $channel);break;case 'ext':return $this->checkExtension($errmsg, $name, $req, $rel, $opt);break;case 'php':return $this->checkPHP($errmsg, $req, $rel);break;case 'prog':return $this->checkProgram($errmsg, $name);break;case 'os':return $this->checkOS($errmsg, $name);break;case 'sapi':return $this->checkSAPI($errmsg, $name);break;case 'zend':return $this->checkZend($errmsg, $name);break;default:return "'{$opts['type']}' dependency type not supported";}}// }}}// {{{ checkPackage()/*** Package dependencies check method** @param string $errmsg Empty string, it will be populated with an error message, if any* @param string $name Name of the package to test* @param string $req The package version required* @param string $relation How to compare versions with each other* @param bool $opt Whether the relationship is optional* @param string $channel Channel name** @return mixed bool false if no error or the error string*/function checkPackage(&$errmsg, $name, $req = null, $relation = 'has',$opt = false, $channel = 'pear.php.net'){if (is_string($req) && substr($req, 0, 2) == 'v.') {$req = substr($req, 2);}switch ($relation) {case 'has':if (!$this->registry->packageExists($name, $channel)) {if ($opt) {$errmsg = "package `$channel/$name' is recommended to utilize some features.";return PEAR_DEPENDENCY_MISSING_OPTIONAL;}$errmsg = "requires package `$channel/$name'";return PEAR_DEPENDENCY_MISSING;}return false;case 'not':if ($this->registry->packageExists($name, $channel)) {$errmsg = "conflicts with package `$channel/$name'";return PEAR_DEPENDENCY_CONFLICT;}return false;case 'lt':case 'le':case 'eq':case 'ne':case 'ge':case 'gt':$version = $this->registry->packageInfo($name, 'version', $channel);if (!$this->registry->packageExists($name, $channel)|| !version_compare("$version", "$req", $relation)){$code = $this->codeFromRelation($relation, $version, $req, $opt);if ($opt) {$errmsg = "package `$channel/$name' version " . $this->signOperator($relation) ." $req is recommended to utilize some features.";if ($version) {$errmsg .= " Installed version is $version";}return $code;}$errmsg = "requires package `$channel/$name' " .$this->signOperator($relation) . " $req";return $code;}return false;}$errmsg = "relation '$relation' with requirement '$req' is not supported (name=$channel/$name)";return PEAR_DEPENDENCY_BAD_DEPENDENCY;}// }}}// {{{ checkPackageUninstall()/*** Check package dependencies on uninstall** @param string $error The resultant error string* @param string $warning The resultant warning string* @param string $name Name of the package to test* @param string $channel Channel name of the package** @return bool true if there were errors*/function checkPackageUninstall(&$error, &$warning, $package, $channel = 'pear.php.net'){$channel = strtolower($channel);$error = null;$channels = $this->registry->listAllPackages();foreach ($channels as $channelname => $packages) {foreach ($packages as $pkg) {if ($pkg == $package && $channel == $channelname) {continue;}$deps = $this->registry->packageInfo($pkg, 'release_deps', $channel);if (empty($deps)) {continue;}foreach ($deps as $dep) {$depchannel = isset($dep['channel']) ? $dep['channel'] : 'pear.php.net';if ($dep['type'] == 'pkg' && (strcasecmp($dep['name'], $package) == 0) &&($depchannel == $channel)) {if ($dep['rel'] == 'ne') {continue;}if (isset($dep['optional']) && $dep['optional'] == 'yes') {$warning .= "\nWarning: Package '$depchannel/$pkg' optionally depends on '$channel:/package'";} else {$error .= "Package '$depchannel/$pkg' depends on '$channel/$package'\n";}}}}}return ($error) ? true : false;}// }}}// {{{ checkExtension()/*** Extension dependencies check method** @param string $name Name of the extension to test* @param string $req_ext_ver Required extension version to compare with* @param string $relation How to compare versions with eachother* @param bool $opt Whether the relationship is optional** @return mixed bool false if no error or the error string*/function checkExtension(&$errmsg, $name, $req = null, $relation = 'has',$opt = false){if ($relation == 'not') {if (extension_loaded($name)) {$errmsg = "conflicts with PHP extension '$name'";return PEAR_DEPENDENCY_CONFLICT;} else {return false;}}if (!extension_loaded($name)) {if ($relation == 'ne') {return false;}if ($opt) {$errmsg = "'$name' PHP extension is recommended to utilize some features";return PEAR_DEPENDENCY_MISSING_OPTIONAL;}$errmsg = "'$name' PHP extension is not installed";return PEAR_DEPENDENCY_MISSING;}if ($relation == 'has') {return false;}$code = false;if (is_string($req) && substr($req, 0, 2) == 'v.') {$req = substr($req, 2);}$ext_ver = phpversion($name);$operator = $relation;// Force params to be strings, otherwise the comparation will fail (ex. 0.9==0.90)if (!version_compare("$ext_ver", "$req", $operator)) {$errmsg = "'$name' PHP extension version " .$this->signOperator($operator) . " $req is required";$code = $this->codeFromRelation($relation, $ext_ver, $req, $opt);if ($opt) {$errmsg = "'$name' PHP extension version " . $this->signOperator($operator) ." $req is recommended to utilize some features";return $code;}}return $code;}// }}}// {{{ checkOS()/*** Operating system dependencies check method** @param string $os Name of the operating system** @return mixed bool false if no error or the error string*/function checkOS(&$errmsg, $os){// XXX Fixme: Implement a more flexible way, like// comma separated values or something similar to PEAR_OSstatic $myos;if (empty($myos)) {$myos = new OS_Guess();}// only 'has' relation is currently supportedif ($myos->matchSignature($os)) {return false;}$errmsg = "'$os' operating system not supported";return PEAR_DEPENDENCY_CONFLICT;}// }}}// {{{ checkPHP()/*** PHP version check method** @param string $req which version to compare* @param string $relation how to compare the version** @return mixed bool false if no error or the error string*/function checkPHP(&$errmsg, $req, $relation = 'ge'){// this would be a bit stupid, but oh well :)if ($relation == 'has') {return false;}if ($relation == 'not') {$errmsg = "Invalid dependency - 'not' is allowed when specifying PHP, you must run PHP in PHP";return PEAR_DEPENDENCY_BAD_DEPENDENCY;}if (substr($req, 0, 2) == 'v.') {$req = substr($req,2, strlen($req) - 2);}$php_ver = phpversion();$operator = $relation;if (!version_compare("$php_ver", "$req", $operator)) {$errmsg = "PHP version " . $this->signOperator($operator) ." $req is required";return PEAR_DEPENDENCY_CONFLICT;}return false;}// }}}// {{{ checkProgram()/*** External program check method. Looks for executable files in* directories listed in the PATH environment variable.** @param string $program which program to look for** @return mixed bool false if no error or the error string*/function checkProgram(&$errmsg, $program){// XXX FIXME honor safe mode$exe_suffix = OS_WINDOWS ? '.exe' : '';$path_elements = explode(PATH_SEPARATOR, getenv('PATH'));foreach ($path_elements as $dir) {$file = $dir . DIRECTORY_SEPARATOR . $program . $exe_suffix;if (file_exists($file) && is_executable($file)) {return false;}}$errmsg = "'$program' program is not present in the PATH";return PEAR_DEPENDENCY_MISSING;}// }}}// {{{ checkSAPI()/*** SAPI backend check method. Version comparison is not yet* available here.** @param string $name name of SAPI backend* @param string $req which version to compare* @param string $relation how to compare versions (currently* hardcoded to 'has')* @return mixed bool false if no error or the error string*/function checkSAPI(&$errmsg, $name, $req = null, $relation = 'has'){// XXX Fixme: There is no way to know if the user has or// not other SAPI backends installed than the installer one$sapi_backend = php_sapi_name();// Version comparisons not supported, sapi backends don't have// version information yet.if ($sapi_backend == $name) {return false;}$errmsg = "'$sapi_backend' SAPI backend not supported";return PEAR_DEPENDENCY_CONFLICT;}// }}}// {{{ checkZend()/*** Zend version check method** @param string $req which version to compare* @param string $relation how to compare the version** @return mixed bool false if no error or the error string*/function checkZend(&$errmsg, $req, $relation = 'ge'){if (substr($req, 0, 2) == 'v.') {$req = substr($req,2, strlen($req) - 2);}$zend_ver = zend_version();$operator = substr($relation,0,2);if (!version_compare("$zend_ver", "$req", $operator)) {$errmsg = "Zend version " . $this->signOperator($operator) ." $req is required";return PEAR_DEPENDENCY_CONFLICT;}return false;}// }}}// {{{ signOperator()/*** Converts text comparing operators to them sign equivalents** Example: 'ge' to '>='** @access public* @param string Operator* @return string Sign equivalent*/function signOperator($operator){switch($operator) {case 'lt': return '<';case 'le': return '<=';case 'gt': return '>';case 'ge': return '>=';case 'eq': return '==';case 'ne': return '!=';default:return $operator;}}// }}}// {{{ codeFromRelation()/*** Convert relation into corresponding code** @access public* @param string Relation* @param string Version* @param string Requirement* @param bool Optional dependency indicator* @return integer*/function codeFromRelation($relation, $version, $req, $opt = false){$code = PEAR_DEPENDENCY_BAD_DEPENDENCY;switch ($relation) {case 'gt': case 'ge': case 'eq':// upgrade$have_major = preg_replace('/\D.*/', '', $version);$need_major = preg_replace('/\D.*/', '', $req);if ($need_major > $have_major) {$code = $opt ? PEAR_DEPENDENCY_UPGRADE_MAJOR_OPTIONAL :PEAR_DEPENDENCY_UPGRADE_MAJOR;} else {$code = $opt ? PEAR_DEPENDENCY_UPGRADE_MINOR_OPTIONAL :PEAR_DEPENDENCY_UPGRADE_MINOR;}break;case 'lt': case 'le': case 'ne':$code = $opt ? PEAR_DEPENDENCY_CONFLICT_OPTIONAL :PEAR_DEPENDENCY_CONFLICT;break;}return $code;}// }}}}?>