Completed
Push — develop ( 722f70...af048b )
by Jaap
15:12 queued 05:04
created

ServiceProvider   C

Complexity

Total Complexity 14

Size/Duplication

Total Lines 331
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 48

Importance

Changes 0
Metric Value
dl 0
loc 331
rs 5
c 0
b 0
f 0
wmc 14
lcom 1
cbo 48

9 Methods

Rating   Name   Duplication   Size   Complexity  
A register() 0 17 1
A attachAssemblersToFactory() 0 67 2
A attachFiltersToManager() 0 22 2
A attachValidators() 0 52 1
B addCache() 0 26 2
A addBuilder() 0 21 2
A addAssemblers() 0 18 1
A addFilters() 0 8 1
A addValidators() 0 16 2
1
<?php
2
/**
3
 * phpDocumentor
4
 *
5
 * PHP Version 5.3
6
 *
7
 * @copyright 2010-2013 Mike van Riel / Naenius (http://www.naenius.com)
8
 * @license   http://www.opensource.org/licenses/mit-license.php MIT
9
 * @link      http://phpdoc.org
10
 */
11
12
namespace phpDocumentor\Descriptor;
13
14
use Cilex\Application;
15
use Cilex\ServiceProviderInterface;
16
use phpDocumentor\Descriptor\Builder\AssemblerFactory;
17
use phpDocumentor\Descriptor\Builder\Reflector\ArgumentAssembler;
18
use phpDocumentor\Descriptor\Builder\Reflector\ClassAssembler;
19
use phpDocumentor\Descriptor\Builder\Reflector\ConstantAssembler;
20
use phpDocumentor\Descriptor\Builder\Reflector\FileAssembler;
21
use phpDocumentor\Descriptor\Builder\Reflector\FunctionAssembler;
22
use phpDocumentor\Descriptor\Builder\Reflector\InterfaceAssembler;
23
use phpDocumentor\Descriptor\Builder\Reflector\MethodAssembler;
24
use phpDocumentor\Descriptor\Builder\Reflector\PropertyAssembler;
25
use phpDocumentor\Descriptor\Builder\Reflector\Tags\AuthorAssembler;
26
use phpDocumentor\Descriptor\Builder\Reflector\Tags\DeprecatedAssembler;
27
use phpDocumentor\Descriptor\Builder\Reflector\Tags\ExampleAssembler;
28
use phpDocumentor\Descriptor\Builder\Reflector\Tags\GenericTagAssembler;
29
use phpDocumentor\Descriptor\Builder\Reflector\Tags\LinkAssembler;
30
use phpDocumentor\Descriptor\Builder\Reflector\Tags\MethodAssembler as MethodTagAssembler;
31
use phpDocumentor\Descriptor\Builder\Reflector\Tags\ParamAssembler;
32
use phpDocumentor\Descriptor\Builder\Reflector\Tags\PropertyAssembler as PropertyTagAssembler;
33
use phpDocumentor\Descriptor\Builder\Reflector\Tags\ReturnAssembler;
34
use phpDocumentor\Descriptor\Builder\Reflector\Tags\SeeAssembler;
35
use phpDocumentor\Descriptor\Builder\Reflector\Tags\SinceAssembler;
36
use phpDocumentor\Descriptor\Builder\Reflector\Tags\ThrowsAssembler;
37
use phpDocumentor\Descriptor\Builder\Reflector\Tags\TypeCollectionAssembler;
38
use phpDocumentor\Descriptor\Builder\Reflector\Tags\UsesAssembler;
39
use phpDocumentor\Descriptor\Builder\Reflector\Tags\VarAssembler;
40
use phpDocumentor\Descriptor\Builder\Reflector\Tags\VersionAssembler;
41
use phpDocumentor\Descriptor\Builder\Reflector\TraitAssembler;
42
use phpDocumentor\Descriptor\Filter\ClassFactory;
43
use phpDocumentor\Descriptor\Filter\Filter;
44
use phpDocumentor\Descriptor\Filter\StripIgnore;
45
use phpDocumentor\Descriptor\Filter\StripInternal;
46
use phpDocumentor\Descriptor\Filter\StripOnVisibility;
47
use phpDocumentor\Plugin\Core\Descriptor\Validator\Constraints as phpDocAssert;
48
use phpDocumentor\Reflection\ClassReflector\ConstantReflector as ClassConstant;
49
use phpDocumentor\Reflection\ClassReflector;
50
use phpDocumentor\Reflection\ConstantReflector;
51
use phpDocumentor\Reflection\DocBlock\Tag\AuthorTag;
52
use phpDocumentor\Reflection\DocBlock\Tag\DeprecatedTag;
53
use phpDocumentor\Reflection\DocBlock\Tag\ExampleTag;
54
use phpDocumentor\Reflection\DocBlock\Tag\LinkTag;
55
use phpDocumentor\Reflection\DocBlock\Tag\MethodTag;
56
use phpDocumentor\Reflection\DocBlock\Tag\ParamTag;
57
use phpDocumentor\Reflection\DocBlock\Tag\PropertyTag;
58
use phpDocumentor\Reflection\DocBlock\Tag\ReturnTag;
59
use phpDocumentor\Reflection\DocBlock\Tag\SeeTag;
60
use phpDocumentor\Reflection\DocBlock\Tag\SinceTag;
61
use phpDocumentor\Reflection\DocBlock\Tag\ThrowsTag;
62
use phpDocumentor\Reflection\DocBlock\Tag\UsesTag;
63
use phpDocumentor\Reflection\DocBlock\Tag\VarTag;
64
use phpDocumentor\Reflection\DocBlock\Tag;
65
use phpDocumentor\Reflection\DocBlock\Type\Collection as TypeCollection;
66
use phpDocumentor\Reflection\FileReflector;
67
use phpDocumentor\Reflection\FunctionReflector;
68
use phpDocumentor\Reflection\InterfaceReflector;
69
use phpDocumentor\Reflection\TraitReflector;
70
use Symfony\Component\Validator\Constraints as Assert;
71
use Symfony\Component\Validator\Mapping\ClassMetadata;
72
use Symfony\Component\Validator\Validator;
73
use Zend\Cache\Storage\Adapter\Filesystem;
74
use Zend\Cache\Storage\Plugin\Serializer as SerializerPlugin;
75
use Zend\Cache\Storage\Plugin\PluginOptions;
76
77
/**
78
 * This provider is responsible for registering the Descriptor component with the given Application.
79
 */
