Viewing file: Dependency.php (17.16 KB) -rw-rw-rw- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?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.41 2006/01/06 04:47:36 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_OS static $myos; if (empty($myos)) { $myos = new OS_Guess(); } // only 'has' relation is currently supported if ($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; }
// }}} } ?>
|