home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / tmp / PEAR-1.7.1 / PEAR / Dependency.php < prev    next >
Encoding:
PHP Script  |  2008-02-15  |  16.7 KB  |  499 lines

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