1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* This file is part of tenside/core-bundle. |
5
|
|
|
* |
6
|
|
|
* (c) Christian Schiffler <[email protected]> |
7
|
|
|
* |
8
|
|
|
* For the full copyright and license information, please view the LICENSE |
9
|
|
|
* file that was distributed with this source code. |
10
|
|
|
* |
11
|
|
|
* This project is provided in good faith and hope to be usable by anyone. |
12
|
|
|
* |
13
|
|
|
* @package tenside/core-bundle |
14
|
|
|
* @author Christian Schiffler <[email protected]> |
15
|
|
|
* @author Andreas Schempp <[email protected]> |
16
|
|
|
* @copyright 2015 Christian Schiffler <[email protected]> |
17
|
|
|
* @license https://github.com/tenside/core-bundle/blob/master/LICENSE MIT |
18
|
|
|
* @link https://github.com/tenside/core-bundle |
19
|
|
|
* @filesource |
20
|
|
|
*/ |
21
|
|
|
|
22
|
|
|
namespace Tenside\CoreBundle\Controller; |
23
|
|
|
|
24
|
|
|
use Composer\Package\AliasPackage; |
25
|
|
|
use Composer\Package\Loader\ArrayLoader; |
26
|
|
|
use Composer\Package\PackageInterface; |
27
|
|
|
use Composer\Repository\RepositoryInterface; |
28
|
|
|
use Composer\Repository\WritableArrayRepository; |
29
|
|
|
use Nelmio\ApiDocBundle\Annotation\ApiDoc; |
30
|
|
|
use Symfony\Component\HttpFoundation\JsonResponse; |
31
|
|
|
use Symfony\Component\HttpFoundation\Request; |
32
|
|
|
use Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException; |
33
|
|
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; |
34
|
|
|
use Tenside\Core\Composer\PackageConverter; |
35
|
|
|
use Tenside\Core\Util\JsonArray; |
36
|
|
|
use Tenside\Core\Util\JsonFile; |
37
|
|
|
use Tenside\CoreBundle\Annotation\ApiDescription; |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* List and manipulate the installed packages. |
41
|
|
|
*/ |
42
|
|
|
class PackageController extends AbstractController |
43
|
|
|
{ |
44
|
|
|
/** |
45
|
|
|
* Retrieve the package list. |
46
|
|
|
* |
47
|
|
|
* @param Request $request The request to process. |
48
|
|
|
* |
49
|
|
|
* @return JsonResponse |
50
|
|
|
* |
51
|
|
|
* @ApiDoc( |
52
|
|
|
* section="package", |
53
|
|
|
* statusCodes = { |
54
|
|
|
* 200 = "When everything worked out ok" |
55
|
|
|
* }, |
56
|
|
|
* authentication = true, |
57
|
|
|
* authenticationRoles = { |
58
|
|
|
* "ROLE_MANIPULATE_REQUIREMENTS" |
59
|
|
|
* }, |
60
|
|
|
* filters = { |
61
|
|
|
* { |
62
|
|
|
* "name"="all", |
63
|
|
|
* "description"="If present, all packages will get listed, only directly required ones otherwise." |
64
|
|
|
* } |
65
|
|
|
* } |
66
|
|
|
* ) |
67
|
|
|
* @ApiDescription( |
68
|
|
|
* response={ |
69
|
|
|
* "package name 1...n" = { |
70
|
|
|
* "actualType" = "object", |
71
|
|
|
* "subType" = "object", |
72
|
|
|
* "description" = "The content of the packages", |
73
|
|
|
* "children" = { |
74
|
|
|
* "name" = { |
75
|
|
|
* "dataType" = "string", |
76
|
|
|
* "description" = "The name of the package" |
77
|
|
|
* }, |
78
|
|
|
* "version" = { |
79
|
|
|
* "dataType" = "string", |
80
|
|
|
* "description" = "The version of the package" |
81
|
|
|
* }, |
82
|
|
|
* "constraint" = { |
83
|
|
|
* "dataType" = "string", |
84
|
|
|
* "description" = "The constraint of the package (when package is installed)" |
85
|
|
|
* }, |
86
|
|
|
* "type" = { |
87
|
|
|
* "dataType" = "string", |
88
|
|
|
* "description" = "The noted package type" |
89
|
|
|
* }, |
90
|
|
|
* "locked" = { |
91
|
|
|
* "dataType" = "string", |
92
|
|
|
* "description" = "Flag if the package has been locked for updates" |
93
|
|
|
* }, |
94
|
|
|
* "time" = { |
95
|
|
|
* "dataType" = "datetime", |
96
|
|
|
* "description" = "The release date" |
97
|
|
|
* }, |
98
|
|
|
* "upgrade_version" = { |
99
|
|
|
* "dataType" = "string", |
100
|
|
|
* "description" = "The version available for upgrade (optional, if any)" |
101
|
|
|
* }, |
102
|
|
|
* "description" = { |
103
|
|
|
* "dataType" = "string", |
104
|
|
|
* "description" = "The package description" |
105
|
|
|
* }, |
106
|
|
|
* "license" = { |
107
|
|
|
* "actualType" = "collection", |
108
|
|
|
* "subType" = "string", |
109
|
|
|
* "description" = "The licenses" |
110
|
|
|
* }, |
111
|
|
|
* "keywords" = { |
112
|
|
|
* "actualType" = "collection", |
113
|
|
|
* "subType" = "string", |
114
|
|
|
* "description" = "The keywords" |
115
|
|
|
* }, |
116
|
|
|
* "homepage" = { |
117
|
|
|
* "dataType" = "string", |
118
|
|
|
* "description" = "The support website (optional, if any)" |
119
|
|
|
* }, |
120
|
|
|
* "authors" = { |
121
|
|
|
* "actualType" = "collection", |
122
|
|
|
* "subType" = "object", |
123
|
|
|
* "description" = "The authors", |
124
|
|
|
* "children" = { |
125
|
|
|
* "name" = { |
126
|
|
|
* "dataType" = "string", |
127
|
|
|
* "description" = "Full name of the author (optional, if any)" |
128
|
|
|
* }, |
129
|
|
|
* "homepage" = { |
130
|
|
|
* "dataType" = "string", |
131
|
|
|
* "description" = "Email address of the author (optional, if any)" |
132
|
|
|
* }, |
133
|
|
|
* "email" = { |
134
|
|
|
* "dataType" = "string", |
135
|
|
|
* "description" = "Homepage URL for the author (optional, if any)" |
136
|
|
|
* }, |
137
|
|
|
* "role" = { |
138
|
|
|
* "dataType" = "string", |
139
|
|
|
* "description" = "Author's role in the project (optional, if any)" |
140
|
|
|
* } |
141
|
|
|
* } |
142
|
|
|
* }, |
143
|
|
|
* "support" = { |
144
|
|
|
* "actualType" = "collection", |
145
|
|
|
* "subType" = "object", |
146
|
|
|
* "description" = "The support options", |
147
|
|
|
* "children" = { |
148
|
|
|
* "email" = { |
149
|
|
|
* "dataType" = "string", |
150
|
|
|
* "description" = "Email address for support (optional, if any)" |
151
|
|
|
* }, |
152
|
|
|
* "issues" = { |
153
|
|
|
* "dataType" = "string", |
154
|
|
|
* "description" = "URL to the issue tracker (optional, if any)" |
155
|
|
|
* }, |
156
|
|
|
* "forum" = { |
157
|
|
|
* "dataType" = "string", |
158
|
|
|
* "description" = "URL to the forum (optional, if any)" |
159
|
|
|
* }, |
160
|
|
|
* "wiki" = { |
161
|
|
|
* "dataType" = "string", |
162
|
|
|
* "description" = "URL to the wiki (optional, if any)" |
163
|
|
|
* }, |
164
|
|
|
* "irc" = { |
165
|
|
|
* "dataType" = "string", |
166
|
|
|
* "description" = "IRC channel for support, as irc://server/channel (optional, if any)" |
167
|
|
|
* }, |
168
|
|
|
* "source" = { |
169
|
|
|
* "dataType" = "string", |
170
|
|
|
* "description" = "URL to browse or download the sources (optional, if any)" |
171
|
|
|
* }, |
172
|
|
|
* "docs" = { |
173
|
|
|
* "dataType" = "string", |
174
|
|
|
* "description" = "URL to the documentation (optional, if any)" |
175
|
|
|
* }, |
176
|
|
|
* } |
177
|
|
|
* }, |
178
|
|
|
* "extra" = { |
179
|
|
|
* "dataType" = "collection", |
180
|
|
|
* "description" = "The extra data from composer.json" |
181
|
|
|
* }, |
182
|
|
|
* "abandoned" = { |
183
|
|
|
* "dataType" = "boolean", |
184
|
|
|
* "description" = "Flag if this package is abandoned" |
185
|
|
|
* }, |
186
|
|
|
* "replacement" = { |
187
|
|
|
* "dataType" = "string", |
188
|
|
|
* "description" = "Replacement for this package (optional, if any)" |
189
|
|
|
* } |
190
|
|
|
* } |
191
|
|
|
* } |
192
|
|
|
* } |
193
|
|
|
* ) |
194
|
|
|
*/ |
195
|
|
|
public function packageListAction(Request $request) |
196
|
|
|
{ |
197
|
|
|
$composer = $this->getComposer(); |
198
|
|
|
$converter = new PackageConverter($composer->getPackage()); |
199
|
|
|
$upgrades = $this->getUpgradeRepository(); |
200
|
|
|
$packages = $converter->convertRepositoryToArray( |
201
|
|
|
$composer->getRepositoryManager()->getLocalRepository(), |
202
|
|
|
!$request->query->has('all'), |
203
|
|
|
$upgrades |
204
|
|
|
)->getData(); |
205
|
|
|
ksort($packages); |
206
|
|
|
|
207
|
|
|
return new JsonResponse($packages, 200); |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
/** |
211
|
|
|
* Retrieve a package. |
212
|
|
|
* |
213
|
|
|
* @param string $vendor The name of the vendor. |
214
|
|
|
* |
215
|
|
|
* @param string $package The name of the package. |
216
|
|
|
* |
217
|
|
|
* @return JsonResponse |
218
|
|
|
* |
219
|
|
|
* @throws NotFoundHttpException When the package has not been found. |
220
|
|
|
* |
221
|
|
|
* @ApiDoc( |
222
|
|
|
* section="package", |
223
|
|
|
* statusCodes = { |
224
|
|
|
* 200 = "When everything worked out ok" |
225
|
|
|
* }, |
226
|
|
|
* authentication = true, |
227
|
|
|
* authenticationRoles = { |
228
|
|
|
* "ROLE_MANIPULATE_REQUIREMENTS" |
229
|
|
|
* } |
230
|
|
|
* ) |
231
|
|
|
* @ApiDescription( |
232
|
|
|
* response={ |
233
|
|
|
* "name" = { |
234
|
|
|
* "dataType" = "string", |
235
|
|
|
* "description" = "The name of the package" |
236
|
|
|
* }, |
237
|
|
|
* "version" = { |
238
|
|
|
* "dataType" = "string", |
239
|
|
|
* "description" = "The version of the package" |
240
|
|
|
* }, |
241
|
|
|
* "constraint" = { |
242
|
|
|
* "dataType" = "string", |
243
|
|
|
* "description" = "The constraint of the package (when package is installed)" |
244
|
|
|
* }, |
245
|
|
|
* "type" = { |
246
|
|
|
* "dataType" = "string", |
247
|
|
|
* "description" = "The noted package type" |
248
|
|
|
* }, |
249
|
|
|
* "locked" = { |
250
|
|
|
* "dataType" = "string", |
251
|
|
|
* "description" = "Flag if the package has been locked for updates" |
252
|
|
|
* }, |
253
|
|
|
* "time" = { |
254
|
|
|
* "dataType" = "datetime", |
255
|
|
|
* "description" = "The release date" |
256
|
|
|
* }, |
257
|
|
|
* "upgrade_version" = { |
258
|
|
|
* "dataType" = "string", |
259
|
|
|
* "description" = "The version available for upgrade (optional, if any)" |
260
|
|
|
* }, |
261
|
|
|
* "description" = { |
262
|
|
|
* "dataType" = "string", |
263
|
|
|
* "description" = "The package description" |
264
|
|
|
* }, |
265
|
|
|
* "license" = { |
266
|
|
|
* "actualType" = "collection", |
267
|
|
|
* "subType" = "string", |
268
|
|
|
* "description" = "The licenses" |
269
|
|
|
* }, |
270
|
|
|
* "keywords" = { |
271
|
|
|
* "actualType" = "collection", |
272
|
|
|
* "subType" = "string", |
273
|
|
|
* "description" = "The keywords" |
274
|
|
|
* }, |
275
|
|
|
* "homepage" = { |
276
|
|
|
* "dataType" = "string", |
277
|
|
|
* "description" = "The support website (optional, if any)" |
278
|
|
|
* }, |
279
|
|
|
* "authors" = { |
280
|
|
|
* "actualType" = "collection", |
281
|
|
|
* "subType" = "object", |
282
|
|
|
* "description" = "The authors", |
283
|
|
|
* "children" = { |
284
|
|
|
* "name" = { |
285
|
|
|
* "dataType" = "string", |
286
|
|
|
* "description" = "Full name of the author (optional, if any)" |
287
|
|
|
* }, |
288
|
|
|
* "homepage" = { |
289
|
|
|
* "dataType" = "string", |
290
|
|
|
* "description" = "Email address of the author (optional, if any)" |
291
|
|
|
* }, |
292
|
|
|
* "email" = { |
293
|
|
|
* "dataType" = "string", |
294
|
|
|
* "description" = "Homepage URL for the author (optional, if any)" |
295
|
|
|
* }, |
296
|
|
|
* "role" = { |
297
|
|
|
* "dataType" = "string", |
298
|
|
|
* "description" = "Author's role in the project (optional, if any)" |
299
|
|
|
* } |
300
|
|
|
* } |
301
|
|
|
* }, |
302
|
|
|
* "support" = { |
303
|
|
|
* "actualType" = "collection", |
304
|
|
|
* "subType" = "object", |
305
|
|
|
* "description" = "The support options", |
306
|
|
|
* "children" = { |
307
|
|
|
* "email" = { |
308
|
|
|
* "dataType" = "string", |
309
|
|
|
* "description" = "Email address for support (optional, if any)" |
310
|
|
|
* }, |
311
|
|
|
* "issues" = { |
312
|
|
|
* "dataType" = "string", |
313
|
|
|
* "description" = "URL to the issue tracker (optional, if any)" |
314
|
|
|
* }, |
315
|
|
|
* "forum" = { |
316
|
|
|
* "dataType" = "string", |
317
|
|
|
* "description" = "URL to the forum (optional, if any)" |
318
|
|
|
* }, |
319
|
|
|
* "wiki" = { |
320
|
|
|
* "dataType" = "string", |
321
|
|
|
* "description" = "URL to the wiki (optional, if any)" |
322
|
|
|
* }, |
323
|
|
|
* "irc" = { |
324
|
|
|
* "dataType" = "string", |
325
|
|
|
* "description" = "IRC channel for support, as irc://server/channel (optional, if any)" |
326
|
|
|
* }, |
327
|
|
|
* "source" = { |
328
|
|
|
* "dataType" = "string", |
329
|
|
|
* "description" = "URL to browse or download the sources (optional, if any)" |
330
|
|
|
* }, |
331
|
|
|
* "docs" = { |
332
|
|
|
* "dataType" = "string", |
333
|
|
|
* "description" = "URL to the documentation (optional, if any)" |
334
|
|
|
* }, |
335
|
|
|
* } |
336
|
|
|
* }, |
337
|
|
|
* "abandoned" = { |
338
|
|
|
* "dataType" = "boolean", |
339
|
|
|
* "description" = "Flag if this package is abandoned" |
340
|
|
|
* }, |
341
|
|
|
* "replacement" = { |
342
|
|
|
* "dataType" = "string", |
343
|
|
|
* "description" = "Replacement for this package (optional, if any)" |
344
|
|
|
* } |
345
|
|
|
* } |
346
|
|
|
* ) |
347
|
|
|
*/ |
348
|
|
|
public function getPackageAction($vendor, $package) |
349
|
|
|
{ |
350
|
|
|
$packageName = $vendor . '/' . $package; |
351
|
|
|
$composer = $this->getComposer(); |
352
|
|
|
|
353
|
|
|
if ($package = $this->findPackage($packageName, $composer->getRepositoryManager()->getLocalRepository())) { |
354
|
|
|
$converter = new PackageConverter($composer->getPackage()); |
355
|
|
|
return new JsonResponse($converter->convertPackageToArray($package), 200); |
356
|
|
|
} |
357
|
|
|
|
358
|
|
|
throw new NotFoundHttpException('Package ' . $packageName . ' not found.'); |
359
|
|
|
} |
360
|
|
|
|
361
|
|
|
/** |
362
|
|
|
* Update the information of a package in the composer.json. |
363
|
|
|
* |
364
|
|
|
* Note that the payload name of the package must match the vendor and package passed as parameter. |
365
|
|
|
* |
366
|
|
|
* @param string $vendor The name of the vendor. |
367
|
|
|
* |
368
|
|
|
* @param string $package The name of the package. |
369
|
|
|
* |
370
|
|
|
* @param Request $request The request to process. |
371
|
|
|
* |
372
|
|
|
* @return JsonResponse |
373
|
|
|
* |
374
|
|
|
* @throws NotAcceptableHttpException When the passed payload is invalid. |
375
|
|
|
* @throws NotFoundHttpException When the package has not been found. |
376
|
|
|
* |
377
|
|
|
* @ApiDoc( |
378
|
|
|
* section="package", |
379
|
|
|
* statusCodes = { |
380
|
|
|
* 200 = "When everything worked out ok" |
381
|
|
|
* }, |
382
|
|
|
* authentication = true, |
383
|
|
|
* authenticationRoles = { |
384
|
|
|
* "ROLE_MANIPULATE_REQUIREMENTS" |
385
|
|
|
* } |
386
|
|
|
* ) |
387
|
|
|
* |
388
|
|
|
* @ApiDescription( |
389
|
|
|
* request={ |
390
|
|
|
* "name" = { |
391
|
|
|
* "dataType" = "string", |
392
|
|
|
* "description" = "The name of the package", |
393
|
|
|
* "required" = true |
394
|
|
|
* }, |
395
|
|
|
* "constraint" = { |
396
|
|
|
* "dataType" = "string", |
397
|
|
|
* "description" = "The constraint of the package (when package is installed)", |
398
|
|
|
* "required" = true |
399
|
|
|
* }, |
400
|
|
|
* "locked" = { |
401
|
|
|
* "dataType" = "string", |
402
|
|
|
* "description" = "Flag if the package has been locked for updates", |
403
|
|
|
* "required" = true |
404
|
|
|
* }, |
405
|
|
|
* }, |
406
|
|
|
* response={ |
407
|
|
|
* "name" = { |
408
|
|
|
* "dataType" = "string", |
409
|
|
|
* "description" = "The name of the package" |
410
|
|
|
* }, |
411
|
|
|
* "version" = { |
412
|
|
|
* "dataType" = "string", |
413
|
|
|
* "description" = "The version of the package" |
414
|
|
|
* }, |
415
|
|
|
* "constraint" = { |
416
|
|
|
* "dataType" = "string", |
417
|
|
|
* "description" = "The constraint of the package (when package is installed)" |
418
|
|
|
* }, |
419
|
|
|
* "type" = { |
420
|
|
|
* "dataType" = "string", |
421
|
|
|
* "description" = "The noted package type" |
422
|
|
|
* }, |
423
|
|
|
* "locked" = { |
424
|
|
|
* "dataType" = "string", |
425
|
|
|
* "description" = "Flag if the package has been locked for updates" |
426
|
|
|
* }, |
427
|
|
|
* "time" = { |
428
|
|
|
* "dataType" = "datetime", |
429
|
|
|
* "description" = "The release date" |
430
|
|
|
* }, |
431
|
|
|
* "upgrade_version" = { |
432
|
|
|
* "dataType" = "string", |
433
|
|
|
* "description" = "The version available for upgrade (optional, if any)" |
434
|
|
|
* }, |
435
|
|
|
* "description" = { |
436
|
|
|
* "dataType" = "string", |
437
|
|
|
* "description" = "The package description" |
438
|
|
|
* }, |
439
|
|
|
* "license" = { |
440
|
|
|
* "actualType" = "collection", |
441
|
|
|
* "subType" = "string", |
442
|
|
|
* "description" = "The licenses" |
443
|
|
|
* }, |
444
|
|
|
* "keywords" = { |
445
|
|
|
* "actualType" = "collection", |
446
|
|
|
* "subType" = "string", |
447
|
|
|
* "description" = "The keywords" |
448
|
|
|
* }, |
449
|
|
|
* "homepage" = { |
450
|
|
|
* "dataType" = "string", |
451
|
|
|
* "description" = "The support website (optional, if any)" |
452
|
|
|
* }, |
453
|
|
|
* "authors" = { |
454
|
|
|
* "actualType" = "collection", |
455
|
|
|
* "subType" = "object", |
456
|
|
|
* "description" = "The authors", |
457
|
|
|
* "children" = { |
458
|
|
|
* "name" = { |
459
|
|
|
* "dataType" = "string", |
460
|
|
|
* "description" = "Full name of the author (optional, if any)" |
461
|
|
|
* }, |
462
|
|
|
* "homepage" = { |
463
|
|
|
* "dataType" = "string", |
464
|
|
|
* "description" = "Email address of the author (optional, if any)" |
465
|
|
|
* }, |
466
|
|
|
* "email" = { |
467
|
|
|
* "dataType" = "string", |
468
|
|
|
* "description" = "Homepage URL for the author (optional, if any)" |
469
|
|
|
* }, |
470
|
|
|
* "role" = { |
471
|
|
|
* "dataType" = "string", |
472
|
|
|
* "description" = "Author's role in the project (optional, if any)" |
473
|
|
|
* } |
474
|
|
|
* } |
475
|
|
|
* }, |
476
|
|
|
* "support" = { |
477
|
|
|
* "actualType" = "collection", |
478
|
|
|
* "subType" = "object", |
479
|
|
|
* "description" = "The support options", |
480
|
|
|
* "children" = { |
481
|
|
|
* "email" = { |
482
|
|
|
* "dataType" = "string", |
483
|
|
|
* "description" = "Email address for support (optional, if any)" |
484
|
|
|
* }, |
485
|
|
|
* "issues" = { |
486
|
|
|
* "dataType" = "string", |
487
|
|
|
* "description" = "URL to the issue tracker (optional, if any)" |
488
|
|
|
* }, |
489
|
|
|
* "forum" = { |
490
|
|
|
* "dataType" = "string", |
491
|
|
|
* "description" = "URL to the forum (optional, if any)" |
492
|
|
|
* }, |
493
|
|
|
* "wiki" = { |
494
|
|
|
* "dataType" = "string", |
495
|
|
|
* "description" = "URL to the wiki (optional, if any)" |
496
|
|
|
* }, |
497
|
|
|
* "irc" = { |
498
|
|
|
* "dataType" = "string", |
499
|
|
|
* "description" = "IRC channel for support, as irc://server/channel (optional, if any)" |
500
|
|
|
* }, |
501
|
|
|
* "source" = { |
502
|
|
|
* "dataType" = "string", |
503
|
|
|
* "description" = "URL to browse or download the sources (optional, if any)" |
504
|
|
|
* }, |
505
|
|
|
* "docs" = { |
506
|
|
|
* "dataType" = "string", |
507
|
|
|
* "description" = "URL to the documentation (optional, if any)" |
508
|
|
|
* }, |
509
|
|
|
* } |
510
|
|
|
* }, |
511
|
|
|
* "abandoned" = { |
512
|
|
|
* "dataType" = "boolean", |
513
|
|
|
* "description" = "Flag if this package is abandoned" |
514
|
|
|
* }, |
515
|
|
|
* "replacement" = { |
516
|
|
|
* "dataType" = "string", |
517
|
|
|
* "description" = "Replacement for this package (optional, if any)" |
518
|
|
|
* } |
519
|
|
|
* } |
520
|
|
|
* ) |
521
|
|
|
*/ |
522
|
|
|
public function putPackageAction($vendor, $package, Request $request) |
523
|
|
|
{ |
524
|
|
|
$packageName = $vendor . '/' . $package; |
525
|
|
|
$info = new JsonArray($request->getContent()); |
|
|
|
|
526
|
|
|
$name = $info->get('name'); |
527
|
|
|
|
528
|
|
|
if (!($info->has('name') && $info->has('locked') && $info->has('constraint'))) { |
529
|
|
|
throw new NotAcceptableHttpException('Invalid package information.'); |
530
|
|
|
} |
531
|
|
|
|
532
|
|
|
if ($name !== $packageName) { |
533
|
|
|
throw new NotAcceptableHttpException('Package name mismatch ' . $packageName . ' vs. ' . $name . '.'); |
534
|
|
|
} |
535
|
|
|
|
536
|
|
|
$composer = $this->getComposer(); |
537
|
|
|
$json = $this->get('tenside.composer_json'); |
538
|
|
|
|
539
|
|
|
$package = $this->findPackage($name, $composer->getRepositoryManager()->getLocalRepository()); |
540
|
|
|
|
541
|
|
|
if (null === $package) { |
542
|
|
|
throw new NotFoundHttpException('Package ' . $packageName . ' not found.'); |
543
|
|
|
} |
544
|
|
|
|
545
|
|
|
$json->setLock($package, $info->get('locked')); |
546
|
|
|
return $this->forward('TensideCoreBundle:Package:getPackage'); |
547
|
|
|
} |
548
|
|
|
|
549
|
|
|
/** |
550
|
|
|
* Search the repository for a package. |
551
|
|
|
* |
552
|
|
|
* @param string $name The pretty name of the package to search. |
553
|
|
|
* |
554
|
|
|
* @param RepositoryInterface $repository The repository to be searched. |
555
|
|
|
* |
556
|
|
|
* @return null|PackageInterface |
557
|
|
|
*/ |
558
|
|
|
private function findPackage($name, RepositoryInterface $repository) |
559
|
|
|
{ |
560
|
|
|
/** @var PackageInterface[] $packages */ |
561
|
|
|
$packages = $repository->findPackages($name); |
562
|
|
|
|
563
|
|
|
while (!empty($packages) && $packages[0] instanceof AliasPackage) { |
564
|
|
|
array_shift($packages); |
565
|
|
|
} |
566
|
|
|
|
567
|
|
|
if (empty($packages)) { |
568
|
|
|
return null; |
569
|
|
|
} |
570
|
|
|
|
571
|
|
|
return $packages[0]; |
572
|
|
|
} |
573
|
|
|
|
574
|
|
|
/** |
575
|
|
|
* Load a repository containing available upgrades. |
576
|
|
|
* |
577
|
|
|
* @return null|RepositoryInterface |
|
|
|
|
578
|
|
|
*/ |
579
|
|
|
private function getUpgradeRepository() |
580
|
|
|
{ |
581
|
|
|
$upgradeFile = $this->getTensideDataDir() . DIRECTORY_SEPARATOR . 'upgrades.json'; |
582
|
|
|
if (!file_exists($upgradeFile)) { |
583
|
|
|
return null; |
584
|
|
|
} |
585
|
|
|
|
586
|
|
|
$packageLoader = new ArrayLoader(); |
587
|
|
|
$packageChanges = new WritableArrayRepository(); |
588
|
|
|
$upgrades = new JsonFile($upgradeFile, null); |
589
|
|
|
foreach ($upgrades->getEntries('/') as $packageName) { |
590
|
|
|
if ($pkgData = $upgrades->get($packageName . '/target')) { |
591
|
|
|
$packageChanges->addPackage($packageLoader->load($pkgData)); |
592
|
|
|
} |
593
|
|
|
} |
594
|
|
|
|
595
|
|
|
return $packageChanges; |
596
|
|
|
} |
597
|
|
|
} |
598
|
|
|
|
This check looks at variables that are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.