Transaction.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  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\DependencyResolver;
  12. use Composer\Package\AliasPackage;
  13. use Composer\DependencyResolver\Operation;
  14. /**
  15. * @author Nils Adermann <naderman@naderman.de>
  16. */
  17. class Transaction
  18. {
  19. protected $policy;
  20. protected $pool;
  21. protected $installedMap;
  22. protected $decisions;
  23. protected $transaction;
  24. public function __construct($policy, $pool, $installedMap, $decisions)
  25. {
  26. $this->policy = $policy;
  27. $this->pool = $pool;
  28. $this->installedMap = $installedMap;
  29. $this->decisions = $decisions;
  30. $this->transaction = array();
  31. }
  32. public function getOperations()
  33. {
  34. $installMeansUpdateMap = array();
  35. foreach ($this->installedMap as $packageId => $void) {
  36. if ($this->decisions->undecided($packageId)) {
  37. $this->decisions->decide(-$packageId, 1, null);
  38. }
  39. }
  40. foreach ($this->decisions as $i => $decision) {
  41. $literal = $decision[Decisions::DECISION_LITERAL];
  42. $package = $this->pool->literalToPackage($literal);
  43. // !wanted & installed
  44. if ($literal <= 0 && isset($this->installedMap[$package->getId()])) {
  45. $updates = $this->policy->findUpdatePackages($this->pool, $this->installedMap, $package);
  46. $literals = array($package->getId());
  47. foreach ($updates as $update) {
  48. $literals[] = $update->getId();
  49. }
  50. foreach ($literals as $updateLiteral) {
  51. if ($updateLiteral !== $literal) {
  52. $installMeansUpdateMap[abs($updateLiteral)] = $package;
  53. }
  54. }
  55. }
  56. }
  57. foreach ($this->decisions as $i => $decision) {
  58. $literal = $decision[Decisions::DECISION_LITERAL];
  59. $package = $this->pool->literalToPackage($literal);
  60. // wanted & installed || !wanted & !installed
  61. if (($literal > 0) == (isset($this->installedMap[$package->getId()]))) {
  62. continue;
  63. }
  64. if ($literal > 0) {
  65. if ($package instanceof AliasPackage) {
  66. $this->markAliasInstalled($package, $decision[Decisions::DECISION_REASON]);
  67. continue;
  68. }
  69. if (isset($installMeansUpdateMap[abs($literal)])) {
  70. $source = $installMeansUpdateMap[abs($literal)];
  71. $this->update($source, $package, $decision[Decisions::DECISION_REASON]);
  72. // avoid updates to one package from multiple origins
  73. unset($installMeansUpdateMap[abs($literal)]);
  74. $ignoreRemove[$source->getId()] = true;
  75. } else {
  76. $this->install($package, $decision[Decisions::DECISION_REASON]);
  77. }
  78. }
  79. }
  80. foreach ($this->decisions as $i => $decision) {
  81. $literal = $decision[Decisions::DECISION_LITERAL];
  82. $package = $this->pool->literalToPackage($literal);
  83. // wanted & installed || !wanted & !installed
  84. if (($literal > 0) == (isset($this->installedMap[$package->getId()]))) {
  85. continue;
  86. }
  87. if ($literal <= 0 && !isset($ignoreRemove[$package->getId()])) {
  88. $this->uninstall($package, $decision[Decisions::DECISION_REASON]);
  89. }
  90. }
  91. return $this->transaction;
  92. }
  93. protected function install($package, $reason)
  94. {
  95. if ($package instanceof AliasPackage) {
  96. return $this->markAliasInstalled($package, $reason);
  97. }
  98. $this->transaction[] = new Operation\InstallOperation($package, $reason);
  99. }
  100. protected function update($from, $to, $reason)
  101. {
  102. $this->transaction[] = new Operation\UpdateOperation($from, $to, $reason);
  103. }
  104. protected function uninstall($package, $reason)
  105. {
  106. if ($package instanceof AliasPackage) {
  107. return $this->markAliasUninstalled($package, $reason);
  108. }
  109. $this->transaction[] = new Operation\UninstallOperation($package, $reason);
  110. }
  111. protected function markAliasInstalled($package, $reason)
  112. {
  113. $this->transaction[] = new Operation\MarkAliasInstalledOperation($package, $reason);
  114. }
  115. protected function markAliasUninstalled($package, $reason)
  116. {
  117. $this->transaction[] = new Operation\MarkAliasUninstalledOperation($package, $reason);
  118. }
  119. }