Completed
Push — master ( 60e59a...334051 )
by Adam
06:35
created

Solver::testDisable()   C

Complexity

Conditions 7
Paths 4

Size

Total Lines 31
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

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