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