Completed
Push — develop ( 8eb671...133594 )
by Mike
19:30 queued 09:24
created

Descriptor/ProjectDescriptorBuilder.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * This file is part of phpDocumentor.
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * @author    Mike van Riel <[email protected]>
11
 * @copyright 2010-2018 Mike van Riel / Naenius (http://www.naenius.com)
12
 * @license   http://www.opensource.org/licenses/mit-license.php MIT
13
 * @link      http://phpdoc.org
14
 */
15
16
namespace phpDocumentor\Descriptor;
17
18
use phpDocumentor\Descriptor\Builder\AssemblerFactory;
19
use phpDocumentor\Descriptor\Builder\AssemblerInterface;
20
use phpDocumentor\Descriptor\Builder\Reflector\AssemblerAbstract;
21
use phpDocumentor\Descriptor\Filter\Filter;
22
use phpDocumentor\Descriptor\Filter\Filterable;
23
use phpDocumentor\Descriptor\ProjectDescriptor\Settings;
24
use phpDocumentor\Reflection\Php\Project;
25
use Psr\Log\LogLevel;
26
27
/**
28
 * Builds a Project Descriptor and underlying tree.
29
 */
30
class ProjectDescriptorBuilder
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
    private $defaultPackage;
45
46
    public function __construct(AssemblerFactory $assemblerFactory, Filter $filterManager)
47
    {
48
        $this->assemblerFactory = $assemblerFactory;
49
        $this->filter = $filterManager;
50
    }
51 1
52
    public function createProjectDescriptor()
53 1
    {
54 1
        $this->project = new ProjectDescriptor(self::DEFAULT_PROJECT_NAME);
55
    }
56 1
57
    public function setProjectDescriptor(ProjectDescriptor $projectDescriptor)
58 1
    {
59 1
        $this->project = $projectDescriptor;
60
    }
61
62
    /**
63
     * Returns the project descriptor that is being built.
64
     *
65
     * @return ProjectDescriptor
66 2
     */
67
    public function getProjectDescriptor()
68 2
    {
69
        return $this->project;
70
    }
71
72
    /**
73
     * Verifies whether the given visibility is allowed to be included in the Descriptors.
74
     *
75
     * This method is used anytime a Descriptor is added to a collection (for example, when adding a Method to a Class)
76
     * to determine whether the visibility of that element is matches what the user has specified when it ran
77
     * phpDocumentor.
78
     *
79
     * @param string|integer $visibility One of the visibility constants of the ProjectDescriptor class or the words
80
     *     'public', 'protected', 'private' or 'internal'.
81
     *
82
     * @see ProjectDescriptor where the visibility is stored and that declares the constants to use.
83
     *
84
     * @return boolean
85 1
     */
86
    public function isVisibilityAllowed($visibility)
87
    {
88 1
        switch ($visibility) {
89
            case 'public':
90
                $visibility = Settings::VISIBILITY_PUBLIC;
91 1
                break;
92
            case 'protected':
93
                $visibility = Settings::VISIBILITY_PROTECTED;
94 1
                break;
95
            case 'private':
96
                $visibility = Settings::VISIBILITY_PRIVATE;
97 1
                break;
98
            case 'internal':
99
                $visibility = Settings::VISIBILITY_INTERNAL;
100
                break;
101
        }
102 1
103
        return $this->getProjectDescriptor()->isVisibilityAllowed($visibility);
104
    }
105
106
    /**
107
     * Takes the given data and attempts to build a Descriptor from it.
108
     *
109
     * @param mixed $data
110
     *
111
     * @throws \InvalidArgumentException if no Assembler could be found that matches the given data.
112
     *
113
     * @return DescriptorAbstract|Collection|null
114
     */
115
    public function buildDescriptor($data)
116
    {
117
        $assembler = $this->getAssembler($data);
118
        if (!$assembler) {
119
            throw new \InvalidArgumentException(
120
                'Unable to build a Descriptor; the provided data did not match any Assembler ' .
121
                get_class($data)
122
            );
123
        }
124
125
        if ($assembler instanceof Builder\AssemblerAbstract) {
126
            $assembler->setBuilder($this);
127
        }
128
129
        // create Descriptor and populate with the provided data
130
        $descriptor = $assembler->create($data);
131
        if (!$descriptor) {
132
            return null;
133
        }
134
135
        return (!is_array($descriptor) && (!$descriptor instanceof Collection))
136
            ? $this->filterDescriptor($descriptor)
137
            : $this->filterEachDescriptor($descriptor);
138
    }
139
140
    /**
141
     * Attempts to find an assembler matching the given data.
142
     *
143
     * @param mixed $data
144
     *
145
     * @return AssemblerInterface|null
146
     */
147
    public function getAssembler($data)
148
    {
149
        return $this->assemblerFactory->get($data);
150
    }
151
152
    /**
153
     * Analyzes a Descriptor and alters its state based on its state or even removes the descriptor.
154
     *
155
     * @return Filterable
156
     */
157
    public function filter(Filterable $descriptor)
158
    {
159
        return $this->filter->filter($descriptor);
160
    }
161
162
    /**
163
     * Filters each descriptor, validates them, stores the validation results and returns a collection of transmuted
164
     * objects.
165
     *
166
     * @param DescriptorAbstract[] $descriptor
167
     *
168
     * @return Collection
169
     */
170
    private function filterEachDescriptor($descriptor)
171
    {
172
        $descriptors = new Collection();
173
        foreach ($descriptor as $key => $item) {
174
            $item = $this->filterDescriptor($item);
175
            if (!$item) {
176
                continue;
177
            }
178
179
            $descriptors[$key] = $item;
180
        }
181
182
        return $descriptors;
183
    }
184
185
    /**
186
     * Filters a descriptor, validates it, stores the validation results and returns the transmuted object or null
187
     * if it is supposed to be removed.
188
     *
189
     * @param Descriptor $descriptor
190
     *
191
     * @return Descriptor|null
192
     */
193
    protected function filterDescriptor(Descriptor $descriptor)
194
    {
195
        if (!$descriptor instanceof Filterable) {
196
            return $descriptor;
197
        }
198
199
        // filter the descriptor; this may result in the descriptor being removed!
200
        $descriptor = $this->filter($descriptor);
201
        if (!$descriptor) {
202
            return null;
203
        }
204
205
        return $descriptor;
206
    }
207
208
    /**
209
     * Map error code to severity.
210
     *
211
     * @param int $code
212
     *
213
     * @return string
214
     */
215
    protected function mapCodeToSeverity($code)
0 ignored issues
show
The parameter $code is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
216
    {
217
        return LogLevel::ERROR;
218
    }
219
220
    public function build(Project $project)
221
    {
222
        $packageName = $project->getRootNamespace()->getFqsen()->getName();
223
        $this->defaultPackage = new PackageDescriptor();
224
        $this->defaultPackage->setFullyQualifiedStructuralElementName(
225
            (string) $project->getRootNamespace()->getFqsen()
226
        );
227
        $this->defaultPackage->setName($packageName);
228
        $this->defaultPackage->setNamespace(
229
            substr((string) $project->getRootNamespace()->getFqsen(), 0, -strlen($packageName) - 1)
230
        );
231
232
        foreach ($project->getFiles() as $file) {
233
            $descriptor = $this->buildDescriptor($file);
234
            if (!$descriptor) {
235
                return;
236
            }
237
238
            $this->getProjectDescriptor()->getFiles()->set($descriptor->getPath(), $descriptor);
239
        }
240
241
        $namespaces = $this->getProjectDescriptor()->getIndexes()->get('namespaces', new Collection());
242
//        $namespaces->add($this->defaultPackage);
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
243
244
        foreach ($project->getNamespaces() as $namespace) {
245
            $namespaces->set((string) $namespace->getFqsen(), $this->buildDescriptor($namespace));
246
        }
247
    }
248
249
    public function getDefaultPackage()
250
    {
251
        return $this->defaultPackage;
252
    }
253
}
254