Completed
Push — develop ( 0b8425...c51867 )
by Jaap
15s queued 11s
created

Descriptor/ProjectDescriptorBuilder.php (1 issue)

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 ' . get_class($data)
121
            );
122
        }
123
124
        if ($assembler instanceof Builder\AssemblerAbstract) {
125
            $assembler->setBuilder($this);
126
        }
127
128
        // create Descriptor and populate with the provided data
129
        $descriptor = $assembler->create($data);
130
        if (!$descriptor) {
131
            return null;
132
        }
133
134
        return (!is_array($descriptor) && (!$descriptor instanceof Collection))
135
            ? $this->filterDescriptor($descriptor)
136
            : $this->filterEachDescriptor($descriptor);
137
    }
138
139
    /**
140
     * Attempts to find an assembler matching the given data.
141
     *
142
     * @param mixed $data
143
     *
144
     * @return AssemblerInterface|null
145
     */
146
    public function getAssembler($data)
147
    {
148
        return $this->assemblerFactory->get($data);
149
    }
150
151
    /**
152
     * Analyzes a Descriptor and alters its state based on its state or even removes the descriptor.
153
     *
154
     * @return Filterable
155
     */
156
    public function filter(Filterable $descriptor)
157
    {
158
        return $this->filter->filter($descriptor);
159
    }
160
161
    /**
162
     * Filters each descriptor, validates them, stores the validation results and returns a collection of transmuted
163
     * objects.
164
     *
165
     * @param DescriptorAbstract[] $descriptor
166
     *
167
     * @return Collection
168
     */
169
    private function filterEachDescriptor($descriptor)
170
    {
171
        $descriptors = new Collection();
172
        foreach ($descriptor as $key => $item) {
173
            $item = $this->filterDescriptor($item);
174
            if (!$item) {
175
                continue;
176
            }
177
178
            $descriptors[$key] = $item;
179
        }
180
181
        return $descriptors;
182
    }
183
184
    /**
185
     * Filters a descriptor, validates it, stores the validation results and returns the transmuted object or null
186
     * if it is supposed to be removed.
187
     *
188
     * @param Descriptor $descriptor
189
     *
190
     * @return Descriptor|null
191
     */
192
    protected function filterDescriptor(Descriptor $descriptor)
193
    {
194
        if (!$descriptor instanceof Filterable) {
195
            return $descriptor;
196
        }
197
198
        // filter the descriptor; this may result in the descriptor being removed!
199
        $descriptor = $this->filter($descriptor);
200
        if (!$descriptor) {
201
            return null;
202
        }
203
204
        return $descriptor;
205
    }
206
207
    /**
208
     * Map error code to severity.
209
     *
210
     * @param int $code
211
     *
212
     * @return string
213
     */
214
    protected function mapCodeToSeverity($code)
215
    {
216
        return LogLevel::ERROR;
217
    }
218
219
    public function build(Project $project)
220
    {
221
        $packageName = $project->getRootNamespace()->getFqsen()->getName();
222
        $this->defaultPackage = new PackageDescriptor();
223
        $this->defaultPackage->setFullyQualifiedStructuralElementName((string) $project->getRootNamespace()->getFqsen());
224
        $this->defaultPackage->setName($packageName);
225
        $this->defaultPackage->setNamespace(
226
            substr((string) $project->getRootNamespace()->getFqsen(), 0, -strlen($packageName) - 1)
227
        );
228
229
        foreach ($project->getFiles() as $file) {
230
            $descriptor = $this->buildDescriptor($file);
231
            if (!$descriptor) {
232
                return;
233
            }
234
235
            $this->getProjectDescriptor()->getFiles()->set($descriptor->getPath(), $descriptor);
236
        }
237
238
        $namespaces = $this->getProjectDescriptor()->getIndexes()->get('namespaces', new Collection());
239
//        $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...
240
241
        foreach ($project->getNamespaces() as $namespace) {
242
            $namespaces->set((string) $namespace->getFqsen(), $this->buildDescriptor($namespace));
243
        }
244
    }
245
246
    public function getDefaultPackage()
247
    {
248
        return $this->defaultPackage;
249
    }
250
}
251