Completed
Pull Request — master (#601)
by
unknown
02:47
created

DocumentGenerator   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 245
Duplicated Lines 8.98 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 5
Bugs 0 Features 1
Metric Value
wmc 27
c 5
b 0
f 1
lcom 1
cbo 0
dl 22
loc 245
rs 10

9 Methods

Rating   Name   Duplication   Size   Complexity  
A generateDocumentClass() 0 15 1
A generateDocumentBody() 0 14 3
A generateDocumentProperties() 11 11 2
A generateDocumentMethods() 11 11 2
A generateDocumentMethod() 0 17 1
C generatePropertyDocBlock() 0 39 11
A generateDocumentDocBlock() 0 17 2
A prefixWithSpaces() 0 12 3
A getClassName() 0 5 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
/*
4
 * This file is part of the ONGR package.
5
 *
6
 * (c) NFQ Technologies UAB <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace ONGR\ElasticsearchBundle\Generator;
13
14
/**
15
 * Document Generator
16
 */
17
class DocumentGenerator
18
{
19
    /**
20
     * @var string
21
     */
22
    private $spaces = '    ';
23
24
    /**
25
     * @var string
26
     */
27
    private $getMethodTemplate =
0 ignored issues
show
Unused Code introduced by
The property $getMethodTemplate is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
28
        '/**
29
 * <description>
30
 *
31
 * @return string
32
 */
33
public function <methodName>()
34
{
35
<spaces>return $this-><fieldName>;
36
}';
37
38
    /**
39
     * @var string
40
     */
41
    private $setMethodTemplate =
0 ignored issues
show
Unused Code introduced by
The property $setMethodTemplate is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
42
        '/**
43
 * <description>
44
 *
45
 * @param string $<variableName>
46
 */
47
public function <methodName>($<variableName>)
48
{
49
<spaces>$this-><fieldName> = $<variableName>;
50
}';
51
52
    /**
53
     * @param array $metadata
54
     *
55
     * @return string
56
     */
57
    public function generateDocumentClass(array $metadata)
58
    {
59
        $lines = [];
60
61
        $lines[] = "<?php\n";
62
        $lines[] = sprintf('namespace %s;', substr($metadata['name'], 0, strrpos($metadata['name'], '\\'))) . "\n";
63
        $lines[] = "use ONGR\\ElasticsearchBundle\\Annotation as ES;\n";
64
        $lines[] = $this->generateDocumentDocBlock($metadata);
65
        $lines[] = 'class ' . $this->getClassName($metadata);
66
        $lines[] = "{";
67
        $lines[] = str_replace('<spaces>', $this->spaces, $this->generateDocumentBody($metadata));
68
        $lines[] = "}\n";
69
70
        return implode("\n", $lines);
71
    }
72
73
    /**
74
     * Generates document body
75
     *
76
     * @param array $metadata
77
     *
78
     * @return string
79
     */
80
    private function generateDocumentBody(array $metadata)
81
    {
82
        $lines = [];
83
84
        if ($properties = $this->generateDocumentProperties($metadata)) {
85
            $lines[] = $properties;
86
        }
87
88
        if ($methods = $this->generateDocumentMethods($metadata)) {
89
            $lines[] = $methods;
90
        }
91
92
        return rtrim(implode("\n", $lines));
93
    }
94
95
    /**
96
     * Generates document properties
97
     *
98
     * @param array $metadata
99
     *
100
     * @return string
101
     */
102 View Code Duplication
    private function generateDocumentProperties(array $metadata)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
103
    {
104
        $lines = [];
105
106
        foreach ($metadata['properties'] as $property) {
107
            $lines[] = $this->generatePropertyDocBlock($property);
108
            $lines[] = $this->spaces . 'private $' . $property['field_name'] . ";\n";
109
        }
110
111
        return implode("\n", $lines);
112
    }
113
114
    /**
115
     * Generates document methods
116
     *
117
     * @param array $metadata
118
     *
119
     * @return string
120
     */
121 View Code Duplication
    private function generateDocumentMethods(array $metadata)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
122
    {
123
        $lines = [];
124
125
        foreach ($metadata['properties'] as $property) {
126
            $lines[] = $this->generateDocumentMethod($property, 'set') . "\n";
127
            $lines[] = $this->generateDocumentMethod($property, 'get') . "\n";
128
        }
129
130
        return implode("\n", $lines);
131
    }
132
133
    /**
134
     * Generates document method
135
     *
136
     * @param array  $metadata
137
     * @param string $type
138
     *
139
     * @return string
140
     */
141
    private function generateDocumentMethod(array $metadata, $type)
142
    {
143
        $replacements = [
144
            '<description>' => ucfirst($type) . ' ' . $metadata['field_name'],
145
            '<variableName>'      => $metadata['field_name'],
146
            '<methodName>'        => $type . ucfirst($metadata['field_name']),
147
            '<fieldName>'         => $metadata['field_name'],
148
        ];
149
150
        return $this->prefixWithSpaces(
151
            str_replace(
152
                array_keys($replacements),
153
                array_values($replacements),
154
                $this->{$type . 'MethodTemplate'}
155
            )
156
        );
157
    }
158
159
    /**
160
     * Returns property doc block
161
     *
162
     * @param array $metadata
163
     *
164
     * @return string
165
     */
166
    private function generatePropertyDocBlock(array $metadata)
167
    {
168
        $lines = [
169
            $this->spaces . '/**',
170
            $this->spaces . ' * @var string',
171
            $this->spaces . ' *',
172
        ];
173
174
        $column = [];
175
        if (isset($metadata['property_name']) && $metadata['property_name'] != $metadata['field_name']) {
176
            $column[] = 'name="' . $metadata['property_name'] . '"';
177
        }
178
179
        if (isset($metadata['property_class'])) {
180
            $column[] = 'class="' . $metadata['property_class'] . '"';
181
        }
182
183
        if (isset($metadata['property_multiple']) && $metadata['property_multiple']) {
184
            $column[] = 'multiple=true';
185
        }
186
187
        if (isset($metadata['property_type']) && $metadata['annotation'] == 'Property') {
188
            $column[] = 'type="' . $metadata['property_type'] . '"';
189
        }
190
191
        if (isset($metadata['property_default'])) {
192
            $column[] = 'default="' . $metadata['property_default'] . '"';
193
        }
194
195
        if (isset($metadata['property_options'])  && $metadata['property_options']) {
196
            $column[] = 'options={' . $metadata['property_options'] . '}';
197
        }
198
199
        $lines[] = $this->spaces . ' * @ES\\' . $metadata['annotation'] . '(' . implode(', ', $column) . ')';
200
201
        $lines[] = $this->spaces . ' */';
202
203
        return implode("\n", $lines);
204
    }
205
206
    /**
207
     * Generates document doc block
208
     *
209
     * @param array $metadata
210
     *
211
     * @return string
212
     */
213
    private function generateDocumentDocBlock(array $metadata)
214
    {
215
        return str_replace(
216
            ['<className>', '<annotation>', '<options>'],
217
            [
218
                $this->getClassName($metadata),
219
                $metadata['annotation'],
220
                $metadata['type'] != lcfirst($this->getClassName($metadata))
221
                    ? sprintf('type="%s"', $metadata['type']) : '',
222
            ],
223
            '/**
224
 * <className>
225
 *
226
 * @ES\<annotation>(<options>)
227
 */'
228
        );
229
    }
230
231
    /**
232
     * @param string $code
233
     *
234
     * @return string
235
     */
236
    private function prefixWithSpaces($code)
237
    {
238
        $lines = explode("\n", $code);
239
240
        foreach ($lines as $key => $value) {
241
            if ($value) {
242
                $lines[$key] = $this->spaces . $lines[$key];
243
            }
244
        }
245
246
        return implode("\n", $lines);
247
    }
248
249
    /**
250
     * Returns class name
251
     *
252
     * @param array $metadata
253
     *
254
     * @return string
255
     */
256
    private function getClassName(array $metadata)
257
    {
258
        return ($pos = strrpos($metadata['name'], '\\'))
259
            ? substr($metadata['name'], $pos + 1, strlen($metadata['name'])) : $metadata['name'];
260
    }
261
}
262