PEAR
[ class tree: PEAR ] [ index: PEAR ] [ all elements ]

Source for file Dependency.php

Documentation is available at Dependency.php

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

Documentation generated on Mon, 11 Mar 2019 15:09:35 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.