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)
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...
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);
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