80
class ServiceProvider implements ServiceProviderInterface
0 ignored issues
show
Complexity introduced by
The class ServiceProvider has a coupling between objects value of 78. Consider to reduce the number of dependencies under 13.
Loading history...
81
{
82
    /**
83
     * Adds the services needed to build the descriptors.
84
     *
85
     * @param Application $app An Application instance
86
     *
87
     * @return void
88
     */
89
    public function register(Application $app)
90
    {
91
        $app['parser.example.finder'] = new Example\Finder();
92
93
        $this->addCache($app);
94
        $this->addAssemblers($app);
95
        $this->addFilters($app);
96
        $this->addValidators($app);
97
        $this->addBuilder($app);
98
99
        // I would prefer to extend it but due to a circular reference will pimple fatal
100
        $this->attachFiltersToManager($app['descriptor.filter'], $app);
101
102
        $app['descriptor.analyzer'] = function () {
103
            return new ProjectAnalyzer();
104
        };
105
    }
106
107
    /**
108
     * Registers the Assemblers used to convert Reflection objects to Descriptors.
109
     *
110
     * @param AssemblerFactory   $factory
111
     * @param \Cilex\Application $app
112
     *
113
     * @return AssemblerFactory
114
     */
115
    public function attachAssemblersToFactory(AssemblerFactory $factory, Application $app)
116
    {
117
        // @codingStandardsIgnoreStart because we limit the verbosity by making all closures single-line
118
        $fileMatcher      = function ($criteria) { return $criteria instanceof FileReflector; };
119
        $constantMatcher  = function ($criteria) {
120
            return $criteria instanceof ConstantReflector || $criteria instanceof ClassConstant;
121
        };
122
        $traitMatcher     = function ($criteria) { return $criteria instanceof TraitReflector; };
123
        $classMatcher     = function ($criteria) { return $criteria instanceof ClassReflector; };
124
        $interfaceMatcher = function ($criteria) { return $criteria instanceof InterfaceReflector; };
125
        $propertyMatcher  = function ($criteria) { return $criteria instanceof ClassReflector\PropertyReflector; };
126
        $methodMatcher    = function ($criteria) { return $criteria instanceof ClassReflector\MethodReflector; };
127
        $argumentMatcher  = function ($criteria) { return $criteria instanceof FunctionReflector\ArgumentReflector; };
128
        $functionMatcher  = function ($criteria) { return $criteria instanceof FunctionReflector; };
129
130
        $authorMatcher      = function ($criteria) { return $criteria instanceof AuthorTag; };
131
        $deprecatedMatcher  = function ($criteria) { return $criteria instanceof DeprecatedTag; };
132
        $exampleMatcher     = function ($criteria) { return $criteria instanceof ExampleTag; };
133
        $linkMatcher        = function ($criteria) { return $criteria instanceof LinkTag; };
134
        $methodTagMatcher   = function ($criteria) { return $criteria instanceof MethodTag; };
135
        $propertyTagMatcher = function ($criteria) { return $criteria instanceof PropertyTag; };
136
        $paramMatcher       = function ($criteria) { return $criteria instanceof ParamTag; };
137
        $throwsMatcher      = function ($criteria) { return $criteria instanceof ThrowsTag; };
138
        $returnMatcher      = function ($criteria) { return $criteria instanceof ReturnTag; };
139
        $usesMatcher        = function ($criteria) { return $criteria instanceof UsesTag; };
140
        $seeMatcher         = function ($criteria) { return $criteria instanceof SeeTag; };
141
        $sinceMatcher       = function ($criteria) { return $criteria instanceof SinceTag; };
142
        $varMatcher         = function ($criteria) { return $criteria instanceof VarTag; };
143
        $versionMatcher     = function ($criteria) { return $criteria instanceof Tag\VersionTag; };
144
145
        $typeCollectionMatcher = function ($criteria) { return $criteria instanceof TypeCollection; };
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $typeCollectionMatcher exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
146
147
        $tagFallbackMatcher = function ($criteria) { return $criteria instanceof Tag; };
148
        // @codingStandardsIgnoreEnd
149
150
        $argumentAssembler = new ArgumentAssembler();
151
        $factory->register($fileMatcher, new FileAssembler());
152
        $factory->register($constantMatcher, new ConstantAssembler());
153
        $factory->register($traitMatcher, new TraitAssembler());
154
        $factory->register($classMatcher, new ClassAssembler());
155
        $factory->register($interfaceMatcher, new InterfaceAssembler());
156
        $factory->register($propertyMatcher, new PropertyAssembler());
157
        $factory->register($argumentMatcher, $argumentAssembler);
158
        $factory->register($methodMatcher, new MethodAssembler($argumentAssembler));
159
        $factory->register($functionMatcher, new FunctionAssembler($argumentAssembler));
160
161
        $factory->register($authorMatcher, new AuthorAssembler());
162
        $factory->register($deprecatedMatcher, new DeprecatedAssembler());
163
        $factory->register($exampleMatcher, new ExampleAssembler($app['parser.example.finder']));
164
        $factory->register($linkMatcher, new LinkAssembler());
165
        $factory->register($methodTagMatcher, new MethodTagAssembler());
166
        $factory->register($propertyTagMatcher, new PropertyTagAssembler());
167
        $factory->register($varMatcher, new VarAssembler());
168
        $factory->register($paramMatcher, new ParamAssembler());
169
        $factory->register($throwsMatcher, new ThrowsAssembler());
170
        $factory->register($returnMatcher, new ReturnAssembler());
171
        $factory->register($usesMatcher, new UsesAssembler());
172
        $factory->register($seeMatcher, new SeeAssembler());
173
        $factory->register($sinceMatcher, new SinceAssembler());
174
        $factory->register($versionMatcher, new VersionAssembler());
175
176
        $factory->register($typeCollectionMatcher, new TypeCollectionAssembler());
177
178
        $factory->registerFallback($tagFallbackMatcher, new GenericTagAssembler());
179
180
        return $factory;
181
    }
182
183
    /**
184
     * Attaches filters to the manager.
185
     *
186
     * @param Filter $filterManager
187
     * @param Application $app
188
     *
189
     * @return Filter
190
     */
191
    public function attachFiltersToManager(Filter $filterManager, Application $app)
192
    {
193
        $stripOnVisibility = new StripOnVisibility($app['descriptor.builder']);
194
        $filtersOnAllDescriptors = array(
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $filtersOnAllDescriptors exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
195
            new StripInternal($app['descriptor.builder']),
196
            new StripIgnore($app['descriptor.builder'])
197
        );
198
199
        foreach ($filtersOnAllDescriptors as $filter) {
200
            $filterManager->attach('phpDocumentor\Descriptor\ConstantDescriptor', $filter);
201
            $filterManager->attach('phpDocumentor\Descriptor\FunctionDescriptor', $filter);
202
            $filterManager->attach('phpDocumentor\Descriptor\InterfaceDescriptor', $filter);
203
            $filterManager->attach('phpDocumentor\Descriptor\TraitDescriptor', $filter);
204
            $filterManager->attach('phpDocumentor\Descriptor\PropertyDescriptor', $filter);
205
            $filterManager->attach('phpDocumentor\Descriptor\MethodDescriptor', $filter);
206
        }
207
208
        $filterManager->attach('phpDocumentor\Descriptor\PropertyDescriptor', $stripOnVisibility);
209
        $filterManager->attach('phpDocumentor\Descriptor\MethodDescriptor', $stripOnVisibility);
210
211
        return $filterManager;
212
    }
213
214
    /**
215
     * Adds validators to check the Descriptors.
216
     *
217
     * @param Validator $validator
218
     *
219
     * @return Validator
220
     */
221
    public function attachValidators(Validator $validator)
222
    {
223
        /** @var ClassMetadata $fileMetadata */
224
        $fileMetadata  = $validator->getMetadataFor('phpDocumentor\Descriptor\FileDescriptor');
225
        /** @var ClassMetadata $constantMetadata */
226
        $constantMetadata  = $validator->getMetadataFor('phpDocumentor\Descriptor\ConstantDescriptor');
0 ignored issues
show
Unused Code introduced by
$constantMetadata is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
227
        /** @var ClassMetadata $functionMetadata */
228
        $functionMetadata  = $validator->getMetadataFor('phpDocumentor\Descriptor\FunctionDescriptor');
229
        /** @var ClassMetadata $classMetadata */
230
        $classMetadata     = $validator->getMetadataFor('phpDocumentor\Descriptor\ClassDescriptor');
231
        /** @var ClassMetadata $interfaceMetadata */
232
        $interfaceMetadata = $validator->getMetadataFor('phpDocumentor\Descriptor\InterfaceDescriptor');
233
        /** @var ClassMetadata $traitMetadata */
234
        $traitMetadata     = $validator->getMetadataFor('phpDocumentor\Descriptor\TraitDescriptor');
235
        /** @var ClassMetadata $propertyMetadata */
236
        $propertyMetadata  = $validator->getMetadataFor('phpDocumentor\Descriptor\PropertyDescriptor');
237
        /** @var ClassMetadata $methodMetadata */
238
        $methodMetadata    = $validator->getMetadataFor('phpDocumentor\Descriptor\MethodDescriptor');
239
240
        $fileMetadata->addPropertyConstraint('summary', new Assert\NotBlank(array('message' => 'PPC:ERR-50000')));
241
        $classMetadata->addPropertyConstraint('summary', new Assert\NotBlank(array('message' => 'PPC:ERR-50005')));
242
        $propertyMetadata->addConstraint(new phpDocAssert\Property\HasSummary());
243
        $methodMetadata->addPropertyConstraint('summary', new Assert\NotBlank(array('message' => 'PPC:ERR-50008')));
244
        $interfaceMetadata->addPropertyConstraint('summary', new Assert\NotBlank(array('message' => 'PPC:ERR-50009')));
245
        $traitMetadata->addPropertyConstraint('summary', new Assert\NotBlank(array('message' => 'PPC:ERR-50010')));
246
        $functionMetadata->addPropertyConstraint('summary', new Assert\NotBlank(array('message' => 'PPC:ERR-50011')));
247
248
        $functionMetadata->addConstraint(new phpDocAssert\Functions\IsReturnTypeNotAnIdeDefault());
249
        $methodMetadata->addConstraint(new phpDocAssert\Functions\IsReturnTypeNotAnIdeDefault());
250
251
        $functionMetadata->addConstraint(new phpDocAssert\Functions\IsParamTypeNotAnIdeDefault());
252
        $methodMetadata->addConstraint(new phpDocAssert\Functions\IsParamTypeNotAnIdeDefault());
253
        $functionMetadata->addConstraint(new phpDocAssert\Functions\AreAllArgumentsValid());
254
        $methodMetadata->addConstraint(new phpDocAssert\Functions\AreAllArgumentsValid());
255
256
        $classMetadata->addConstraint(new phpDocAssert\Classes\HasSinglePackage());
257
        $interfaceMetadata->addConstraint(new phpDocAssert\Classes\HasSinglePackage());
258
        $traitMetadata->addConstraint(new phpDocAssert\Classes\HasSinglePackage());
259
        $fileMetadata->addConstraint(new phpDocAssert\Classes\HasSinglePackage());
260
261
        $classMetadata->addConstraint(new phpDocAssert\Classes\HasSingleSubpackage());
262
        $interfaceMetadata->addConstraint(new phpDocAssert\Classes\HasSingleSubpackage());
263
        $traitMetadata->addConstraint(new phpDocAssert\Classes\HasSingleSubpackage());
264
        $fileMetadata->addConstraint(new phpDocAssert\Classes\HasSingleSubpackage());
265
266
        $classMetadata->addConstraint(new phpDocAssert\Classes\HasPackageWithSubpackage());
267
        $interfaceMetadata->addConstraint(new phpDocAssert\Classes\HasPackageWithSubpackage());
268
        $traitMetadata->addConstraint(new phpDocAssert\Classes\HasPackageWithSubpackage());
269
        $fileMetadata->addConstraint(new phpDocAssert\Classes\HasPackageWithSubpackage());
270
271
        return $validator;
272
    }
273
274
    /**
275
     * Adds the caching mechanism to the dependency injection container with key 'descriptor.cache'.
276
     *
277
     * @param Application $app
278
     *
279
     * @return void
280
     */
281
    protected function addCache(Application $app)
282
    {
283
        $app['descriptor.cache'] = $app->share(
284
            function () {
285
                $cache = new Filesystem();
286
                $cache->setOptions(
287
                    array(
288
                         'namespace' => 'phpdoc-cache',
289
                         'cache_dir' => sys_get_temp_dir(),
290
                    )
291
                );
292
                $plugin = new SerializerPlugin();
293
294
                if (extension_loaded('igbinary')) {
295
                    $options = new PluginOptions();
296
                    $options->setSerializer('igbinary');
297
298
                    $plugin->setOptions($options);
299
                }
300
301
                $cache->addPlugin($plugin);
302
303
                return $cache;
304
            }
305
        );
306
    }
307
308
    /**
309
     * Adds the Building mechanism using the key 'descriptor.builder'.
310
     *
311
     * Please note that the type of serializer can be configured using the parameter 'descriptor.builder.serializer'; it
312
     * accepts any parameter that Zend\Serializer supports.
313
     *
314
     * @param Application $app
315
     *
316
     * @return void
317
     */
318
    protected function addBuilder(Application $app)
319
    {
320
        if (extension_loaded('igbinary')) {
321
            $app['descriptor.builder.serializer'] = 'IgBinary';
322
        } else {
323
            $app['descriptor.builder.serializer'] = 'PhpSerialize';
324
        }
325
326
        $app['descriptor.builder'] = $app->share(
327
            function ($container) {
328
                $builder = new ProjectDescriptorBuilder(
329
                    $container['descriptor.builder.assembler.factory'],
330
                    $container['descriptor.filter'],
331
                    $container['validator']
332
                );
333
                $builder->setTranslator($container['translator']);
334
335
                return $builder;
336
            }
337
        );
338
    }
339
340
    /**
341
     * Adds the assembler factory and attaches the basic assemblers with key 'descriptor.builder.assembler.factory'.
342
     *
343
     * @param Application $app
344
     *
345
     * @return void
346
     */
347
    protected function addAssemblers(Application $app)
348
    {
349
        $app['descriptor.builder.assembler.factory'] = $app->share(
350
            function () {
351
                return new AssemblerFactory();
352
            }
353
        );
354
355
        $provider = $this;
356
        $app['descriptor.builder.assembler.factory'] = $app->share(
357
            $app->extend(
358
                'descriptor.builder.assembler.factory',
359
                function ($factory) use ($provider, $app) {
360
                    return $provider->attachAssemblersToFactory($factory, $app);
361
                }
362
            )
363
        );
364
    }
365
366
    /**
367
     * Adds the descriptor filtering mechanism and using key 'descriptor.filter'.
368
     *
369
     * Please note that filters can only be attached after the builder is instantiated because it is needed; so the
370
     * filters can be attached by extending 'descriptor.builder'.
371
     *
372
     * @param Application $app
373
     *
374
     * @return void
375
     */
376
    protected function addFilters(Application $app)
377
    {
378
        $app['descriptor.filter'] = $app->share(
379
            function () {
380
                return new Filter(new ClassFactory());
381
            }
382
        );
383
    }
384
385
    /**
386
     * Adds validators for the descriptors to the validator manager.
387
     *
388
     * @param Application $app
389
     *
390
     * @throws Exception\MissingDependencyException if the validator could not be found.
391
     *
392
     * @return void
393
     */
394
    protected function addValidators(Application $app)
395
    {
396
        if (!isset($app['validator'])) {
397
            throw new Exception\MissingDependencyException('The validator manager is missing');
398
        }
399
400
        $provider = $this;
401
        $app['validator'] = $app->share(
402
            $app->extend(
403
                'validator',
404
                function ($validatorManager) use ($provider) {
405
                    return $provider->attachValidators($validatorManager);
406
                }
407
            )
408
        );
409
    }
410
}
411