Completed
Push — develop ( 8eb671...133594 )
by Mike
19:30 queued 09:24
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 ' .
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);
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