Completed
Push — develop ( bd0ea7...cbc256 )
by Mike
08:51
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\Reflector\AssemblerAbstract;
20
use phpDocumentor\Descriptor\Filter\Filter;
21
use phpDocumentor\Descriptor\Filter\Filterable;
22
use phpDocumentor\Descriptor\ProjectDescriptor\Settings;
23
use phpDocumentor\Reflection\Php\Project;
24
use Psr\Log\LogLevel;
25
26
/**
27
 * Builds a Project Descriptor and underlying tree.
28
 */
29
class ProjectDescriptorBuilder
30
{
31
    /** @var string */
32
    const DEFAULT_PROJECT_NAME = 'Untitled project';
33
34
    /** @var AssemblerFactory $assemblerFactory */
35
    protected $assemblerFactory;
36
37
    /** @var Filter $filter */
38
    protected $filter;
39
40
    /** @var ProjectDescriptor $project */
41
    protected $project;
42
43
    private $defaultPackage;
44
45
    public function __construct(AssemblerFactory $assemblerFactory, Filter $filterManager)
46
    {
47
        $this->assemblerFactory = $assemblerFactory;
48
        $this->filter = $filterManager;
49
    }
50
51 1
    public function createProjectDescriptor()
52
    {
53 1
        $this->project = new ProjectDescriptor(self::DEFAULT_PROJECT_NAME);
54 1
    }
55
56 1
    public function setProjectDescriptor(ProjectDescriptor $projectDescriptor)
57
    {
58 1
        $this->project = $projectDescriptor;
59 1
    }
60
61
    /**
62
     * Returns the project descriptor that is being built.
63
     *
64
     * @return ProjectDescriptor
65
     */
66 2
    public function getProjectDescriptor()
67
    {
68 2
        return $this->project;
69
    }
70
71
    /**
72
     * Verifies whether the given visibility is allowed to be included in the Descriptors.
73
     *
74
     * This method is used anytime a Descriptor is added to a collection (for example, when adding a Method to a Class)
75
     * to determine whether the visibility of that element is matches what the user has specified when it ran
76
     * phpDocumentor.
77
     *
78
     * @param string|integer $visibility One of the visibility constants of the ProjectDescriptor class or the words
79
     *     'public', 'protected', 'private' or 'internal'.
80
     *
81
     * @see ProjectDescriptor where the visibility is stored and that declares the constants to use.
82
     *
83
     * @return boolean
84
     */
85 1
    public function isVisibilityAllowed($visibility)
86
    {
87
        switch ($visibility) {
88 1
            case 'public':
89
                $visibility = Settings::VISIBILITY_PUBLIC;
90
                break;
91 1
            case 'protected':
92
                $visibility = Settings::VISIBILITY_PROTECTED;
93
                break;
94 1
            case 'private':
95
                $visibility = Settings::VISIBILITY_PRIVATE;
96
                break;
97 1
            case 'internal':
98
                $visibility = Settings::VISIBILITY_INTERNAL;
99
                break;
100
        }
101
102 1
        return $this->getProjectDescriptor()->isVisibilityAllowed($visibility);
103
    }
104
105
    /**
106
     * Takes the given data and attempts to build a Descriptor from it.
107
     *
108
     * @param mixed $data
109
     *
110
     * @throws \InvalidArgumentException if no Assembler could be found that matches the given data.
111
     *
112
     * @return DescriptorAbstract|Collection|null
113
     */
114
    public function buildDescriptor($data)
115
    {
116
        $assembler = $this->getAssembler($data);
117
        if (!$assembler) {
118
            throw new \InvalidArgumentException(
119
                'Unable to build a Descriptor; the provided data did not match any Assembler ' . get_class($data)
120
            );
121
        }
122
123
        if ($assembler instanceof Builder\AssemblerAbstract) {
124
            $assembler->setBuilder($this);
125
        }
126
127
        // create Descriptor and populate with the provided data
128
        $descriptor = $assembler->create($data);
129
        if (!$descriptor) {
130
            return null;
131
        }
132
133
        return (!is_array($descriptor) && (!$descriptor instanceof Collection))
134
            ? $this->filterDescriptor($descriptor)
135
            : $this->filterEachDescriptor($descriptor);
136
    }
137
138
    /**
139
     * Attempts to find an assembler matching the given data.
140
     *
141
     * @param mixed $data
142
     *
143
     * @return AssemblerAbstract
144
     */
145
    public function getAssembler($data)
146
    {
147
        return $this->assemblerFactory->get($data);
148
    }
149
150
    /**
151
     * Analyzes a Descriptor and alters its state based on its state or even removes the descriptor.
152
     *
153
     * @return Filterable
154
     */
155
    public function filter(Filterable $descriptor)
156
    {
157
        return $this->filter->filter($descriptor);
158
    }
159
160
    /**
161
     * Filters each descriptor, validates them, stores the validation results and returns a collection of transmuted
162
     * objects.
163
     *
164
     * @param DescriptorAbstract[] $descriptor
165
     *
166
     * @return Collection
167
     */
168
    private function filterEachDescriptor($descriptor)
169
    {
170
        $descriptors = new Collection();
171
        foreach ($descriptor as $key => $item) {
172
            $item = $this->filterDescriptor($item);
173
            if (!$item) {
174
                continue;
175
            }
176
177
            $descriptors[$key] = $item;
178
        }
179
180
        return $descriptors;
181
    }
182
183
    /**
184
     * Filters a descriptor, validates it, stores the validation results and returns the transmuted object or null
185
     * if it is supposed to be removed.
186
     *
187
     * @param DescriptorAbstract $descriptor
188
     *
189
     * @return DescriptorAbstract|null
190
     */
191
    protected function filterDescriptor($descriptor)
192
    {
193
        if (!$descriptor instanceof Filterable) {
194
            return $descriptor;
195
        }
196
197
        // filter the descriptor; this may result in the descriptor being removed!
198
        $descriptor = $this->filter($descriptor);
199
        if (!$descriptor) {
200
            return null;
201
        }
202
203
        return $descriptor;
204
    }
205
206
    /**
207
     * Map error code to severity.
208
     *
209
     * @param int $code
210
     *
211
     * @return string
212
     */
213
    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...
214
    {
215
        return LogLevel::ERROR;
216
    }
217
218
    public function build(Project $project)
219
    {
220
        $packageName = $project->getRootNamespace()->getFqsen()->getName();
221
        $this->defaultPackage = new PackageDescriptor();
222
        $this->defaultPackage->setFullyQualifiedStructuralElementName((string) $project->getRootNamespace()->getFqsen());
223
        $this->defaultPackage->setName($packageName);
224
        $this->defaultPackage->setNamespace(
225
            substr((string) $project->getRootNamespace()->getFqsen(), 0, -strlen($packageName) - 1)
226
        );
227
228
        foreach ($project->getFiles() as $file) {
229
            $descriptor = $this->buildDescriptor($file);
230
            if (!$descriptor) {
231
                return;
232
            }
233
234
            $this->getProjectDescriptor()->getFiles()->set($descriptor->getPath(), $descriptor);
235
        }
236
237
        $namespaces = $this->getProjectDescriptor()->getIndexes()->get('namespaces', new Collection());
238
//        $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...
239
240
        foreach ($project->getNamespaces() as $namespace) {
241
            $namespaces->set((string) $namespace->getFqsen(), $this->buildDescriptor($namespace));
242
        }
243
    }
244
245
    public function getDefaultPackage()
246
    {
247
        return $this->defaultPackage;
248
    }
249
}
250