BaseRepository.php 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. <?php
  2. /*
  3. * This file is part of Composer.
  4. *
  5. * (c) Nils Adermann <naderman@naderman.de>
  6. * Jordi Boggiano <j.boggiano@seld.be>
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11. namespace Composer\Repository;
  12. use Composer\Package\RootPackageInterface;
  13. use Composer\Semver\Constraint\ConstraintInterface;
  14. /**
  15. * Common ancestor class for generic repository functionality.
  16. *
  17. * @author Niels Keurentjes <niels.keurentjes@omines.com>
  18. */
  19. abstract class BaseRepository implements RepositoryInterface
  20. {
  21. /**
  22. * Returns a list of links causing the requested needle packages to be installed, as an associative array with the
  23. * dependent's name as key, and an array containing in order the PackageInterface and Link describing the relationship
  24. * as values. If recursive lookup was requested a third value is returned containing an identically formed array up
  25. * to the root package.
  26. *
  27. * @param string|string[] $needle The package name(s) to inspect.
  28. * @param ConstraintInterface|null $constraint Optional constraint to filter by.
  29. * @param bool $invert Whether to invert matches to discover reasons for the package *NOT* to be installed.
  30. * @param bool $recurse Whether to recursively expand the requirement tree up to the root package.
  31. * @return array An associative array of arrays as described above.
  32. */
  33. public function getDependents($needle, $constraint = null, $invert = false, $recurse = true)
  34. {
  35. $needles = is_array($needle) ? $needle : array($needle);
  36. $results = array();
  37. // Loop over all currently installed packages.
  38. foreach ($this->getPackages() as $package) {
  39. $links = $package->getRequires();
  40. // Replacements are considered valid reasons for a package to be installed during forward resolution
  41. if (!$invert) {
  42. $links += $package->getReplaces();
  43. }
  44. // Require-dev is only relevant for the root package
  45. if ($package instanceof RootPackageInterface) {
  46. $links += $package->getDevRequires();
  47. }
  48. // Cross-reference all discovered links to the needles
  49. foreach ($links as $link) {
  50. foreach ($needles as $needle) {
  51. if ($link->getTarget() === $needle) {
  52. if (is_null($constraint) || (($link->getConstraint()->matches($constraint) === !$invert))) {
  53. $results[$link->getSource()] = array($package, $link, $recurse ? $this->getDependents($link->getSource(), null, false, true) : array());
  54. }
  55. }
  56. }
  57. }
  58. }
  59. ksort($results);
  60. return $results;
  61. }
  62. }