Solver::testDisable()   B
last analyzed

Complexity

Conditions 7
Paths 4

Size

Total Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 31
rs 8.4906
c 0
b 0
f 0
cc 7
nc 4
nop 2
1
<?php
2
/**
3
 * Solver.php
4
 *
5
 * @copyright      More in license.md
6
 * @license        https://www.ipublikuj.eu
7
 * @author         Adam Kadlec <[email protected]>
8
 * @package        iPublikuj:Packages!
9
 * @subpackage     DependencyResolver
10
 * @since          2.0.0
11
 *
12
 * @date           27.06.16
13
 */
14
15
declare(strict_types = 1);
16
17
namespace IPub\Packages\DependencyResolver;
18
19
use IPub\Packages;
20
use IPub\Packages\Entities;
21
use IPub\Packages\Exceptions;
22
use IPub\Packages\Repository;
23
24
/**
25
 * Dependency solver
26
 *
27
 * @package        iPublikuj:Packages!
28
 * @subpackage     DependencyResolver
29
 *
30
 * @author         Josef Kříž <[email protected]>
31
 * @author         Adam Kadlec <[email protected]>
32
 */
33
class Solver
34
{
35
	/**
36
	 * @var Entities\IPackage[]
37
	 */
38
	private $packages;
39
40
	/**
41
	 * @var Entities\IPackage[]
42
	 */
43
	private $enabledPackages;
44
45
	/**
46
	 * @param Repository\IRepository $repository
47
	 * @param Packages\PackagesManager $manager
48
	 */
49
	public function __construct(
50
		Repository\IRepository $repository,
51
		Packages\PackagesManager $manager
52
	) {
53
		// Get all installed packages
54
		$this->packages = $repository->getPackages();
55
56
		// Get all enabled packages
57
		$this->enabledPackages = $repository->filterPackages(function (Entities\IPackage $package) use ($manager) : bool {
58
			return $manager->getStatus($package) === Entities\IPackage::STATE_ENABLED;
59
		});
60
	}
61
62
	/**
63
	 * @param Entities\IPackage $package
64
	 * @param Problem|NULL $problem
65
	 *
66
	 * @return void
67
	 */
68
	public function testEnable(Entities\IPackage $package, ?Problem $problem = NULL) : void
69
	{
70
		foreach ($package->getRequire() as $name) {
71
			// Check if required package is enabled...
72
			if (!isset($this->enabledPackages[$name])) {
73
				if ($problem && isset($this->packages[$name])) {
74
					//... if not try to check if is possible to enable it
75
					$this->testEnable($this->packages[$name], $problem);
76
77
					$job = new Job(Job::ACTION_ENABLE, $this->packages[$name]);
78
79
					if (!$problem->hasSolution($job)) {
80
						$problem->addSolution($job);
81
					}
82
83
					$this->enabledPackages[$name] = $this->packages[$name];
84
85
				} else {
86
					throw new Exceptions\InvalidArgumentException(sprintf(
87
						'Package "%s" depend on "%s", which was not found.',
88
						$package->getName(),
89
						$name
90
					));
91
				}
92
			}
93
		}
94
	}
95
96
	/**
97
	 * @param Entities\IPackage $package
98
	 * @param Problem|NULL $problem
99
	 *
100
	 * @return void
101
	 */
102
	public function testDisable(Entities\IPackage $package, ?Problem $problem = NULL) : void
103
	{
104
		foreach ($this->enabledPackages as $sourcePackage) {
105
			if ($sourcePackage->getName() === $package->getName()) {
106
				continue;
107
			}
108
109
			foreach ($sourcePackage->getRequire() as $name) {
110
				if ($name === $package->getName()) {
111
					if ($problem) {
112
						$this->testDisable($sourcePackage, $problem);
113
114
						$job = new Job(Job::ACTION_DISABLE, $sourcePackage);
115
116
						if (!$problem->hasSolution($job)) {
117
							$problem->addSolution($job);
118
						}
119
120
						unset($this->enabledPackages[$name]);
121
122
					} else {
123
						throw new Exceptions\InvalidArgumentException(sprintf(
124
							'Package "%s" depend on "%s".',
125
							$sourcePackage->getName(),
126
							$package->getName()
127
						));
128
					}
129
				}
130
			}
131
		}
132
	}
133
}
134