1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Application\Renderer; |
4
|
|
|
|
5
|
|
|
use DomainModel\Renderer; |
6
|
|
|
use phpDocumentor\DomainModel\Path; |
7
|
|
|
use phpDocumentor\DomainModel\Views\View; |
8
|
|
|
|
9
|
|
|
/** |
10
|
|
|
* Writes the collected data as a series of JSONP files. |
11
|
|
|
* |
12
|
|
|
* This writer will create a series of JSONP files that represent all of the data collected by phpDocumentor on a |
13
|
|
|
* project. These JSONP files can then be exposed by an API, consumed by a Javascript framework or otherwise be |
14
|
|
|
* re-used. |
15
|
|
|
* |
16
|
|
|
* The original reason for creating this writer was to use it to fuel a Javascript framework based template and as |
17
|
|
|
* such some assumptions have been done in the layout that help with that goal. One of those has been the choice for |
18
|
|
|
* JSONP opposed to JSON as JSONP makes it possible to open the JSON content from a local file (`file://`) without |
19
|
|
|
* having issues with Cross-domain requests. |
20
|
|
|
* |
21
|
|
|
* Because these are static pre-generated files the callback name is not configurable via a query parameter $callback |
22
|
|
|
* as is usually the case but a fixed callback name is used for each individual file. |
23
|
|
|
* |
24
|
|
|
* The following files are generated: |
25
|
|
|
* |
26
|
|
|
* namespaces.json (callback name: `namespaces`) |
27
|
|
|
* Contains a tree structure of all namespaces and has a listing of all child elements. Constants |
28
|
|
|
* and functions have their complete contents included but classes, interfaces and traits only have |
29
|
|
|
* an FQCN listed so that you can refer to another JSONP file. |
30
|
|
|
* |
31
|
|
|
* packages.json (callback name: `packages`) |
32
|
|
|
* Contains a tree structure of all packages and has a listing of all child elements. Constants |
33
|
|
|
* and functions have their complete contents included but classes, interfaces and traits only have |
34
|
|
|
* an FQCN listed so that you can refer to another JSONP file. |
35
|
|
|
* |
36
|
|
|
* files/*.json (callback name: `fileDefinition`) |
37
|
|
|
* The subfolder `files` will contain a JSONP file for each file in a project. This file contains a listing of all |
38
|
|
|
* child elements. Constants and functions have their complete contents included but classes, interfaces and |
39
|
|
|
* traits only have an FQCN listed so that you can refer to another JSONP file. |
40
|
|
|
* |
41
|
|
|
* classes/*.json (callback name: `classDefinition`) |
42
|
|
|
* The subfolder `classes` will contain a JSONP file for each class, interface and trait in a project. Each file |
43
|
|
|
* contains a listing of all properties and child elements for a class, interface or trait. This includes a |
44
|
|
|
* member `type` that can be either 'class', 'interface' or 'trait' to distinguish between the three types |
45
|
|
|
* of 'classes'. |
46
|
|
|
*/ |
47
|
|
|
class JsonpRenderer implements Renderer |
|
|
|
|
48
|
|
|
{ |
49
|
|
|
public function render(View $view, Path $destination, $template = null) |
50
|
|
|
{ |
51
|
|
|
// TODO: Implement render() method. |
52
|
|
|
} |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* Generate a series of JSONP files based on the ProjectDescriptor's structure in the target directory. |
56
|
|
|
* |
57
|
|
|
* This method is responsible for writing a series of JSONP files to disk in the directory specified by the |
58
|
|
|
* user when starting phpDocumentor. A complete description of what is generated can be found in the documentation |
59
|
|
|
* of this class itself. |
60
|
|
|
* |
61
|
|
|
* @param Jsonp $action |
62
|
|
|
* |
63
|
|
|
* @return void |
64
|
|
|
*/ |
65
|
|
|
public function handle(Action $action) |
66
|
|
|
{ |
67
|
|
|
$project = $this->analyzer->getProjectDescriptor(); |
68
|
|
|
$folder = $action->getRenderPass()->getDestination() . '/' . ltrim($action->getDestination(), '\\/'); |
69
|
|
|
@mkdir($folder . 'classes'); |
|
|
|
|
70
|
|
|
@mkdir($folder . 'files'); |
|
|
|
|
71
|
|
|
|
72
|
|
|
// Generate namespaces json |
73
|
|
|
$namespaces = $this->getNamespaceTree($project->getNamespace()); |
74
|
|
|
file_put_contents($folder . '/namespaces.json', 'namespaces(' . json_encode($namespaces) . ');'); |
75
|
|
|
|
76
|
|
|
// Generate packages json |
77
|
|
|
$packages = $this->getPackageTree($project->getIndexes()->get('packages')->get('\\')); |
78
|
|
|
file_put_contents($folder . '/packages.json', 'packages(' . json_encode($packages) . ');'); |
79
|
|
|
|
80
|
|
|
// Generate per-class json |
81
|
|
|
foreach ($project->getIndexes()->get('elements') as $element) { |
82
|
|
|
if ($element instanceof ClassDescriptor) { |
|
|
|
|
83
|
|
|
$this->writeClassToDisk($folder, $element, $this->transformClass($element)); |
84
|
|
|
continue; |
85
|
|
|
} |
86
|
|
|
if ($element instanceof InterfaceDescriptor) { |
|
|
|
|
87
|
|
|
$this->writeClassToDisk($folder, $element, $this->transformInterface($element)); |
88
|
|
|
continue; |
89
|
|
|
} |
90
|
|
|
if ($element instanceof TraitDescriptor) { |
|
|
|
|
91
|
|
|
$this->writeClassToDisk($folder, $element, $this->transformTrait($element)); |
92
|
|
|
continue; |
93
|
|
|
} |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
// Generate files json |
97
|
|
|
foreach ($project->getFiles() as $file) { |
98
|
|
|
$this->writeFileToDisk($folder, $file, $this->transformFile($file)); |
99
|
|
|
} |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
/** |
103
|
|
|
* Generates an associative array containing all properties and child elements for a file. |
104
|
|
|
* |
105
|
|
|
* @param FileDescriptor $element |
106
|
|
|
* |
107
|
|
|
* @return string[] |
108
|
|
|
*/ |
109
|
|
|
private function transformFile(FileDescriptor $element) |
|
|
|
|
110
|
|
|
{ |
111
|
|
|
$file = array( |
112
|
|
|
'name' => $element->getName(), |
113
|
|
|
'path' => $element->getPath(), |
114
|
|
|
'summary' => $element->getSummary(), |
115
|
|
|
'description' => $element->getDescription(), |
116
|
|
|
'package' => $element instanceof PackageDescriptor |
|
|
|
|
117
|
|
|
? $element->getFullyQualifiedStructuralElementName() |
118
|
|
|
: (string)$element, |
119
|
|
|
'constants' => array(), |
120
|
|
|
'functions' => array(), |
121
|
|
|
'classes' => array(), |
122
|
|
|
'interfaces' => array(), |
123
|
|
|
'traits' => array(), |
124
|
|
|
'namespace-aliases' => array(), |
125
|
|
|
'markers' => array(), |
126
|
|
|
); |
127
|
|
|
|
128
|
|
|
foreach ($element->getNamespaceAliases() as $alias => $namespace) { |
129
|
|
|
$file['namespace-aliases'][$alias] = $namespace; |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
foreach ($element->getConstants() as $constant) { |
133
|
|
|
$file['constants'][] = $this->transformConstant($constant); |
134
|
|
|
} |
135
|
|
|
foreach ($element->getFunctions() as $function) { |
136
|
|
|
$file['functions'][] = $this->transformFunction($function); |
137
|
|
|
} |
138
|
|
|
/** @var TraitDescriptor $trait */ |
139
|
|
|
foreach ($element->getTraits() as $trait) { |
140
|
|
|
$file['traits'][] = $trait->getFullyQualifiedStructuralElementName(); |
141
|
|
|
} |
142
|
|
|
/** @var InterfaceDescriptor $interface */ |
143
|
|
|
foreach ($element->getInterfaces() as $interface) { |
144
|
|
|
$file['interface'][] = $interface->getFullyQualifiedStructuralElementName(); |
145
|
|
|
} |
146
|
|
|
/** @var ClassDescriptor $class */ |
147
|
|
|
foreach ($element->getClasses() as $class) { |
148
|
|
|
$file['classes'][] = $class->getFullyQualifiedStructuralElementName(); |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
foreach ($element->getMarkers() as $marker) { |
152
|
|
|
$file['markers'] = $marker; |
153
|
|
|
} |
154
|
|
|
foreach ($element->getAllErrors() as $error) { |
155
|
|
|
$file['errors'][] = $error; |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
return $file; |
159
|
|
|
} |
160
|
|
|
|
161
|
|
|
/** |
162
|
|
|
* Generates an associative array containing all properties and child elements for a class. |
163
|
|
|
* |
164
|
|
|
* @param ClassDescriptor $element |
165
|
|
|
* |
166
|
|
|
* @return string[] |
167
|
|
|
*/ |
168
|
|
|
private function transformClass(ClassDescriptor $element) |
|
|
|
|
169
|
|
|
{ |
170
|
|
|
$class = array( |
171
|
|
|
'type' => 'class', |
172
|
|
|
'name' => $element->getName(), |
173
|
|
|
'line' => $element->getLine(), |
174
|
|
|
'fqsen' => $element->getFullyQualifiedStructuralElementName(), |
175
|
|
|
'final' => $element->isFinal(), |
176
|
|
|
'abstract' => $element->isAbstract(), |
177
|
|
|
'namespace' => $element->getNamespace()->getFullyQualifiedStructuralElementName(), |
178
|
|
|
'summary' => $element->getSummary(), |
179
|
|
|
'description' => $element->getDescription(), |
180
|
|
|
'extends' => $element->getParent() instanceof ClassDescriptor |
|
|
|
|
181
|
|
|
? $element->getParent()->getFullyQualifiedStructuralElementName() |
182
|
|
|
: $element->getParent(), |
183
|
|
|
'implements' => array(), |
184
|
|
|
'package' => $element instanceof PackageDescriptor |
|
|
|
|
185
|
|
|
? $element->getFullyQualifiedStructuralElementName() |
186
|
|
|
: (string)$element, |
187
|
|
|
'file' => $element->getFile()->getPath(), |
188
|
|
|
'uses' => array(), |
189
|
|
|
'constants' => array(), |
190
|
|
|
'methods' => array(), |
191
|
|
|
'properties' => array() |
192
|
|
|
); |
193
|
|
|
|
194
|
|
|
/** @var TraitDescriptor|string $trait */ |
195
|
|
|
foreach ($element->getUsedTraits() as $trait) { |
196
|
|
|
$class['uses'][] = $trait instanceof TraitDescriptor |
|
|
|
|
197
|
|
|
? $trait->getFullyQualifiedStructuralElementName() |
198
|
|
|
: $trait; |
199
|
|
|
} |
200
|
|
|
|
201
|
|
|
/** @var InterfaceDescriptor $interface */ |
202
|
|
|
foreach ($element->getInterfaces() as $interface) { |
203
|
|
|
$interfaceFqcn = is_string($interface) |
204
|
|
|
? $interface |
205
|
|
|
: $interface->getFullyQualifiedStructuralElementName(); |
206
|
|
|
$class['implements'][] = $interfaceFqcn; |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
/** @var ConstantDescriptor $constant */ |
210
|
|
|
foreach ($element->getConstants() as $constant) { |
211
|
|
|
$class['constants'][] = $this->transformConstant($constant); |
212
|
|
|
} |
213
|
|
|
|
214
|
|
|
/** @var ConstantDescriptor $constant */ |
215
|
|
|
foreach ($element->getInheritedConstants() as $constant) { |
216
|
|
|
$class['constants'][] = $this->transformConstant($constant); |
217
|
|
|
} |
218
|
|
|
|
219
|
|
|
/** @var PropertyDescriptor $property */ |
220
|
|
|
foreach ($element->getProperties() as $property) { |
221
|
|
|
$class['properties'][] = $this->transformProperty($property); |
222
|
|
|
} |
223
|
|
|
|
224
|
|
|
/** @var PropertyDescriptor $property */ |
225
|
|
|
foreach ($element->getInheritedProperties() as $property) { |
226
|
|
|
$class['properties'][] = $this->transformProperty($property); |
227
|
|
|
} |
228
|
|
|
|
229
|
|
|
/** @var PropertyDescriptor $property */ |
230
|
|
|
foreach ($element->getMagicProperties() as $property) { |
231
|
|
|
$class['properties'][] = $this->transformProperty($property); |
232
|
|
|
} |
233
|
|
|
|
234
|
|
|
/** @var MethodDescriptor $method */ |
235
|
|
|
foreach ($element->getMethods() as $method) { |
236
|
|
|
$class['methods'][] = $this->transformMethod($method); |
237
|
|
|
} |
238
|
|
|
|
239
|
|
|
/** @var MethodDescriptor $property */ |
240
|
|
|
foreach ($element->getInheritedMethods() as $method) { |
241
|
|
|
$class['methods'][] = $this->transformMethod($method); |
242
|
|
|
} |
243
|
|
|
|
244
|
|
|
/** @var MethodDescriptor $property */ |
245
|
|
|
foreach ($element->getMagicMethods() as $method) { |
246
|
|
|
$class['methods'][] = $this->transformMethod($method); |
247
|
|
|
} |
248
|
|
|
|
249
|
|
|
$class['tags'] = $this->transformTags($element); |
250
|
|
|
|
251
|
|
|
return $class; |
252
|
|
|
} |
253
|
|
|
|
254
|
|
|
/** |
255
|
|
|
* Generates an associative array containing all properties and child elements for an interface. |
256
|
|
|
* |
257
|
|
|
* @param InterfaceDescriptor $element |
258
|
|
|
* |
259
|
|
|
* @return string[] |
260
|
|
|
*/ |
261
|
|
|
private function transformInterface(InterfaceDescriptor $element) |
|
|
|
|
262
|
|
|
{ |
263
|
|
|
$interface = array( |
264
|
|
|
'type' => 'interface', |
265
|
|
|
'name' => $element->getName(), |
266
|
|
|
'line' => $element->getLine(), |
267
|
|
|
'fqsen' => $element->getFullyQualifiedStructuralElementName(), |
268
|
|
|
'namespace' => $element->getNamespace()->getFullyQualifiedStructuralElementName(), |
269
|
|
|
'summary' => $element->getSummary(), |
270
|
|
|
'description' => $element->getDescription(), |
271
|
|
|
'extends' => array(), |
272
|
|
|
'package' => $element instanceof PackageDescriptor |
|
|
|
|
273
|
|
|
? $element->getFullyQualifiedStructuralElementName() |
274
|
|
|
: (string)$element, |
275
|
|
|
'file' => $element->getFile()->getPath(), |
276
|
|
|
'constants' => array(), |
277
|
|
|
'methods' => array(), |
278
|
|
|
); |
279
|
|
|
|
280
|
|
|
/** @var InterfaceDescriptor $extendedInterface */ |
281
|
|
|
foreach ($element->getParent() as $extendedInterface) { |
282
|
|
|
$interfaceFqcn = is_string($extendedInterface) |
283
|
|
|
? $extendedInterface |
284
|
|
|
: $extendedInterface->getFullyQualifiedStructuralElementName(); |
285
|
|
|
$interface['extends'][] = $interfaceFqcn; |
286
|
|
|
} |
287
|
|
|
|
288
|
|
|
/** @var ConstantDescriptor $property */ |
289
|
|
|
foreach ($element->getConstants() as $constant) { |
290
|
|
|
$interface['constants'][] = $this->transformConstant($constant); |
291
|
|
|
} |
292
|
|
|
|
293
|
|
|
/** @var ConstantDescriptor $constant */ |
294
|
|
|
foreach ($element->getInheritedConstants() as $constant) { |
295
|
|
|
$interface['constants'][] = $this->transformConstant($constant); |
296
|
|
|
} |
297
|
|
|
|
298
|
|
|
/** @var MethodDescriptor $method */ |
299
|
|
|
foreach ($element->getMethods() as $method) { |
300
|
|
|
$interface['methods'][] = $this->transformMethod($method); |
301
|
|
|
} |
302
|
|
|
|
303
|
|
|
/** @var MethodDescriptor $property */ |
304
|
|
|
foreach ($element->getInheritedMethods() as $method) { |
305
|
|
|
$interface['methods'][] = $this->transformMethod($method); |
306
|
|
|
} |
307
|
|
|
|
308
|
|
|
$interface['tags'] = $this->transformTags($element); |
309
|
|
|
|
310
|
|
|
return $interface; |
311
|
|
|
} |
312
|
|
|
|
313
|
|
|
/** |
314
|
|
|
* Generates an associative array containing all properties and child elements for a trait. |
315
|
|
|
* |
316
|
|
|
* @param TraitDescriptor $element |
317
|
|
|
* |
318
|
|
|
* @return string[] |
319
|
|
|
*/ |
320
|
|
|
private function transformTrait(TraitDescriptor $element) |
|
|
|
|
321
|
|
|
{ |
322
|
|
|
$trait = array( |
323
|
|
|
'type' => 'trait', |
324
|
|
|
'name' => $element->getName(), |
325
|
|
|
'line' => $element->getLine(), |
326
|
|
|
'fqsen' => $element->getFullyQualifiedStructuralElementName(), |
327
|
|
|
'namespace' => $element->getNamespace()->getFullyQualifiedStructuralElementName(), |
328
|
|
|
'summary' => $element->getSummary(), |
329
|
|
|
'description' => $element->getDescription(), |
330
|
|
|
'package' => $element instanceof PackageDescriptor |
|
|
|
|
331
|
|
|
? $element->getFullyQualifiedStructuralElementName() |
332
|
|
|
: (string)$element, |
333
|
|
|
'file' => $element->getFile()->getPath(), |
334
|
|
|
'uses' => array(), |
335
|
|
|
'constants' => array(), |
336
|
|
|
'methods' => array(), |
337
|
|
|
); |
338
|
|
|
|
339
|
|
|
/** @var TraitDescriptor|string $usedTrait */ |
340
|
|
|
foreach ($element->getUsedTraits() as $usedTrait) { |
341
|
|
|
$trait['uses'][] = $usedTrait instanceof TraitDescriptor |
|
|
|
|
342
|
|
|
? $usedTrait->getFullyQualifiedStructuralElementName() |
343
|
|
|
: $usedTrait; |
344
|
|
|
} |
345
|
|
|
|
346
|
|
|
/** @var PropertyDescriptor $property */ |
347
|
|
|
foreach ($element->getProperties() as $property) { |
348
|
|
|
$trait['properties'][] = $this->transformProperty($property); |
349
|
|
|
} |
350
|
|
|
|
351
|
|
|
/** @var PropertyDescriptor $property */ |
352
|
|
|
foreach ($element->getInheritedProperties() as $property) { |
353
|
|
|
$trait['properties'][] = $this->transformProperty($property); |
354
|
|
|
} |
355
|
|
|
|
356
|
|
|
/** @var PropertyDescriptor $property */ |
357
|
|
|
foreach ($element->getMagicProperties() as $property) { |
358
|
|
|
$trait['properties'][] = $this->transformProperty($property); |
359
|
|
|
} |
360
|
|
|
|
361
|
|
|
/** @var MethodDescriptor $method */ |
362
|
|
|
foreach ($element->getMethods() as $method) { |
363
|
|
|
$trait['methods'][] = $this->transformMethod($method); |
364
|
|
|
} |
365
|
|
|
|
366
|
|
|
/** @var MethodDescriptor $property */ |
367
|
|
|
foreach ($element->getInheritedMethods() as $method) { |
368
|
|
|
$trait['methods'][] = $this->transformMethod($method); |
369
|
|
|
} |
370
|
|
|
|
371
|
|
|
/** @var MethodDescriptor $property */ |
372
|
|
|
foreach ($element->getMagicMethods() as $method) { |
373
|
|
|
$trait['methods'][] = $this->transformMethod($method); |
374
|
|
|
} |
375
|
|
|
|
376
|
|
|
$trait['tags'] = $this->transformTags($element); |
377
|
|
|
|
378
|
|
|
return $trait; |
379
|
|
|
} |
380
|
|
|
|
381
|
|
|
/** |
382
|
|
|
* Generates an associative array containing all properties for a constant. |
383
|
|
|
* |
384
|
|
|
* @param ConstantDescriptor $constant |
385
|
|
|
* |
386
|
|
|
* @return string[] |
387
|
|
|
*/ |
388
|
|
|
private function transformConstant(ConstantDescriptor $constant) |
389
|
|
|
{ |
390
|
|
|
$result = array( |
391
|
|
|
'name' => $constant->getName(), |
392
|
|
|
'fqsen' => $constant->getValue(), |
393
|
|
|
'summary' => $constant->getSummary(), |
394
|
|
|
'description' => $constant->getDescription(), |
395
|
|
|
'type' => $this->transformTypes($constant->getTypes()), |
396
|
|
|
'line' => $constant->getLine(), |
397
|
|
|
'file' => $constant->getFile()->getPath() |
398
|
|
|
); |
399
|
|
|
|
400
|
|
|
$fullyQualifiedNamespaceName = $constant->getNamespace() instanceof NamespaceDescriptor |
|
|
|
|
401
|
|
|
? $constant->getNamespace()->getFullyQualifiedStructuralElementName() |
402
|
|
|
: null; |
403
|
|
|
if ($fullyQualifiedNamespaceName) { |
404
|
|
|
$result['namespace'] = $fullyQualifiedNamespaceName; |
405
|
|
|
} |
406
|
|
|
|
407
|
|
|
$result['tags'] = $this->transformTags($constant); |
408
|
|
|
|
409
|
|
|
return $result; |
410
|
|
|
} |
411
|
|
|
|
412
|
|
|
/** |
413
|
|
|
* Generates an associative array containing all properties for a property. |
414
|
|
|
* |
415
|
|
|
* @param PropertyDescriptor $property |
416
|
|
|
* |
417
|
|
|
* @return string[] |
418
|
|
|
*/ |
419
|
|
|
private function transformProperty(PropertyDescriptor $property) |
420
|
|
|
{ |
421
|
|
|
$result = array( |
422
|
|
|
'name' => $property->getName(), |
423
|
|
|
'fqsen' => $property->getFullyQualifiedStructuralElementName(), |
424
|
|
|
'summary' => $property->getSummary(), |
425
|
|
|
'description' => $property->getDescription(), |
426
|
|
|
'line' => $property->getLine(), |
427
|
|
|
'visibility' => $property->getVisibility(), |
428
|
|
|
'static' => $property->isStatic(), |
429
|
|
|
'default' => $property->getDefault(), |
430
|
|
|
'type' => $this->transformTypes($property->getTypes()), |
431
|
|
|
); |
432
|
|
|
|
433
|
|
|
$result['tags'] = $this->transformTags($property); |
434
|
|
|
|
435
|
|
|
return $result; |
436
|
|
|
} |
437
|
|
|
|
438
|
|
|
/** |
439
|
|
|
* Generates an associative array containing all properties for a function. |
440
|
|
|
* |
441
|
|
|
* @param FunctionDescriptor $function |
442
|
|
|
* |
443
|
|
|
* @return string[] |
444
|
|
|
*/ |
445
|
|
|
private function transformFunction(FunctionDescriptor $function) |
446
|
|
|
{ |
447
|
|
|
$result = array( |
448
|
|
|
'name' => $function->getName(), |
449
|
|
|
'namespace' => $function->getNamespace()->getFullyQualifiedStructuralElementName(), |
450
|
|
|
'fqsen' => $function->getFullyQualifiedStructuralElementName(), |
451
|
|
|
'line' => $function->getLine(), |
452
|
|
|
'summary' => $function->getSummary(), |
453
|
|
|
'description' => $function->getDescription(), |
454
|
|
|
'file' => $function->getFile()->getPath(), |
455
|
|
|
'arguments' => array() |
456
|
|
|
); |
457
|
|
|
|
458
|
|
|
/** @var ArgumentDescriptor $argument */ |
459
|
|
|
foreach ($function->getArguments() as $argument) { |
460
|
|
|
$result['arguments'][] = $this->transformArgument($argument); |
461
|
|
|
} |
462
|
|
|
|
463
|
|
|
$result['tags'] = $this->transformTags($function); |
464
|
|
|
|
465
|
|
|
return $result; |
466
|
|
|
} |
467
|
|
|
|
468
|
|
|
/** |
469
|
|
|
* Generates an associative array containing all properties for a method. |
470
|
|
|
* |
471
|
|
|
* @param MethodDescriptor $method |
472
|
|
|
* |
473
|
|
|
* @return string[] |
474
|
|
|
*/ |
475
|
|
|
private function transformMethod(MethodDescriptor $method) |
476
|
|
|
{ |
477
|
|
|
$result = array( |
478
|
|
|
'name' => $method->getName(), |
479
|
|
|
'fqsen' => $method->getFullyQualifiedStructuralElementName(), |
480
|
|
|
'summary' => $method->getSummary(), |
481
|
|
|
'description' => $method->getDescription(), |
482
|
|
|
'line' => $method->getLine(), |
483
|
|
|
'abstract' => $method->isAbstract(), |
484
|
|
|
'final' => $method->isFinal(), |
485
|
|
|
'static' => $method->isStatic(), |
486
|
|
|
'visibility' => $method->getVisibility(), |
487
|
|
|
'arguments' => array(), |
488
|
|
|
); |
489
|
|
|
|
490
|
|
|
/** @var ArgumentDescriptor $argument */ |
491
|
|
|
foreach ($method->getArguments() as $argument) { |
492
|
|
|
$result['arguments'][] = $this->transformArgument($argument); |
493
|
|
|
} |
494
|
|
|
|
495
|
|
|
$result['tags'] = $this->transformTags($method); |
496
|
|
|
|
497
|
|
|
return $result; |
498
|
|
|
} |
499
|
|
|
|
500
|
|
|
/** |
501
|
|
|
* Generates an associative array containing all properties for an argument. |
502
|
|
|
* |
503
|
|
|
* @param ArgumentDescriptor $argument |
504
|
|
|
* |
505
|
|
|
* @return string[] |
506
|
|
|
*/ |
507
|
|
|
private function transformArgument(ArgumentDescriptor $argument) |
508
|
|
|
{ |
509
|
|
|
$argument = array( |
510
|
|
|
'name' => $argument->getName(), |
511
|
|
|
'description' => $argument->getDescription(), |
512
|
|
|
'type' => $this->transformTypes($argument->getTypes()), |
513
|
|
|
'default' => $argument->getDefault(), |
514
|
|
|
'byReference' => $argument->isByReference(), |
515
|
|
|
'variadic' => $argument->isVariadic(), |
516
|
|
|
); |
517
|
|
|
return $argument; |
518
|
|
|
} |
519
|
|
|
|
520
|
|
|
/** |
521
|
|
|
* Generates an associative array containing all properties for all tags of the given element. |
522
|
|
|
* |
523
|
|
|
* @param DescriptorAbstract $element |
524
|
|
|
* |
525
|
|
|
* @return string |
526
|
|
|
*/ |
527
|
|
|
private function transformTags(DescriptorAbstract $element) |
528
|
|
|
{ |
529
|
|
|
$tags = array(); |
530
|
|
|
foreach ($element->getTags() as $tagName => $tagGroup) { |
531
|
|
|
$tags[$tagName] = array(); |
532
|
|
|
|
533
|
|
|
/** @var TagDescriptor $tag */ |
534
|
|
|
foreach ($tagGroup as $tag) { |
535
|
|
|
$tags[$tagName][] = $this->transformTag($tag); |
536
|
|
|
} |
537
|
|
|
} |
538
|
|
|
return $tags; |
539
|
|
|
} |
540
|
|
|
|
541
|
|
|
/** |
542
|
|
|
* Generates an associative array containing all properties for a tag. |
543
|
|
|
* |
544
|
|
|
* @param TagDescriptor $tag |
545
|
|
|
* |
546
|
|
|
* @return string[] |
547
|
|
|
*/ |
548
|
|
|
private function transformTag(TagDescriptor $tag) |
549
|
|
|
{ |
550
|
|
|
$tagArray = array( |
551
|
|
|
'name' => $tag->getName(), |
552
|
|
|
'description' => $tag->getDescription(), |
553
|
|
|
); |
554
|
|
|
|
555
|
|
|
// TODO: make the tests below configurable from the outside so that more could be added using plugins |
556
|
|
|
if (method_exists($tag, 'getTypes')) { |
557
|
|
|
$tagArray['type'] = $this->transformTypes($tag->getTypes()); |
558
|
|
|
} elseif (method_exists($tag, 'getType')) { |
559
|
|
|
$tagArray['type'] = $this->transformTypes($tag->getType()); |
560
|
|
|
} |
561
|
|
|
if (method_exists($tag, 'getVariableName')) { |
562
|
|
|
$tagArray['variable'] = $tag->getVariableName(); |
563
|
|
|
} |
564
|
|
|
if (method_exists($tag, 'getReference')) { |
565
|
|
|
$tagArray['link'] = $tag->getReference(); |
566
|
|
|
} elseif (method_exists($tag, 'getLink')) { |
567
|
|
|
$tagArray['link'] = $tag->getLink(); |
568
|
|
|
} |
569
|
|
|
if (method_exists($tag, 'getMethodName')) { |
570
|
|
|
$tagArray['methodName'] = $tag->getMethodName(); |
571
|
|
|
} |
572
|
|
|
|
573
|
|
|
return $tagArray; |
574
|
|
|
} |
575
|
|
|
|
576
|
|
|
/** |
577
|
|
|
* Generates an associative array containing all types that are detected in the given type collection. |
578
|
|
|
* |
579
|
|
|
* @param DescriptorAbstract[]|string[] $types |
580
|
|
|
* |
581
|
|
|
* @return string[] |
582
|
|
|
*/ |
583
|
|
|
private function transformTypes($types) |
584
|
|
|
{ |
585
|
|
|
$typeStrings = array(); |
586
|
|
|
foreach ($types as $type) { |
587
|
|
|
$typeStrings[] = $type instanceof DescriptorAbstract |
|
|
|
|
588
|
|
|
? $type->getFullyQualifiedStructuralElementName() |
589
|
|
|
: (string)$type; |
590
|
|
|
} |
591
|
|
|
|
592
|
|
|
return $typeStrings; |
593
|
|
|
} |
594
|
|
|
|
595
|
|
|
/** |
596
|
|
|
* Composes a tree of namespaces with their children. |
597
|
|
|
* |
598
|
|
|
* Note that only constants, functions and child-namespaces are fully specified. Classes, interfaces and |
599
|
|
|
* traits are FQCNs that can be used to look up the right details in the classes folder. This is done on |
600
|
|
|
* purpose to reduce bandwidth, |
601
|
|
|
* |
602
|
|
|
* @param NamespaceDescriptor $namespaceDescriptor |
603
|
|
|
* |
604
|
|
|
* @return string[] |
605
|
|
|
*/ |
606
|
|
|
private function getNamespaceTree($namespaceDescriptor) |
607
|
|
|
{ |
608
|
|
|
$namespace = array( |
609
|
|
|
'name' => $namespaceDescriptor->getName(), |
610
|
|
|
'fqnn' => $namespaceDescriptor->getFullyQualifiedStructuralElementName(), |
611
|
|
|
'namespaces' => array(), |
612
|
|
|
'constants' => array(), |
613
|
|
|
'functions' => array(), |
614
|
|
|
'classes' => array(), |
615
|
|
|
'interfaces' => array(), |
616
|
|
|
'traits' => array(), |
617
|
|
|
); |
618
|
|
|
|
619
|
|
|
foreach ($namespaceDescriptor->getChildren() as $subNamespace) { |
620
|
|
|
$namespace['namespaces'][] = $this->getNamespaceTree($subNamespace); |
621
|
|
|
} |
622
|
|
|
|
623
|
|
|
/** @var ConstantDescriptor $constant */ |
624
|
|
|
foreach ($namespaceDescriptor->getConstants() as $constant) { |
625
|
|
|
$namespace['constants'][] = $this->transformConstant($constant); |
626
|
|
|
} |
627
|
|
|
|
628
|
|
|
/** @var FunctionDescriptor $function */ |
629
|
|
|
foreach ($namespaceDescriptor->getFunctions() as $function) { |
630
|
|
|
$namespace['functions'][] = $this->transformFunction($function); |
631
|
|
|
} |
632
|
|
|
|
633
|
|
|
/** @var ClassDescriptor $class */ |
634
|
|
|
foreach ($namespaceDescriptor->getClasses() as $class) { |
635
|
|
|
$namespace['classes'][] = $class->getFullyQualifiedStructuralElementName(); |
636
|
|
|
} |
637
|
|
|
|
638
|
|
|
/** @var TraitDescriptor $trait */ |
639
|
|
|
foreach ($namespaceDescriptor->getTraits() as $trait) { |
640
|
|
|
$namespace['traits'][] = $trait->getFullyQualifiedStructuralElementName(); |
641
|
|
|
} |
642
|
|
|
|
643
|
|
|
/** @var InterfaceDescriptor $class */ |
644
|
|
|
foreach ($namespaceDescriptor->getInterfaces() as $interface) { |
645
|
|
|
$namespace['interfaces'][] = $interface->getFullyQualifiedStructuralElementName(); |
646
|
|
|
} |
647
|
|
|
|
648
|
|
|
return $namespace; |
649
|
|
|
} |
650
|
|
|
|
651
|
|
|
/** |
652
|
|
|
* Composes a tree of packages with their children. |
653
|
|
|
* |
654
|
|
|
* Note that only constants, functions and child-packages are fully specified. Classes, interfaces and |
655
|
|
|
* traits are FQCNs that can be used to look up the right details in the classes folder. This is done on |
656
|
|
|
* purpose to reduce bandwidth, |
657
|
|
|
* |
658
|
|
|
* @param PackageDescriptor $packageDescriptor |
659
|
|
|
* |
660
|
|
|
* @return string[] |
661
|
|
|
*/ |
662
|
|
|
private function getPackageTree($packageDescriptor) |
663
|
|
|
{ |
664
|
|
|
$package = array( |
665
|
|
|
'name' => $packageDescriptor->getName(), |
666
|
|
|
'fqnn' => $packageDescriptor->getFullyQualifiedStructuralElementName(), |
667
|
|
|
'packages' => array(), |
668
|
|
|
'constants' => array(), |
669
|
|
|
'functions' => array(), |
670
|
|
|
'classes' => array(), |
671
|
|
|
'interfaces' => array(), |
672
|
|
|
'traits' => array(), |
673
|
|
|
); |
674
|
|
|
|
675
|
|
|
foreach ($packageDescriptor->getChildren() as $subPackage) { |
676
|
|
|
$package['packages'][] = $this->getPackageTree($subPackage); |
677
|
|
|
} |
678
|
|
|
|
679
|
|
|
/** @var ConstantDescriptor $constant */ |
680
|
|
|
foreach ($packageDescriptor->getConstants() as $constant) { |
681
|
|
|
$package['constants'][] = $this->transformConstant($constant); |
682
|
|
|
} |
683
|
|
|
|
684
|
|
|
/** @var FunctionDescriptor $function */ |
685
|
|
|
foreach ($packageDescriptor->getFunctions() as $function) { |
686
|
|
|
$package['functions'][] = $this->transformFunction($function); |
687
|
|
|
} |
688
|
|
|
|
689
|
|
|
/** @var ClassDescriptor $class */ |
690
|
|
|
foreach ($packageDescriptor->getClasses() as $class) { |
691
|
|
|
$package['classes'][] = $class->getFullyQualifiedStructuralElementName(); |
692
|
|
|
} |
693
|
|
|
|
694
|
|
|
/** @var TraitDescriptor $trait */ |
695
|
|
|
foreach ($packageDescriptor->getTraits() as $trait) { |
696
|
|
|
$package['traits'][] = $trait->getFullyQualifiedStructuralElementName(); |
697
|
|
|
} |
698
|
|
|
|
699
|
|
|
/** @var InterfaceDescriptor $class */ |
700
|
|
|
foreach ($packageDescriptor->getInterfaces() as $interface) { |
701
|
|
|
$package['interfaces'][] = $interface->getFullyQualifiedStructuralElementName(); |
702
|
|
|
} |
703
|
|
|
|
704
|
|
|
return $package; |
705
|
|
|
} |
706
|
|
|
|
707
|
|
|
/** |
708
|
|
|
* Renders the given class to the provided folder with the FQCN in the element as filename. |
709
|
|
|
* |
710
|
|
|
* @param string $folder |
711
|
|
|
* @param ClassDescriptor|InterfaceDescriptor|TraitDescriptor $element |
712
|
|
|
* @param string[] $class |
713
|
|
|
* |
714
|
|
|
* @return void |
715
|
|
|
*/ |
716
|
|
|
private function writeClassToDisk($folder, $element, array $class) |
717
|
|
|
{ |
718
|
|
|
file_put_contents( |
719
|
|
|
$folder . 'classes/' |
720
|
|
|
. str_replace('\\', '.', ltrim($element->getFullyQualifiedStructuralElementName(), '\\')) |
721
|
|
|
. '.json', |
722
|
|
|
'classDefinition(' . json_encode($class) . ');' |
723
|
|
|
); |
724
|
|
|
} |
725
|
|
|
|
726
|
|
|
/** |
727
|
|
|
* Renders the given file description to the provided folder with the path in the element as filename. |
728
|
|
|
* |
729
|
|
|
* @param string $folder |
730
|
|
|
* @param FileDescriptor $element |
731
|
|
|
* @param string[] $file |
732
|
|
|
* |
733
|
|
|
* @return void |
734
|
|
|
*/ |
735
|
|
|
private function writeFileToDisk($folder, FileDescriptor $element, array $file) |
736
|
|
|
{ |
737
|
|
|
file_put_contents( |
738
|
|
|
$folder . 'files/' |
739
|
|
|
. str_replace(array('\\', '/'), '.', ltrim($element->getPath(), '/\\')) |
740
|
|
|
. '.json', |
741
|
|
|
'fileDefinition(' . json_encode($file) . ');' |
742
|
|
|
); |
743
|
|
|
} |
744
|
|
|
} |
745
|
|
|
|
The class complexity is the sum of the complexity of all methods. A very high value is usually an indication that your class does not follow the single reponsibility principle and does more than one job.
Some resources for further reading:
You can also find more detailed suggestions for refactoring in the “Code” section of your repository.