New file |
0,0 → 1,495 |
<?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_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; |
} |
|
// }}} |
} |
?> |