PageRenderTime 44ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/common/libraries/plugin/pear/PEAR/DependencyDB.php

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