Completed
Push — develop ( 4b36a1...568a5c )
by Jaap
07:06
created

ProjectDescriptorBuilder   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 244
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 10

Test Coverage

Coverage 16.66%

Importance

Changes 0
Metric Value
dl 0
loc 244
ccs 14
cts 84
cp 0.1666
rs 9.6
c 0
b 0
f 0
wmc 32
lcom 2
cbo 10

14 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A createProjectDescriptor() 0 4 1
A setProjectDescriptor() 0 4 1
A getProjectDescriptor() 0 4 1
B buildDescriptor() 0 25 6
A getAssembler() 0 4 1
A filter() 0 4 1
A filterEachDescriptor() 0 14 3
A filterDescriptor() 0 14 3
A mapCodeToSeverity() 0 10 3
A setTranslator() 0 4 1
B build() 0 24 4
A getDefaultPackage() 0 4 1
B isVisibilityAllowed() 0 19 5
1
<?php
2
/**
3
 * phpDocumentor
4
 *
5
 * PHP Version 5.3
6
 *
7
 * @copyright 2010-2014 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 phpDocumentor\Descriptor\Builder\AssemblerFactory;
15
use phpDocumentor\Descriptor\Builder\Reflector\AssemblerAbstract;
16
use phpDocumentor\Descriptor\Filter\Filter;
17
use phpDocumentor\Descriptor\Filter\Filterable;
18
use phpDocumentor\Descriptor\ProjectDescriptor\Settings;
19
use phpDocumentor\Descriptor\Validator\Error;
20
use phpDocumentor\Reflection\Fqsen;
21
use phpDocumentor\Reflection\Php\Project;
22
use phpDocumentor\Translator\Translator;
23
use Psr\Log\LogLevel;
24
use Symfony\Component\Validator\ConstraintViolation;
25
use Symfony\Component\Validator\Validator;
26
27
/**
28
 * Builds a Project Descriptor and underlying tree.
29
 */
