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

Source for file DependencyDB.php

Documentation is available at DependencyDB.php

  1. <?php
  2. /**
  3.  * PEAR_DependencyDB, advanced installed packages dependency database
  4.  *
  5.  * PHP versions 4 and 5
  6.  *
  7.  * @category   pear
  8.  * @package    PEAR
  9.  * @author     Tomas V. V. Cox <cox@idecnet.com>
  10.  * @author     Greg Beaver <cellog@php.net>
  11.  * @copyright  1997-2009 The Authors
  12.  * @license    http://opensource.org/licenses/bsd-license.php New BSD License
  13.  * @version    CVS: $Id: DependencyDB.php 313023 2011-07-06 19:17:11Z dufuz $
  14.  * @link       http://pear.php.net/package/PEAR
  15.  * @since      File available since Release 1.4.0a1
  16.  */
  17.  
  18. /**
  19.  * Needed for error handling
  20.  */
  21. require_once 'PEAR.php';
  22. require_once 'PEAR/Config.php';
  23.  
  24. $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'= array();
  25. /**
  26.  * Track dependency relationships between installed packages
  27.  * @category   pear
  28.  * @package    PEAR
  29.  * @author     Greg Beaver <cellog@php.net>
  30.  * @author     Tomas V.V.Cox <cox@idec.net.com>
  31.  * @copyright  1997-2009 The Authors
  32.  * @license    http://opensource.org/licenses/bsd-license.php New BSD License
  33.  * @version    Release: 1.9.4
  34.  * @link       http://pear.php.net/package/PEAR
  35.  * @since      Class available since Release 1.4.0a1
  36.  */
  37. {
  38.     // {{{ properties
  39.  
  40.     /**
  41.      * This is initialized by {@link setConfig()}
  42.      * @var PEAR_Config 
  43.      * @access private
  44.      */
  45.     var $_config;
  46.     /**
  47.      * This is initialized by {@link setConfig()}
  48.      * @var PEAR_Registry 
  49.      * @access private
  50.      */
  51.     var $_registry;
  52.     /**
  53.      * Filename of the dependency DB (usually .depdb)
  54.      * @var string 
  55.      * @access private
  56.      */
  57.     var $_depdb = false;
  58.     /**
  59.      * File name of the lockfile (usually .depdblock)
  60.      * @var string 
  61.      * @access private
  62.      */
  63.     var $_lockfile = false;
  64.     /**
  65.      * Open file resource for locking the lockfile
  66.      * @var resource|false
  67.      * @access private
  68.      */
  69.     var $_lockFp = false;
  70.     /**
  71.      * API version of this class, used to validate a file on-disk
  72.      * @var string 
  73.      * @access private
  74.      */
  75.     var $_version '1.0';
  76.     /**
  77.      * Cached dependency database file
  78.      * @var array|null
  79.      * @access private
  80.      */
  81.     var $_cache;
  82.  
  83.     // }}}
  84.     // {{{ & singleton()
  85.  
  86.     /**
  87.      * Get a raw dependency database.  Calls setConfig() and assertDepsDB()
  88.      * @param PEAR_Config 
  89.      * @param string|falsefull path to the dependency database, or false to use default
  90.      * @return PEAR_DependencyDB|PEAR_Error
  91.      * @static
  92.      */
  93.     function &singleton(&$config$depdb = false)
  94.     {
  95.         $phpdir $config->get('php_dir'null'pear.php.net');
  96.         if (!isset($GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir])) {
  97.             $a = new PEAR_DependencyDB;
  98.             $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir&$a;
  99.             $a->setConfig($config$depdb);
  100.             $e $a->assertDepsDB();
  101.             if (PEAR::isError($e)) {
  102.                 return $e;
  103.             }
  104.         }
  105.  
  106.         return $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir];
  107.     }
  108.  
  109.     /**
  110.      * Set up the registry/location of dependency DB
  111.      * @param PEAR_Config|false
  112.      * @param string|falsefull path to the dependency database, or false to use default
  113.      */
  114.     function setConfig(&$config$depdb = false)
  115.     {
  116.         if (!$config{
  117.             $this->_config &PEAR_Config::singleton();
  118.         else {
  119.             $this->_config &$config;
  120.         }
  121.  
  122.         $this->_registry &$this->_config->getRegistry();
  123.         if (!$depdb{
  124.             $this->_depdb $this->_config->get('php_dir'null'pear.php.net'.
  125.                 DIRECTORY_SEPARATOR . '.depdb';
  126.         else {
  127.             $this->_depdb $depdb;
  128.         }
  129.  
  130.         $this->_lockfile dirname($this->_depdb. DIRECTORY_SEPARATOR . '.depdblock';
  131.     }
  132.     // }}}
  133.  
  134.     function hasWriteAccess()
  135.     {
  136.         if (!file_exists($this->_depdb)) {
  137.             $dir $this->_depdb;
  138.             while ($dir && $dir != '.'{
  139.                 $dir dirname($dir)// cd ..
  140.                 if ($dir != '.' && file_exists($dir)) {
  141.                     if (is_writeable($dir)) {
  142.                         return true;
  143.                     }
  144.  
  145.                     return false;
  146.                 }
  147.             }
  148.  
  149.             return false;
  150.         }
  151.  
  152.         return is_writeable($this->_depdb);
  153.     }
  154.  
  155.     // {{{ assertDepsDB()
  156.  
  157.     /**
  158.      * Create the dependency database, if it doesn't exist.  Error if the database is
  159.      * newer than the code reading it.
  160.      * @return void|PEAR_Error
  161.      */
  162.     function assertDepsDB()
  163.     {
  164.         if (!is_file($this->_depdb)) {
  165.             $this->rebuildDB();
  166.             return;
  167.         }
  168.  
  169.         $depdb $this->_getDepDB();
  170.         // Datatype format has been changed, rebuild the Deps DB
  171.         if ($depdb['_version'$this->_version{
  172.             $this->rebuildDB();
  173.         }
  174.  
  175.         if ($depdb['_version']{0$this->_version{0}{
  176.             return PEAR::raiseError('Dependency database is version ' .
  177.                 $depdb['_version'', and we are version ' .
  178.                 $this->_version . ', cannot continue');
  179.         }
  180.     }
  181.  
  182.     /**
  183.      * Get a list of installed packages that depend on this package
  184.      * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array
  185.      * @return array|false
  186.      */
  187.     function getDependentPackages(&$pkg)
  188.     {
  189.         $data $this->_getDepDB();
  190.         if (is_object($pkg)) {
  191.             $channel strtolower($pkg->getChannel());
  192.             $package strtolower($pkg->getPackage());
  193.         else {
  194.             $channel strtolower($pkg['channel']);
  195.             $package strtolower($pkg['package']);
  196.         }
  197.  
  198.         if (isset($data['packages'][$channel][$package])) {
  199.             return $data['packages'][$channel][$package];
  200.         }
  201.  
  202.         return false;
  203.     }
  204.  
  205.     /**
  206.      * Get a list of the actual dependencies of installed packages that depend on
  207.      * a package.
  208.      * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array
  209.      * @return array|false
  210.      */
  211.     function getDependentPackageDependencies(&$pkg)
  212.     {
  213.         $data $this->_getDepDB();
  214.         if (is_object($pkg)) {
  215.             $channel strtolower($pkg->getChannel());
  216.             $package strtolower($pkg->getPackage());
  217.         else {
  218.             $channel strtolower($pkg['channel']);
  219.             $package strtolower($pkg['package']);
  220.         }
  221.  
  222.         $depend $this->getDependentPackages($pkg);
  223.         if (!$depend{
  224.             return false;
  225.         }
  226.  
  227.         $dependencies = array();
  228.         foreach ($depend as $info{
  229.             $temp $this->getDependencies($info);
  230.             foreach ($temp as $dep{
  231.                 if (
  232.                     isset($dep['dep']$dep['dep']['channel']$dep['dep']['name']&&
  233.                     strtolower($dep['dep']['channel']== $channel &&
  234.                     strtolower($dep['dep']['name']== $package
  235.                 {
  236.                     if (!isset($dependencies[$info['channel']])) {
  237.                         $dependencies[$info['channel']] = array();
  238.                     }
  239.  
  240.                     if (!isset($dependencies[$info['channel']][$info['package']])) {
  241.                         $dependencies[$info['channel']][$info['package']] = array();
  242.                     }
  243.                     $dependencies[$info['channel']][$info['package']][$dep;
  244.                 }
  245.             }
  246.         }
  247.  
  248.         return $dependencies;
  249.     }
  250.  
  251.     /**
  252.      * Get a list of dependencies of this installed package
  253.      * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array
  254.      * @return array|false
  255.      */
  256.     function getDependencies(&$pkg)
  257.     {
  258.         if (is_object($pkg)) {
  259.             $channel strtolower($pkg->getChannel());
  260.             $package strtolower($pkg->getPackage());
  261.         else {
  262.             $channel strtolower($pkg['channel']);
  263.             $package strtolower($pkg['package']);
  264.         }
  265.  
  266.         $data $this->_getDepDB();
  267.         if (isset($data['dependencies'][$channel][$package])) {
  268.             return $data['dependencies'][$channel][$package];
  269.         }
  270.  
  271.         return false;
  272.     }
  273.  
  274.     /**
  275.      * Determine whether $parent depends on $child, near or deep
  276.      * @param array|PEAR_PackageFile_v2|PEAR_PackageFile_v2
  277.      * @param array|PEAR_PackageFile_v2|PEAR_PackageFile_v2
  278.      */
  279.     function dependsOn($parent$child)
  280.     {
  281.         $c = array();
  282.         $this->_getDepDB();
  283.         return $this->_dependsOn($parent$child$c);
  284.     }
  285.  
  286.     function _dependsOn($parent$child&$checked)
  287.     {
  288.         if (is_object($parent)) {
  289.             $channel strtolower($parent->getChannel());
  290.             $package strtolower($parent->getPackage());
  291.         else {
  292.             $channel strtolower($parent['channel']);
  293.             $package strtolower($parent['package']);
  294.         }
  295.  
  296.         if (is_object($child)) {
  297.             $depchannel strtolower($child->getChannel());
  298.             $deppackage strtolower($child->getPackage());
  299.         else {
  300.             $depchannel strtolower($child['channel']);
  301.             $deppackage strtolower($child['package']);
  302.         }
  303.  
  304.         if (isset($checked[$channel][$package][$depchannel][$deppackage])) {
  305.             return false; // avoid endless recursion
  306.         }
  307.  
  308.         $checked[$channel][$package][$depchannel][$deppackage= true;
  309.         if (!isset($this->_cache['dependencies'][$channel][$package])) {
  310.             return false;
  311.         }
  312.  
  313.         foreach ($this->_cache['dependencies'][$channel][$packageas $info{
  314.             if (isset($info['dep']['uri'])) {
  315.                 if (is_object($child)) {
  316.                     if ($info['dep']['uri'== $child->getURI()) {
  317.                         return true;
  318.                     }
  319.                 elseif (isset($child['uri'])) {
  320.                     if ($info['dep']['uri'== $child['uri']{
  321.                         return true;
  322.                     }
  323.                 }
  324.                 return false;
  325.             }
  326.  
  327.             if (strtolower($info['dep']['channel']== $depchannel &&
  328.                   strtolower($info['dep']['name']== $deppackage{
  329.                 return true;
  330.             }
  331.         }
  332.  
  333.         foreach ($this->_cache['dependencies'][$channel][$packageas $info{
  334.             if (isset($info['dep']['uri'])) {
  335.                 if ($this->_dependsOn(array(
  336.                         'uri' => $info['dep']['uri'],
  337.                         'package' => $info['dep']['name'])$child$checked)) {
  338.                     return true;
  339.                 }
  340.             else {
  341.                 if ($this->_dependsOn(array(
  342.                         'channel' => $info['dep']['channel'],
  343.                         'package' => $info['dep']['name'])$child$checked)) {
  344.                     return true;
  345.                 }
  346.             }
  347.         }
  348.  
  349.         return false;
  350.     }
  351.  
  352.     /**
  353.      * Register dependencies of a package that is being installed or upgraded
  354.      * @param PEAR_PackageFile_v2|PEAR_PackageFile_v2
  355.      */
  356.     function installPackage(&$package)
  357.     {
  358.         $data $this->_getDepDB();
  359.         unset($this->_cache);
  360.         $this->_setPackageDeps($data$package);
  361.         $this->_writeDepDB($data);
  362.     }
  363.  
  364.     /**
  365.      * Remove dependencies of a package that is being uninstalled, or upgraded.
  366.      *
  367.      * Upgraded packages first uninstall, then install
  368.      * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|arrayIf an array, then it must have
  369.      *         indices 'channel' and 'package'
  370.      */
  371.     function uninstallPackage(&$pkg)
  372.     {
  373.         $data $this->_getDepDB();
  374.         unset($this->_cache);
  375.         if (is_object($pkg)) {
  376.             $channel strtolower($pkg->getChannel());
  377.             $package strtolower($pkg->getPackage());
  378.         else {
  379.             $channel strtolower($pkg['channel']);
  380.             $package strtolower($pkg['package']);
  381.         }
  382.  
  383.         if (!isset($data['dependencies'][$channel][$package])) {
  384.             return true;
  385.         }
  386.  
  387.         foreach ($data['dependencies'][$channel][$packageas $dep{
  388.             $found      = false;
  389.             $depchannel = isset($dep['dep']['uri']'__uri' strtolower($dep['dep']['channel']);
  390.             $depname    strtolower($dep['dep']['name']);
  391.             if (isset($data['packages'][$depchannel][$depname])) {
  392.                 foreach ($data['packages'][$depchannel][$depnameas $i => $info{
  393.                     if ($info['channel'== $channel && $info['package'== $package{
  394.                         $found = true;
  395.                         break;
  396.                     }
  397.                 }
  398.             }
  399.  
  400.             if ($found{
  401.                 unset($data['packages'][$depchannel][$depname][$i]);
  402.                 if (!count($data['packages'][$depchannel][$depname])) {
  403.                     unset($data['packages'][$depchannel][$depname]);
  404.                     if (!count($data['packages'][$depchannel])) {
  405.                         unset($data['packages'][$depchannel]);
  406.                     }
  407.                 else {
  408.                     $data['packages'][$depchannel][$depname=
  409.                         array_values($data['packages'][$depchannel][$depname]);
  410.                 }
  411.             }
  412.         }
  413.  
  414.         unset($data['dependencies'][$channel][$package]);
  415.         if (!count($data['dependencies'][$channel])) {
  416.             unset($data['dependencies'][$channel]);
  417.         }
  418.  
  419.         if (!count($data['dependencies'])) {
  420.             unset($data['dependencies']);
  421.         }
  422.  
  423.         if (!count($data['packages'])) {
  424.             unset($data['packages']);
  425.         }
  426.  
  427.         $this->_writeDepDB($data);
  428.     }
  429.  
  430.     /**
  431.      * Rebuild the dependency DB by reading registry entries.
  432.      * @return true|PEAR_Error
  433.      */
  434.     function rebuildDB()
  435.     {
  436.         $depdb = array('_version' => $this->_version);
  437.         if (!$this->hasWriteAccess()) {
  438.             // allow startup for read-only with older Registry
  439.             return $depdb;
  440.         }
  441.  
  442.         $packages $this->_registry->listAllPackages();
  443.         if (PEAR::isError($packages)) {
  444.             return $packages;
  445.         }
  446.  
  447.         foreach ($packages as $channel => $ps{
  448.             foreach ($ps as $package{
  449.                 $package $this->_registry->getPackage($package$channel);
  450.                 if (PEAR::isError($package)) {
  451.                     return $package;
  452.                 }
  453.                 $this->_setPackageDeps($depdb$package);
  454.             }
  455.         }
  456.  
  457.         $error $this->_writeDepDB($depdb);
  458.         if (PEAR::isError($error)) {
  459.             return $error;
  460.         }
  461.  
  462.         $this->_cache = $depdb;
  463.         return true;
  464.     }
  465.  
  466.     /**
  467.      * Register usage of the dependency DB to prevent race conditions
  468.      * @param int one of the LOCK_* constants
  469.      * @return true|PEAR_Error
  470.      * @access private
  471.      */
  472.     function _lock($mode = LOCK_EX)
  473.     {
  474.         if (stristr(php_uname()'Windows 9')) {
  475.             return true;
  476.         }
  477.  
  478.         if ($mode != LOCK_UN && is_resource($this->_lockFp)) {
  479.             // XXX does not check type of lock (LOCK_SH/LOCK_EX)
  480.             return true;
  481.         }
  482.  
  483.         $open_mode 'w';
  484.         // XXX People reported problems with LOCK_SH and 'w'
  485.         if ($mode === LOCK_SH{
  486.             if (!file_exists($this->_lockfile)) {
  487.                 touch($this->_lockfile);
  488.             elseif (!is_file($this->_lockfile)) {
  489.                 return PEAR::raiseError('could not create Dependency lock file, ' .
  490.                     'it exists and is not a regular file');
  491.             }
  492.             $open_mode 'r';
  493.         }
  494.  
  495.         if (!is_resource($this->_lockFp)) {
  496.             $this->_lockFp = @fopen($this->_lockfile$open_mode);
  497.         }
  498.  
  499.         if (!is_resource($this->_lockFp)) {
  500.             return PEAR::raiseError("could not create Dependency lock file" .
  501.                                      (isset($php_errormsg": " $php_errormsg ""));
  502.         }
  503.  
  504.         if (!(int)flock($this->_lockFp$mode)) {
  505.             switch ($mode{
  506.                 case LOCK_SH: $str 'shared';    break;
  507.                 case LOCK_EX: $str 'exclusive'; break;
  508.                 case LOCK_UN: $str 'unlock';    break;
  509.                 default:      $str 'unknown';   break;
  510.             }
  511.  
  512.             return PEAR::raiseError("could not acquire $str lock ($this->_lockfile)");
  513.         }
  514.  
  515.         return true;
  516.     }
  517.  
  518.     /**
  519.      * Release usage of dependency DB
  520.      * @return true|PEAR_Error
  521.      * @access private
  522.      */
  523.     function _unlock()
  524.     {
  525.         $ret $this->_lock(LOCK_UN);
  526.         if (is_resource($this->_lockFp)) {
  527.             fclose($this->_lockFp);
  528.         }
  529.         $this->_lockFp = null;
  530.         return $ret;
  531.     }
  532.  
  533.     /**
  534.      * Load the dependency database from disk, or return the cache
  535.      * @return array|PEAR_Error
  536.      */
  537.     function _getDepDB()
  538.     {
  539.         if (!$this->hasWriteAccess()) {
  540.             return array('_version' => $this->_version);
  541.         }
  542.  
  543.         if (isset($this->_cache)) {
  544.             return $this->_cache;
  545.         }
  546.  
  547.         if (!$fp fopen($this->_depdb'r')) {
  548.             $err PEAR::raiseError("Could not open dependencies file `".$this->_depdb."'");
  549.             return $err;
  550.         }
  551.  
  552.         $rt get_magic_quotes_runtime();
  553.         set_magic_quotes_runtime(0);
  554.         clearstatcache();
  555.         fclose($fp);
  556.         $data unserialize(file_get_contents($this->_depdb));
  557.         set_magic_quotes_runtime($rt);
  558.         $this->_cache = $data;
  559.         return $data;
  560.     }
  561.  
  562.     /**
  563.      * Write out the dependency database to disk
  564.      * @param array the database
  565.      * @return true|PEAR_Error
  566.      * @access private
  567.      */
  568.     function _writeDepDB(&$deps)
  569.     {
  570.         if (PEAR::isError($e $this->_lock(LOCK_EX))) {
  571.             return $e;
  572.         }
  573.  
  574.         if (!$fp fopen($this->_depdb'wb')) {
  575.             $this->_unlock();
  576.             return PEAR::raiseError("Could not open dependencies file `".$this->_depdb."' for writing");
  577.         }
  578.  
  579.         $rt get_magic_quotes_runtime();
  580.         set_magic_quotes_runtime(0);
  581.         fwrite($fpserialize($deps));
  582.         set_magic_quotes_runtime($rt);
  583.         fclose($fp);
  584.         $this->_unlock();
  585.         $this->_cache = $deps;
  586.         return true;
  587.     }
  588.  
  589.     /**
  590.      * Register all dependencies from a package in the dependencies database, in essence
  591.      * "installing" the package's dependency information
  592.      * @param array the database
  593.      * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
  594.      * @access private
  595.      */
  596.     function _setPackageDeps(&$data&$pkg)
  597.     {
  598.         $pkg->setConfig($this->_config);
  599.         if ($pkg->getPackagexmlVersion(== '1.0'{
  600.             $gen &$pkg->getDefaultGenerator();
  601.             $deps $gen->dependenciesToV2();
  602.         else {
  603.             $deps $pkg->getDeps(true);
  604.         }
  605.  
  606.         if (!$deps{
  607.             return;
  608.         }
  609.  
  610.         if (!is_array($data)) {
  611.             $data = array();
  612.         }
  613.  
  614.         if (!isset($data['dependencies'])) {
  615.             $data['dependencies'= array();
  616.         }
  617.  
  618.         $channel strtolower($pkg->getChannel());
  619.         $package strtolower($pkg->getPackage());
  620.  
  621.         if (!isset($data['dependencies'][$channel])) {
  622.             $data['dependencies'][$channel= array();
  623.         }
  624.  
  625.         $data['dependencies'][$channel][$package= array();
  626.         if (isset($deps['required']['package'])) {
  627.             if (!isset($deps['required']['package'][0])) {
  628.                 $deps['required']['package'= array($deps['required']['package']);
  629.             }
  630.  
  631.             foreach ($deps['required']['package'as $dep{
  632.                 $this->_registerDep($data$pkg$dep'required');
  633.             }
  634.         }
  635.  
  636.         if (isset($deps['optional']['package'])) {
  637.             if (!isset($deps['optional']['package'][0])) {
  638.                 $deps['optional']['package'= array($deps['optional']['package']);
  639.             }
  640.  
  641.             foreach ($deps['optional']['package'as $dep{
  642.                 $this->_registerDep($data$pkg$dep'optional');
  643.             }
  644.         }
  645.  
  646.         if (isset($deps['required']['subpackage'])) {
  647.             if (!isset($deps['required']['subpackage'][0])) {
  648.                 $deps['required']['subpackage'= array($deps['required']['subpackage']);
  649.             }
  650.  
  651.             foreach ($deps['required']['subpackage'as $dep{
  652.                 $this->_registerDep($data$pkg$dep'required');
  653.             }
  654.         }
  655.  
  656.         if (isset($deps['optional']['subpackage'])) {
  657.             if (!isset($deps['optional']['subpackage'][0])) {
  658.                 $deps['optional']['subpackage'= array($deps['optional']['subpackage']);
  659.             }
  660.  
  661.             foreach ($deps['optional']['subpackage'as $dep{
  662.                 $this->_registerDep($data$pkg$dep'optional');
  663.             }
  664.         }
  665.  
  666.         if (isset($deps['group'])) {
  667.             if (!isset($deps['group'][0])) {
  668.                 $deps['group'= array($deps['group']);
  669.             }
  670.  
  671.             foreach ($deps['group'as $group{
  672.                 if (isset($group['package'])) {
  673.                     if (!isset($group['package'][0])) {
  674.                         $group['package'= array($group['package']);
  675.                     }
  676.  
  677.                     foreach ($group['package'as $dep{
  678.                         $this->_registerDep($data$pkg$dep'optional',
  679.                             $group['attribs']['name']);
  680.                     }
  681.                 }
  682.  
  683.                 if (isset($group['subpackage'])) {
  684.                     if (!isset($group['subpackage'][0])) {
  685.                         $group['subpackage'= array($group['subpackage']);
  686.                     }
  687.  
  688.                     foreach ($group['subpackage'as $dep{
  689.                         $this->_registerDep($data$pkg$dep'optional',
  690.                             $group['attribs']['name']);
  691.                     }
  692.                 }
  693.             }
  694.         }
  695.  
  696.         if ($data['dependencies'][$channel][$package== array()) {
  697.             unset($data['dependencies'][$channel][$package]);
  698.             if (!count($data['dependencies'][$channel])) {
  699.                 unset($data['dependencies'][$channel]);
  700.             }
  701.         }
  702.     }
  703.  
  704.     /**
  705.      * @param array the database
  706.      * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
  707.      * @param array the specific dependency
  708.      * @param required|optionalwhether this is a required or an optional dep
  709.      * @param string|falsedependency group this dependency is from, or false for ordinary dep
  710.      */
  711.     function _registerDep(&$data&$pkg$dep$type$group = false)
  712.     {
  713.         $info = array(
  714.             'dep'   => $dep,
  715.             'type'  => $type,
  716.             'group' => $group
  717.         );
  718.  
  719.         $dep  array_map('strtolower'$dep);
  720.         $depchannel = isset($dep['channel']$dep['channel''__uri';
  721.         if (!isset($data['dependencies'])) {
  722.             $data['dependencies'= array();
  723.         }
  724.  
  725.         $channel strtolower($pkg->getChannel());
  726.         $package strtolower($pkg->getPackage());
  727.  
  728.         if (!isset($data['dependencies'][$channel])) {
  729.             $data['dependencies'][$channel= array();
  730.         }
  731.  
  732.         if (!isset($data['dependencies'][$channel][$package])) {
  733.             $data['dependencies'][$channel][$package= array();
  734.         }
  735.  
  736.         $data['dependencies'][$channel][$package][$info;
  737.         if (isset($data['packages'][$depchannel][$dep['name']])) {
  738.             $found = false;
  739.             foreach ($data['packages'][$depchannel][$dep['name']] as $i => $p{
  740.                 if ($p['channel'== $channel && $p['package'== $package{
  741.                     $found = true;
  742.                     break;
  743.                 }
  744.             }
  745.         else {
  746.             if (!isset($data['packages'])) {
  747.                 $data['packages'= array();
  748.             }
  749.  
  750.             if (!isset($data['packages'][$depchannel])) {
  751.                 $data['packages'][$depchannel= array();
  752.             }
  753.  
  754.             if (!isset($data['packages'][$depchannel][$dep['name']])) {
  755.                 $data['packages'][$depchannel][$dep['name']] = array();
  756.             }
  757.  
  758.             $found = false;
  759.         }
  760.  
  761.         if (!$found{
  762.             $data['packages'][$depchannel][$dep['name']][= array(
  763.                 'channel' => $channel,
  764.                 'package' => $package
  765.             );
  766.         }
  767.     }
  768. }

Documentation generated on Wed, 06 Jul 2011 23:30:43 +0000 by phpDocumentor 1.4.3. PEAR Logo Copyright © PHP Group 2004.