1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace MagentoHackathon\Composer\Magento\Repository; |
4
|
|
|
|
5
|
|
|
use MagentoHackathon\Composer\Magento\InstalledPackage; |
6
|
|
|
use MagentoHackathon\Composer\Magento\InstalledPackageDumper; |
7
|
|
|
|
8
|
|
|
/** |
9
|
|
|
* Class InstalledPackageFileSystemRepository |
10
|
|
|
* @package MagentoHackathon\Composer\Magento\Repository |
11
|
|
|
* @author Aydin Hassan <[email protected]> |
12
|
|
|
*/ |
13
|
|
|
class InstalledPackageFileSystemRepository implements InstalledPackageRepositoryInterface |
14
|
|
|
{ |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* @var string Path to state file |
18
|
|
|
*/ |
19
|
|
|
protected $filePath; |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* @var array |
23
|
|
|
*/ |
24
|
|
|
protected $packages = array(); |
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* @var bool Flag to indicate if we have read the existing file |
28
|
|
|
*/ |
29
|
|
|
protected $isLoaded = false; |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* @var bool Flag to indicate if we need to write once we are finished |
33
|
|
|
*/ |
34
|
|
|
protected $hasChanges = false; |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* @var InstalledPackageDumper |
38
|
|
|
*/ |
39
|
|
|
protected $dumper; |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* If file exists, check its readable |
43
|
|
|
* Check in any case that it's writeable |
44
|
|
|
* |
45
|
|
|
* @param string $filePath |
46
|
|
|
* @param InstalledPackageDumper $dumper |
47
|
|
|
*/ |
48
|
18 |
|
public function __construct($filePath, InstalledPackageDumper $dumper) |
49
|
|
|
{ |
50
|
18 |
View Code Duplication |
if (file_exists($filePath) && !is_writable($filePath)) { |
|
|
|
|
51
|
1 |
|
throw new \InvalidArgumentException(sprintf('File "%s" is not writable', $filePath)); |
52
|
|
|
} |
53
|
|
|
|
54
|
18 |
|
if (file_exists($filePath) && !is_readable($filePath)) { |
55
|
1 |
|
throw new \InvalidArgumentException(sprintf('File "%s" is not readable', $filePath)); |
56
|
|
|
} |
57
|
|
|
|
58
|
18 |
View Code Duplication |
if (!file_exists($filePath) && !is_writable(dirname($filePath))) { |
|
|
|
|
59
|
1 |
|
throw new \InvalidArgumentException(sprintf('Directory "%s" is not writable', dirname($filePath))); |
60
|
|
|
} |
61
|
|
|
|
62
|
18 |
|
$this->filePath = $filePath; |
63
|
18 |
|
$this->dumper = $dumper; |
64
|
18 |
|
} |
65
|
|
|
|
66
|
|
|
/** |
67
|
|
|
* @return array |
68
|
|
|
*/ |
69
|
8 |
|
public function findAll() |
70
|
|
|
{ |
71
|
8 |
|
$this->load(); |
72
|
8 |
|
return $this->packages; |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* @param string $packageName |
77
|
|
|
* @return InstalledPackage |
78
|
|
|
* @throws \Exception |
79
|
|
|
*/ |
80
|
13 |
|
public function findByPackageName($packageName) |
81
|
|
|
{ |
82
|
13 |
|
$this->load(); |
83
|
13 |
|
foreach ($this->packages as $package) { |
84
|
8 |
|
if ($package->getName() === $packageName) { |
85
|
8 |
|
return $package; |
86
|
|
|
} |
87
|
|
|
} |
88
|
|
|
|
89
|
12 |
|
throw new \Exception(sprintf('Package Installed Files for: "%s" not found', $packageName)); |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
/** |
93
|
|
|
* If version specified, perform a strict check, |
94
|
|
|
* which only returns true if repository has the package in the specified version |
95
|
|
|
* |
96
|
|
|
* @param string $packageName |
97
|
|
|
* @param string $version |
98
|
|
|
* @return bool |
99
|
|
|
*/ |
100
|
6 |
|
public function has($packageName, $version = null) |
101
|
|
|
{ |
102
|
6 |
|
$this->load(); |
103
|
|
|
try { |
104
|
6 |
|
$package = $this->findByPackageName($packageName); |
105
|
|
|
|
106
|
5 |
|
if (null === $version) { |
107
|
|
|
return true; |
108
|
|
|
} |
109
|
|
|
|
110
|
5 |
|
return $package->getVersion() === $version; |
111
|
3 |
|
} catch (\Exception $e) { |
112
|
3 |
|
return false; |
113
|
|
|
} |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
/** |
117
|
|
|
* @param InstalledPackage $package |
118
|
|
|
* @throws \Exception |
119
|
|
|
*/ |
120
|
11 |
|
public function add(InstalledPackage $package) |
121
|
|
|
{ |
122
|
11 |
|
$this->load(); |
123
|
|
|
|
124
|
|
|
try { |
125
|
11 |
|
$this->findByPackageName($package->getName()); |
126
|
11 |
|
} catch (\Exception $e) { |
127
|
11 |
|
$this->packages[] = $package; |
128
|
11 |
|
$this->hasChanges = true; |
129
|
11 |
|
return; |
130
|
|
|
} |
131
|
|
|
|
132
|
1 |
|
throw new \Exception(sprintf('Package: "%s" is already installed', $package->getName())); |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
/** |
136
|
|
|
* @param InstalledPackage $package |
137
|
|
|
* @throws \Exception |
138
|
|
|
*/ |
139
|
7 |
|
public function remove(InstalledPackage $package) |
140
|
|
|
{ |
141
|
7 |
|
$this->load(); |
142
|
|
|
|
143
|
7 |
|
foreach ($this->packages as $key => $installedPackage) { |
144
|
6 |
|
if ($installedPackage->getName() === $package->getName()) { |
145
|
6 |
|
array_splice($this->packages, $key, 1); |
146
|
6 |
|
$this->hasChanges = true; |
147
|
6 |
|
return; |
148
|
|
|
} |
149
|
|
|
} |
150
|
|
|
|
151
|
1 |
|
throw new \Exception(sprintf('Package: "%s" not found', $package->getName())); |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
/** |
155
|
|
|
* Load the Mappings File |
156
|
|
|
* |
157
|
|
|
* @return array |
158
|
|
|
*/ |
159
|
14 |
|
private function load() |
160
|
|
|
{ |
161
|
14 |
|
if (!$this->isLoaded && file_exists($this->filePath)) { |
162
|
1 |
|
$data = json_decode(file_get_contents($this->filePath), true); |
163
|
|
|
|
164
|
1 |
|
foreach ($data as $installedPackageData) { |
165
|
1 |
|
$this->packages[] = $this->dumper->restore($installedPackageData); |
166
|
|
|
} |
167
|
|
|
} |
168
|
|
|
|
169
|
14 |
|
$this->isLoaded = true; |
170
|
14 |
|
} |
171
|
|
|
|
172
|
|
|
/** |
173
|
|
|
* Do the write on destruct, we shouldn't have to do this manually |
174
|
|
|
* - you don't call save after adding an entry to the database |
175
|
|
|
* and at the same time, do want to perform IO for each package addition/removal. |
176
|
|
|
* |
177
|
|
|
* Also I don't like enforcing the consumer to call save and load. |
178
|
|
|
*/ |
179
|
11 |
|
public function __destruct() |
180
|
|
|
{ |
181
|
11 |
|
if ($this->hasChanges) { |
182
|
4 |
|
$data = array(); |
183
|
4 |
|
foreach ($this->packages as $installedPackage) { |
184
|
3 |
|
$data[] = $this->dumper->dump($installedPackage); |
185
|
|
|
} |
186
|
|
|
|
187
|
4 |
|
file_put_contents($this->filePath, json_encode($data, JSON_PRETTY_PRINT)); |
188
|
|
|
} |
189
|
11 |
|
} |
190
|
|
|
} |
191
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.