30
class ProjectDescriptorBuilder
0 ignored issues
show
Complexity introduced by
The class ProjectDescriptorBuilder has a coupling between objects value of 18. Consider to reduce the number of dependencies under 13.
Loading history...
31
{
32
    /** @var string */
33
    const DEFAULT_PROJECT_NAME = 'Untitled project';
34
35
    /** @var AssemblerFactory $assemblerFactory */
36
    protected $assemblerFactory;
37
38
    /** @var Filter $filter */
39
    protected $filter;
40
41
    /** @var ProjectDescriptor $project */
42
    protected $project;
43
44
    /** @var Translator $translator */
45
    protected $translator;
46
    private $defaultPackage;
47
48
    public function __construct(AssemblerFactory $assemblerFactory, Filter $filterManager)
49
    {
50
        $this->assemblerFactory = $assemblerFactory;
51
        $this->filter           = $filterManager;
52
    }
53
54 1
    public function createProjectDescriptor()
55
    {
56 1
        $this->project = new ProjectDescriptor(self::DEFAULT_PROJECT_NAME);
57 1
    }
58
59 1
    public function setProjectDescriptor(ProjectDescriptor $projectDescriptor)
60
    {
61 1
        $this->project = $projectDescriptor;
62 1
    }
63
64
    /**
65
     * Returns the project descriptor that is being built.
66
     *
67
     * @return ProjectDescriptor
68
     */
69 2
    public function getProjectDescriptor()
70
    {
71 2
        return $this->project;
72
    }
73
74
    /**
75
     * Verifies whether the given visibility is allowed to be included in the Descriptors.
76
     *
77
     * This method is used anytime a Descriptor is added to a collection (for example, when adding a Method to a Class)
78
     * to determine whether the visibility of that element is matches what the user has specified when it ran
79
     * phpDocumentor.
80
     *
81
     * @param string|integer $visibility One of the visibility constants of the ProjectDescriptor class or the words
82
     *     'public', 'protected', 'private' or 'internal'.
83
     *
84
     * @see ProjectDescriptor where the visibility is stored and that declares the constants to use.
85
     *
86
     * @return boolean
87
     */
88 1
    public function isVisibilityAllowed($visibility)
89
    {
90
        switch ($visibility) {
91 1
            case 'public':
92
                $visibility = Settings::VISIBILITY_PUBLIC;
93
                break;
94 1
            case 'protected':
95
                $visibility = Settings::VISIBILITY_PROTECTED;
96
                break;
97 1
            case 'private':
98
                $visibility = Settings::VISIBILITY_PRIVATE;
99
                break;
100 1
            case 'internal':
101
                $visibility = Settings::VISIBILITY_INTERNAL;
102
                break;
103
        }
104
105 1
        return $this->getProjectDescriptor()->isVisibilityAllowed($visibility);
106
    }
107
108
    /**
109
     * Takes the given data and attempts to build a Descriptor from it.
110
     *
111
     * @param mixed $data
112
     *
113
     * @throws \InvalidArgumentException if no Assembler could be found that matches the given data.
114
     *
115
     * @return DescriptorAbstract|Collection|null
116
     */
117
    public function buildDescriptor($data)
118
    {
119
        $assembler = $this->getAssembler($data);
120
        if (!$assembler) {
121
            throw new \InvalidArgumentException(
122
                'Unable to build a Descriptor; the provided data did not match any Assembler '. get_class($data)
123
            );
124
        }
125
126
        if ($assembler instanceof Builder\AssemblerAbstract) {
127
            $assembler->setBuilder($this);
128
        }
129
130
        // create Descriptor and populate with the provided data
131
        $descriptor = $assembler->create($data);
132
        if (!$descriptor) {
133
            return null;
134
        }
135
136
        $descriptor = (!is_array($descriptor) && (!$descriptor instanceof Collection))
137
            ? $this->filterDescriptor($descriptor)
138
            : $this->filterEachDescriptor($descriptor);
0 ignored issues
show
Documentation introduced by
$descriptor is of type array|object<phpDocumentor\Descriptor\Collection>, but the function expects a array<integer,object<php...or\DescriptorAbstract>>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
139
140
        return $descriptor;
141
    }
142
143
    /**
144
     * Attempts to find an assembler matching the given data.
145
     *
146
     * @param mixed $data
147
     *
148
     * @return AssemblerAbstract
149
     */
150
    public function getAssembler($data)
151
    {
152
        return $this->assemblerFactory->get($data);
153
    }
154
155
    /**
156
     * Analyzes a Descriptor and alters its state based on its state or even removes the descriptor.
157
     *
158
     * @param Filterable $descriptor
159
     *
160
     * @return Filterable
161
     */
162
    public function filter(Filterable $descriptor)
163
    {
164
        return $this->filter->filter($descriptor);
165
    }
166
167
    /**
168
     * Filters each descriptor, validates them, stores the validation results and returns a collection of transmuted
169
     * objects.
170
     *
171
     * @param DescriptorAbstract[] $descriptor
172
     *
173
     * @return Collection
174
     */
175
    private function filterEachDescriptor($descriptor)
176
    {
177
        $descriptors = new Collection();
178
        foreach ($descriptor as $key => $item) {
179
            $item = $this->filterDescriptor($item);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $item is correct as $this->filterDescriptor($item) (which targets phpDocumentor\Descriptor...der::filterDescriptor()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
180
            if (!$item) {
181
                continue;
182
            }
183
184
            $descriptors[$key] = $item;
185
        }
186
187
        return $descriptors;
188
    }
189
190
    /**
191
     * Filters a descriptor, validates it, stores the validation results and returns the transmuted object or null
192
     * if it is supposed to be removed.
193
     *
194
     * @param DescriptorAbstract $descriptor
195
     *
196
     * @return DescriptorAbstract|null
197
     */
198
    protected function filterDescriptor($descriptor)
199
    {
200
        if (!$descriptor instanceof Filterable) {
201
            return $descriptor;
202
        }
203
204
        // filter the descriptor; this may result in the descriptor being removed!
205
        $descriptor = $this->filter($descriptor);
206
        if (!$descriptor) {
207
            return null;
208
        }
209
210
        return $descriptor;
211
	}
212
213
    /**
214
     * Map error code to severity.
215
     *
216
     * @param int $code
217
     *
218
     * @return string
219
     */
220
    protected function mapCodeToSeverity($code)
221
    {
222
        if (is_int($code) && $this->translator->translate('VAL:ERRLVL-'.$code)) {
223
            $severity = $this->translator->translate('VAL:ERRLVL-'.$code);
224
        } else {
225
             $severity = LogLevel::ERROR;
226
        }
227
228
        return $severity;
229
    }
230
231
    /**
232
     * @param Translator $translator
233
     *
234
     * @return void
235
     */
236
    public function setTranslator(Translator $translator)
237
    {
238
        $this->translator = $translator;
239
    }
240
241
    public function build(Project $project)
242
    {
243
        $packageName = $project->getRootNamespace()->getFqsen()->getName();
244
        $this->defaultPackage = new PackageDescriptor();
245
        $this->defaultPackage->setFullyQualifiedStructuralElementName((string)$project->getRootNamespace()->getFqsen());
246
        $this->defaultPackage->setName($packageName);
247
        $this->defaultPackage->setNamespace(substr((string)$project->getRootNamespace()->getFqsen(), 0, -strlen($packageName)-1));
248
249
        foreach ($project->getFiles() as $file) {
250
            $descriptor = $this->buildDescriptor($file);
251
            if (!$descriptor) {
252
                return;
253
            }
254
255
            $this->getProjectDescriptor()->getFiles()->set($descriptor->getPath(), $descriptor);
256
        }
257
258
        $namespaces = $this->getProjectDescriptor()->getIndexes()->get('namespaces', new Collection());
259
//        $namespaces->add($this->defaultPackage);
260
261
        foreach ($project->getNamespaces() as $namespace) {
262
            $namespaces->set((string)$namespace->getFqsen(), $this->buildDescriptor($namespace));
263
        }
264
    }
265
266
    /**
267
     * @return string
268
     */
269
    public function getDefaultPackage()
270
    {
271
        return $this->defaultPackage;
272
    }
273
}
274