ClassDefinition::createUseStatement()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 12
c 0
b 0
f 0
dl 0
loc 17
rs 9.8666
cc 2
nc 2
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Jellyfish\Transfer\Definition;
6
7
use RuntimeException;
8
9
use function sprintf;
10
11
class ClassDefinition implements ClassDefinitionInterface
12
{
13
    public const NAMESPACE_PREFIX = 'Generated\\Transfer';
14
    public const NAMESPACE_SEPARATOR = '\\';
15
    public const FACTORY_NAME_SUFFIX = 'Factory';
16
17
    protected const PATTERN_ID = '/(?<=\\w)(?=[A-Z])/';
18
    protected const REPLACEMENT_ID = '_$1';
19
20
    /**
21
     * @var string
22
     */
23
    protected $name;
24
25
    /**
26
     * @var string|null
27
     */
28
    protected $namespace;
29
30
    /**
31
     * @var \Jellyfish\Transfer\Definition\ClassPropertyDefinition[]
32
     */
33
    protected $properties;
34
35
    /**
36
     * @return string
37
     */
38
    public function getId(): string
39
    {
40
        $id = static::NAMESPACE_PREFIX;
41
42
        if ($this->namespace !== null) {
43
            $id .= $this->namespace;
44
        }
45
46
        $id .= $this->name;
47
        $id = \str_replace('\\', '', $id);
48
        $id = @\preg_replace(static::PATTERN_ID, static::REPLACEMENT_ID, $id);
49
50
        if ($id === null) {
51
            throw new RuntimeException('Could not perform a regular expression search and replace.');
52
        }
53
54
        return \strtolower($id);
55
    }
56
57
    /**
58
     * @return string
59
     */
60
    public function getName(): string
61
    {
62
        return $this->name;
63
    }
64
65
    /**
66
     * @param string $name
67
     *
68
     * @return \Jellyfish\Transfer\Definition\ClassDefinitionInterface
69
     */
70
    public function setName(string $name): ClassDefinitionInterface
71
    {
72
        $this->name = $name;
73
74
        return $this;
75
    }
76
77
    /**
78
     * @return string|null
79
     */
80
    public function getNamespace(): ?string
81
    {
82
        return $this->namespace;
83
    }
84
85
    /**
86
     * @param string|null $namespace
87
     *
88
     * @return \Jellyfish\Transfer\Definition\ClassDefinitionInterface
89
     */
90
    public function setNamespace(?string $namespace): ClassDefinitionInterface
91
    {
92
        $this->namespace = $namespace;
93
94
        return $this;
95
    }
96
97
    /**
98
     * @return string
99
     */
100
    public function getNamespaceStatement(): string
101
    {
102
        return sprintf('namespace %s\\%s;', static::NAMESPACE_PREFIX, $this->namespace);
103
    }
104
105
    /**
106
     * @return array
107
     */
108
    public function getUseStatements(): array
109
    {
110
        $useStatements = [];
111
112
        foreach ($this->properties as $property) {
113
            if (!$this->canCreateUseStatement($property)) {
114
                continue;
115
            }
116
117
            $useStatement = $this->createUseStatement($property);
118
            $useStatementKey = \sha1($useStatement);
119
120
            if (array_key_exists($useStatementKey, $useStatements)) {
121
                continue;
122
            }
123
124
            $useStatements[$useStatementKey] = $useStatement;
125
        }
126
127
        return $useStatements;
128
    }
129
130
    /**
131
     * @param \Jellyfish\Transfer\Definition\ClassPropertyDefinitionInterface $property
132
     *
133
     * @return bool
134
     */
135
    protected function canCreateUseStatement(ClassPropertyDefinitionInterface $property): bool
136
    {
137
        return $property->isPrimitive() === false
138
            && ($property->getTypeNamespace() !== $this->namespace || $property->getTypeAlias() !== null);
139
    }
140
141
    /**
142
     * @param \Jellyfish\Transfer\Definition\ClassPropertyDefinitionInterface $property
143
     *
144
     * @return string
145
     */
146
    protected function createUseStatement(ClassPropertyDefinitionInterface $property): string
147
    {
148
        if ($property->getTypeAlias() === null) {
149
            return sprintf(
150
                'use %s\\%s\\%s;',
151
                static::NAMESPACE_PREFIX,
152
                $property->getTypeNamespace(),
153
                $property->getType()
154
            );
155
        }
156
157
        return sprintf(
158
            'use %s\\%s\\%s as %s;',
159
            static::NAMESPACE_PREFIX,
160
            $property->getTypeNamespace(),
161
            $property->getType(),
162
            $property->getTypeAlias()
163
        );
164
    }
165
166
    /**
167
     * @return \Jellyfish\Transfer\Definition\ClassPropertyDefinition[]
168
     */
169
    public function getProperties(): array
170
    {
171
        return $this->properties;
172
    }
173
174
    /**
175
     * @param \Jellyfish\Transfer\Definition\ClassPropertyDefinition[] $properties
176
     *
177
     * @return \Jellyfish\Transfer\Definition\ClassDefinitionInterface
178
     */
179
    public function setProperties(array $properties): ClassDefinitionInterface
180
    {
181
        $this->properties = $properties;
182
183
        return $this;
184
    }
185
}
186