|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/* |
|
4
|
|
|
* This file is part of the Zikula package. |
|
5
|
|
|
* |
|
6
|
|
|
* Copyright Zikula Foundation - http://zikula.org/ |
|
7
|
|
|
* |
|
8
|
|
|
* For the full copyright and license information, please view the LICENSE |
|
9
|
|
|
* file that was distributed with this source code. |
|
10
|
|
|
*/ |
|
11
|
|
|
|
|
12
|
|
|
namespace Zikula\Bundle\CoreBundle\Bundle; |
|
13
|
|
|
|
|
14
|
|
|
use Symfony\Component\HttpKernel\Exception\PreconditionRequiredHttpException; |
|
15
|
|
|
use Zikula\Common\Translator\TranslatorTrait; |
|
16
|
|
|
|
|
17
|
|
|
class MetaData implements \ArrayAccess |
|
18
|
|
|
{ |
|
19
|
|
|
use TranslatorTrait; |
|
20
|
|
|
|
|
21
|
|
|
const TYPE_MODULE = 2; |
|
22
|
|
|
|
|
23
|
|
|
const TYPE_SYSTEM = 3; |
|
24
|
|
|
|
|
25
|
|
|
const TYPE_CORE = 4; |
|
26
|
|
|
|
|
27
|
|
|
const DEPENDENCY_REQUIRED = 1; |
|
28
|
|
|
|
|
29
|
|
|
const DEPENDENCY_RECOMMENDED = 2; |
|
30
|
|
|
|
|
31
|
|
|
const DEPENDENCY_CONFLICTS = 3; |
|
32
|
|
|
|
|
33
|
|
|
private $name; |
|
34
|
|
|
|
|
35
|
|
|
private $version; |
|
36
|
|
|
|
|
37
|
|
|
private $description; |
|
38
|
|
|
|
|
39
|
|
|
private $type; |
|
40
|
|
|
|
|
41
|
|
|
private $dependencies; |
|
42
|
|
|
|
|
43
|
|
|
private $shortName; |
|
44
|
|
|
|
|
45
|
|
|
private $class; |
|
46
|
|
|
|
|
47
|
|
|
private $namespace; |
|
48
|
|
|
|
|
49
|
|
|
private $basePath; |
|
50
|
|
|
|
|
51
|
|
|
private $rootPath; |
|
52
|
|
|
|
|
53
|
|
|
private $autoload; |
|
54
|
|
|
|
|
55
|
|
|
private $displayName; |
|
56
|
|
|
|
|
57
|
|
|
private $url; |
|
58
|
|
|
|
|
59
|
|
|
private $oldNames; |
|
60
|
|
|
|
|
61
|
|
|
private $capabilities; |
|
62
|
|
|
|
|
63
|
|
|
private $securitySchema; |
|
64
|
|
|
|
|
65
|
|
|
private $extensionType; |
|
66
|
|
|
|
|
67
|
|
|
private $coreCompatibility; |
|
68
|
|
|
|
|
69
|
|
|
public function __construct($json) |
|
70
|
|
|
{ |
|
71
|
|
|
$this->name = $json['name']; |
|
72
|
|
|
$this->version = isset($json['version']) ? $json['version'] : ''; |
|
73
|
|
|
$this->description = isset($json['description']) ? $json['description'] : ''; |
|
74
|
|
|
$this->type = $json['type']; |
|
75
|
|
|
$this->dependencies = $this->formatDependencies($json); |
|
76
|
|
|
$this->shortName = $json['extra']['zikula']['short-name']; |
|
77
|
|
|
$this->class = $json['extra']['zikula']['class']; |
|
78
|
|
|
$this->namespace = substr($this->class, 0, strrpos($this->class, '\\') + 1); |
|
79
|
|
|
$this->basePath = $json['extra']['zikula']['base-path']; |
|
80
|
|
|
$this->rootPath = $json['extra']['zikula']['root-path']; |
|
81
|
|
|
$this->autoload = $json['autoload']; |
|
82
|
|
|
$this->displayName = isset($json['extra']['zikula']['displayname']) ? $json['extra']['zikula']['displayname'] : ''; |
|
83
|
|
|
$this->url = isset($json['extra']['zikula']['url']) ? $json['extra']['zikula']['url'] : ''; |
|
84
|
|
|
$this->oldNames = isset($json['extra']['zikula']['oldnames']) ? $json['extra']['zikula']['oldnames'] : []; |
|
85
|
|
|
$this->capabilities = isset($json['extra']['zikula']['capabilities']) ? $json['extra']['zikula']['capabilities'] : []; |
|
86
|
|
|
$this->securitySchema = isset($json['extra']['zikula']['securityschema']) ? $json['extra']['zikula']['securityschema'] : []; |
|
87
|
|
|
$this->extensionType = isset($json['extensionType']) ? $json['extensionType'] : self::TYPE_MODULE; |
|
88
|
|
|
$this->coreCompatibility = isset($json['extra']['zikula']['core-compatibility']) ? $json['extra']['zikula']['core-compatibility'] : '>=1.4.0 <3.0.0'; // @todo >=1.4.1 |
|
89
|
|
|
} |
|
90
|
|
|
|
|
91
|
|
|
public function getName() |
|
92
|
|
|
{ |
|
93
|
|
|
return $this->name; |
|
94
|
|
|
} |
|
95
|
|
|
|
|
96
|
|
|
public function getVersion() |
|
97
|
|
|
{ |
|
98
|
|
|
return $this->version; |
|
99
|
|
|
} |
|
100
|
|
|
|
|
101
|
|
|
public function getShortName() |
|
102
|
|
|
{ |
|
103
|
|
|
return $this->shortName; |
|
104
|
|
|
} |
|
105
|
|
|
|
|
106
|
|
|
public function getPsr0() |
|
107
|
|
|
{ |
|
108
|
|
|
return isset($this->autoload['psr-0']) ? $this->autoload['psr-0'] : []; |
|
109
|
|
|
} |
|
110
|
|
|
|
|
111
|
|
|
public function getPsr4() |
|
112
|
|
|
{ |
|
113
|
|
|
return isset($this->autoload['psr-4']) ? $this->autoload['psr-4'] : []; |
|
114
|
|
|
} |
|
115
|
|
|
|
|
116
|
|
|
public function getAutoload() |
|
117
|
|
|
{ |
|
118
|
|
|
return $this->autoload; |
|
119
|
|
|
} |
|
120
|
|
|
|
|
121
|
|
|
public function getBasePath() |
|
122
|
|
|
{ |
|
123
|
|
|
return $this->basePath; |
|
124
|
|
|
} |
|
125
|
|
|
|
|
126
|
|
|
public function getRootPath() |
|
127
|
|
|
{ |
|
128
|
|
|
return $this->rootPath; |
|
129
|
|
|
} |
|
130
|
|
|
|
|
131
|
|
|
public function getClass() |
|
132
|
|
|
{ |
|
133
|
|
|
return $this->class; |
|
134
|
|
|
} |
|
135
|
|
|
|
|
136
|
|
|
public function getNamespace() |
|
137
|
|
|
{ |
|
138
|
|
|
return $this->namespace; |
|
139
|
|
|
} |
|
140
|
|
|
|
|
141
|
|
|
public function getType() |
|
142
|
|
|
{ |
|
143
|
|
|
return $this->type; |
|
144
|
|
|
} |
|
145
|
|
|
|
|
146
|
|
|
public function getDescription() |
|
147
|
|
|
{ |
|
148
|
|
|
$this->confirmTranslator(); |
|
149
|
|
|
|
|
150
|
|
|
$description = $this->__(/** @Ignore */$this->description); |
|
151
|
|
|
|
|
152
|
|
|
return (empty($description)) ? $this->description : $description; |
|
153
|
|
|
} |
|
154
|
|
|
|
|
155
|
|
|
public function setDescription($description) |
|
156
|
|
|
{ |
|
157
|
|
|
$this->description = $description; |
|
158
|
|
|
} |
|
159
|
|
|
|
|
160
|
|
|
public function getDependencies() |
|
161
|
|
|
{ |
|
162
|
|
|
return $this->dependencies; |
|
163
|
|
|
} |
|
164
|
|
|
|
|
165
|
|
|
public function getDisplayName() |
|
166
|
|
|
{ |
|
167
|
|
|
$this->confirmTranslator(); |
|
168
|
|
|
|
|
169
|
|
|
$display_name = $this->__(/** @Ignore */$this->displayName); |
|
170
|
|
|
|
|
171
|
|
|
return (empty($display_name)) ? $this->displayName : $display_name; |
|
172
|
|
|
} |
|
173
|
|
|
|
|
174
|
|
|
public function setDisplayName($name) |
|
175
|
|
|
{ |
|
176
|
|
|
$this->displayName = $name; |
|
177
|
|
|
} |
|
178
|
|
|
|
|
179
|
|
|
public function getUrl($translated = true) |
|
180
|
|
|
{ |
|
181
|
|
|
$this->confirmTranslator(); |
|
182
|
|
|
|
|
183
|
|
|
$url = $this->__(/** @Ignore */$this->url); |
|
184
|
|
|
|
|
185
|
|
|
return $translated ? ((empty($url)) ? $this->$url : $url) : $this->url; |
|
186
|
|
|
} |
|
187
|
|
|
|
|
188
|
|
|
public function setUrl($url) |
|
189
|
|
|
{ |
|
190
|
|
|
$this->url = $url; |
|
191
|
|
|
} |
|
192
|
|
|
|
|
193
|
|
|
public function getOldNames() |
|
194
|
|
|
{ |
|
195
|
|
|
return $this->oldNames; |
|
196
|
|
|
} |
|
197
|
|
|
|
|
198
|
|
|
public function getCapabilities() |
|
199
|
|
|
{ |
|
200
|
|
|
return $this->capabilities; |
|
201
|
|
|
} |
|
202
|
|
|
|
|
203
|
|
|
public function getSecuritySchema() |
|
204
|
|
|
{ |
|
205
|
|
|
return $this->securitySchema; |
|
206
|
|
|
} |
|
207
|
|
|
|
|
208
|
|
|
public function getExtensionType() |
|
209
|
|
|
{ |
|
210
|
|
|
return $this->extensionType; |
|
211
|
|
|
} |
|
212
|
|
|
|
|
213
|
|
|
public function getCoreCompatibility() |
|
214
|
|
|
{ |
|
215
|
|
|
return $this->coreCompatibility; |
|
216
|
|
|
} |
|
217
|
|
|
|
|
218
|
|
|
private function formatDependencies(array $json) |
|
219
|
|
|
{ |
|
220
|
|
|
$dependencies = []; |
|
221
|
|
|
if (!empty($json['require'])) { |
|
222
|
|
|
foreach ($json['require'] as $package => $version) { |
|
223
|
|
|
$dependencies[] = [ |
|
224
|
|
|
'modname' => $package, |
|
225
|
|
|
'minversion' => $version, |
|
226
|
|
|
'maxversion' => $version, |
|
227
|
|
|
'status' => self::DEPENDENCY_REQUIRED |
|
228
|
|
|
]; |
|
229
|
|
|
} |
|
230
|
|
|
} else { |
|
231
|
|
|
$dependencies[] = [ |
|
232
|
|
|
'modname' => 'zikula/core', |
|
233
|
|
|
'minversion' => '>=1.4.1 <3.0.0', |
|
234
|
|
|
'maxversion' => '>=1.4.1 <3.0.0', |
|
235
|
|
|
'status' => self::DEPENDENCY_REQUIRED |
|
236
|
|
|
]; |
|
237
|
|
|
} |
|
238
|
|
|
if (!empty($json['suggest'])) { |
|
239
|
|
|
foreach ($json['suggest'] as $package => $reason) { |
|
240
|
|
|
if (strpos($package, ':')) { |
|
241
|
|
|
list($name, $version) = explode(':', $package, 2); |
|
242
|
|
|
} else { |
|
243
|
|
|
$name = $package; |
|
244
|
|
|
$version = '-1'; |
|
245
|
|
|
} |
|
246
|
|
|
$dependencies[] = [ |
|
247
|
|
|
'modname' => $name, |
|
248
|
|
|
'minversion' => $version, |
|
249
|
|
|
'maxversion' => $version, |
|
250
|
|
|
'reason' => $reason, |
|
251
|
|
|
'status' => self::DEPENDENCY_RECOMMENDED |
|
252
|
|
|
]; |
|
253
|
|
|
} |
|
254
|
|
|
} |
|
255
|
|
|
|
|
256
|
|
|
return $dependencies; |
|
257
|
|
|
} |
|
258
|
|
|
|
|
259
|
|
|
public function setTranslator($translator) |
|
260
|
|
|
{ |
|
261
|
|
|
$this->translator = $translator; |
|
262
|
|
|
} |
|
263
|
|
|
|
|
264
|
|
|
private function confirmTranslator() |
|
265
|
|
|
{ |
|
266
|
|
|
if (!isset($this->translator)) { |
|
267
|
|
|
throw new PreconditionRequiredHttpException(sprintf("The translator property is not set correctly in %s", __CLASS__)); |
|
268
|
|
|
} |
|
269
|
|
|
} |
|
270
|
|
|
|
|
271
|
|
|
/** |
|
272
|
|
|
* Theme MetaData as array |
|
273
|
|
|
* |
|
274
|
|
|
* @return array |
|
275
|
|
|
*/ |
|
276
|
|
|
public function getThemeFilteredVersionInfoArray() |
|
277
|
|
|
{ |
|
278
|
|
|
$capabilities = $this->getCapabilities(); |
|
279
|
|
|
|
|
280
|
|
|
return [ |
|
281
|
|
|
'name' => $this->getShortName(), |
|
282
|
|
|
'type' => $this->getExtensionType(), |
|
283
|
|
|
'displayname' => $this->getDisplayName(), |
|
284
|
|
|
'description' => $this->getDescription(), |
|
285
|
|
|
'version' => $this->getVersion(), |
|
286
|
|
|
// 'capabilities' => $this->getCapabilities(), |
|
|
|
|
|
|
287
|
|
|
// @todo temp - add to DB and move to inverse in legacy code and refactor later checks |
|
288
|
|
|
'user' => isset($capabilities['user']) ? $capabilities['user'] : true, |
|
289
|
|
|
'admin' => isset($capabilities['admin']) ? $capabilities['admin'] : true, |
|
290
|
|
|
'system' => isset($capabilities['system']) ? $capabilities['system'] : false, |
|
291
|
|
|
'xhtml' => isset($capabilities['xhtml']) ? $capabilities['xhtml'] : true, // @todo is this valid any longer? |
|
292
|
|
|
]; |
|
293
|
|
|
} |
|
294
|
|
|
|
|
295
|
|
|
/** |
|
296
|
|
|
* Module MetaData as array |
|
297
|
|
|
* |
|
298
|
|
|
* @return array |
|
299
|
|
|
*/ |
|
300
|
|
|
public function getFilteredVersionInfoArray() |
|
301
|
|
|
{ |
|
302
|
|
|
return [ |
|
303
|
|
|
'name' => $this->getShortName(), |
|
304
|
|
|
'type' => $this->getExtensionType(), |
|
305
|
|
|
'displayname' => $this->getDisplayName(), |
|
306
|
|
|
'oldnames' => $this->getOldNames(), |
|
307
|
|
|
'description' => $this->getDescription(), |
|
308
|
|
|
'version' => $this->getVersion(), |
|
309
|
|
|
'url' => $this->getUrl(), |
|
310
|
|
|
'capabilities' => $this->getCapabilities(), |
|
311
|
|
|
'securityschema' => $this->getSecuritySchema(), |
|
312
|
|
|
'dependencies' => $this->getDependencies(), |
|
313
|
|
|
'corecompatibility' => $this->getCoreCompatibility(), |
|
314
|
|
|
'core_max' => '' // core_min is set from corecompatibility |
|
315
|
|
|
]; |
|
316
|
|
|
} |
|
317
|
|
|
|
|
318
|
|
|
public function offsetExists($offset) |
|
319
|
|
|
{ |
|
320
|
|
|
return isset($this->$offset); |
|
321
|
|
|
} |
|
322
|
|
|
|
|
323
|
|
|
public function offsetGet($offset) |
|
324
|
|
|
{ |
|
325
|
|
|
$method = "get" . ucwords($offset); |
|
326
|
|
|
|
|
327
|
|
|
return $this->$method(); |
|
328
|
|
|
} |
|
329
|
|
|
|
|
330
|
|
|
public function offsetSet($offset, $value) |
|
331
|
|
|
{ |
|
332
|
|
|
// not allowed |
|
333
|
|
|
throw new \Exception('Setting values by array access is not allowed.'); |
|
334
|
|
|
} |
|
335
|
|
|
|
|
336
|
|
|
public function offsetUnset($offset) |
|
337
|
|
|
{ |
|
338
|
|
|
// not allowed |
|
339
|
|
|
throw new \Exception('Unsetting values by array access is not allowed.'); |
|
340
|
|
|
} |
|
341
|
|
|
} |
|
342
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.